xref: /linux-6.15/scripts/checkpatch.pl (revision 4ce9f970)
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";
66bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
6752178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
68ced69da1SQuentin Monnetmy $typedefsfile;
69737c0767SJohn Brooksmy $color = "auto";
7098005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
71dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
72dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
73713a09deSAntonio Borneomy $tabsize = 8;
743e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_";
7577f5b10aSHannes Eder
7677f5b10aSHannes Edersub help {
7777f5b10aSHannes Eder	my ($exitcode) = @_;
7877f5b10aSHannes Eder
7977f5b10aSHannes Eder	print << "EOM";
8077f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
8177f5b10aSHannes EderVersion: $V
8277f5b10aSHannes Eder
8377f5b10aSHannes EderOptions:
8477f5b10aSHannes Eder  -q, --quiet                quiet
8552178ce0SDwaipayan Ray  -v, --verbose              verbose mode
8677f5b10aSHannes Eder  --no-tree                  run without a kernel tree
8777f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
8877f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
8977f5b10aSHannes Eder  --emacs                    emacs compile window format
9077f5b10aSHannes Eder  --terse                    one line per report
9134d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
924a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
934a593c34SDu, Changbin                             single git commit with:
944a593c34SDu, Changbin                               <rev>
954a593c34SDu, Changbin                               <rev>^
964a593c34SDu, Changbin                               <rev>~n
974a593c34SDu, Changbin                             multiple git commits with:
984a593c34SDu, Changbin                               <rev1>..<rev2>
994a593c34SDu, Changbin                               <rev1>...<rev2>
1004a593c34SDu, Changbin                               <rev>-<count>
1014a593c34SDu, Changbin                             git merges are ignored
10277f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
10377f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
1043beb42ecSJoe Perches  --list-types               list the possible message types
10591bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
106000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1073beb42ecSJoe Perches  --show-types               show the specific message type in the output
108bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
109bdc48fa1SJoe Perches                             if exceeded, warn on patches
110bdc48fa1SJoe Perches                             requires --strict for use with --file
11156193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
112bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
11377f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
11477f5b10aSHannes Eder  --no-summary               suppress the per-file summary
11577f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
11677f5b10aSHannes Eder  --summary-file             include the filename in summary
11777f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
11877f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
11977f5b10aSHannes Eder                             is all off)
12077f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
12177f5b10aSHannes Eder                             literally
1223705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1233705ce5bSJoe Perches                             If correctable single-line errors exist, create
1243705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1253705ce5bSJoe Perches                             with potential errors corrected to the preferred
1263705ce5bSJoe Perches                             checkpatch style
1279624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1289624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1299624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
130d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
131d62a201fSDave Hansen                             runtime errors.
132ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
133f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
134ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
13575ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
136737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
137737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
1383e89ad85SJerome Forissier  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1393e89ad85SJerome Forissier                             ${CONFIG_})
14077f5b10aSHannes Eder  -h, --help, --version      display this help and exit
14177f5b10aSHannes Eder
14277f5b10aSHannes EderWhen FILE is - read standard input.
14377f5b10aSHannes EderEOM
14477f5b10aSHannes Eder
14577f5b10aSHannes Eder	exit($exitcode);
14677f5b10aSHannes Eder}
14777f5b10aSHannes Eder
1483beb42ecSJoe Perchessub uniq {
1493beb42ecSJoe Perches	my %seen;
1503beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1513beb42ecSJoe Perches}
1523beb42ecSJoe Perches
1533beb42ecSJoe Perchessub list_types {
1543beb42ecSJoe Perches	my ($exitcode) = @_;
1553beb42ecSJoe Perches
1563beb42ecSJoe Perches	my $count = 0;
1573beb42ecSJoe Perches
1583beb42ecSJoe Perches	local $/ = undef;
1593beb42ecSJoe Perches
1603beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1613beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1623beb42ecSJoe Perches
1633beb42ecSJoe Perches	my $text = <$script>;
1643beb42ecSJoe Perches	close($script);
1653beb42ecSJoe Perches
16652178ce0SDwaipayan Ray	my %types = ();
1670547fa58SJean Delvare	# Also catch when type or level is passed through a variable
16852178ce0SDwaipayan Ray	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
16952178ce0SDwaipayan Ray		if (defined($1)) {
17052178ce0SDwaipayan Ray			if (exists($types{$2})) {
17152178ce0SDwaipayan Ray				$types{$2} .= ",$1" if ($types{$2} ne $1);
17252178ce0SDwaipayan Ray			} else {
17352178ce0SDwaipayan Ray				$types{$2} = $1;
1743beb42ecSJoe Perches			}
17552178ce0SDwaipayan Ray		} else {
17652178ce0SDwaipayan Ray			$types{$2} = "UNDETERMINED";
17752178ce0SDwaipayan Ray		}
17852178ce0SDwaipayan Ray	}
17952178ce0SDwaipayan Ray
1803beb42ecSJoe Perches	print("#\tMessage type\n\n");
18152178ce0SDwaipayan Ray	if ($color) {
18252178ce0SDwaipayan Ray		print(" ( Color coding: ");
18352178ce0SDwaipayan Ray		print(RED . "ERROR" . RESET);
18452178ce0SDwaipayan Ray		print(" | ");
18552178ce0SDwaipayan Ray		print(YELLOW . "WARNING" . RESET);
18652178ce0SDwaipayan Ray		print(" | ");
18752178ce0SDwaipayan Ray		print(GREEN . "CHECK" . RESET);
18852178ce0SDwaipayan Ray		print(" | ");
18952178ce0SDwaipayan Ray		print("Multiple levels / Undetermined");
19052178ce0SDwaipayan Ray		print(" )\n\n");
19152178ce0SDwaipayan Ray	}
19252178ce0SDwaipayan Ray
19352178ce0SDwaipayan Ray	foreach my $type (sort keys %types) {
19452178ce0SDwaipayan Ray		my $orig_type = $type;
19552178ce0SDwaipayan Ray		if ($color) {
19652178ce0SDwaipayan Ray			my $level = $types{$type};
19752178ce0SDwaipayan Ray			if ($level eq "ERROR") {
19852178ce0SDwaipayan Ray				$type = RED . $type . RESET;
19952178ce0SDwaipayan Ray			} elsif ($level eq "WARN") {
20052178ce0SDwaipayan Ray				$type = YELLOW . $type . RESET;
20152178ce0SDwaipayan Ray			} elsif ($level eq "CHK") {
20252178ce0SDwaipayan Ray				$type = GREEN . $type . RESET;
20352178ce0SDwaipayan Ray			}
20452178ce0SDwaipayan Ray		}
2053beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
20652178ce0SDwaipayan Ray		if ($verbose && exists($verbose_messages{$orig_type})) {
20752178ce0SDwaipayan Ray			my $message = $verbose_messages{$orig_type};
20852178ce0SDwaipayan Ray			$message =~ s/\n/\n\t/g;
20952178ce0SDwaipayan Ray			print("\t" . $message . "\n\n");
21052178ce0SDwaipayan Ray		}
2113beb42ecSJoe Perches	}
2123beb42ecSJoe Perches
2133beb42ecSJoe Perches	exit($exitcode);
2143beb42ecSJoe Perches}
2153beb42ecSJoe Perches
216000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
217000d1cc1SJoe Perchesif (-f $conf) {
218000d1cc1SJoe Perches	my @conf_args;
219000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
220000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
221000d1cc1SJoe Perches
222000d1cc1SJoe Perches	while (<$conffile>) {
223000d1cc1SJoe Perches		my $line = $_;
224000d1cc1SJoe Perches
225000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
226000d1cc1SJoe Perches		$line =~ s/^\s*//g;
227000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
228000d1cc1SJoe Perches
229000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
230000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
231000d1cc1SJoe Perches
232000d1cc1SJoe Perches		my @words = split(" ", $line);
233000d1cc1SJoe Perches		foreach my $word (@words) {
234000d1cc1SJoe Perches			last if ($word =~ m/^#/);
235000d1cc1SJoe Perches			push (@conf_args, $word);
236000d1cc1SJoe Perches		}
237000d1cc1SJoe Perches	}
238000d1cc1SJoe Perches	close($conffile);
239000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
240000d1cc1SJoe Perches}
241000d1cc1SJoe Perches
24252178ce0SDwaipayan Raysub load_docs {
24352178ce0SDwaipayan Ray	open(my $docs, '<', "$docsfile")
24452178ce0SDwaipayan Ray	    or warn "$P: Can't read the documentation file $docsfile $!\n";
24552178ce0SDwaipayan Ray
24652178ce0SDwaipayan Ray	my $type = '';
24752178ce0SDwaipayan Ray	my $desc = '';
24852178ce0SDwaipayan Ray	my $in_desc = 0;
24952178ce0SDwaipayan Ray
25052178ce0SDwaipayan Ray	while (<$docs>) {
25152178ce0SDwaipayan Ray		chomp;
25252178ce0SDwaipayan Ray		my $line = $_;
25352178ce0SDwaipayan Ray		$line =~ s/\s+$//;
25452178ce0SDwaipayan Ray
25552178ce0SDwaipayan Ray		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
25652178ce0SDwaipayan Ray			if ($desc ne '') {
25752178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
25852178ce0SDwaipayan Ray			}
25952178ce0SDwaipayan Ray			$type = $1;
26052178ce0SDwaipayan Ray			$desc = '';
26152178ce0SDwaipayan Ray			$in_desc = 1;
26252178ce0SDwaipayan Ray		} elsif ($in_desc) {
26352178ce0SDwaipayan Ray			if ($line =~ /^(?:\s{4,}|$)/) {
26452178ce0SDwaipayan Ray				$line =~ s/^\s{4}//;
26552178ce0SDwaipayan Ray				$desc .= $line;
26652178ce0SDwaipayan Ray				$desc .= "\n";
26752178ce0SDwaipayan Ray			} else {
26852178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
26952178ce0SDwaipayan Ray				$type = '';
27052178ce0SDwaipayan Ray				$desc = '';
27152178ce0SDwaipayan Ray				$in_desc = 0;
27252178ce0SDwaipayan Ray			}
27352178ce0SDwaipayan Ray		}
27452178ce0SDwaipayan Ray	}
27552178ce0SDwaipayan Ray
27652178ce0SDwaipayan Ray	if ($desc ne '') {
27752178ce0SDwaipayan Ray		$verbose_messages{$type} = trim($desc);
27852178ce0SDwaipayan Ray	}
27952178ce0SDwaipayan Ray	close($docs);
28052178ce0SDwaipayan Ray}
28152178ce0SDwaipayan Ray
282737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
283737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
284737c0767SJohn Brooksforeach (@ARGV) {
285737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
286737c0767SJohn Brooks		$_ = "--color=$color";
287737c0767SJohn Brooks	}
288737c0767SJohn Brooks}
289737c0767SJohn Brooks
2900a920b5bSAndy WhitcroftGetOptions(
2916c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
29252178ce0SDwaipayan Ray	'v|verbose!'	=> \$verbose,
2930a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2940a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2950a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2966c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2978905a67cSAndy Whitcroft	'terse!'	=> \$terse,
29834d8815fSJoe Perches	'showfile!'	=> \$showfile,
29977f5b10aSHannes Eder	'f|file!'	=> \$file,
3004a593c34SDu, Changbin	'g|git!'	=> \$git,
3016c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
3026c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
303000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
30491bfe484SJoe Perches	'types=s'	=> \@use,
305000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
3063beb42ecSJoe Perches	'list-types!'	=> \$list_types,
3076cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
30856193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
309713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
3106c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
3118905a67cSAndy Whitcroft	'summary!'	=> \$summary,
3128905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
31313214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
3143705ce5bSJoe Perches	'fix!'		=> \$fix,
3159624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
316d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
317c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
318773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
319ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
320ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
32175ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
322737c0767SJohn Brooks	'color=s'	=> \$color,
323737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
324737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
3253e89ad85SJerome Forissier	'kconfig-prefix=s'	=> \${CONFIG_},
32677f5b10aSHannes Eder	'h|help'	=> \$help,
32777f5b10aSHannes Eder	'version'	=> \$help
32877f5b10aSHannes Eder) or help(1);
32977f5b10aSHannes Eder
33077f5b10aSHannes Ederhelp(0) if ($help);
3310a920b5bSAndy Whitcroft
33252178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
33352178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
33452178ce0SDwaipayan Ray
33552178ce0SDwaipayan Rayif ($color =~ /^[01]$/) {
33652178ce0SDwaipayan Ray	$color = !$color;
33752178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) {
33852178ce0SDwaipayan Ray	$color = 1;
33952178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) {
34052178ce0SDwaipayan Ray	$color = 0;
34152178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) {
34252178ce0SDwaipayan Ray	$color = (-t STDOUT);
34352178ce0SDwaipayan Ray} else {
34452178ce0SDwaipayan Ray	die "$P: Invalid color mode: $color\n";
34552178ce0SDwaipayan Ray}
34652178ce0SDwaipayan Ray
34752178ce0SDwaipayan Rayload_docs() if ($verbose);
3483beb42ecSJoe Percheslist_types(0) if ($list_types);
3493beb42ecSJoe Perches
3509624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
3512ac73b4fSJoe Perches$check_orig = $check;
3529624b8d6SJoe Perches
3530a920b5bSAndy Whitcroftmy $exit = 0;
3540a920b5bSAndy Whitcroft
3555b57980dSJoe Perchesmy $perl_version_ok = 1;
356d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
3575b57980dSJoe Perches	$perl_version_ok = 0;
358d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
3595b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
360d62a201fSDave Hansen}
361d62a201fSDave Hansen
36245107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
3630a920b5bSAndy Whitcroftif ($#ARGV < 0) {
36445107ff6SAllen Hubbe	push(@ARGV, '-');
3650a920b5bSAndy Whitcroft}
3660a920b5bSAndy Whitcroft
367713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
36832f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
369713a09deSAntonio Borneo
37091bfe484SJoe Perchessub hash_save_array_words {
37191bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
37291bfe484SJoe Perches
37391bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
37491bfe484SJoe Perches	foreach my $word (@array) {
375000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
376000d1cc1SJoe Perches		$word =~ s/^\s*//g;
377000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
378000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
379000d1cc1SJoe Perches
380000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
381000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
382000d1cc1SJoe Perches
38391bfe484SJoe Perches		$hashRef->{$word}++;
384000d1cc1SJoe Perches	}
38591bfe484SJoe Perches}
38691bfe484SJoe Perches
38791bfe484SJoe Perchessub hash_show_words {
38891bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
38991bfe484SJoe Perches
3903c816e49SJoe Perches	if (keys %$hashRef) {
391d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
39258cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
39391bfe484SJoe Perches			print " $word";
39491bfe484SJoe Perches		}
395d8469f16SJoe Perches		print "\n";
39691bfe484SJoe Perches	}
39791bfe484SJoe Perches}
39891bfe484SJoe Perches
39991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
40091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
401000d1cc1SJoe Perches
402c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
403c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
4047429c690SAndy Whitcroftmy $dbg_type = 0;
405a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
406c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
40721caa13cSAndy Whitcroft	## no critic
40821caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
40921caa13cSAndy Whitcroft	die "$@" if ($@);
410c2fdda0dSAndy Whitcroft}
411c2fdda0dSAndy Whitcroft
412d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
413d2c0a235SAndy Whitcroft
4148905a67cSAndy Whitcroftif ($terse) {
4158905a67cSAndy Whitcroft	$emacs = 1;
4168905a67cSAndy Whitcroft	$quiet++;
4178905a67cSAndy Whitcroft}
4188905a67cSAndy Whitcroft
4196c72ffaaSAndy Whitcroftif ($tree) {
4206c72ffaaSAndy Whitcroft	if (defined $root) {
4216c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
4226c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
4236c72ffaaSAndy Whitcroft		}
4246c72ffaaSAndy Whitcroft	} else {
4256c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
4266c72ffaaSAndy Whitcroft			$root = '.';
4276c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
4286c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
4296c72ffaaSAndy Whitcroft			$root = $1;
4306c72ffaaSAndy Whitcroft		}
4316c72ffaaSAndy Whitcroft	}
4326c72ffaaSAndy Whitcroft
4336c72ffaaSAndy Whitcroft	if (!defined $root) {
4340a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
4350a920b5bSAndy Whitcroft		exit(2);
4360a920b5bSAndy Whitcroft	}
4376c72ffaaSAndy Whitcroft}
4386c72ffaaSAndy Whitcroft
4396c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
4406c72ffaaSAndy Whitcroft
4412ceb532bSAndy Whitcroftour $Ident	= qr{
4422ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
4432ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
4442ceb532bSAndy Whitcroft		}x;
4456c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
4466c72ffaaSAndy Whitcroftour $Sparse	= qr{
4476c72ffaaSAndy Whitcroft			__user|
4486c72ffaaSAndy Whitcroft			__kernel|
4496c72ffaaSAndy Whitcroft			__force|
4506c72ffaaSAndy Whitcroft			__iomem|
4516c72ffaaSAndy Whitcroft			__must_check|
452417495edSAndy Whitcroft			__kprobes|
453165e72a6SSven Eckelmann			__ref|
45433aa4597SGeert Uytterhoeven			__refconst|
45533aa4597SGeert Uytterhoeven			__refdata|
456ad315455SBoqun Feng			__rcu|
457ad315455SBoqun Feng			__private
4586c72ffaaSAndy Whitcroft		}x;
459e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
460e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
461e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
462e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
463e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
4648716de38SJoe Perches
46552131292SWolfram Sang# Notes to $Attribute:
46652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
4676c72ffaaSAndy Whitcroftour $Attribute	= qr{
4686c72ffaaSAndy Whitcroft			const|
469b5e8736aSJoe Perches			volatile|
47003f1df7dSJoe Perches			__percpu|
47103f1df7dSJoe Perches			__nocast|
47203f1df7dSJoe Perches			__safe|
47346d832f5SMichael S. Tsirkin			__bitwise|
47403f1df7dSJoe Perches			__packed__|
47503f1df7dSJoe Perches			__packed2__|
47603f1df7dSJoe Perches			__naked|
47703f1df7dSJoe Perches			__maybe_unused|
47803f1df7dSJoe Perches			__always_unused|
47903f1df7dSJoe Perches			__noreturn|
48003f1df7dSJoe Perches			__used|
48103f1df7dSJoe Perches			__cold|
482e23ef1f3SJoe Perches			__pure|
48303f1df7dSJoe Perches			__noclone|
48403f1df7dSJoe Perches			__deprecated|
4856c72ffaaSAndy Whitcroft			__read_mostly|
486c5967e98SJoe Perches			__ro_after_init|
4876c72ffaaSAndy Whitcroft			__kprobes|
4888716de38SJoe Perches			$InitAttribute|
48924e1d81aSAndy Whitcroft			____cacheline_aligned|
49024e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
4915fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
4925fe3af11SAndy Whitcroft			__weak
4936c72ffaaSAndy Whitcroft		  }x;
494c45dcabdSAndy Whitcroftour $Modifier;
49591cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
4966c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
4976c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
4986c72ffaaSAndy Whitcroft
49995e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
50095e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
50195e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
50295e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
5032435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
504d2af5aa6SJoe Perchesour $String	= qr{(?:\b[Lu])?"[X\t]*"};
505326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
506326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
507326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
50874349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
5092435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
510326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
511447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
51223f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
5136c72ffaaSAndy Whitcroftour $Operators	= qr{
5146c72ffaaSAndy Whitcroft			<=|>=|==|!=|
5156c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
51623f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
5176c72ffaaSAndy Whitcroft		  }x;
5186c72ffaaSAndy Whitcroft
51991cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
52091cb5195SJoe Perches
521ab7e23f3SJoe Perchesour $BasicType;
5228905a67cSAndy Whitcroftour $NonptrType;
5231813087dSJoe Perchesour $NonptrTypeMisordered;
5248716de38SJoe Perchesour $NonptrTypeWithAttr;
5258905a67cSAndy Whitcroftour $Type;
5261813087dSJoe Perchesour $TypeMisordered;
5278905a67cSAndy Whitcroftour $Declare;
5281813087dSJoe Perchesour $DeclareMisordered;
5298905a67cSAndy Whitcroft
53015662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
53115662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
532171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
533171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
534171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
535171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
536171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
537171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
538171ae1a4SAndy Whitcroft}x;
539171ae1a4SAndy Whitcroft
54015662b3eSJoe Perchesour $UTF8	= qr{
54115662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
54215662b3eSJoe Perches	| $NON_ASCII_UTF8
54315662b3eSJoe Perches}x;
54415662b3eSJoe Perches
545e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
546021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
547021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
548021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
549021158b4SJoe Perches)};
550e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
551fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
5528ed22cadSAndy Whitcroft	atomic_t
5538ed22cadSAndy Whitcroft)};
554e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
555e6176fa4SJoe Perches	$typeC99Typedefs\b|
556e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
557e6176fa4SJoe Perches	$typeKernelTypedefs\b
558e6176fa4SJoe Perches)};
5598ed22cadSAndy Whitcroft
5606d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
5616d32f7a3SJoe Perches
562691e669bSJoe Perchesour $logFunctions = qr{(?x:
563758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
5647d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
56587bd499aSJoe Perches	TP_printk|
5666e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
567b0531722SJoe Perches	panic|
56806668727SJoe Perches	MODULE_[A-Z_]+|
56906668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
570691e669bSJoe Perches)};
571691e669bSJoe Perches
572e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
573e29a70f1SJoe Perches	(?:(?:devm_)?
57458f02267SJoe Perches		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
575e29a70f1SJoe Perches		kstrdup(?:_const)? |
576e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
577461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
578e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
579e29a70f1SJoe Perches	dma_alloc_coherent
580e29a70f1SJoe Perches)};
581e29a70f1SJoe Perches
58220112475SJoe Perchesour $signature_tags = qr{(?xi:
58320112475SJoe Perches	Signed-off-by:|
584d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
58520112475SJoe Perches	Acked-by:|
58620112475SJoe Perches	Tested-by:|
58720112475SJoe Perches	Reviewed-by:|
58820112475SJoe Perches	Reported-by:|
5898543ae12SMugunthan V N	Suggested-by:|
59020112475SJoe Perches	To:|
59120112475SJoe Perches	Cc:
59220112475SJoe Perches)};
59320112475SJoe Perches
594adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
595adb2da82SJoe Perches	[=-]*> |
596adb2da82SJoe Perches	<[=-]* |
597adb2da82SJoe Perches	\[ |
598adb2da82SJoe Perches	\] |
599adb2da82SJoe Perches	start |
600adb2da82SJoe Perches	called |
601adb2da82SJoe Perches	entered |
602adb2da82SJoe Perches	entry |
603adb2da82SJoe Perches	enter |
604adb2da82SJoe Perches	in |
605adb2da82SJoe Perches	inside |
606adb2da82SJoe Perches	here |
607adb2da82SJoe Perches	begin |
608adb2da82SJoe Perches	exit |
609adb2da82SJoe Perches	end |
610adb2da82SJoe Perches	done |
611adb2da82SJoe Perches	leave |
612adb2da82SJoe Perches	completed |
613adb2da82SJoe Perches	out |
614adb2da82SJoe Perches	return |
615adb2da82SJoe Perches	[\.\!:\s]*
616adb2da82SJoe Perches)};
617adb2da82SJoe Perches
618831242abSAditya Srivastavasub edit_distance_min {
619831242abSAditya Srivastava	my (@arr) = @_;
620831242abSAditya Srivastava	my $len = scalar @arr;
621831242abSAditya Srivastava	if ((scalar @arr) < 1) {
622831242abSAditya Srivastava		# if underflow, return
623831242abSAditya Srivastava		return;
624831242abSAditya Srivastava	}
625831242abSAditya Srivastava	my $min = $arr[0];
626831242abSAditya Srivastava	for my $i (0 .. ($len-1)) {
627831242abSAditya Srivastava		if ($arr[$i] < $min) {
628831242abSAditya Srivastava			$min = $arr[$i];
629831242abSAditya Srivastava		}
630831242abSAditya Srivastava	}
631831242abSAditya Srivastava	return $min;
632831242abSAditya Srivastava}
633831242abSAditya Srivastava
634831242abSAditya Srivastavasub get_edit_distance {
635831242abSAditya Srivastava	my ($str1, $str2) = @_;
636831242abSAditya Srivastava	$str1 = lc($str1);
637831242abSAditya Srivastava	$str2 = lc($str2);
638831242abSAditya Srivastava	$str1 =~ s/-//g;
639831242abSAditya Srivastava	$str2 =~ s/-//g;
640831242abSAditya Srivastava	my $len1 = length($str1);
641831242abSAditya Srivastava	my $len2 = length($str2);
642831242abSAditya Srivastava	# two dimensional array storing minimum edit distance
643831242abSAditya Srivastava	my @distance;
644831242abSAditya Srivastava	for my $i (0 .. $len1) {
645831242abSAditya Srivastava		for my $j (0 .. $len2) {
646831242abSAditya Srivastava			if ($i == 0) {
647831242abSAditya Srivastava				$distance[$i][$j] = $j;
648831242abSAditya Srivastava			} elsif ($j == 0) {
649831242abSAditya Srivastava				$distance[$i][$j] = $i;
650831242abSAditya Srivastava			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
651831242abSAditya Srivastava				$distance[$i][$j] = $distance[$i - 1][$j - 1];
652831242abSAditya Srivastava			} else {
653831242abSAditya Srivastava				my $dist1 = $distance[$i][$j - 1]; #insert distance
654831242abSAditya Srivastava				my $dist2 = $distance[$i - 1][$j]; # remove
655831242abSAditya Srivastava				my $dist3 = $distance[$i - 1][$j - 1]; #replace
656831242abSAditya Srivastava				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
657831242abSAditya Srivastava			}
658831242abSAditya Srivastava		}
659831242abSAditya Srivastava	}
660831242abSAditya Srivastava	return $distance[$len1][$len2];
661831242abSAditya Srivastava}
662831242abSAditya Srivastava
663831242abSAditya Srivastavasub find_standard_signature {
664831242abSAditya Srivastava	my ($sign_off) = @_;
665831242abSAditya Srivastava	my @standard_signature_tags = (
666831242abSAditya Srivastava		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
667831242abSAditya Srivastava		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
668831242abSAditya Srivastava	);
669831242abSAditya Srivastava	foreach my $signature (@standard_signature_tags) {
670831242abSAditya Srivastava		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
671831242abSAditya Srivastava	}
672831242abSAditya Srivastava
673831242abSAditya Srivastava	return "";
674831242abSAditya Srivastava}
675831242abSAditya Srivastava
6761813087dSJoe Perchesour @typeListMisordered = (
6771813087dSJoe Perches	qr{char\s+(?:un)?signed},
6781813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
6791813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
6801813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
6811813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
6821813087dSJoe Perches	qr{short\s+(?:un)?signed},
6831813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
6841813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
6851813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
6861813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
6871813087dSJoe Perches	qr{int\s+(?:un)?signed},
6881813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
6891813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
6901813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
6911813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
6921813087dSJoe Perches	qr{long\s+(?:un)?signed},
6931813087dSJoe Perches);
6941813087dSJoe Perches
6958905a67cSAndy Whitcroftour @typeList = (
6968905a67cSAndy Whitcroft	qr{void},
6970c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
6980c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
6990c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
7000c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
7010c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
7020c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
7030c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
7040c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
7050c773d9dSJoe Perches	qr{(?:un)?signed},
7068905a67cSAndy Whitcroft	qr{float},
7078905a67cSAndy Whitcroft	qr{double},
7088905a67cSAndy Whitcroft	qr{bool},
7098905a67cSAndy Whitcroft	qr{struct\s+$Ident},
7108905a67cSAndy Whitcroft	qr{union\s+$Ident},
7118905a67cSAndy Whitcroft	qr{enum\s+$Ident},
7128905a67cSAndy Whitcroft	qr{${Ident}_t},
7138905a67cSAndy Whitcroft	qr{${Ident}_handler},
7148905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
7151813087dSJoe Perches	@typeListMisordered,
7168905a67cSAndy Whitcroft);
717938224b5SJoe Perches
718938224b5SJoe Perchesour $C90_int_types = qr{(?x:
719938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
720938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
721938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
722938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
723938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
724938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
725938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
726938224b5SJoe Perches
727938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
728938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
729938224b5SJoe Perches	long\s+(?:un)?signed|
730938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
731938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
732938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
733938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
734938224b5SJoe Perches
735938224b5SJoe Perches	int\s+(?:un)?signed|
736938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
737938224b5SJoe Perches)};
738938224b5SJoe Perches
739485ff23eSAlex Dowadour @typeListFile = ();
7408716de38SJoe Perchesour @typeListWithAttr = (
7418716de38SJoe Perches	@typeList,
7428716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
7438716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
7448716de38SJoe Perches);
7458716de38SJoe Perches
746c45dcabdSAndy Whitcroftour @modifierList = (
747c45dcabdSAndy Whitcroft	qr{fastcall},
748c45dcabdSAndy Whitcroft);
749485ff23eSAlex Dowadour @modifierListFile = ();
7508905a67cSAndy Whitcroft
7512435880fSJoe Perchesour @mode_permission_funcs = (
7522435880fSJoe Perches	["module_param", 3],
7532435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
7542435880fSJoe Perches	["module_param_array_named", 5],
7552435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
7562435880fSJoe Perches	["proc_create(?:_data|)", 2],
757459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
758459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
759459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
760459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
761459cf0aeSJoe Perches	["__ATTR", 2],
7622435880fSJoe Perches);
7632435880fSJoe Perches
7641a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
7651a3dcf2eSJoe Perches
766515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
767515a235eSJoe Perchesour $mode_perms_search = "";
768515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
769515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
770515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
771515a235eSJoe Perches}
77200180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
773515a235eSJoe Perches
7749189c7e7SJoe Perchesour %deprecated_apis = (
7759189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
7769189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
7779189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
7789189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
7799189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
7809189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
7819189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
7829189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
7839189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
7849189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
7859189c7e7SJoe Perches);
7869189c7e7SJoe Perches
7879189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
7889189c7e7SJoe Perchesour $deprecated_apis_search = "";
7899189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
7909189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
7919189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
7929189c7e7SJoe Perches}
7939189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
7949189c7e7SJoe Perches
795b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
796b392c64fSJoe Perches	S_IWUGO		|
797b392c64fSJoe Perches	S_IWOTH		|
798b392c64fSJoe Perches	S_IRWXUGO	|
799b392c64fSJoe Perches	S_IALLUGO	|
800b392c64fSJoe Perches	0[0-7][0-7][2367]
801b392c64fSJoe Perches}x;
802b392c64fSJoe Perches
803f90774e1SJoe Perchesour %mode_permission_string_types = (
804f90774e1SJoe Perches	"S_IRWXU" => 0700,
805f90774e1SJoe Perches	"S_IRUSR" => 0400,
806f90774e1SJoe Perches	"S_IWUSR" => 0200,
807f90774e1SJoe Perches	"S_IXUSR" => 0100,
808f90774e1SJoe Perches	"S_IRWXG" => 0070,
809f90774e1SJoe Perches	"S_IRGRP" => 0040,
810f90774e1SJoe Perches	"S_IWGRP" => 0020,
811f90774e1SJoe Perches	"S_IXGRP" => 0010,
812f90774e1SJoe Perches	"S_IRWXO" => 0007,
813f90774e1SJoe Perches	"S_IROTH" => 0004,
814f90774e1SJoe Perches	"S_IWOTH" => 0002,
815f90774e1SJoe Perches	"S_IXOTH" => 0001,
816f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
817f90774e1SJoe Perches	"S_IRUGO" => 0444,
818f90774e1SJoe Perches	"S_IWUGO" => 0222,
819f90774e1SJoe Perches	"S_IXUGO" => 0111,
820f90774e1SJoe Perches);
821f90774e1SJoe Perches
822f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
823f90774e1SJoe Perchesour $mode_perms_string_search = "";
824f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
825f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
826f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
827f90774e1SJoe Perches}
82800180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
82900180468SJoe Perchesour $multi_mode_perms_string_search = qr{
83000180468SJoe Perches	${single_mode_perms_string_search}
83100180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
83200180468SJoe Perches}x;
83300180468SJoe Perches
83400180468SJoe Perchessub perms_to_octal {
83500180468SJoe Perches	my ($string) = @_;
83600180468SJoe Perches
83700180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
83800180468SJoe Perches
83900180468SJoe Perches	my $val = "";
84000180468SJoe Perches	my $oval = "";
84100180468SJoe Perches	my $to = 0;
84200180468SJoe Perches	my $curpos = 0;
84300180468SJoe Perches	my $lastpos = 0;
84400180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
84500180468SJoe Perches		$curpos = pos($string);
84600180468SJoe Perches		my $match = $2;
84700180468SJoe Perches		my $omatch = $1;
84800180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
84900180468SJoe Perches		$lastpos = $curpos;
85000180468SJoe Perches		$to |= $mode_permission_string_types{$match};
85100180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
85200180468SJoe Perches		$val .= $match;
85300180468SJoe Perches		$oval .= $omatch;
85400180468SJoe Perches	}
85500180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
85600180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
85700180468SJoe Perches	return sprintf("%04o", $to);
85800180468SJoe Perches}
859f90774e1SJoe Perches
8607840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
8617840a94cSWolfram Sang	irq|
862cdcee686SSergey Ryazanov	memory|
863cdcee686SSergey Ryazanov	time|
864cdcee686SSergey Ryazanov	reboot
8657840a94cSWolfram Sang)};
8667840a94cSWolfram Sang# memory.h: ARM has a custom one
8677840a94cSWolfram Sang
86866b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
86966b47b4aSKees Cookmy $misspellings;
87066b47b4aSKees Cookmy %spelling_fix;
87136061e38SJoe Perches
87236061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
87366b47b4aSKees Cook	while (<$spelling>) {
87466b47b4aSKees Cook		my $line = $_;
87566b47b4aSKees Cook
87666b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
87766b47b4aSKees Cook		$line =~ s/^\s*//g;
87866b47b4aSKees Cook
87966b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
88066b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
88166b47b4aSKees Cook
88266b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
88366b47b4aSKees Cook
88466b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
88566b47b4aSKees Cook	}
88666b47b4aSKees Cook	close($spelling);
88736061e38SJoe Perches} else {
88836061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
88936061e38SJoe Perches}
89066b47b4aSKees Cook
891ebfd7d62SJoe Perchesif ($codespell) {
892ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
893ebfd7d62SJoe Perches		while (<$spelling>) {
894ebfd7d62SJoe Perches			my $line = $_;
895ebfd7d62SJoe Perches
896ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
897ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
898ebfd7d62SJoe Perches
899ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
900ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
901ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
902ebfd7d62SJoe Perches
903ebfd7d62SJoe Perches			$line =~ s/,.*$//;
904ebfd7d62SJoe Perches
905ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
906ebfd7d62SJoe Perches
907ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
908ebfd7d62SJoe Perches		}
909ebfd7d62SJoe Perches		close($spelling);
910ebfd7d62SJoe Perches	} else {
911ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
912ebfd7d62SJoe Perches	}
913ebfd7d62SJoe Perches}
914ebfd7d62SJoe Perches
915ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
916ebfd7d62SJoe Perches
91775ad8c57SJerome Forissiersub read_words {
91875ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
91975ad8c57SJerome Forissier
92075ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
92175ad8c57SJerome Forissier		while (<$words>) {
922bf1fa1daSJoe Perches			my $line = $_;
923bf1fa1daSJoe Perches
924bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
925bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
926bf1fa1daSJoe Perches
927bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
928bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
929bf1fa1daSJoe Perches			if ($line =~ /\s/) {
93075ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
931bf1fa1daSJoe Perches				next;
932bf1fa1daSJoe Perches			}
933bf1fa1daSJoe Perches
934ced69da1SQuentin Monnet			$$wordsRef .= '|' if (defined $$wordsRef);
93575ad8c57SJerome Forissier			$$wordsRef .= $line;
936bf1fa1daSJoe Perches		}
93775ad8c57SJerome Forissier		close($file);
93875ad8c57SJerome Forissier		return 1;
939bf1fa1daSJoe Perches	}
940bf1fa1daSJoe Perches
94175ad8c57SJerome Forissier	return 0;
94275ad8c57SJerome Forissier}
94375ad8c57SJerome Forissier
944ced69da1SQuentin Monnetmy $const_structs;
945ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) {
94675ad8c57SJerome Forissier	read_words(\$const_structs, $conststructsfile)
94775ad8c57SJerome Forissier	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
948ced69da1SQuentin Monnet}
94975ad8c57SJerome Forissier
950ced69da1SQuentin Monnetif (defined($typedefsfile)) {
951ced69da1SQuentin Monnet	my $typeOtherTypedefs;
95275ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
95375ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
954ced69da1SQuentin Monnet	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
95575ad8c57SJerome Forissier}
95675ad8c57SJerome Forissier
9578905a67cSAndy Whitcroftsub build_types {
958485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
959485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
9601813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
9618716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
962c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
963ab7e23f3SJoe Perches	$BasicType	= qr{
964ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
965ab7e23f3SJoe Perches				(?:${all}\b)
966ab7e23f3SJoe Perches		}x;
9678905a67cSAndy Whitcroft	$NonptrType	= qr{
968d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
969cf655043SAndy Whitcroft			(?:
9706b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
9718ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
972c45dcabdSAndy Whitcroft				(?:${all}\b)
973cf655043SAndy Whitcroft			)
974c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
9758905a67cSAndy Whitcroft		  }x;
9761813087dSJoe Perches	$NonptrTypeMisordered	= qr{
9771813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
9781813087dSJoe Perches			(?:
9791813087dSJoe Perches				(?:${Misordered}\b)
9801813087dSJoe Perches			)
9811813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
9821813087dSJoe Perches		  }x;
9838716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
9848716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
9858716de38SJoe Perches			(?:
9868716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
9878716de38SJoe Perches				(?:$typeTypedefs\b)|
9888716de38SJoe Perches				(?:${allWithAttr}\b)
9898716de38SJoe Perches			)
9908716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
9918716de38SJoe Perches		  }x;
9928905a67cSAndy Whitcroft	$Type	= qr{
993c45dcabdSAndy Whitcroft			$NonptrType
9947b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
995c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
9968905a67cSAndy Whitcroft		  }x;
9971813087dSJoe Perches	$TypeMisordered	= qr{
9981813087dSJoe Perches			$NonptrTypeMisordered
9997b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
10001813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
10011813087dSJoe Perches		  }x;
100291cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
10031813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
10048905a67cSAndy Whitcroft}
10058905a67cSAndy Whitcroftbuild_types();
10066c72ffaaSAndy Whitcroft
10077d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
1008d1fe9c09SJoe Perches
1009d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1010d1fe9c09SJoe Perches# requires at least perl version v5.10.0
1011d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
1012d1fe9c09SJoe Perches
1013d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
10142435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
1015c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
10167d2367afSJoe Perches
1017f8422308SJoe Perchesour $declaration_macros = qr{(?x:
10183e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
1019fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
10203d102fc0SGilad Ben-Yossef	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
1021f8422308SJoe Perches)};
1022f8422308SJoe Perches
10238d0325ccSAditya Srivastavaour %allow_repeated_words = (
10248d0325ccSAditya Srivastava	add => '',
10258d0325ccSAditya Srivastava	added => '',
10268d0325ccSAditya Srivastava	bad => '',
10278d0325ccSAditya Srivastava	be => '',
10288d0325ccSAditya Srivastava);
10298d0325ccSAditya Srivastava
10307d2367afSJoe Perchessub deparenthesize {
10317d2367afSJoe Perches	my ($string) = @_;
10327d2367afSJoe Perches	return "" if (!defined($string));
10335b9553abSJoe Perches
10345b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
10355b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
10365b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
10375b9553abSJoe Perches	}
10385b9553abSJoe Perches
10397d2367afSJoe Perches	$string =~ s@\s+@ @g;
10405b9553abSJoe Perches
10417d2367afSJoe Perches	return $string;
10427d2367afSJoe Perches}
10437d2367afSJoe Perches
10443445686aSJoe Perchessub seed_camelcase_file {
10453445686aSJoe Perches	my ($file) = @_;
10463445686aSJoe Perches
10473445686aSJoe Perches	return if (!(-f $file));
10483445686aSJoe Perches
10493445686aSJoe Perches	local $/;
10503445686aSJoe Perches
10513445686aSJoe Perches	open(my $include_file, '<', "$file")
10523445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
10533445686aSJoe Perches	my $text = <$include_file>;
10543445686aSJoe Perches	close($include_file);
10553445686aSJoe Perches
10563445686aSJoe Perches	my @lines = split('\n', $text);
10573445686aSJoe Perches
10583445686aSJoe Perches	foreach my $line (@lines) {
10593445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
10603445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
10613445686aSJoe Perches			$camelcase{$1} = 1;
106211ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
106311ea516aSJoe Perches			$camelcase{$1} = 1;
106411ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
10653445686aSJoe Perches			$camelcase{$1} = 1;
10663445686aSJoe Perches		}
10673445686aSJoe Perches	}
10683445686aSJoe Perches}
10693445686aSJoe Perches
1070cd28b119SJoe Perchesour %maintained_status = ();
1071cd28b119SJoe Perches
107285b0ee18SJoe Perchessub is_maintained_obsolete {
107385b0ee18SJoe Perches	my ($filename) = @_;
107485b0ee18SJoe Perches
1075f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
107685b0ee18SJoe Perches
1077cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
1078cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1079cd28b119SJoe Perches	}
108085b0ee18SJoe Perches
1081cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
108285b0ee18SJoe Perches}
108385b0ee18SJoe Perches
10843b6e8ac9SJoe Perchessub is_SPDX_License_valid {
10853b6e8ac9SJoe Perches	my ($license) = @_;
10863b6e8ac9SJoe Perches
1087f9363b31SGuenter Roeck	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
10883b6e8ac9SJoe Perches
108956294112SJoe Perches	my $root_path = abs_path($root);
1090f9363b31SGuenter Roeck	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
10913b6e8ac9SJoe Perches	return 0 if ($status ne "");
10923b6e8ac9SJoe Perches	return 1;
10933b6e8ac9SJoe Perches}
10943b6e8ac9SJoe Perches
10953445686aSJoe Perchesmy $camelcase_seeded = 0;
10963445686aSJoe Perchessub seed_camelcase_includes {
10973445686aSJoe Perches	return if ($camelcase_seeded);
10983445686aSJoe Perches
10993445686aSJoe Perches	my $files;
1100c707a81dSJoe Perches	my $camelcase_cache = "";
1101c707a81dSJoe Perches	my @include_files = ();
1102c707a81dSJoe Perches
1103c707a81dSJoe Perches	$camelcase_seeded = 1;
1104351b2a1fSJoe Perches
11050f7f635bSJoe Perches	if (-e "$gitroot") {
1106dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1107351b2a1fSJoe Perches		chomp $git_last_include_commit;
1108c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1109c707a81dSJoe Perches	} else {
1110c707a81dSJoe Perches		my $last_mod_date = 0;
1111c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
1112c707a81dSJoe Perches		@include_files = split('\n', $files);
1113c707a81dSJoe Perches		foreach my $file (@include_files) {
1114c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
1115c707a81dSJoe Perches						   localtime((stat $file)[9]));
1116c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
1117c707a81dSJoe Perches		}
1118c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1119c707a81dSJoe Perches	}
1120c707a81dSJoe Perches
1121c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1122c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
1123c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1124351b2a1fSJoe Perches		while (<$camelcase_file>) {
1125351b2a1fSJoe Perches			chomp;
1126351b2a1fSJoe Perches			$camelcase{$_} = 1;
1127351b2a1fSJoe Perches		}
1128351b2a1fSJoe Perches		close($camelcase_file);
1129351b2a1fSJoe Perches
1130351b2a1fSJoe Perches		return;
1131351b2a1fSJoe Perches	}
1132c707a81dSJoe Perches
11330f7f635bSJoe Perches	if (-e "$gitroot") {
1134dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
1135c707a81dSJoe Perches		@include_files = split('\n', $files);
11363445686aSJoe Perches	}
1137c707a81dSJoe Perches
11383445686aSJoe Perches	foreach my $file (@include_files) {
11393445686aSJoe Perches		seed_camelcase_file($file);
11403445686aSJoe Perches	}
1141351b2a1fSJoe Perches
1142c707a81dSJoe Perches	if ($camelcase_cache ne "") {
1143351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
1144c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
1145c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1146351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1147351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
1148351b2a1fSJoe Perches		}
1149351b2a1fSJoe Perches		close($camelcase_file);
1150351b2a1fSJoe Perches	}
11513445686aSJoe Perches}
11523445686aSJoe Perches
1153f5f61325SJoe Perchessub git_is_single_file {
1154f5f61325SJoe Perches	my ($filename) = @_;
1155f5f61325SJoe Perches
1156f5f61325SJoe Perches	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1157f5f61325SJoe Perches
1158f5f61325SJoe Perches	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1159f5f61325SJoe Perches	my $count = $output =~ tr/\n//;
1160f5f61325SJoe Perches	return $count eq 1 && $output =~ m{^${filename}$};
1161f5f61325SJoe Perches}
1162f5f61325SJoe Perches
1163d311cd44SJoe Perchessub git_commit_info {
1164d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
1165d311cd44SJoe Perches
11660f7f635bSJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1167d311cd44SJoe Perches
1168dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1169d311cd44SJoe Perches	$output =~ s/^\s*//gm;
1170d311cd44SJoe Perches	my @lines = split("\n", $output);
1171d311cd44SJoe Perches
11720d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
11730d7835fcSJoe Perches
11745a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1175d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
1176d311cd44SJoe Perches# all matching commit ids, but it's very slow...
1177d311cd44SJoe Perches#
1178d311cd44SJoe Perches#		echo "checking commits $1..."
1179d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
1180d311cd44SJoe Perches#		while read line ; do
1181d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
1182d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
1183d311cd44SJoe Perches#		done
1184*4ce9f970SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
1185*4ce9f970SJoe Perches		 $lines[0] =~ /^fatal: bad object $commit/) {
1186948b133aSHeinrich Schuchardt		$id = undef;
1187d311cd44SJoe Perches	} else {
1188d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1189d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1190d311cd44SJoe Perches	}
1191d311cd44SJoe Perches
1192d311cd44SJoe Perches	return ($id, $desc);
1193d311cd44SJoe Perches}
1194d311cd44SJoe Perches
11956c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
11960a920b5bSAndy Whitcroft
119700df344fSAndy Whitcroftmy @rawlines = ();
1198c2fdda0dSAndy Whitcroftmy @lines = ();
11993705ce5bSJoe Perchesmy @fixed = ();
1200d752fcc8SJoe Perchesmy @fixed_inserted = ();
1201d752fcc8SJoe Perchesmy @fixed_deleted = ();
1202194f66fcSJoe Perchesmy $fixlinenr = -1;
1203194f66fcSJoe Perches
12044a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
12054a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
12060f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
12074a593c34SDu, Changbin
12084a593c34SDu, Changbinif ($git) {
12094a593c34SDu, Changbin	my @commits = ();
12100dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
12114a593c34SDu, Changbin		my $git_range;
121228898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
121328898fd1SJoe Perches			$git_range = "-$2 $1";
12144a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
12154a593c34SDu, Changbin			$git_range = "$commit_expr";
12164a593c34SDu, Changbin		} else {
12170dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
12180dea9f1eSJoe Perches		}
1219dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
12200dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
122128898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
122228898fd1SJoe Perches			next if (!defined($1) || !defined($2));
12230dea9f1eSJoe Perches			my $sha1 = $1;
12240dea9f1eSJoe Perches			my $subject = $2;
12250dea9f1eSJoe Perches			unshift(@commits, $sha1);
12260dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
12274a593c34SDu, Changbin		}
12284a593c34SDu, Changbin	}
12294a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
12304a593c34SDu, Changbin	@ARGV = @commits;
12314a593c34SDu, Changbin}
12324a593c34SDu, Changbin
1233c2fdda0dSAndy Whitcroftmy $vname;
123498005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
12356c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
123621caa13cSAndy Whitcroft	my $FILE;
1237f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1238f5f61325SJoe Perches	my $oldfile = $file;
1239f5f61325SJoe Perches	$file = 1 if ($is_git_file);
12404a593c34SDu, Changbin	if ($git) {
12414a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
12424a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
12434a593c34SDu, Changbin	} elsif ($file) {
124421caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
12456c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
124621caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
124721caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
12486c72ffaaSAndy Whitcroft	} else {
124921caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
12506c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
12516c72ffaaSAndy Whitcroft	}
1252c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1253c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
12544a593c34SDu, Changbin	} elsif ($git) {
12550dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1256c2fdda0dSAndy Whitcroft	} else {
1257c2fdda0dSAndy Whitcroft		$vname = $filename;
1258c2fdda0dSAndy Whitcroft	}
125921caa13cSAndy Whitcroft	while (<$FILE>) {
12600a920b5bSAndy Whitcroft		chomp;
126100df344fSAndy Whitcroft		push(@rawlines, $_);
1262c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
12636c72ffaaSAndy Whitcroft	}
126421caa13cSAndy Whitcroft	close($FILE);
1265d8469f16SJoe Perches
1266d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1267d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1268d8469f16SJoe Perches		print "$vname\n";
1269d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1270d8469f16SJoe Perches	}
1271d8469f16SJoe Perches
1272c2fdda0dSAndy Whitcroft	if (!process($filename)) {
12730a920b5bSAndy Whitcroft		$exit = 1;
12740a920b5bSAndy Whitcroft	}
127500df344fSAndy Whitcroft	@rawlines = ();
127613214adfSAndy Whitcroft	@lines = ();
12773705ce5bSJoe Perches	@fixed = ();
1278d752fcc8SJoe Perches	@fixed_inserted = ();
1279d752fcc8SJoe Perches	@fixed_deleted = ();
1280194f66fcSJoe Perches	$fixlinenr = -1;
1281485ff23eSAlex Dowad	@modifierListFile = ();
1282485ff23eSAlex Dowad	@typeListFile = ();
1283485ff23eSAlex Dowad	build_types();
1284f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
12850a920b5bSAndy Whitcroft}
12860a920b5bSAndy Whitcroft
1287d8469f16SJoe Perchesif (!$quiet) {
12883c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
12893c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
12903c816e49SJoe Perches
12915b57980dSJoe Perches	if (!$perl_version_ok) {
1292d8469f16SJoe Perches		print << "EOM"
1293d8469f16SJoe Perches
1294d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
12955b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1296d8469f16SJoe PerchesEOM
1297d8469f16SJoe Perches	}
1298d8469f16SJoe Perches	if ($exit) {
1299d8469f16SJoe Perches		print << "EOM"
1300d8469f16SJoe Perches
1301d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1302d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1303d8469f16SJoe PerchesEOM
1304d8469f16SJoe Perches	}
1305d8469f16SJoe Perches}
1306d8469f16SJoe Perches
13070a920b5bSAndy Whitcroftexit($exit);
13080a920b5bSAndy Whitcroft
13090a920b5bSAndy Whitcroftsub top_of_kernel_tree {
13106c72ffaaSAndy Whitcroft	my ($root) = @_;
13116c72ffaaSAndy Whitcroft
13126c72ffaaSAndy Whitcroft	my @tree_check = (
13136c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
13146c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
13156c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
13166c72ffaaSAndy Whitcroft	);
13176c72ffaaSAndy Whitcroft
13186c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
13196c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
13200a920b5bSAndy Whitcroft			return 0;
13210a920b5bSAndy Whitcroft		}
13226c72ffaaSAndy Whitcroft	}
13236c72ffaaSAndy Whitcroft	return 1;
13246c72ffaaSAndy Whitcroft}
13250a920b5bSAndy Whitcroft
132620112475SJoe Perchessub parse_email {
132720112475SJoe Perches	my ($formatted_email) = @_;
132820112475SJoe Perches
132920112475SJoe Perches	my $name = "";
1330fccaebf0SDwaipayan Ray	my $quoted = "";
1331dfa05c28SJoe Perches	my $name_comment = "";
133220112475SJoe Perches	my $address = "";
133320112475SJoe Perches	my $comment = "";
133420112475SJoe Perches
133520112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
133620112475SJoe Perches		$name = $1;
133720112475SJoe Perches		$address = $2;
133820112475SJoe Perches		$comment = $3 if defined $3;
133920112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
134020112475SJoe Perches		$address = $1;
134120112475SJoe Perches		$comment = $2 if defined $2;
134220112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
134320112475SJoe Perches		$address = $1;
134420112475SJoe Perches		$comment = $2 if defined $2;
134585e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
134620112475SJoe Perches		$name = $formatted_email;
13473705ce5bSJoe Perches		$name = trim($name);
134820112475SJoe Perches		$name =~ s/^\"|\"$//g;
134920112475SJoe Perches		# If there's a name left after stripping spaces and
135020112475SJoe Perches		# leading quotes, and the address doesn't have both
135120112475SJoe Perches		# leading and trailing angle brackets, the address
135220112475SJoe Perches		# is invalid. ie:
135320112475SJoe Perches		#   "joe smith [email protected]" bad
135420112475SJoe Perches		#   "joe smith <[email protected]" bad
135520112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
135620112475SJoe Perches			$name = "";
135720112475SJoe Perches			$address = "";
135820112475SJoe Perches			$comment = "";
135920112475SJoe Perches		}
136020112475SJoe Perches	}
136120112475SJoe Perches
1362fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1363fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1364fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1365fccaebf0SDwaipayan Ray		$quoted = $1;
1366dfa05c28SJoe Perches	}
1367fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1368fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1369fccaebf0SDwaipayan Ray	}
1370fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1371fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1372fccaebf0SDwaipayan Ray
13733705ce5bSJoe Perches	$address = trim($address);
137420112475SJoe Perches	$address =~ s/^\<|\>$//g;
1375fccaebf0SDwaipayan Ray	$comment = trim($comment);
137620112475SJoe Perches
137720112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
137820112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
137920112475SJoe Perches		$name = "\"$name\"";
138020112475SJoe Perches	}
138120112475SJoe Perches
1382dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
138320112475SJoe Perches}
138420112475SJoe Perches
138520112475SJoe Perchessub format_email {
138648ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
138720112475SJoe Perches
138820112475SJoe Perches	my $formatted_email;
138920112475SJoe Perches
1390fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
13913705ce5bSJoe Perches	$address = trim($address);
1392fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
139320112475SJoe Perches
139420112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
139520112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
139620112475SJoe Perches		$name = "\"$name\"";
139720112475SJoe Perches	}
139820112475SJoe Perches
1399fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1400fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1401fccaebf0SDwaipayan Ray	$comment = trim($comment);
1402fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1403fccaebf0SDwaipayan Ray
140420112475SJoe Perches	if ("$name" eq "") {
140520112475SJoe Perches		$formatted_email = "$address";
140620112475SJoe Perches	} else {
140748ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
140820112475SJoe Perches	}
140948ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
141020112475SJoe Perches	return $formatted_email;
141120112475SJoe Perches}
141220112475SJoe Perches
1413dfa05c28SJoe Perchessub reformat_email {
1414dfa05c28SJoe Perches	my ($email) = @_;
1415dfa05c28SJoe Perches
1416dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
141748ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1418dfa05c28SJoe Perches}
1419dfa05c28SJoe Perches
1420dfa05c28SJoe Perchessub same_email_addresses {
1421fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1422dfa05c28SJoe Perches
1423dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1424dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1425dfa05c28SJoe Perches
142648ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
142748ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
142848ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
142948ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
143048ca2d8aSDwaipayan Ray}
1431dfa05c28SJoe Perches
1432d311cd44SJoe Perchessub which {
1433d311cd44SJoe Perches	my ($bin) = @_;
1434d311cd44SJoe Perches
1435d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1436d311cd44SJoe Perches		if (-e "$path/$bin") {
1437d311cd44SJoe Perches			return "$path/$bin";
1438d311cd44SJoe Perches		}
1439d311cd44SJoe Perches	}
1440d311cd44SJoe Perches
1441d311cd44SJoe Perches	return "";
1442d311cd44SJoe Perches}
1443d311cd44SJoe Perches
1444000d1cc1SJoe Perchessub which_conf {
1445000d1cc1SJoe Perches	my ($conf) = @_;
1446000d1cc1SJoe Perches
1447000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1448000d1cc1SJoe Perches		if (-e "$path/$conf") {
1449000d1cc1SJoe Perches			return "$path/$conf";
1450000d1cc1SJoe Perches		}
1451000d1cc1SJoe Perches	}
1452000d1cc1SJoe Perches
1453000d1cc1SJoe Perches	return "";
1454000d1cc1SJoe Perches}
1455000d1cc1SJoe Perches
14560a920b5bSAndy Whitcroftsub expand_tabs {
14570a920b5bSAndy Whitcroft	my ($str) = @_;
14580a920b5bSAndy Whitcroft
14590a920b5bSAndy Whitcroft	my $res = '';
14600a920b5bSAndy Whitcroft	my $n = 0;
14610a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
14620a920b5bSAndy Whitcroft		if ($c eq "\t") {
14630a920b5bSAndy Whitcroft			$res .= ' ';
14640a920b5bSAndy Whitcroft			$n++;
1465713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
14660a920b5bSAndy Whitcroft				$res .= ' ';
14670a920b5bSAndy Whitcroft			}
14680a920b5bSAndy Whitcroft			next;
14690a920b5bSAndy Whitcroft		}
14700a920b5bSAndy Whitcroft		$res .= $c;
14710a920b5bSAndy Whitcroft		$n++;
14720a920b5bSAndy Whitcroft	}
14730a920b5bSAndy Whitcroft
14740a920b5bSAndy Whitcroft	return $res;
14750a920b5bSAndy Whitcroft}
14766c72ffaaSAndy Whitcroftsub copy_spacing {
1477773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
14786c72ffaaSAndy Whitcroft	return $res;
14796c72ffaaSAndy Whitcroft}
14800a920b5bSAndy Whitcroft
14814a0df2efSAndy Whitcroftsub line_stats {
14824a0df2efSAndy Whitcroft	my ($line) = @_;
14834a0df2efSAndy Whitcroft
14844a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
14854a0df2efSAndy Whitcroft	$line =~ s/^.//;
14864a0df2efSAndy Whitcroft	$line = expand_tabs($line);
14874a0df2efSAndy Whitcroft
14884a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
14894a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
14904a0df2efSAndy Whitcroft
14914a0df2efSAndy Whitcroft	return (length($line), length($white));
14924a0df2efSAndy Whitcroft}
14934a0df2efSAndy Whitcroft
1494773647a0SAndy Whitcroftmy $sanitise_quote = '';
1495773647a0SAndy Whitcroft
1496773647a0SAndy Whitcroftsub sanitise_line_reset {
1497773647a0SAndy Whitcroft	my ($in_comment) = @_;
1498773647a0SAndy Whitcroft
1499773647a0SAndy Whitcroft	if ($in_comment) {
1500773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1501773647a0SAndy Whitcroft	} else {
1502773647a0SAndy Whitcroft		$sanitise_quote = '';
1503773647a0SAndy Whitcroft	}
1504773647a0SAndy Whitcroft}
150500df344fSAndy Whitcroftsub sanitise_line {
150600df344fSAndy Whitcroft	my ($line) = @_;
150700df344fSAndy Whitcroft
150800df344fSAndy Whitcroft	my $res = '';
150900df344fSAndy Whitcroft	my $l = '';
151000df344fSAndy Whitcroft
1511c2fdda0dSAndy Whitcroft	my $qlen = 0;
1512773647a0SAndy Whitcroft	my $off = 0;
1513773647a0SAndy Whitcroft	my $c;
151400df344fSAndy Whitcroft
1515773647a0SAndy Whitcroft	# Always copy over the diff marker.
1516773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1517773647a0SAndy Whitcroft
1518773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1519773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1520773647a0SAndy Whitcroft
15218d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1522773647a0SAndy Whitcroft		# and end, all to $;.
1523773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1524773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1525773647a0SAndy Whitcroft
1526773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1527773647a0SAndy Whitcroft			$off++;
152800df344fSAndy Whitcroft			next;
1529773647a0SAndy Whitcroft		}
153081bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1531773647a0SAndy Whitcroft			$sanitise_quote = '';
1532773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1533773647a0SAndy Whitcroft			$off++;
1534773647a0SAndy Whitcroft			next;
1535773647a0SAndy Whitcroft		}
1536113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1537113f04a8SDaniel Walker			$sanitise_quote = '//';
1538113f04a8SDaniel Walker
1539113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1540113f04a8SDaniel Walker			$off++;
1541113f04a8SDaniel Walker			next;
1542113f04a8SDaniel Walker		}
1543773647a0SAndy Whitcroft
1544773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1545773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1546773647a0SAndy Whitcroft		    $c eq "\\") {
1547773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1548773647a0SAndy Whitcroft			$off++;
1549773647a0SAndy Whitcroft			next;
1550773647a0SAndy Whitcroft		}
1551773647a0SAndy Whitcroft		# Regular quotes.
1552773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1553773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1554773647a0SAndy Whitcroft				$sanitise_quote = $c;
1555773647a0SAndy Whitcroft
1556773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1557773647a0SAndy Whitcroft				next;
1558773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1559773647a0SAndy Whitcroft				$sanitise_quote = '';
156000df344fSAndy Whitcroft			}
156100df344fSAndy Whitcroft		}
1562773647a0SAndy Whitcroft
1563fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1564773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1565773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1566113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1567113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1568773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1569773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
157000df344fSAndy Whitcroft		} else {
1571773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
157200df344fSAndy Whitcroft		}
1573c2fdda0dSAndy Whitcroft	}
1574c2fdda0dSAndy Whitcroft
1575113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1576113f04a8SDaniel Walker		$sanitise_quote = '';
1577113f04a8SDaniel Walker	}
1578113f04a8SDaniel Walker
1579c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1580c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1581c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1582c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1583c2fdda0dSAndy Whitcroft
1584c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1585c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1586c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1587c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1588c2fdda0dSAndy Whitcroft	}
1589c2fdda0dSAndy Whitcroft
1590dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1591dadf680dSJoe Perches		my $match = $1;
1592dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1593dadf680dSJoe Perches	}
1594dadf680dSJoe Perches
159500df344fSAndy Whitcroft	return $res;
159600df344fSAndy Whitcroft}
159700df344fSAndy Whitcroft
1598a6962d72SJoe Perchessub get_quoted_string {
1599a6962d72SJoe Perches	my ($line, $rawline) = @_;
1600a6962d72SJoe Perches
1601478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
160233acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1603a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1604a6962d72SJoe Perches}
1605a6962d72SJoe Perches
16068905a67cSAndy Whitcroftsub ctx_statement_block {
16078905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16088905a67cSAndy Whitcroft	my $line = $linenr - 1;
16098905a67cSAndy Whitcroft	my $blk = '';
16108905a67cSAndy Whitcroft	my $soff = $off;
16118905a67cSAndy Whitcroft	my $coff = $off - 1;
1612773647a0SAndy Whitcroft	my $coff_set = 0;
16138905a67cSAndy Whitcroft
161413214adfSAndy Whitcroft	my $loff = 0;
161513214adfSAndy Whitcroft
16168905a67cSAndy Whitcroft	my $type = '';
16178905a67cSAndy Whitcroft	my $level = 0;
1618a2750645SAndy Whitcroft	my @stack = ();
1619cf655043SAndy Whitcroft	my $p;
16208905a67cSAndy Whitcroft	my $c;
16218905a67cSAndy Whitcroft	my $len = 0;
162213214adfSAndy Whitcroft
162313214adfSAndy Whitcroft	my $remainder;
16248905a67cSAndy Whitcroft	while (1) {
1625a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1626a2750645SAndy Whitcroft
1627773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
16288905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
16298905a67cSAndy Whitcroft		# context.
16308905a67cSAndy Whitcroft		if ($off >= $len) {
16318905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1632dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1633c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
16348905a67cSAndy Whitcroft				$remain--;
163513214adfSAndy Whitcroft				$loff = $len;
1636c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
16378905a67cSAndy Whitcroft				$len = length($blk);
16388905a67cSAndy Whitcroft				$line++;
16398905a67cSAndy Whitcroft				last;
16408905a67cSAndy Whitcroft			}
16418905a67cSAndy Whitcroft			# Bail if there is no further context.
16428905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
164313214adfSAndy Whitcroft			if ($off >= $len) {
16448905a67cSAndy Whitcroft				last;
16458905a67cSAndy Whitcroft			}
1646f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1647f74bd194SAndy Whitcroft				$level++;
1648f74bd194SAndy Whitcroft				$type = '#';
1649f74bd194SAndy Whitcroft			}
16508905a67cSAndy Whitcroft		}
1651cf655043SAndy Whitcroft		$p = $c;
16528905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
165313214adfSAndy Whitcroft		$remainder = substr($blk, $off);
16548905a67cSAndy Whitcroft
1655773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
16564635f4fbSAndy Whitcroft
16574635f4fbSAndy Whitcroft		# Handle nested #if/#else.
16584635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
16594635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
16604635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
16614635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
16624635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
16634635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
16644635f4fbSAndy Whitcroft		}
16654635f4fbSAndy Whitcroft
16668905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
16678905a67cSAndy Whitcroft		# outermost level.
16688905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
16698905a67cSAndy Whitcroft			last;
16708905a67cSAndy Whitcroft		}
16718905a67cSAndy Whitcroft
167213214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1673773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1674773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1675773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1676773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1677773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1678773647a0SAndy Whitcroft			$coff_set = 1;
1679773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1680773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
168113214adfSAndy Whitcroft		}
168213214adfSAndy Whitcroft
16838905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
16848905a67cSAndy Whitcroft			$level++;
16858905a67cSAndy Whitcroft			$type = '(';
16868905a67cSAndy Whitcroft		}
16878905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
16888905a67cSAndy Whitcroft			$level--;
16898905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
16908905a67cSAndy Whitcroft
16918905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
16928905a67cSAndy Whitcroft				$coff = $off;
1693773647a0SAndy Whitcroft				$coff_set = 1;
1694773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
16958905a67cSAndy Whitcroft			}
16968905a67cSAndy Whitcroft		}
16978905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
16988905a67cSAndy Whitcroft			$level++;
16998905a67cSAndy Whitcroft			$type = '{';
17008905a67cSAndy Whitcroft		}
17018905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
17028905a67cSAndy Whitcroft			$level--;
17038905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
17048905a67cSAndy Whitcroft
17058905a67cSAndy Whitcroft			if ($level == 0) {
1706b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1707b998e001SPatrick Pannuto					$off++;
1708b998e001SPatrick Pannuto				}
17098905a67cSAndy Whitcroft				last;
17108905a67cSAndy Whitcroft			}
17118905a67cSAndy Whitcroft		}
1712f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1713f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1714f74bd194SAndy Whitcroft			$level--;
1715f74bd194SAndy Whitcroft			$type = '';
1716f74bd194SAndy Whitcroft			$off++;
1717f74bd194SAndy Whitcroft			last;
1718f74bd194SAndy Whitcroft		}
17198905a67cSAndy Whitcroft		$off++;
17208905a67cSAndy Whitcroft	}
1721a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
172213214adfSAndy Whitcroft	if ($off == $len) {
1723a3bb97a7SAndy Whitcroft		$loff = $len + 1;
172413214adfSAndy Whitcroft		$line++;
172513214adfSAndy Whitcroft		$remain--;
172613214adfSAndy Whitcroft	}
17278905a67cSAndy Whitcroft
17288905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
17298905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
17308905a67cSAndy Whitcroft
17318905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
17328905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
17338905a67cSAndy Whitcroft
1734773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
173513214adfSAndy Whitcroft
173613214adfSAndy Whitcroft	return ($statement, $condition,
173713214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
173813214adfSAndy Whitcroft}
173913214adfSAndy Whitcroft
1740cf655043SAndy Whitcroftsub statement_lines {
1741cf655043SAndy Whitcroft	my ($stmt) = @_;
1742cf655043SAndy Whitcroft
1743cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1744cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1745cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1746cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1747cf655043SAndy Whitcroft
1748cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1749cf655043SAndy Whitcroft
1750cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1751cf655043SAndy Whitcroft}
1752cf655043SAndy Whitcroft
1753cf655043SAndy Whitcroftsub statement_rawlines {
1754cf655043SAndy Whitcroft	my ($stmt) = @_;
1755cf655043SAndy Whitcroft
1756cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1757cf655043SAndy Whitcroft
1758cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1759cf655043SAndy Whitcroft}
1760cf655043SAndy Whitcroft
1761cf655043SAndy Whitcroftsub statement_block_size {
1762cf655043SAndy Whitcroft	my ($stmt) = @_;
1763cf655043SAndy Whitcroft
1764cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1765cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1766cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1767cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1768cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1769cf655043SAndy Whitcroft
1770cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1771cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1772cf655043SAndy Whitcroft
1773cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1774cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1775cf655043SAndy Whitcroft
1776cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1777cf655043SAndy Whitcroft		return $stmt_lines;
1778cf655043SAndy Whitcroft	} else {
1779cf655043SAndy Whitcroft		return $stmt_statements;
1780cf655043SAndy Whitcroft	}
1781cf655043SAndy Whitcroft}
1782cf655043SAndy Whitcroft
178313214adfSAndy Whitcroftsub ctx_statement_full {
178413214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
178513214adfSAndy Whitcroft	my ($statement, $condition, $level);
178613214adfSAndy Whitcroft
178713214adfSAndy Whitcroft	my (@chunks);
178813214adfSAndy Whitcroft
1789cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
179013214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
179113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1792773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
179313214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1794cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1795cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1796cf655043SAndy Whitcroft	}
1797cf655043SAndy Whitcroft
1798cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1799cf655043SAndy Whitcroft	# could continue the statement.
1800cf655043SAndy Whitcroft	for (;;) {
180113214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
180213214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1803cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1804773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1805cf655043SAndy Whitcroft		#print "C: push\n";
1806cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
180713214adfSAndy Whitcroft	}
180813214adfSAndy Whitcroft
180913214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
18108905a67cSAndy Whitcroft}
18118905a67cSAndy Whitcroft
18124a0df2efSAndy Whitcroftsub ctx_block_get {
1813f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
18144a0df2efSAndy Whitcroft	my $line;
18154a0df2efSAndy Whitcroft	my $start = $linenr - 1;
18164a0df2efSAndy Whitcroft	my $blk = '';
18174a0df2efSAndy Whitcroft	my @o;
18184a0df2efSAndy Whitcroft	my @c;
18194a0df2efSAndy Whitcroft	my @res = ();
18204a0df2efSAndy Whitcroft
1821f0a594c1SAndy Whitcroft	my $level = 0;
18224635f4fbSAndy Whitcroft	my @stack = ($level);
182300df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
182400df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
182500df344fSAndy Whitcroft		$remain--;
182600df344fSAndy Whitcroft
182700df344fSAndy Whitcroft		$blk .= $rawlines[$line];
18284635f4fbSAndy Whitcroft
18294635f4fbSAndy Whitcroft		# Handle nested #if/#else.
183001464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
18314635f4fbSAndy Whitcroft			push(@stack, $level);
183201464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
18334635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
183401464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
18354635f4fbSAndy Whitcroft			$level = pop(@stack);
18364635f4fbSAndy Whitcroft		}
18374635f4fbSAndy Whitcroft
183801464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1839f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1840f0a594c1SAndy Whitcroft			if ($off > 0) {
1841f0a594c1SAndy Whitcroft				$off--;
1842f0a594c1SAndy Whitcroft				next;
1843f0a594c1SAndy Whitcroft			}
18444a0df2efSAndy Whitcroft
1845f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1846f0a594c1SAndy Whitcroft				$level--;
1847f0a594c1SAndy Whitcroft				last if ($level == 0);
1848f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1849f0a594c1SAndy Whitcroft				$level++;
1850f0a594c1SAndy Whitcroft			}
1851f0a594c1SAndy Whitcroft		}
18524a0df2efSAndy Whitcroft
1853f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
185400df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
18554a0df2efSAndy Whitcroft		}
18564a0df2efSAndy Whitcroft
1857f0a594c1SAndy Whitcroft		last if ($level == 0);
18584a0df2efSAndy Whitcroft	}
18594a0df2efSAndy Whitcroft
1860f0a594c1SAndy Whitcroft	return ($level, @res);
18614a0df2efSAndy Whitcroft}
18624a0df2efSAndy Whitcroftsub ctx_block_outer {
18634a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
18644a0df2efSAndy Whitcroft
1865f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1866f0a594c1SAndy Whitcroft	return @r;
18674a0df2efSAndy Whitcroft}
18684a0df2efSAndy Whitcroftsub ctx_block {
18694a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
18704a0df2efSAndy Whitcroft
1871f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1872f0a594c1SAndy Whitcroft	return @r;
1873653d4876SAndy Whitcroft}
1874653d4876SAndy Whitcroftsub ctx_statement {
1875f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1876f0a594c1SAndy Whitcroft
1877f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1878f0a594c1SAndy Whitcroft	return @r;
1879f0a594c1SAndy Whitcroft}
1880f0a594c1SAndy Whitcroftsub ctx_block_level {
1881653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1882653d4876SAndy Whitcroft
1883f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
18844a0df2efSAndy Whitcroft}
18859c0ca6f9SAndy Whitcroftsub ctx_statement_level {
18869c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
18879c0ca6f9SAndy Whitcroft
18889c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
18899c0ca6f9SAndy Whitcroft}
18904a0df2efSAndy Whitcroft
18914a0df2efSAndy Whitcroftsub ctx_locate_comment {
18924a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
18934a0df2efSAndy Whitcroft
1894a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1895a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1896a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1897a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1898a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1899a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1900a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1901a55ee0ccSJoe Perches
19024a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1903a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
19044a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
19054a0df2efSAndy Whitcroft
19064a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
19074a0df2efSAndy Whitcroft	# comment.
19084a0df2efSAndy Whitcroft	my $in_comment = 0;
19094a0df2efSAndy Whitcroft	$current_comment = '';
19104a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
191100df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
191200df344fSAndy Whitcroft		#warn "           $line\n";
19134a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
19144a0df2efSAndy Whitcroft			$in_comment = 1;
19154a0df2efSAndy Whitcroft		}
19164a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
19174a0df2efSAndy Whitcroft			$in_comment = 1;
19184a0df2efSAndy Whitcroft		}
19194a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
19204a0df2efSAndy Whitcroft			$current_comment = '';
19214a0df2efSAndy Whitcroft		}
19224a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
19234a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
19244a0df2efSAndy Whitcroft			$in_comment = 0;
19254a0df2efSAndy Whitcroft		}
19264a0df2efSAndy Whitcroft	}
19274a0df2efSAndy Whitcroft
19284a0df2efSAndy Whitcroft	chomp($current_comment);
19294a0df2efSAndy Whitcroft	return($current_comment);
19304a0df2efSAndy Whitcroft}
19314a0df2efSAndy Whitcroftsub ctx_has_comment {
19324a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19334a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
19344a0df2efSAndy Whitcroft
193500df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
19364a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
19374a0df2efSAndy Whitcroft
19384a0df2efSAndy Whitcroft	return ($cmt ne '');
19394a0df2efSAndy Whitcroft}
19404a0df2efSAndy Whitcroft
19414d001e4dSAndy Whitcroftsub raw_line {
19424d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
19434d001e4dSAndy Whitcroft
19444d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
19454d001e4dSAndy Whitcroft	$cnt++;
19464d001e4dSAndy Whitcroft
19474d001e4dSAndy Whitcroft	my $line;
19484d001e4dSAndy Whitcroft	while ($cnt) {
19494d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
19504d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
19514d001e4dSAndy Whitcroft		$cnt--;
19524d001e4dSAndy Whitcroft	}
19534d001e4dSAndy Whitcroft
19544d001e4dSAndy Whitcroft	return $line;
19554d001e4dSAndy Whitcroft}
19564d001e4dSAndy Whitcroft
19572a9f9d85STobin C. Hardingsub get_stat_real {
19582a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
19592a9f9d85STobin C. Harding
19602a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
19612a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
19622a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
19632a9f9d85STobin C. Harding	}
19642a9f9d85STobin C. Harding
19652a9f9d85STobin C. Harding	return $stat_real;
19662a9f9d85STobin C. Harding}
19672a9f9d85STobin C. Harding
1968e3d95a2aSTobin C. Hardingsub get_stat_here {
1969e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1970e3d95a2aSTobin C. Harding
1971e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1972e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1973e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1974e3d95a2aSTobin C. Harding	}
1975e3d95a2aSTobin C. Harding
1976e3d95a2aSTobin C. Harding	return $herectx;
1977e3d95a2aSTobin C. Harding}
1978e3d95a2aSTobin C. Harding
19790a920b5bSAndy Whitcroftsub cat_vet {
19800a920b5bSAndy Whitcroft	my ($vet) = @_;
19819c0ca6f9SAndy Whitcroft	my ($res, $coded);
19820a920b5bSAndy Whitcroft
19839c0ca6f9SAndy Whitcroft	$res = '';
19846c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
19856c72ffaaSAndy Whitcroft		$res .= $1;
19866c72ffaaSAndy Whitcroft		if ($2 ne '') {
19879c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
19886c72ffaaSAndy Whitcroft			$res .= $coded;
19896c72ffaaSAndy Whitcroft		}
19909c0ca6f9SAndy Whitcroft	}
19919c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
19920a920b5bSAndy Whitcroft
19939c0ca6f9SAndy Whitcroft	return $res;
19940a920b5bSAndy Whitcroft}
19950a920b5bSAndy Whitcroft
1996c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1997cf655043SAndy Whitcroftmy $av_pending;
1998c2fdda0dSAndy Whitcroftmy @av_paren_type;
19991f65f947SAndy Whitcroftmy $av_pend_colon;
2000c2fdda0dSAndy Whitcroft
2001c2fdda0dSAndy Whitcroftsub annotate_reset {
2002c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
2003cf655043SAndy Whitcroft	$av_pending = '_';
2004cf655043SAndy Whitcroft	@av_paren_type = ('E');
20051f65f947SAndy Whitcroft	$av_pend_colon = 'O';
2006c2fdda0dSAndy Whitcroft}
2007c2fdda0dSAndy Whitcroft
20086c72ffaaSAndy Whitcroftsub annotate_values {
20096c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
20106c72ffaaSAndy Whitcroft
20116c72ffaaSAndy Whitcroft	my $res;
20121f65f947SAndy Whitcroft	my $var = '_' x length($stream);
20136c72ffaaSAndy Whitcroft	my $cur = $stream;
20146c72ffaaSAndy Whitcroft
2015c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
20166c72ffaaSAndy Whitcroft
20176c72ffaaSAndy Whitcroft	while (length($cur)) {
2018773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
2019cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
2020171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
20216c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
2022c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
2023c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
2024cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
2025c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
20266c72ffaaSAndy Whitcroft			}
20276c72ffaaSAndy Whitcroft
2028c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
20299446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
20309446ef56SAndy Whitcroft			push(@av_paren_type, $type);
2031addcdceaSAndy Whitcroft			$type = 'c';
20329446ef56SAndy Whitcroft
2033e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2034c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
20356c72ffaaSAndy Whitcroft			$type = 'T';
20366c72ffaaSAndy Whitcroft
2037389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
2038389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
2039389a2fe5SAndy Whitcroft			$type = 'T';
2040389a2fe5SAndy Whitcroft
2041c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2042171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2043c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2044171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
2045171ae1a4SAndy Whitcroft			if ($2 ne '') {
2046cf655043SAndy Whitcroft				$av_pending = 'N';
2047171ae1a4SAndy Whitcroft			}
2048171ae1a4SAndy Whitcroft			$type = 'E';
2049171ae1a4SAndy Whitcroft
2050c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2051171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
2052171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
2053171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
20546c72ffaaSAndy Whitcroft
2055c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2056cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
2057c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2058cf655043SAndy Whitcroft
2059cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2060cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2061171ae1a4SAndy Whitcroft			$type = 'E';
2062cf655043SAndy Whitcroft
2063c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2064cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2065cf655043SAndy Whitcroft			$av_preprocessor = 1;
2066cf655043SAndy Whitcroft
2067cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2068cf655043SAndy Whitcroft
2069171ae1a4SAndy Whitcroft			$type = 'E';
2070cf655043SAndy Whitcroft
2071c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2072cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
2073cf655043SAndy Whitcroft
2074cf655043SAndy Whitcroft			$av_preprocessor = 1;
2075cf655043SAndy Whitcroft
2076cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
2077cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
2078cf655043SAndy Whitcroft			pop(@av_paren_type);
2079cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2080171ae1a4SAndy Whitcroft			$type = 'E';
20816c72ffaaSAndy Whitcroft
20826c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
2083c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
20846c72ffaaSAndy Whitcroft
2085171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2086171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2087171ae1a4SAndy Whitcroft			$av_pending = $type;
2088171ae1a4SAndy Whitcroft			$type = 'N';
2089171ae1a4SAndy Whitcroft
20906c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2091c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
20926c72ffaaSAndy Whitcroft			if (defined $2) {
2093cf655043SAndy Whitcroft				$av_pending = 'V';
20946c72ffaaSAndy Whitcroft			}
20956c72ffaaSAndy Whitcroft			$type = 'N';
20966c72ffaaSAndy Whitcroft
209714b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2098c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
209914b111c1SAndy Whitcroft			$av_pending = 'E';
21006c72ffaaSAndy Whitcroft			$type = 'N';
21016c72ffaaSAndy Whitcroft
21021f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
21031f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
21041f65f947SAndy Whitcroft			$av_pend_colon = 'C';
21051f65f947SAndy Whitcroft			$type = 'N';
21061f65f947SAndy Whitcroft
210714b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2108c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
21096c72ffaaSAndy Whitcroft			$type = 'N';
21106c72ffaaSAndy Whitcroft
21116c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2112c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2113cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2114cf655043SAndy Whitcroft			$av_pending = '_';
21156c72ffaaSAndy Whitcroft			$type = 'N';
21166c72ffaaSAndy Whitcroft
21176c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2118cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2119cf655043SAndy Whitcroft			if ($new_type ne '_') {
2120cf655043SAndy Whitcroft				$type = $new_type;
2121c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2122c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
21236c72ffaaSAndy Whitcroft			} else {
2124c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
21256c72ffaaSAndy Whitcroft			}
21266c72ffaaSAndy Whitcroft
2127c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2128c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2129c8cb2ca3SAndy Whitcroft			$type = 'V';
2130cf655043SAndy Whitcroft			$av_pending = 'V';
21316c72ffaaSAndy Whitcroft
21328e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
21338e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
21341f65f947SAndy Whitcroft				$av_pend_colon = 'B';
21358e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
21368e761b04SAndy Whitcroft				$av_pend_colon = 'L';
21371f65f947SAndy Whitcroft			}
21381f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
21391f65f947SAndy Whitcroft			$type = 'V';
21401f65f947SAndy Whitcroft
21416c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2142c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
21436c72ffaaSAndy Whitcroft			$type = 'V';
21446c72ffaaSAndy Whitcroft
21456c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2146c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
21476c72ffaaSAndy Whitcroft			$type = 'N';
21486c72ffaaSAndy Whitcroft
2149cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2150c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
215113214adfSAndy Whitcroft			$type = 'E';
21521f65f947SAndy Whitcroft			$av_pend_colon = 'O';
215313214adfSAndy Whitcroft
21548e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
21558e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
21568e761b04SAndy Whitcroft			$type = 'C';
21578e761b04SAndy Whitcroft
21581f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
21591f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
21601f65f947SAndy Whitcroft			$type = 'N';
21611f65f947SAndy Whitcroft
21621f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
21631f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
21641f65f947SAndy Whitcroft
21651f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
21661f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
21671f65f947SAndy Whitcroft				$type = 'E';
21681f65f947SAndy Whitcroft			} else {
21691f65f947SAndy Whitcroft				$type = 'N';
21701f65f947SAndy Whitcroft			}
21711f65f947SAndy Whitcroft			$av_pend_colon = 'O';
21721f65f947SAndy Whitcroft
21738e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
217413214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
21756c72ffaaSAndy Whitcroft			$type = 'N';
21766c72ffaaSAndy Whitcroft
21770d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
217874048ed8SAndy Whitcroft			my $variant;
217974048ed8SAndy Whitcroft
218074048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
218174048ed8SAndy Whitcroft			if ($type eq 'V') {
218274048ed8SAndy Whitcroft				$variant = 'B';
218374048ed8SAndy Whitcroft			} else {
218474048ed8SAndy Whitcroft				$variant = 'U';
218574048ed8SAndy Whitcroft			}
218674048ed8SAndy Whitcroft
218774048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
218874048ed8SAndy Whitcroft			$type = 'N';
218974048ed8SAndy Whitcroft
21906c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2191c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
21926c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
21936c72ffaaSAndy Whitcroft				$type = 'N';
21946c72ffaaSAndy Whitcroft			}
21956c72ffaaSAndy Whitcroft
21966c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2197c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
21986c72ffaaSAndy Whitcroft		}
21996c72ffaaSAndy Whitcroft		if (defined $1) {
22006c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
22016c72ffaaSAndy Whitcroft			$res .= $type x length($1);
22026c72ffaaSAndy Whitcroft		}
22036c72ffaaSAndy Whitcroft	}
22046c72ffaaSAndy Whitcroft
22051f65f947SAndy Whitcroft	return ($res, $var);
22066c72ffaaSAndy Whitcroft}
22076c72ffaaSAndy Whitcroft
22088905a67cSAndy Whitcroftsub possible {
220913214adfSAndy Whitcroft	my ($possible, $line) = @_;
22109a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
22110776e594SAndy Whitcroft		^(?:
22120776e594SAndy Whitcroft			$Modifier|
22130776e594SAndy Whitcroft			$Storage|
22140776e594SAndy Whitcroft			$Type|
22159a974fdbSAndy Whitcroft			DEFINE_\S+
22169a974fdbSAndy Whitcroft		)$|
22179a974fdbSAndy Whitcroft		^(?:
22180776e594SAndy Whitcroft			goto|
22190776e594SAndy Whitcroft			return|
22200776e594SAndy Whitcroft			case|
22210776e594SAndy Whitcroft			else|
22220776e594SAndy Whitcroft			asm|__asm__|
222389a88353SAndy Whitcroft			do|
222489a88353SAndy Whitcroft			\#|
222589a88353SAndy Whitcroft			\#\#|
22269a974fdbSAndy Whitcroft		)(?:\s|$)|
22270776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
22289a974fdbSAndy Whitcroft	    )}x;
22299a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
22309a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2231c45dcabdSAndy Whitcroft		# Check for modifiers.
2232c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2233c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2234c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2235c45dcabdSAndy Whitcroft
2236c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2237c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2238d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
22399a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2240d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2241485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2242d2506586SAndy Whitcroft				}
22439a974fdbSAndy Whitcroft			}
2244c45dcabdSAndy Whitcroft
2245c45dcabdSAndy Whitcroft		} else {
224613214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2247485ff23eSAlex Dowad			push(@typeListFile, $possible);
2248c45dcabdSAndy Whitcroft		}
22498905a67cSAndy Whitcroft		build_types();
22500776e594SAndy Whitcroft	} else {
22510776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
22528905a67cSAndy Whitcroft	}
22538905a67cSAndy Whitcroft}
22548905a67cSAndy Whitcroft
22556c72ffaaSAndy Whitcroftmy $prefix = '';
22566c72ffaaSAndy Whitcroft
2257000d1cc1SJoe Perchessub show_type {
2258cbec18afSJoe Perches	my ($type) = @_;
225991bfe484SJoe Perches
2260522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2261522b837cSAlexey Dobriyan
2262cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2263cbec18afSJoe Perches
2264cbec18afSJoe Perches	return !defined $ignore_type{$type};
2265000d1cc1SJoe Perches}
2266000d1cc1SJoe Perches
2267f0a594c1SAndy Whitcroftsub report {
2268cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2269cbec18afSJoe Perches
2270cbec18afSJoe Perches	if (!show_type($type) ||
2271cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2272773647a0SAndy Whitcroft		return 0;
2273773647a0SAndy Whitcroft	}
227457230297SJoe Perches	my $output = '';
2275737c0767SJohn Brooks	if ($color) {
227657230297SJoe Perches		if ($level eq 'ERROR') {
227757230297SJoe Perches			$output .= RED;
227857230297SJoe Perches		} elsif ($level eq 'WARNING') {
227957230297SJoe Perches			$output .= YELLOW;
2280000d1cc1SJoe Perches		} else {
228157230297SJoe Perches			$output .= GREEN;
2282000d1cc1SJoe Perches		}
228357230297SJoe Perches	}
228457230297SJoe Perches	$output .= $prefix . $level . ':';
228557230297SJoe Perches	if ($show_types) {
2286737c0767SJohn Brooks		$output .= BLUE if ($color);
228757230297SJoe Perches		$output .= "$type:";
228857230297SJoe Perches	}
2289737c0767SJohn Brooks	$output .= RESET if ($color);
229057230297SJoe Perches	$output .= ' ' . $msg . "\n";
229134d8815fSJoe Perches
229234d8815fSJoe Perches	if ($showfile) {
229334d8815fSJoe Perches		my @lines = split("\n", $output, -1);
229434d8815fSJoe Perches		splice(@lines, 1, 1);
229534d8815fSJoe Perches		$output = join("\n", @lines);
229634d8815fSJoe Perches	}
229752178ce0SDwaipayan Ray
229852178ce0SDwaipayan Ray	if ($terse) {
229952178ce0SDwaipayan Ray		$output = (split('\n', $output))[0] . "\n";
230052178ce0SDwaipayan Ray	}
230152178ce0SDwaipayan Ray
230252178ce0SDwaipayan Ray	if ($verbose && exists($verbose_messages{$type}) &&
230352178ce0SDwaipayan Ray	    !exists($verbose_emitted{$type})) {
230452178ce0SDwaipayan Ray		$output .= $verbose_messages{$type} . "\n\n";
230552178ce0SDwaipayan Ray		$verbose_emitted{$type} = 1;
230652178ce0SDwaipayan Ray	}
23078905a67cSAndy Whitcroft
230857230297SJoe Perches	push(our @report, $output);
2309773647a0SAndy Whitcroft
2310773647a0SAndy Whitcroft	return 1;
2311f0a594c1SAndy Whitcroft}
2312cbec18afSJoe Perches
2313f0a594c1SAndy Whitcroftsub report_dump {
231413214adfSAndy Whitcroft	our @report;
2315f0a594c1SAndy Whitcroft}
2316000d1cc1SJoe Perches
2317d752fcc8SJoe Perchessub fixup_current_range {
2318d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2319d752fcc8SJoe Perches
2320d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2321d752fcc8SJoe Perches		my $o = $1;
2322d752fcc8SJoe Perches		my $l = $2;
2323d752fcc8SJoe Perches		my $no = $o + $offset;
2324d752fcc8SJoe Perches		my $nl = $l + $length;
2325d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2326d752fcc8SJoe Perches	}
2327d752fcc8SJoe Perches}
2328d752fcc8SJoe Perches
2329d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2330d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2331d752fcc8SJoe Perches
2332d752fcc8SJoe Perches	my $range_last_linenr = 0;
2333d752fcc8SJoe Perches	my $delta_offset = 0;
2334d752fcc8SJoe Perches
2335d752fcc8SJoe Perches	my $old_linenr = 0;
2336d752fcc8SJoe Perches	my $new_linenr = 0;
2337d752fcc8SJoe Perches
2338d752fcc8SJoe Perches	my $next_insert = 0;
2339d752fcc8SJoe Perches	my $next_delete = 0;
2340d752fcc8SJoe Perches
2341d752fcc8SJoe Perches	my @lines = ();
2342d752fcc8SJoe Perches
2343d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2344d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2345d752fcc8SJoe Perches
2346d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2347d752fcc8SJoe Perches		my $save_line = 1;
2348d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2349323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2350d752fcc8SJoe Perches			$delta_offset = 0;
2351d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2352d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2353d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2354d752fcc8SJoe Perches		}
2355d752fcc8SJoe Perches
2356d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2357d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2358d752fcc8SJoe Perches			$save_line = 0;
2359d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2360d752fcc8SJoe Perches		}
2361d752fcc8SJoe Perches
2362d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2363d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2364d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2365d752fcc8SJoe Perches			$new_linenr++;
2366d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2367d752fcc8SJoe Perches		}
2368d752fcc8SJoe Perches
2369d752fcc8SJoe Perches		if ($save_line) {
2370d752fcc8SJoe Perches			push(@lines, $line);
2371d752fcc8SJoe Perches			$new_linenr++;
2372d752fcc8SJoe Perches		}
2373d752fcc8SJoe Perches
2374d752fcc8SJoe Perches		$old_linenr++;
2375d752fcc8SJoe Perches	}
2376d752fcc8SJoe Perches
2377d752fcc8SJoe Perches	return @lines;
2378d752fcc8SJoe Perches}
2379d752fcc8SJoe Perches
2380f2d7e4d4SJoe Perchessub fix_insert_line {
2381f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2382f2d7e4d4SJoe Perches
2383f2d7e4d4SJoe Perches	my $inserted = {
2384f2d7e4d4SJoe Perches		LINENR => $linenr,
2385f2d7e4d4SJoe Perches		LINE => $line,
2386f2d7e4d4SJoe Perches	};
2387f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2388f2d7e4d4SJoe Perches}
2389f2d7e4d4SJoe Perches
2390f2d7e4d4SJoe Perchessub fix_delete_line {
2391f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2392f2d7e4d4SJoe Perches
2393f2d7e4d4SJoe Perches	my $deleted = {
2394f2d7e4d4SJoe Perches		LINENR => $linenr,
2395f2d7e4d4SJoe Perches		LINE => $line,
2396f2d7e4d4SJoe Perches	};
2397f2d7e4d4SJoe Perches
2398f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2399f2d7e4d4SJoe Perches}
2400f2d7e4d4SJoe Perches
2401de7d4f0eSAndy Whitcroftsub ERROR {
2402cbec18afSJoe Perches	my ($type, $msg) = @_;
2403cbec18afSJoe Perches
2404cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2405de7d4f0eSAndy Whitcroft		our $clean = 0;
24066c72ffaaSAndy Whitcroft		our $cnt_error++;
24073705ce5bSJoe Perches		return 1;
2408de7d4f0eSAndy Whitcroft	}
24093705ce5bSJoe Perches	return 0;
2410773647a0SAndy Whitcroft}
2411de7d4f0eSAndy Whitcroftsub WARN {
2412cbec18afSJoe Perches	my ($type, $msg) = @_;
2413cbec18afSJoe Perches
2414cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2415de7d4f0eSAndy Whitcroft		our $clean = 0;
24166c72ffaaSAndy Whitcroft		our $cnt_warn++;
24173705ce5bSJoe Perches		return 1;
2418de7d4f0eSAndy Whitcroft	}
24193705ce5bSJoe Perches	return 0;
2420773647a0SAndy Whitcroft}
2421de7d4f0eSAndy Whitcroftsub CHK {
2422cbec18afSJoe Perches	my ($type, $msg) = @_;
2423cbec18afSJoe Perches
2424cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2425de7d4f0eSAndy Whitcroft		our $clean = 0;
24266c72ffaaSAndy Whitcroft		our $cnt_chk++;
24273705ce5bSJoe Perches		return 1;
24286c72ffaaSAndy Whitcroft	}
24293705ce5bSJoe Perches	return 0;
2430de7d4f0eSAndy Whitcroft}
2431de7d4f0eSAndy Whitcroft
24326ecd9674SAndy Whitcroftsub check_absolute_file {
24336ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
24346ecd9674SAndy Whitcroft	my $file = $absolute;
24356ecd9674SAndy Whitcroft
24366ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
24376ecd9674SAndy Whitcroft
24386ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
24396ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
24406ecd9674SAndy Whitcroft		if (-f "$root/$file") {
24416ecd9674SAndy Whitcroft			##print "file<$file>\n";
24426ecd9674SAndy Whitcroft			last;
24436ecd9674SAndy Whitcroft		}
24446ecd9674SAndy Whitcroft	}
24456ecd9674SAndy Whitcroft	if (! -f _)  {
24466ecd9674SAndy Whitcroft		return 0;
24476ecd9674SAndy Whitcroft	}
24486ecd9674SAndy Whitcroft
24496ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
24506ecd9674SAndy Whitcroft	my $prefix = $absolute;
24516ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
24526ecd9674SAndy Whitcroft
24536ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
24546ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2455000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2456000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
24576ecd9674SAndy Whitcroft	}
24586ecd9674SAndy Whitcroft}
24596ecd9674SAndy Whitcroft
24603705ce5bSJoe Perchessub trim {
24613705ce5bSJoe Perches	my ($string) = @_;
24623705ce5bSJoe Perches
2463b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2464b34c648bSJoe Perches
2465b34c648bSJoe Perches	return $string;
2466b34c648bSJoe Perches}
2467b34c648bSJoe Perches
2468b34c648bSJoe Perchessub ltrim {
2469b34c648bSJoe Perches	my ($string) = @_;
2470b34c648bSJoe Perches
2471b34c648bSJoe Perches	$string =~ s/^\s+//;
2472b34c648bSJoe Perches
2473b34c648bSJoe Perches	return $string;
2474b34c648bSJoe Perches}
2475b34c648bSJoe Perches
2476b34c648bSJoe Perchessub rtrim {
2477b34c648bSJoe Perches	my ($string) = @_;
2478b34c648bSJoe Perches
2479b34c648bSJoe Perches	$string =~ s/\s+$//;
24803705ce5bSJoe Perches
24813705ce5bSJoe Perches	return $string;
24823705ce5bSJoe Perches}
24833705ce5bSJoe Perches
248452ea8506SJoe Perchessub string_find_replace {
248552ea8506SJoe Perches	my ($string, $find, $replace) = @_;
248652ea8506SJoe Perches
248752ea8506SJoe Perches	$string =~ s/$find/$replace/g;
248852ea8506SJoe Perches
248952ea8506SJoe Perches	return $string;
249052ea8506SJoe Perches}
249152ea8506SJoe Perches
24923705ce5bSJoe Perchessub tabify {
24933705ce5bSJoe Perches	my ($leading) = @_;
24943705ce5bSJoe Perches
2495713a09deSAntonio Borneo	my $source_indent = $tabsize;
24963705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
24973705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
24983705ce5bSJoe Perches
24993705ce5bSJoe Perches	#convert leading spaces to tabs
25003705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
25013705ce5bSJoe Perches	#Remove spaces before a tab
25023705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
25033705ce5bSJoe Perches
25043705ce5bSJoe Perches	return "$leading";
25053705ce5bSJoe Perches}
25063705ce5bSJoe Perches
2507d1fe9c09SJoe Perchessub pos_last_openparen {
2508d1fe9c09SJoe Perches	my ($line) = @_;
2509d1fe9c09SJoe Perches
2510d1fe9c09SJoe Perches	my $pos = 0;
2511d1fe9c09SJoe Perches
2512d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2513d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2514d1fe9c09SJoe Perches
2515d1fe9c09SJoe Perches	my $last_openparen = 0;
2516d1fe9c09SJoe Perches
2517d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2518d1fe9c09SJoe Perches		return -1;
2519d1fe9c09SJoe Perches	}
2520d1fe9c09SJoe Perches
2521d1fe9c09SJoe Perches	my $len = length($line);
2522d1fe9c09SJoe Perches
2523d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2524d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2525d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2526d1fe9c09SJoe Perches			$pos += length($1) - 1;
2527d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2528d1fe9c09SJoe Perches			$last_openparen = $pos;
2529d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2530d1fe9c09SJoe Perches			last;
2531d1fe9c09SJoe Perches		}
2532d1fe9c09SJoe Perches	}
2533d1fe9c09SJoe Perches
253491cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2535d1fe9c09SJoe Perches}
2536d1fe9c09SJoe Perches
2537f36d3eb8SJoe Perchessub get_raw_comment {
2538f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2539f36d3eb8SJoe Perches	my $comment = '';
2540f36d3eb8SJoe Perches
2541f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2542f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2543f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2544f36d3eb8SJoe Perches		}
2545f36d3eb8SJoe Perches	}
2546f36d3eb8SJoe Perches
2547f36d3eb8SJoe Perches	return $comment;
2548f36d3eb8SJoe Perches}
2549f36d3eb8SJoe Perches
25505b8f82e1SSong Liusub exclude_global_initialisers {
25515b8f82e1SSong Liu	my ($realfile) = @_;
25525b8f82e1SSong Liu
25535b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
25545b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
25555b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
25565b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
25575b8f82e1SSong Liu}
25585b8f82e1SSong Liu
25590a920b5bSAndy Whitcroftsub process {
25600a920b5bSAndy Whitcroft	my $filename = shift;
25610a920b5bSAndy Whitcroft
25620a920b5bSAndy Whitcroft	my $linenr=0;
25630a920b5bSAndy Whitcroft	my $prevline="";
2564c2fdda0dSAndy Whitcroft	my $prevrawline="";
25650a920b5bSAndy Whitcroft	my $stashline="";
2566c2fdda0dSAndy Whitcroft	my $stashrawline="";
25670a920b5bSAndy Whitcroft
25684a0df2efSAndy Whitcroft	my $length;
25690a920b5bSAndy Whitcroft	my $indent;
25700a920b5bSAndy Whitcroft	my $previndent=0;
25710a920b5bSAndy Whitcroft	my $stashindent=0;
25720a920b5bSAndy Whitcroft
2573de7d4f0eSAndy Whitcroft	our $clean = 1;
25740a920b5bSAndy Whitcroft	my $signoff = 0;
2575cd261496SGeert Uytterhoeven	my $author = '';
2576cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
257748ca2d8aSDwaipayan Ray	my $author_sob = '';
25780a920b5bSAndy Whitcroft	my $is_patch = 0;
2579133712a2SRob Herring	my $is_binding_patch = -1;
258029ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
258115662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
258244d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2583ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2584490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2585bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
25862a076f40SJoe Perches	my $commit_log_long_line = 0;
2587e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
258813f1937eSJoe Perches	my $reported_maintainer_file = 0;
2589fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2590fa64205dSPasi Savanainen
2591*4ce9f970SJoe Perches	my $last_git_commit_id_linenr = -1;
2592*4ce9f970SJoe Perches
2593365dd4eaSJoe Perches	my $last_blank_line = 0;
25945e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2595365dd4eaSJoe Perches
259613214adfSAndy Whitcroft	our @report = ();
25976c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
25986c72ffaaSAndy Whitcroft	our $cnt_error = 0;
25996c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
26006c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
26016c72ffaaSAndy Whitcroft
26020a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
26030a920b5bSAndy Whitcroft	my $realfile = '';
26040a920b5bSAndy Whitcroft	my $realline = 0;
26050a920b5bSAndy Whitcroft	my $realcnt = 0;
26060a920b5bSAndy Whitcroft	my $here = '';
260777cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
26080a920b5bSAndy Whitcroft	my $in_comment = 0;
2609c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
26100a920b5bSAndy Whitcroft	my $first_line = 0;
26111e855726SWolfram Sang	my $p1_prefix = '';
26120a920b5bSAndy Whitcroft
261313214adfSAndy Whitcroft	my $prev_values = 'E';
261413214adfSAndy Whitcroft
261513214adfSAndy Whitcroft	# suppression flags
2616773647a0SAndy Whitcroft	my %suppress_ifbraces;
2617170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
26182b474a1aSAndy Whitcroft	my %suppress_export;
26193e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2620653d4876SAndy Whitcroft
26217e51f197SJoe Perches	my %signatures = ();
2622323c1260SJoe Perches
2623c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2624de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2625c2fdda0dSAndy Whitcroft	#
2626de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2627de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2628773647a0SAndy Whitcroft
2629d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2630d8b07710SJoe Perches
26319f3a8992SRob Herring	my $checklicenseline = 1;
26329f3a8992SRob Herring
2633773647a0SAndy Whitcroft	sanitise_line_reset();
2634c2fdda0dSAndy Whitcroft	my $line;
2635c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2636773647a0SAndy Whitcroft		$linenr++;
2637773647a0SAndy Whitcroft		$line = $rawline;
2638c2fdda0dSAndy Whitcroft
26393705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
26403705ce5bSJoe Perches
2641773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2642de7d4f0eSAndy Whitcroft			$setup_docs = 0;
26432581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2644de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2645de7d4f0eSAndy Whitcroft			}
2646773647a0SAndy Whitcroft			#next;
2647de7d4f0eSAndy Whitcroft		}
264874fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2649773647a0SAndy Whitcroft			$realline=$1-1;
2650773647a0SAndy Whitcroft			if (defined $2) {
2651773647a0SAndy Whitcroft				$realcnt=$3+1;
2652773647a0SAndy Whitcroft			} else {
2653773647a0SAndy Whitcroft				$realcnt=1+1;
2654773647a0SAndy Whitcroft			}
2655c45dcabdSAndy Whitcroft			$in_comment = 0;
2656773647a0SAndy Whitcroft
2657773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2658773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2659773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2660773647a0SAndy Whitcroft			# at context start.
2661773647a0SAndy Whitcroft			my $edge;
266201fa9147SAndy Whitcroft			my $cnt = $realcnt;
266301fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
266401fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
266501fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
266601fa9147SAndy Whitcroft				$cnt--;
266701fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2668721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2669fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2670fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2671fae17daeSAndy Whitcroft					($edge) = $1;
2672fae17daeSAndy Whitcroft					last;
2673fae17daeSAndy Whitcroft				}
2674773647a0SAndy Whitcroft			}
2675773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2676773647a0SAndy Whitcroft				$in_comment = 1;
2677773647a0SAndy Whitcroft			}
2678773647a0SAndy Whitcroft
2679773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2680773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2681773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2682773647a0SAndy Whitcroft			if (!defined $edge &&
268383242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2684773647a0SAndy Whitcroft			{
2685773647a0SAndy Whitcroft				$in_comment = 1;
2686773647a0SAndy Whitcroft			}
2687773647a0SAndy Whitcroft
2688773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2689773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2690773647a0SAndy Whitcroft
2691171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2692773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2693171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2694773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2695773647a0SAndy Whitcroft		}
2696773647a0SAndy Whitcroft		push(@lines, $line);
2697773647a0SAndy Whitcroft
2698773647a0SAndy Whitcroft		if ($realcnt > 1) {
2699773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2700773647a0SAndy Whitcroft		} else {
2701773647a0SAndy Whitcroft			$realcnt = 0;
2702773647a0SAndy Whitcroft		}
2703773647a0SAndy Whitcroft
2704773647a0SAndy Whitcroft		#print "==>$rawline\n";
2705773647a0SAndy Whitcroft		#print "-->$line\n";
2706de7d4f0eSAndy Whitcroft
2707de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2708de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2709de7d4f0eSAndy Whitcroft		}
2710de7d4f0eSAndy Whitcroft	}
2711de7d4f0eSAndy Whitcroft
27126c72ffaaSAndy Whitcroft	$prefix = '';
27136c72ffaaSAndy Whitcroft
2714773647a0SAndy Whitcroft	$realcnt = 0;
2715773647a0SAndy Whitcroft	$linenr = 0;
2716194f66fcSJoe Perches	$fixlinenr = -1;
27170a920b5bSAndy Whitcroft	foreach my $line (@lines) {
27180a920b5bSAndy Whitcroft		$linenr++;
2719194f66fcSJoe Perches		$fixlinenr++;
27201b5539b1SJoe Perches		my $sline = $line;	#copy of $line
27211b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
27220a920b5bSAndy Whitcroft
2723c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2724f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
27256c72ffaaSAndy Whitcroft
272612c253abSJoe Perches# check if it's a mode change, rename or start of a patch
272712c253abSJoe Perches		if (!$in_commit_log &&
272812c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
272912c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
273012c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
273112c253abSJoe Perches			$is_patch = 1;
273212c253abSJoe Perches		}
273312c253abSJoe Perches
27340a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2735e518e9a5SJoe Perches		if (!$in_commit_log &&
273674fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
273774fd4f34SJoe Perches			my $context = $4;
27380a920b5bSAndy Whitcroft			$is_patch = 1;
27394a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
27400a920b5bSAndy Whitcroft			$realline=$1-1;
27410a920b5bSAndy Whitcroft			if (defined $2) {
27420a920b5bSAndy Whitcroft				$realcnt=$3+1;
27430a920b5bSAndy Whitcroft			} else {
27440a920b5bSAndy Whitcroft				$realcnt=1+1;
27450a920b5bSAndy Whitcroft			}
2746c2fdda0dSAndy Whitcroft			annotate_reset();
274713214adfSAndy Whitcroft			$prev_values = 'E';
274813214adfSAndy Whitcroft
2749773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2750170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
27512b474a1aSAndy Whitcroft			%suppress_export = ();
27523e469cdcSAndy Whitcroft			$suppress_statement = 0;
275374fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
275474fd4f34SJoe Perches				$context_function = $1;
275574fd4f34SJoe Perches			} else {
275674fd4f34SJoe Perches				undef $context_function;
275774fd4f34SJoe Perches			}
27580a920b5bSAndy Whitcroft			next;
27590a920b5bSAndy Whitcroft
27604a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
27614a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
27624a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2763773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
27640a920b5bSAndy Whitcroft			$realline++;
2765d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
27660a920b5bSAndy Whitcroft
27674a0df2efSAndy Whitcroft			# Measure the line length and indent.
2768c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
27690a920b5bSAndy Whitcroft
27700a920b5bSAndy Whitcroft			# Track the previous line.
27710a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
27720a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2773c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2774c2fdda0dSAndy Whitcroft
2775773647a0SAndy Whitcroft			#warn "line<$line>\n";
27766c72ffaaSAndy Whitcroft
2777d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2778d8aaf121SAndy Whitcroft			$realcnt--;
27790a920b5bSAndy Whitcroft		}
27800a920b5bSAndy Whitcroft
2781cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2782cc77cdcaSAndy Whitcroft
27836c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
27846c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2785773647a0SAndy Whitcroft
27862ac73b4fSJoe Perches		my $found_file = 0;
2787773647a0SAndy Whitcroft		# extract the filename as it passes
27883bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
27893bf9a009SRabin Vincent			$realfile = $1;
27902b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2791270c49a0SJoe Perches			$in_commit_log = 0;
27922ac73b4fSJoe Perches			$found_file = 1;
27933bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2794773647a0SAndy Whitcroft			$realfile = $1;
27952b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2796270c49a0SJoe Perches			$in_commit_log = 0;
27971e855726SWolfram Sang
27981e855726SWolfram Sang			$p1_prefix = $1;
2799e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2800e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2801000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2802000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
28031e855726SWolfram Sang			}
2804773647a0SAndy Whitcroft
2805c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2806000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2807000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2808773647a0SAndy Whitcroft			}
28092ac73b4fSJoe Perches			$found_file = 1;
28102ac73b4fSJoe Perches		}
28112ac73b4fSJoe Perches
281234d8815fSJoe Perches#make up the handle for any error we report on this line
281334d8815fSJoe Perches		if ($showfile) {
281434d8815fSJoe Perches			$prefix = "$realfile:$realline: "
281534d8815fSJoe Perches		} elsif ($emacs) {
28167d3a9f67SJoe Perches			if ($file) {
28177d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
28187d3a9f67SJoe Perches			} else {
281934d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
282034d8815fSJoe Perches			}
28217d3a9f67SJoe Perches		}
282234d8815fSJoe Perches
28232ac73b4fSJoe Perches		if ($found_file) {
282485b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
282585b0ee18SJoe Perches				WARN("OBSOLETE",
282685b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
282785b0ee18SJoe Perches			}
28287bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
28292ac73b4fSJoe Perches				$check = 1;
28302ac73b4fSJoe Perches			} else {
28312ac73b4fSJoe Perches				$check = $check_orig;
28322ac73b4fSJoe Perches			}
28339f3a8992SRob Herring			$checklicenseline = 1;
2834133712a2SRob Herring
2835133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2836133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2837133712a2SRob Herring
2838133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2839133712a2SRob Herring
2840133712a2SRob Herring				if (($last_binding_patch != -1) &&
2841133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2842133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2843858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2844133712a2SRob Herring				}
2845133712a2SRob Herring			}
2846133712a2SRob Herring
2847773647a0SAndy Whitcroft			next;
2848773647a0SAndy Whitcroft		}
2849773647a0SAndy Whitcroft
2850389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
28510a920b5bSAndy Whitcroft
2852c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2853c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2854c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
28550a920b5bSAndy Whitcroft
28566c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
28576c72ffaaSAndy Whitcroft
2858490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2859490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2860490b292cSJoe Perches		if ($in_commit_log) {
2861490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2862490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2863490b292cSJoe Perches			}
2864490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2865490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2866490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2867490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2868490b292cSJoe Perches		}
2869490b292cSJoe Perches
2870e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2871e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
287213e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
287313e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2874e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2875e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2876e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2877e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2878e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2879e518e9a5SJoe Perches		}
2880e518e9a5SJoe Perches
28813bf9a009SRabin Vincent# Check for incorrect file permissions
28823bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
28833bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
288404db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
288504db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2886000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2887000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
28883bf9a009SRabin Vincent			}
28893bf9a009SRabin Vincent		}
28903bf9a009SRabin Vincent
2891cd261496SGeert Uytterhoeven# Check the patch for a From:
2892cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2893cd261496SGeert Uytterhoeven			$author = $1;
2894e7f929f3SDwaipayan Ray			my $curline = $linenr;
2895e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2896e7f929f3SDwaipayan Ray				$author .= $1;
2897e7f929f3SDwaipayan Ray			}
2898cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2899cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2900dfa05c28SJoe Perches			$author = reformat_email($author);
2901cd261496SGeert Uytterhoeven		}
2902cd261496SGeert Uytterhoeven
290320112475SJoe Perches# Check the patch for a signoff:
2904dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
29054a0df2efSAndy Whitcroft			$signoff++;
290615662b3eSJoe Perches			$in_commit_log = 0;
290748ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2908fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2909cd261496SGeert Uytterhoeven					$authorsignoff = 1;
291048ca2d8aSDwaipayan Ray				} else {
291148ca2d8aSDwaipayan Ray					my $ctx = $1;
291248ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
291348ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
291448ca2d8aSDwaipayan Ray
2915046fc741SMimi Zohar					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
291648ca2d8aSDwaipayan Ray						$author_sob = $ctx;
291748ca2d8aSDwaipayan Ray						$authorsignoff = 2;
2918046fc741SMimi Zohar					} elsif (lc $email_address eq lc $author_address) {
291948ca2d8aSDwaipayan Ray						$author_sob = $ctx;
292048ca2d8aSDwaipayan Ray						$authorsignoff = 3;
292148ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
292248ca2d8aSDwaipayan Ray						$author_sob = $ctx;
292348ca2d8aSDwaipayan Ray						$authorsignoff = 4;
292448ca2d8aSDwaipayan Ray
292548ca2d8aSDwaipayan Ray						my $address1 = $email_address;
292648ca2d8aSDwaipayan Ray						my $address2 = $author_address;
292748ca2d8aSDwaipayan Ray
292848ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
292948ca2d8aSDwaipayan Ray							$address1 = "$1$2";
293048ca2d8aSDwaipayan Ray						}
293148ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
293248ca2d8aSDwaipayan Ray							$address2 = "$1$2";
293348ca2d8aSDwaipayan Ray						}
293448ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
293548ca2d8aSDwaipayan Ray							$authorsignoff = 5;
293648ca2d8aSDwaipayan Ray						}
293748ca2d8aSDwaipayan Ray					}
2938cd261496SGeert Uytterhoeven				}
2939cd261496SGeert Uytterhoeven			}
29400a920b5bSAndy Whitcroft		}
294120112475SJoe Perches
294244d303ebSJoe Perches# Check for patch separator
294344d303ebSJoe Perches		if ($line =~ /^---$/) {
294444d303ebSJoe Perches			$has_patch_separator = 1;
294544d303ebSJoe Perches			$in_commit_log = 0;
294644d303ebSJoe Perches		}
294744d303ebSJoe Perches
2948e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2949e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2950e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2951e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2952e0d975b1SJoe Perches		}
2953e0d975b1SJoe Perches
295420112475SJoe Perches# Check signature styles
2955270c49a0SJoe Perches		if (!$in_header_lines &&
2956ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
295720112475SJoe Perches			my $space_before = $1;
295820112475SJoe Perches			my $sign_off = $2;
295920112475SJoe Perches			my $space_after = $3;
296020112475SJoe Perches			my $email = $4;
296120112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
296220112475SJoe Perches
2963ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2964831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
2965831242abSAditya Srivastava				if ($suggested_signature eq "") {
2966ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
2967ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
2968831242abSAditya Srivastava				} else {
2969831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
2970831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2971831242abSAditya Srivastava					    $fix) {
2972831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2973831242abSAditya Srivastava					}
2974831242abSAditya Srivastava				}
2975ce0338dfSJoe Perches			}
297620112475SJoe Perches			if (defined $space_before && $space_before ne "") {
29773705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29783705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
29793705ce5bSJoe Perches				    $fix) {
2980194f66fcSJoe Perches					$fixed[$fixlinenr] =
29813705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29823705ce5bSJoe Perches				}
298320112475SJoe Perches			}
298420112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
29853705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29863705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
29873705ce5bSJoe Perches				    $fix) {
2988194f66fcSJoe Perches					$fixed[$fixlinenr] =
29893705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29903705ce5bSJoe Perches				}
29913705ce5bSJoe Perches
299220112475SJoe Perches			}
299320112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
29943705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29953705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
29963705ce5bSJoe Perches				    $fix) {
2997194f66fcSJoe Perches					$fixed[$fixlinenr] =
29983705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29993705ce5bSJoe Perches				}
300020112475SJoe Perches			}
300120112475SJoe Perches
3002dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
300348ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
300420112475SJoe Perches			if ($suggested_email eq "") {
3005000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
3006000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
300720112475SJoe Perches			} else {
300820112475SJoe Perches				my $dequoted = $suggested_email;
300920112475SJoe Perches				$dequoted =~ s/^"//;
301020112475SJoe Perches				$dequoted =~ s/" </ </;
301120112475SJoe Perches				# Don't force email to have quotes
301220112475SJoe Perches				# Allow just an angle bracketed address
3013fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
3014fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3015fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3016fccaebf0SDwaipayan Ray					    $fix) {
3017fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3018fccaebf0SDwaipayan Ray					}
3019fccaebf0SDwaipayan Ray				}
3020fccaebf0SDwaipayan Ray
3021fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
3022fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
3023fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
3024fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
3025fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3026fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3027fccaebf0SDwaipayan Ray					    $fix) {
3028fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3029fccaebf0SDwaipayan Ray					}
3030fccaebf0SDwaipayan Ray				}
3031fccaebf0SDwaipayan Ray
3032fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
3033fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3034fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
3035000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
3036fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
3037fccaebf0SDwaipayan Ray				}
3038fccaebf0SDwaipayan Ray
3039fccaebf0SDwaipayan Ray
3040fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
3041e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
3042fccaebf0SDwaipayan Ray				# begin with a #
3043fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3044fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
3045fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
3046fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
3047fccaebf0SDwaipayan Ray						my $new_comment = $comment;
3048fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3049fccaebf0SDwaipayan Ray
3050fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
3051fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
3052fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
3053fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
3054fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
3055fccaebf0SDwaipayan Ray
3056fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3057fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
3058fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
3059fccaebf0SDwaipayan Ray
3060fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3061fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3062fccaebf0SDwaipayan Ray						    $fix) {
3063fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3064fccaebf0SDwaipayan Ray						}
3065fccaebf0SDwaipayan Ray					}
3066fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3067fccaebf0SDwaipayan Ray					my $new_comment = $comment;
3068fccaebf0SDwaipayan Ray
3069fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
3070fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
3071fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
3072fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3073fccaebf0SDwaipayan Ray
3074fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
3075fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3076fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
3077fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3078fccaebf0SDwaipayan Ray
3079fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3080fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3081fccaebf0SDwaipayan Ray					    $fix) {
3082fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3083fccaebf0SDwaipayan Ray					}
308420112475SJoe Perches				}
30850a920b5bSAndy Whitcroft			}
30867e51f197SJoe Perches
30877e51f197SJoe Perches# Check for duplicate signatures
30887e51f197SJoe Perches			my $sig_nospace = $line;
30897e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
30907e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
30917e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
30927e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
30937e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
30947e51f197SJoe Perches			} else {
30957e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
30967e51f197SJoe Perches			}
30976c5d24eeSSean Christopherson
30986c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
30996c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
31006c5d24eeSSean Christopherson				if ($email eq $author) {
31016c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31026c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
31036c5d24eeSSean Christopherson				}
31046c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
31056c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31066c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
31076c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
31086c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31096c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31106c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
31116c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31126c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31136c5d24eeSSean Christopherson				}
31146c5d24eeSSean Christopherson			}
31150a920b5bSAndy Whitcroft		}
31160a920b5bSAndy Whitcroft
3117a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3118a2fe16b9SJoe Perches		if ($in_header_lines &&
3119a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3120a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3121a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3122a2fe16b9SJoe Perches		}
3123a2fe16b9SJoe Perches
312444d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
312544d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
31267580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
31277580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
31287580c5b9SAditya Srivastava			    $fix) {
31297580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
31307580c5b9SAditya Srivastava			}
31317ebd05efSChristopher Covington		}
31327ebd05efSChristopher Covington
3133369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3134369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3135369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3136369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3137369c8dd3SJoe Perches					# timestamp
3138634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3139634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3140634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3141634cffccSJoe Perches					# stack dump address styles
3142369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3143369c8dd3SJoe Perches		}
3144369c8dd3SJoe Perches
31452a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
31462a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3147bf4daf12SJoe Perches		    length($line) > 75 &&
3148bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3149bf4daf12SJoe Perches					# file delta changes
3150bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
3151bf4daf12SJoe Perches					# filename then :
315227b379afSAditya Srivastava		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
315327b379afSAditya Srivastava					# A Fixes: or Link: line or signature tag line
3154bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
31552a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
31562a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
31572a076f40SJoe Perches			$commit_log_long_line = 1;
31582a076f40SJoe Perches		}
31592a076f40SJoe Perches
3160bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3161bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3162bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3163bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3164bf4daf12SJoe Perches		}
3165bf4daf12SJoe Perches
3166084a617aSDwaipayan Ray# Check for lines starting with a #
3167084a617aSDwaipayan Ray		if ($in_commit_log && $line =~ /^#/) {
3168084a617aSDwaipayan Ray			if (WARN("COMMIT_COMMENT_SYMBOL",
3169084a617aSDwaipayan Ray				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3170084a617aSDwaipayan Ray			    $fix) {
3171084a617aSDwaipayan Ray				$fixed[$fixlinenr] =~ s/^/ /;
3172084a617aSDwaipayan Ray			}
3173084a617aSDwaipayan Ray		}
3174084a617aSDwaipayan Ray
31750d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
3176*4ce9f970SJoe Perches# A correctly formed commit description is:
3177*4ce9f970SJoe Perches#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
3178*4ce9f970SJoe Perches# with the commit subject '("' prefix and '")' suffix
3179*4ce9f970SJoe Perches# This is a fairly compilicated block as it tests for what appears to be
3180*4ce9f970SJoe Perches# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
3181*4ce9f970SJoe Perches# possible SHA-1 matches.
3182*4ce9f970SJoe Perches# A commit match can span multiple lines so this block attempts to find a
3183*4ce9f970SJoe Perches# complete typical commit on a maximum of 3 lines
3184*4ce9f970SJoe Perches		if ($perl_version_ok &&
3185*4ce9f970SJoe Perches		    $in_commit_log && !$commit_log_possible_stack_dump &&
3186a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3187e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
3188*4ce9f970SJoe Perches		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3189*4ce9f970SJoe Perches		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
3190aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3191369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3192bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3193fe043ea1SJoe Perches			my $init_char = "c";
3194fe043ea1SJoe Perches			my $orig_commit = "";
31950d7835fcSJoe Perches			my $short = 1;
31960d7835fcSJoe Perches			my $long = 0;
31970d7835fcSJoe Perches			my $case = 1;
31980d7835fcSJoe Perches			my $space = 1;
31990d7835fcSJoe Perches			my $id = '0123456789ab';
32000d7835fcSJoe Perches			my $orig_desc = "commit description";
32010d7835fcSJoe Perches			my $description = "";
3202*4ce9f970SJoe Perches			my $herectx = $herecurr;
3203*4ce9f970SJoe Perches			my $has_parens = 0;
3204*4ce9f970SJoe Perches			my $has_quotes = 0;
32050d7835fcSJoe Perches
3206*4ce9f970SJoe Perches			my $input = $line;
3207*4ce9f970SJoe Perches			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
3208*4ce9f970SJoe Perches				for (my $n = 0; $n < 2; $n++) {
3209*4ce9f970SJoe Perches					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
3210*4ce9f970SJoe Perches						$orig_desc = $1;
3211*4ce9f970SJoe Perches						$has_parens = 1;
3212*4ce9f970SJoe Perches						# Always strip leading/trailing parens then double quotes if existing
3213*4ce9f970SJoe Perches						$orig_desc = substr($orig_desc, 1, -1);
3214*4ce9f970SJoe Perches						if ($orig_desc =~ /^".*"$/) {
3215*4ce9f970SJoe Perches							$orig_desc = substr($orig_desc, 1, -1);
3216*4ce9f970SJoe Perches							$has_quotes = 1;
3217*4ce9f970SJoe Perches						}
3218*4ce9f970SJoe Perches						last;
3219*4ce9f970SJoe Perches					}
3220*4ce9f970SJoe Perches					last if ($#lines < $linenr + $n);
3221*4ce9f970SJoe Perches					$input .= " " . trim($rawlines[$linenr + $n]);
3222*4ce9f970SJoe Perches					$herectx .= "$rawlines[$linenr + $n]\n";
3223*4ce9f970SJoe Perches				}
3224*4ce9f970SJoe Perches				$herectx = $herecurr if (!$has_parens);
3225fe043ea1SJoe Perches			}
3226fe043ea1SJoe Perches
3227*4ce9f970SJoe Perches			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3228*4ce9f970SJoe Perches				$init_char = $1;
3229*4ce9f970SJoe Perches				$orig_commit = lc($2);
3230*4ce9f970SJoe Perches				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
3231*4ce9f970SJoe Perches				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
3232*4ce9f970SJoe Perches				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
3233*4ce9f970SJoe Perches				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
3234*4ce9f970SJoe Perches			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
3235*4ce9f970SJoe Perches				$orig_commit = lc($1);
32360d7835fcSJoe Perches			}
32370d7835fcSJoe Perches
32380d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
32390d7835fcSJoe Perches							      $id, $orig_desc);
32400d7835fcSJoe Perches
3241948b133aSHeinrich Schuchardt			if (defined($id) &&
3242*4ce9f970SJoe Perches			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
3243*4ce9f970SJoe Perches			    $last_git_commit_id_linenr != $linenr - 1) {
3244d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
3245*4ce9f970SJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
32460d7835fcSJoe Perches			}
3247*4ce9f970SJoe Perches			#don't report the next line if this line ends in commit and the sha1 hash is the next line
3248*4ce9f970SJoe Perches			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
3249d311cd44SJoe Perches		}
3250d311cd44SJoe Perches
325113f1937eSJoe Perches# Check for added, moved or deleted files
325213f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
325313f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
325413f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
325513f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
325613f1937eSJoe Perches		      (defined($1) || defined($2))))) {
3257a82603a8SAndrew Jeffery			$is_patch = 1;
325813f1937eSJoe Perches			$reported_maintainer_file = 1;
325913f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
326013f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
326113f1937eSJoe Perches		}
326213f1937eSJoe Perches
3263e400edb1SRob Herring# Check for adding new DT bindings not in schema format
3264e400edb1SRob Herring		if (!$in_commit_log &&
3265e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3266e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3267e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
326856ddc4cdSMauro Carvalho Chehab			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3269e400edb1SRob Herring		}
3270e400edb1SRob Herring
327100df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
32728905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3273000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
3274000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
32756c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
3276de7d4f0eSAndy Whitcroft		}
3277de7d4f0eSAndy Whitcroft
3278de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3279de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3280171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
3281171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3282171ae1a4SAndy Whitcroft
3283171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
3284171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3285171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
3286171ae1a4SAndy Whitcroft
328734d99219SJoe Perches			CHK("INVALID_UTF8",
3288000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
328900df344fSAndy Whitcroft		}
32900a920b5bSAndy Whitcroft
329115662b3eSJoe Perches# Check if it's the start of a commit log
329215662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
329315662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
3294eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
3295eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
329615662b3eSJoe Perches			$in_header_lines = 0;
329715662b3eSJoe Perches			$in_commit_log = 1;
3298ed43c4e5SAllen Hubbe			$has_commit_log = 1;
329915662b3eSJoe Perches		}
330015662b3eSJoe Perches
3301fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
3302fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
3303fa64205dSPasi Savanainen		if ($in_header_lines &&
3304fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3305fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
3306fa64205dSPasi Savanainen			$non_utf8_charset = 1;
3307fa64205dSPasi Savanainen		}
3308fa64205dSPasi Savanainen
3309fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
331015662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3311fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
331215662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
331315662b3eSJoe Perches		}
331415662b3eSJoe Perches
3315d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3316d6430f71SJoe Perches		if ($tree && $in_commit_log) {
3317d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3318d6430f71SJoe Perches				my $file = $1;
3319d6430f71SJoe Perches
3320d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3321d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
3322d6430f71SJoe Perches					#
3323d6430f71SJoe Perches				} else {
3324d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
3325d6430f71SJoe Perches				}
3326d6430f71SJoe Perches			}
3327d6430f71SJoe Perches		}
3328d6430f71SJoe Perches
332966b47b4aSKees Cook# Check for various typo / spelling mistakes
333066d7a382SJoe Perches		if (defined($misspellings) &&
333166d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
33327da07c31SDwaipayan Ray			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
333366b47b4aSKees Cook				my $typo = $1;
33347da07c31SDwaipayan Ray				my $blank = copy_spacing($rawline);
33357da07c31SDwaipayan Ray				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
33367da07c31SDwaipayan Ray				my $hereptr = "$hereline$ptr\n";
333766b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
333866b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
333966b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
33400675a8fbSJean Delvare				my $msg_level = \&WARN;
33410675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
33420675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
33437da07c31SDwaipayan Ray						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
334466b47b4aSKees Cook				    $fix) {
334566b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
334666b47b4aSKees Cook				}
334766b47b4aSKees Cook			}
334866b47b4aSKees Cook		}
334966b47b4aSKees Cook
3350a8dd86bfSMatteo Croce# check for invalid commit id
3351a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3352a8dd86bfSMatteo Croce			my $id;
3353a8dd86bfSMatteo Croce			my $description;
3354a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
3355a8dd86bfSMatteo Croce			if (!defined($id)) {
3356a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
3357a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3358a8dd86bfSMatteo Croce			}
3359a8dd86bfSMatteo Croce		}
3360a8dd86bfSMatteo Croce
3361310cd06bSJoe Perches# check for repeated words separated by a single space
33628d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
33638d0325ccSAditya Srivastava		if (($rawline =~ /^\+/ || $in_commit_log) &&
33648d0325ccSAditya Srivastava		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
33651db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3366310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3367310cd06bSJoe Perches
3368310cd06bSJoe Perches				my $first = $1;
3369310cd06bSJoe Perches				my $second = $2;
33701db81a68SDwaipayan Ray				my $start_pos = $-[1];
33711db81a68SDwaipayan Ray				my $end_pos = $+[2];
3372310cd06bSJoe Perches				if ($first =~ /(?:struct|union|enum)/) {
3373310cd06bSJoe Perches					pos($rawline) += length($first) + length($second) + 1;
3374310cd06bSJoe Perches					next;
3375310cd06bSJoe Perches				}
3376310cd06bSJoe Perches
33771db81a68SDwaipayan Ray				next if (lc($first) ne lc($second));
3378310cd06bSJoe Perches				next if ($first eq 'long');
3379310cd06bSJoe Perches
33801db81a68SDwaipayan Ray				# check for character before and after the word matches
33811db81a68SDwaipayan Ray				my $start_char = '';
33821db81a68SDwaipayan Ray				my $end_char = '';
33831db81a68SDwaipayan Ray				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
33841db81a68SDwaipayan Ray				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
33851db81a68SDwaipayan Ray
33861db81a68SDwaipayan Ray				next if ($start_char =~ /^\S$/);
33871db81a68SDwaipayan Ray				next if (index(" \t.,;?!", $end_char) == -1);
33881db81a68SDwaipayan Ray
33898d0325ccSAditya Srivastava				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
33908d0325ccSAditya Srivastava				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
33918d0325ccSAditya Srivastava					next if (!exists($allow_repeated_words{lc($first)}));
33928d0325ccSAditya Srivastava				}
33938d0325ccSAditya Srivastava
3394310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3395310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3396310cd06bSJoe Perches				    $fix) {
3397310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3398310cd06bSJoe Perches				}
3399310cd06bSJoe Perches			}
3400310cd06bSJoe Perches
3401310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3402310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
3403310cd06bSJoe Perches			    $prevrawline =~ /($word_pattern)\s*$/) {
3404310cd06bSJoe Perches				my $last_word = $1;
3405310cd06bSJoe Perches				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3406310cd06bSJoe Perches					if (WARN("REPEATED_WORD",
3407310cd06bSJoe Perches						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3408310cd06bSJoe Perches					    $fix) {
3409310cd06bSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3410310cd06bSJoe Perches					}
3411310cd06bSJoe Perches				}
3412310cd06bSJoe Perches			}
3413310cd06bSJoe Perches		}
3414310cd06bSJoe Perches
341530670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
341630670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
341700df344fSAndy Whitcroft
34180a920b5bSAndy Whitcroft#trailing whitespace
34199c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
3420c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3421d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3422d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
3423d5e616fcSJoe Perches			    $fix) {
3424194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3425d5e616fcSJoe Perches			}
3426c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3427c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34283705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
34293705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
34303705ce5bSJoe Perches			    $fix) {
3431194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
34323705ce5bSJoe Perches			}
34333705ce5bSJoe Perches
3434d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
34350a920b5bSAndy Whitcroft		}
34365368df20SAndy Whitcroft
34374783f894SJosh Triplett# Check for FSF mailing addresses.
3438109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
34391bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
34403e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
34413e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
34424783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34430675a8fbSJean Delvare			my $msg_level = \&ERROR;
34440675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
34450675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
34464783f894SJosh Triplett				      "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
34474783f894SJosh Triplett		}
34484783f894SJosh Triplett
34493354957aSAndi Kleen# check for Kconfig help text having a real description
34509fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
34519fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
34523354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3453678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3454678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3455678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3456678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
34573354957aSAndi Kleen			my $length = 0;
34589fe287d7SAndy Whitcroft			my $cnt = $realcnt;
34599fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
34609fe287d7SAndy Whitcroft			my $f;
3461a1385803SAndy Whitcroft			my $is_start = 0;
34629fe287d7SAndy Whitcroft			my $is_end = 0;
3463a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
34649fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
34659fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
34669fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
34679fe287d7SAndy Whitcroft
34689fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
34698d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3470a1385803SAndy Whitcroft
347186adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3472a1385803SAndy Whitcroft					$is_start = 1;
347322a4ac02SMasahiro Yamada				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
3474a1385803SAndy Whitcroft					$length = -1;
3475a1385803SAndy Whitcroft				}
3476a1385803SAndy Whitcroft
34779fe287d7SAndy Whitcroft				$f =~ s/^.//;
34783354957aSAndi Kleen				$f =~ s/#.*//;
34793354957aSAndi Kleen				$f =~ s/^\s+//;
34803354957aSAndi Kleen				next if ($f =~ /^$/);
3481678ae162SUlf Magnusson
3482678ae162SUlf Magnusson				# This only checks context lines in the patch
3483678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3484678ae162SUlf Magnusson				# positives, even though some of these are
3485678ae162SUlf Magnusson				# common words in help texts
3486678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3487678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
34889fe287d7SAndy Whitcroft					$is_end = 1;
34899fe287d7SAndy Whitcroft					last;
34909fe287d7SAndy Whitcroft				}
34913354957aSAndi Kleen				$length++;
34923354957aSAndi Kleen			}
349356193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3494000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
349556193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
349656193274SVadim Bendebury			}
3497a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
34983354957aSAndi Kleen		}
34993354957aSAndi Kleen
35007ccf41a8SJoe Perches# check MAINTAINERS entries
35017ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
35027ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
35037ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3504628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3505628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3506628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3507628f91a2SJoe Perches				    $fix) {
3508628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3509628f91a2SJoe Perches				}
3510628f91a2SJoe Perches			}
35117ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
35127ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
35137ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
35147ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
35157ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
35167ccf41a8SJoe Perches				my $cur = $1;
35177ccf41a8SJoe Perches				my $curval = $2;
35187ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
35197ccf41a8SJoe Perches				my $prev = $1;
35207ccf41a8SJoe Perches				my $prevval = $2;
35217ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
35227ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
35237ccf41a8SJoe Perches				if ($curindex < 0) {
35247ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
35257ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
35267ccf41a8SJoe Perches				} else {
35277ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
35287ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
35297ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
35307ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
35317ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
35327ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
35337ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
35347ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
35357ccf41a8SJoe Perches					}
35367ccf41a8SJoe Perches				}
35377ccf41a8SJoe Perches			}
35387ccf41a8SJoe Perches		}
3539628f91a2SJoe Perches
3540c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3541c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3542c68e5878SArnaud Lacombe			my $flag = $1;
3543c68e5878SArnaud Lacombe			my $replacement = {
3544c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3545c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3546c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3547c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3548c68e5878SArnaud Lacombe			};
3549c68e5878SArnaud Lacombe
3550c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3551c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3552c68e5878SArnaud Lacombe		}
3553c68e5878SArnaud Lacombe
3554bff5da43SRob Herring# check for DT compatible documentation
35557dd05b38SFlorian Vaussard		if (defined $root &&
35567dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
35577dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
35587dd05b38SFlorian Vaussard
3559bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3560bff5da43SRob Herring
3561cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3562852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3563cc93319bSFlorian Vaussard
3564bff5da43SRob Herring			foreach my $compat (@compats) {
3565bff5da43SRob Herring				my $compat2 = $compat;
3566185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3567185d566bSRob Herring				my $compat3 = $compat;
3568185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3569185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3570bff5da43SRob Herring				if ( $? >> 8 ) {
3571bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3572bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3573bff5da43SRob Herring				}
3574bff5da43SRob Herring
35754fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
35764fbf32a6SFlorian Vaussard				my $vendor = $1;
3577852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3578bff5da43SRob Herring				if ( $? >> 8 ) {
3579bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3580cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3581bff5da43SRob Herring				}
3582bff5da43SRob Herring			}
3583bff5da43SRob Herring		}
3584bff5da43SRob Herring
35859f3a8992SRob Herring# check for using SPDX license tag at beginning of files
35869f3a8992SRob Herring		if ($realline == $checklicenseline) {
35879f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
35889f3a8992SRob Herring				$checklicenseline = 2;
35899f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
35909f3a8992SRob Herring				my $comment = "";
35919f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
35929f3a8992SRob Herring					$comment = '/*';
35939f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
35949f3a8992SRob Herring					$comment = '//';
3595c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
35969f3a8992SRob Herring					$comment = '#';
35979f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
35989f3a8992SRob Herring					$comment = '..';
35999f3a8992SRob Herring				}
36009f3a8992SRob Herring
3601fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3602fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3603fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3604ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3605fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3606fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3607fdf13693SJoe Perches				}
3608fdf13693SJoe Perches
36099f3a8992SRob Herring				if ($comment !~ /^$/ &&
3610ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
36119f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
36129f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
36133b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
36143b6e8ac9SJoe Perches					my $spdx_license = $1;
36153b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
36163b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
36173b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
36183b6e8ac9SJoe Perches					}
361950c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
362050c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
362150c92900SLubomir Rintel						my $msg_level = \&WARN;
362250c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
362350c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
362450c92900SLubomir Rintel
362550c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
362650c92900SLubomir Rintel						    $fix) {
362750c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
362850c92900SLubomir Rintel						}
362950c92900SLubomir Rintel					}
36309f3a8992SRob Herring				}
36319f3a8992SRob Herring			}
36329f3a8992SRob Herring		}
36339f3a8992SRob Herring
3634a0154cdbSJoe Perches# check for embedded filenames
3635a0154cdbSJoe Perches		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3636a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3637a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3638a0154cdbSJoe Perches		}
3639a0154cdbSJoe Perches
36405368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3641d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
36425368df20SAndy Whitcroft
3643a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3644a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3645a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3646a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3647a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3648a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3649a8da38a9SJoe Perches		}
3650a8da38a9SJoe Perches
365147e0c88bSJoe Perches# line length limit (with some exclusions)
365247e0c88bSJoe Perches#
365347e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
365447e0c88bSJoe Perches#	logging functions like pr_info that end in a string
365547e0c88bSJoe Perches#	lines with a single string
365647e0c88bSJoe Perches#	#defines that are a single string
36572e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
365847e0c88bSJoe Perches#
365947e0c88bSJoe Perches# There are 3 different line length message types:
3660ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
366147e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
366247e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
366347e0c88bSJoe Perches#
366447e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
366547e0c88bSJoe Perches#
366647e0c88bSJoe Perches
3667b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
366847e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
366947e0c88bSJoe Perches
367047e0c88bSJoe Perches			# Check the allowed long line types first
367147e0c88bSJoe Perches
367247e0c88bSJoe Perches			# logging functions that end in a string that starts
367347e0c88bSJoe Perches			# before $max_line_length
367447e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
367547e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
367647e0c88bSJoe Perches				$msg_type = "";
367747e0c88bSJoe Perches
367847e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
367947e0c88bSJoe Perches			# #defines with only strings
368047e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
368147e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
368247e0c88bSJoe Perches				$msg_type = "";
368347e0c88bSJoe Perches
3684cc147506SJoe Perches			# More special cases
3685cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3686cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3687d560a5f8SJoe Perches				$msg_type = "";
3688d560a5f8SJoe Perches
36892e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
36902e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
36912e4bbbc5SAndreas Brauchli				$msg_type = "";
36922e4bbbc5SAndreas Brauchli
369347e0c88bSJoe Perches			# Otherwise set the alternate message types
369447e0c88bSJoe Perches
369547e0c88bSJoe Perches			# a comment starts before $max_line_length
369647e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
369747e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
369847e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
369947e0c88bSJoe Perches
370047e0c88bSJoe Perches			# a quoted string starts before $max_line_length
370147e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
370247e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
370347e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
370447e0c88bSJoe Perches			}
370547e0c88bSJoe Perches
370647e0c88bSJoe Perches			if ($msg_type ne "" &&
370747e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3708bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3709bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3710bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3711bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
37120a920b5bSAndy Whitcroft			}
371347e0c88bSJoe Perches		}
37140a920b5bSAndy Whitcroft
37158905a67cSAndy Whitcroft# check for adding lines without a newline.
37168905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
371747ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
371847ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
371947ca69b8STom Rix			    $fix) {
372047ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
372147ca69b8STom Rix			}
37228905a67cSAndy Whitcroft		}
37238905a67cSAndy Whitcroft
3724de93245cSAditya Srivastava# check for .L prefix local symbols in .S files
3725de93245cSAditya Srivastava		if ($realfile =~ /\.S$/ &&
3726de93245cSAditya Srivastava		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3727de93245cSAditya Srivastava			WARN("AVOID_L_PREFIX",
3728de93245cSAditya Srivastava			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr);
3729de93245cSAditya Srivastava		}
3730de93245cSAditya Srivastava
3731b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3732de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
37330a920b5bSAndy Whitcroft
37340a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3735713a09deSAntonio Borneo# more than $tabsize must use tabs.
3736c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3737c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3738c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3739d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
37403705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
37413705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
37423705ce5bSJoe Perches			    $fix) {
3743194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
37443705ce5bSJoe Perches			}
37450a920b5bSAndy Whitcroft		}
37460a920b5bSAndy Whitcroft
374708e44365SAlberto Panizzo# check for space before tabs.
374808e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
374908e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
37503705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
37513705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
37523705ce5bSJoe Perches			    $fix) {
3753194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3754713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3755194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3756c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
37573705ce5bSJoe Perches			}
375808e44365SAlberto Panizzo		}
375908e44365SAlberto Panizzo
37606a487211SJoe Perches# check for assignments on the start of a line
37616a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3762da7355abSAditya Srivastava			my $operator = $1;
3763da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3764da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3765da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3766da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3767da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3768da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3769da7355abSAditya Srivastava			}
37706a487211SJoe Perches		}
37716a487211SJoe Perches
3772d1fe9c09SJoe Perches# check for && or || at the start of a line
3773d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
37748e08f076SAditya Srivastava			my $operator = $1;
37758e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
37768e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
37778e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
37788e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
37798e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
37808e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
37818e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
37828e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
37838e08f076SAditya Srivastava			}
3784d1fe9c09SJoe Perches		}
3785d1fe9c09SJoe Perches
3786a91e8994SJoe Perches# check indentation starts on a tab stop
37875b57980dSJoe Perches		if ($perl_version_ok &&
3788bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3789a91e8994SJoe Perches			my $indent = length($1);
3790713a09deSAntonio Borneo			if ($indent % $tabsize) {
3791a91e8994SJoe Perches				if (WARN("TABSTOP",
3792a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3793a91e8994SJoe Perches				    $fix) {
3794713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3795a91e8994SJoe Perches				}
3796a91e8994SJoe Perches			}
3797a91e8994SJoe Perches		}
3798a91e8994SJoe Perches
3799d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
38005b57980dSJoe Perches		if ($perl_version_ok &&
3801fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3802d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3803d1fe9c09SJoe Perches			my $oldindent = $1;
3804d1fe9c09SJoe Perches			my $rest = $2;
3805d1fe9c09SJoe Perches
3806d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3807d1fe9c09SJoe Perches			if ($pos >= 0) {
3808b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3809b34a26f3SJoe Perches				my $newindent = $2;
3810d1fe9c09SJoe Perches
3811d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3812713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3813713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3814d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3815d1fe9c09SJoe Perches
3816d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3817d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
38183705ce5bSJoe Perches
38193705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
38203705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
38213705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3822194f66fcSJoe Perches						$fixed[$fixlinenr] =~
38233705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
38243705ce5bSJoe Perches					}
3825d1fe9c09SJoe Perches				}
3826d1fe9c09SJoe Perches			}
3827d1fe9c09SJoe Perches		}
3828d1fe9c09SJoe Perches
38296ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
38306ab3a970SJoe Perches# avoid checking a few false positives:
38316ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
38326ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
38336ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
38346ab3a970SJoe Perches#   multiline macros that define functions
38356ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
38366ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
38376ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
38383705ce5bSJoe Perches			if (CHK("SPACING",
3839f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
38403705ce5bSJoe Perches			    $fix) {
3841194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3842f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
38433705ce5bSJoe Perches			}
3844aad4f614SJoe Perches		}
3845aad4f614SJoe Perches
384686406b1cSJoe Perches# Block comment styles
384786406b1cSJoe Perches# Networking with an initial /*
384805880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3849fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
385085ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
3851c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
385205880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
385305880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
385405880600SJoe Perches		}
385505880600SJoe Perches
385686406b1cSJoe Perches# Block comments use * on subsequent lines
385786406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
385886406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3859a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
386061135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3861a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
386286406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
386386406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3864a605e32eSJoe Perches		}
3865a605e32eSJoe Perches
386686406b1cSJoe Perches# Block comments use */ on trailing lines
386786406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3868c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3869c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3870c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
387186406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
387286406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
387305880600SJoe Perches		}
387405880600SJoe Perches
387508eb9b80SJoe Perches# Block comment * alignment
387608eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3877af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3878af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3879af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
388008eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3881af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3882af207524SJoe Perches			my $oldindent;
388308eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3884af207524SJoe Perches			if (defined($1)) {
3885af207524SJoe Perches				$oldindent = expand_tabs($1);
3886af207524SJoe Perches			} else {
3887af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3888af207524SJoe Perches				$oldindent = expand_tabs($1);
3889af207524SJoe Perches			}
389008eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
389108eb9b80SJoe Perches			my $newindent = $1;
389208eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3893af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
389408eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
389508eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
389608eb9b80SJoe Perches			}
389708eb9b80SJoe Perches		}
389808eb9b80SJoe Perches
38997f619191SJoe Perches# check for missing blank lines after struct/union declarations
39007f619191SJoe Perches# with exceptions for various attributes and macros
39017f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
39027f619191SJoe Perches		    $line =~ /^\+/ &&
39037f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
39047f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
39057f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
39067f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
39077f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
39087f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
39097f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
39100bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
39117f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3912d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3913d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3914d752fcc8SJoe Perches			    $fix) {
3915f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3916d752fcc8SJoe Perches			}
39177f619191SJoe Perches		}
39187f619191SJoe Perches
3919365dd4eaSJoe Perches# check for multiple consecutive blank lines
3920365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3921365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3922365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3923d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3924d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3925d752fcc8SJoe Perches			    $fix) {
3926f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3927d752fcc8SJoe Perches			}
3928d752fcc8SJoe Perches
3929365dd4eaSJoe Perches			$last_blank_line = $linenr;
3930365dd4eaSJoe Perches		}
3931365dd4eaSJoe Perches
39323b617e3bSJoe Perches# check for missing blank lines after declarations
3933b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
3934b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3935b5e8736aSJoe Perches			# use temporaries
3936b5e8736aSJoe Perches			my $sl = $sline;
3937b5e8736aSJoe Perches			my $pl = $prevline;
3938b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
3939b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3940b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3941b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
39425a4e1fd3SJoe Perches			# function pointer declarations
3943b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
39443f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3945b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
39463f7bac03SJoe Perches			# known declaration macros
3947b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
39483f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
3949b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
39503f7bac03SJoe Perches			# other possible extensions of declaration lines
3951b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
39523f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
3953b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
39543f7bac03SJoe Perches			# looks like a declaration
3955b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
39565a4e1fd3SJoe Perches			# function pointer declarations
3957b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
39583f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3959b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
39603f7bac03SJoe Perches			# known declaration macros
3961b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
39623f7bac03SJoe Perches			# start of struct or union or enum
3963b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
39643f7bac03SJoe Perches			# start or end of block or continuation of declaration
3965b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
39663f7bac03SJoe Perches			# bitfield continuation
3967b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
39683f7bac03SJoe Perches			# other possible extensions of declaration lines
3969b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3970d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
3971d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
3972d752fcc8SJoe Perches				    $fix) {
3973f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
3974d752fcc8SJoe Perches				}
39753b617e3bSJoe Perches			}
3976b5e8736aSJoe Perches		}
39773b617e3bSJoe Perches
39785f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
39796b4c5bebSAndy Whitcroft# Exceptions:
39806b4c5bebSAndy Whitcroft#  1) within comments
39816b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
39826b4c5bebSAndy Whitcroft#  3) hanging labels
39833705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
39845f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
39853705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
39863705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
39873705ce5bSJoe Perches			    $fix) {
3988194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
39893705ce5bSJoe Perches			}
39905f7ddae6SRaffaele Recalcati		}
39915f7ddae6SRaffaele Recalcati
3992b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3993b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3994b9ea10d6SAndy Whitcroft
39955751a24eSJoe Perches# check for unusual line ending [ or (
39965751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
39975751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
39985751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
39995751a24eSJoe Perches		}
40005751a24eSJoe Perches
40014dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
40024dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
40034dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
40044dbed76fSJoe Perches			$context_function = $1;
40054dbed76fSJoe Perches		}
40064dbed76fSJoe Perches
40074dbed76fSJoe Perches# check if this appears to be the end of function declaration
40084dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
40094dbed76fSJoe Perches			undef $context_function;
40104dbed76fSJoe Perches		}
40114dbed76fSJoe Perches
4012032a4c0fSJoe Perches# check indentation of any line with a bare else
4013840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
4014032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
4015032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
4016032a4c0fSJoe Perches			my $tabs = length($1) + 1;
4017840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
4018840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
4019840080a0SJoe Perches			     defined $lines[$linenr] &&
4020840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
4021032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
4022032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
4023032a4c0fSJoe Perches			}
4024032a4c0fSJoe Perches		}
4025032a4c0fSJoe Perches
4026c00df19aSJoe Perches# check indentation of a line with a break;
4027dc58bc55SJoe Perches# if the previous line is a goto, return or break
4028dc58bc55SJoe Perches# and is indented the same # of tabs
4029c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4030c00df19aSJoe Perches			my $tabs = $1;
4031dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4032dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
4033dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
4034dc58bc55SJoe Perches				    $fix) {
4035dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
4036dc58bc55SJoe Perches				}
4037c00df19aSJoe Perches			}
4038c00df19aSJoe Perches		}
4039c00df19aSJoe Perches
4040c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
4041cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4042000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
4043000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4044c2fdda0dSAndy Whitcroft		}
404522f2a2efSAndy Whitcroft
404656e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
404756e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
404856e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
404956e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
405056e77d70SJoe Perches		}
405156e77d70SJoe Perches
40529c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
40532b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
40542b474a1aSAndy Whitcroft		    $realline_next);
40553e469cdcSAndy Whitcroft#print "LINE<$line>\n";
4056ca819864SJoe Perches		if ($linenr > $suppress_statement &&
40571b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
4058170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4059f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4060171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
4061171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
4062171ae1a4SAndy Whitcroft
40633e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
40643e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
40653e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
40663e469cdcSAndy Whitcroft			# until we hit end of it.
40673e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
40683e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
40693e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
40703e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
40713e469cdcSAndy Whitcroft			}
4072f74bd194SAndy Whitcroft
40732b474a1aSAndy Whitcroft			# Find the real next line.
40742b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
40752b474a1aSAndy Whitcroft			if (defined $realline_next &&
40762b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
40772b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
40782b474a1aSAndy Whitcroft				$realline_next++;
40792b474a1aSAndy Whitcroft			}
40802b474a1aSAndy Whitcroft
4081171ae1a4SAndy Whitcroft			my $s = $stat;
4082171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
4083cf655043SAndy Whitcroft
4084c2fdda0dSAndy Whitcroft			# Ignore goto labels.
4085171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
4086c2fdda0dSAndy Whitcroft
4087c2fdda0dSAndy Whitcroft			# Ignore functions being called
4088171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
4089c2fdda0dSAndy Whitcroft
4090463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
4091463f2864SAndy Whitcroft
4092c45dcabdSAndy Whitcroft			# declarations always start with types
4093d2506586SAndy 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) {
4094c45dcabdSAndy Whitcroft				my $type = $1;
4095c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
4096c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
4097c45dcabdSAndy Whitcroft
40986c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
4099a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4100c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
4101c2fdda0dSAndy Whitcroft			}
41028905a67cSAndy Whitcroft
41036c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
410465863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4105c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
41069c0ca6f9SAndy Whitcroft			}
41078905a67cSAndy Whitcroft
41088905a67cSAndy Whitcroft			# Check for any sort of function declaration.
41098905a67cSAndy Whitcroft			# int foo(something bar, other baz);
41108905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
4111171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
41128905a67cSAndy Whitcroft				my ($name_len) = length($1);
41138905a67cSAndy Whitcroft
4114cf655043SAndy Whitcroft				my $ctx = $s;
4115773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
41168905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
4117cf655043SAndy Whitcroft
41188905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4119c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
41208905a67cSAndy Whitcroft
4121c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
41228905a67cSAndy Whitcroft					}
41238905a67cSAndy Whitcroft				}
41248905a67cSAndy Whitcroft			}
41258905a67cSAndy Whitcroft
41269c0ca6f9SAndy Whitcroft		}
41279c0ca6f9SAndy Whitcroft
412800df344fSAndy Whitcroft#
412900df344fSAndy Whitcroft# Checks which may be anchored in the context.
413000df344fSAndy Whitcroft#
413100df344fSAndy Whitcroft
413200df344fSAndy Whitcroft# Check for switch () and associated case and default
413300df344fSAndy Whitcroft# statements should be at the same indent.
413400df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
413500df344fSAndy Whitcroft			my $err = '';
413600df344fSAndy Whitcroft			my $sep = '';
413700df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
413800df344fSAndy Whitcroft			shift(@ctx);
413900df344fSAndy Whitcroft			for my $ctx (@ctx) {
414000df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
414100df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
414200df344fSAndy Whitcroft							$indent != $cindent) {
414300df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
414400df344fSAndy Whitcroft					$sep = '';
414500df344fSAndy Whitcroft				} else {
414600df344fSAndy Whitcroft					$sep = "[...]\n";
414700df344fSAndy Whitcroft				}
414800df344fSAndy Whitcroft			}
414900df344fSAndy Whitcroft			if ($err ne '') {
4150000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4151000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4152de7d4f0eSAndy Whitcroft			}
4153de7d4f0eSAndy Whitcroft		}
4154de7d4f0eSAndy Whitcroft
4155de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4156de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
41570fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4158773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4159773647a0SAndy Whitcroft
41609c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
41618eef05ddSJoe Perches
41628eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
41638eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
41648eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
41658eef05ddSJoe Perches			}
41668eef05ddSJoe Perches
4167de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4168de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4169de7d4f0eSAndy Whitcroft
4170548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4171548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4172de7d4f0eSAndy Whitcroft
4173548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4174548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4175548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4176548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4177548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4178773647a0SAndy Whitcroft				$ctx_ln++;
4179773647a0SAndy Whitcroft			}
4180548596d5SAndy Whitcroft
418153210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
418253210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4183773647a0SAndy Whitcroft
4184773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4185000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4186000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
418701464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
418800df344fSAndy Whitcroft			}
4189773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4190773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4191773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4192773647a0SAndy Whitcroft			{
41939c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
41949c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4195000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4196000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
419701464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
41989c0ca6f9SAndy Whitcroft				}
41999c0ca6f9SAndy Whitcroft			}
420000df344fSAndy Whitcroft		}
420100df344fSAndy Whitcroft
42024d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4203f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
42043e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
42053e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
42063e469cdcSAndy Whitcroft					if (!defined $stat);
42074d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
42084d001e4dSAndy Whitcroft
42094d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
42104d001e4dSAndy Whitcroft
42119f5af480SJoe Perches			# remove inline comments
42129f5af480SJoe Perches			$s =~ s/$;/ /g;
42139f5af480SJoe Perches			$c =~ s/$;/ /g;
42144d001e4dSAndy Whitcroft
42154d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
42166f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
42176f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
42184d001e4dSAndy Whitcroft
42199f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
42209f5af480SJoe Perches			# none on the first line, and are going to readd them
42219f5af480SJoe Perches			# where necessary.
42229f5af480SJoe Perches			$s =~ s/\n./\n/gs;
42239f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
42249f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
42259f5af480SJoe Perches			}
42269f5af480SJoe Perches
42274d001e4dSAndy Whitcroft			# We want to check the first line inside the block
42284d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
42294d001e4dSAndy Whitcroft			#  1) any blank line termination
42304d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
42314d001e4dSAndy Whitcroft			#  3) any do (...) {
42324d001e4dSAndy Whitcroft			my $continuation = 0;
42334d001e4dSAndy Whitcroft			my $check = 0;
42344d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
42354d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
42364d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
42374d001e4dSAndy Whitcroft				$continuation = 1;
42384d001e4dSAndy Whitcroft			}
42399bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
42404d001e4dSAndy Whitcroft				$check = 1;
42414d001e4dSAndy Whitcroft				$cond_lines++;
42424d001e4dSAndy Whitcroft			}
42434d001e4dSAndy Whitcroft
42444d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
42454d001e4dSAndy Whitcroft			# preprocessor statement.
42464d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
42474d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
42484d001e4dSAndy Whitcroft				$check = 0;
42494d001e4dSAndy Whitcroft			}
42504d001e4dSAndy Whitcroft
42519bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4252740504c6SAndy Whitcroft			$continuation = 0;
42539bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
42549bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
42554d001e4dSAndy Whitcroft
4256f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4257f16fa28fSAndy Whitcroft				# is not linear.
4258f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4259f16fa28fSAndy Whitcroft					$check = 0;
4260f16fa28fSAndy Whitcroft				}
4261f16fa28fSAndy Whitcroft
42629bd49efeSAndy Whitcroft				# Ignore:
42639bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
42649bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
42659bd49efeSAndy Whitcroft				#  3) labels.
4266740504c6SAndy Whitcroft				if ($continuation ||
4267740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
42689bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
42699bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4270740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
427130dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
42729bd49efeSAndy Whitcroft						$cond_lines++;
42739bd49efeSAndy Whitcroft					}
42744d001e4dSAndy Whitcroft				}
427530dad6ebSAndy Whitcroft			}
42764d001e4dSAndy Whitcroft
42774d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
42784d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
42794d001e4dSAndy Whitcroft
42804d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
42814d001e4dSAndy Whitcroft			# this is not this patch's fault.
42824d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
42834d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
42844d001e4dSAndy Whitcroft				$check = 0;
42854d001e4dSAndy Whitcroft			}
42864d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
42874d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
42884d001e4dSAndy Whitcroft			}
42894d001e4dSAndy Whitcroft
42909bd49efeSAndy 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";
42914d001e4dSAndy Whitcroft
42929f5af480SJoe Perches			if ($check && $s ne '' &&
4293713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
42949f5af480SJoe Perches			     ($sindent < $indent) ||
4295f6950a73SJoe Perches			     ($sindent == $indent &&
4296f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4297713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4298000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4299000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
43004d001e4dSAndy Whitcroft			}
43014d001e4dSAndy Whitcroft		}
43024d001e4dSAndy Whitcroft
43036c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
43046c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
43051f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
43061f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
43076c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4308c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4309c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4310cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4311cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
43121f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4313c2fdda0dSAndy Whitcroft		}
43146c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
43156c72ffaaSAndy Whitcroft
431600df344fSAndy Whitcroft#ignore lines not being added
43173705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
431800df344fSAndy Whitcroft
431999ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
432099ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
432199ca38c2SJoe Perches#	struct foo bar = *(&(bar));
432299ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
432399ca38c2SJoe Perches			my $var = $1;
432499ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
432599ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
432699ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
432799ca38c2SJoe Perches			}
432899ca38c2SJoe Perches		}
432999ca38c2SJoe Perches
433011ca40a0SJoe Perches# check for dereferences that span multiple lines
433111ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
433211ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
433311ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
433411ca40a0SJoe Perches			my $ref = $1;
433511ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
433611ca40a0SJoe Perches			$ref .= $1;
433711ca40a0SJoe Perches			$ref =~ s/\s//g;
433811ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
433911ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
434011ca40a0SJoe Perches		}
434111ca40a0SJoe Perches
4342a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4343c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4344a1ce18e4SJoe Perches			my $type = $1;
4345a1ce18e4SJoe Perches			my $var = $2;
4346207a8e84SJoe Perches			$var = "" if (!defined $var);
4347207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4348a1ce18e4SJoe Perches				my $sign = $1;
4349a1ce18e4SJoe Perches				my $pointer = $2;
4350a1ce18e4SJoe Perches
4351a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4352a1ce18e4SJoe Perches
4353a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4354a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4355a1ce18e4SJoe Perches				    $fix) {
4356a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4357207a8e84SJoe Perches					my $comp_pointer = $pointer;
4358207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4359207a8e84SJoe Perches					$decl .= $comp_pointer;
4360207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4361207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4362a1ce18e4SJoe Perches				}
4363a1ce18e4SJoe Perches			}
4364a1ce18e4SJoe Perches		}
4365a1ce18e4SJoe Perches
4366653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
43677429c690SAndy Whitcroft		if ($dbg_type) {
43687429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4369000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4370000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
43717429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4372000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4373000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
43747429c690SAndy Whitcroft			}
4375653d4876SAndy Whitcroft			next;
4376653d4876SAndy Whitcroft		}
4377a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4378a1ef277eSAndy Whitcroft		if ($dbg_attr) {
43799360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4380000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4381000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
43829360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4383000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4384000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4385a1ef277eSAndy Whitcroft			}
4386a1ef277eSAndy Whitcroft			next;
4387a1ef277eSAndy Whitcroft		}
4388653d4876SAndy Whitcroft
4389f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
439099423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
439199423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4392d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4393d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4394f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4395f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4396f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4397d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4398d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4399f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4400d752fcc8SJoe Perches				$fixedline = $line;
44018d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4402f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4403d752fcc8SJoe Perches			}
4404f0a594c1SAndy Whitcroft		}
4405f0a594c1SAndy Whitcroft
440600df344fSAndy Whitcroft#
440700df344fSAndy Whitcroft# Checks which are anchored on the added line.
440800df344fSAndy Whitcroft#
440900df344fSAndy Whitcroft
4410653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4411c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4412653d4876SAndy Whitcroft			my $path = $1;
4413653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4414000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4415495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4416495e9d84SJoe Perches			}
4417495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4418495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4419495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4420653d4876SAndy Whitcroft			}
4421653d4876SAndy Whitcroft		}
4422653d4876SAndy Whitcroft
442300df344fSAndy Whitcroft# no C99 // comments
442400df344fSAndy Whitcroft		if ($line =~ m{//}) {
44253705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
44263705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
44273705ce5bSJoe Perches			    $fix) {
4428194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
44293705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
44303705ce5bSJoe Perches					my $comment = trim($1);
4431194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
44323705ce5bSJoe Perches				}
44333705ce5bSJoe Perches			}
443400df344fSAndy Whitcroft		}
443500df344fSAndy Whitcroft		# Remove C99 comments.
44360a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
44376c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
44380a920b5bSAndy Whitcroft
44392b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
44402b474a1aSAndy Whitcroft# the whole statement.
44412b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
44422b474a1aSAndy Whitcroft		if (defined $realline_next &&
44432b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
44442b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
444536794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
44463cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
44473cbf62dfSAndy Whitcroft			# a prefix:
44483cbf62dfSAndy Whitcroft			#   XXX(foo);
44493cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4450653d4876SAndy Whitcroft			my $name = $1;
445187a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
44523cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
44533cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
44543cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
44553cbf62dfSAndy Whitcroft
44563cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
44572b474a1aSAndy Whitcroft				\n.}\s*$|
445848012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
445948012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
446048012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
44612b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
44622b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
446348012058SAndy Whitcroft			    )/x) {
44642b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
44652b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
44662b474a1aSAndy Whitcroft			} else {
44672b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
44680a920b5bSAndy Whitcroft			}
44690a920b5bSAndy Whitcroft		}
44702b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
44712b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
447236794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
44732b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
44742b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
44752b474a1aSAndy Whitcroft		}
44762b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
44772b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4478000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4479000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
44802b474a1aSAndy Whitcroft		}
44810a920b5bSAndy Whitcroft
44825150bda4SJoe Eloff# check for global initialisers.
44835b8f82e1SSong Liu		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
44845b8f82e1SSong Liu		    !exclude_global_initialisers($realfile)) {
4485d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
44866d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4487d5e616fcSJoe Perches			    $fix) {
44886d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4489d5e616fcSJoe Perches			}
4490f0a594c1SAndy Whitcroft		}
44910a920b5bSAndy Whitcroft# check for static initialisers.
44926d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4493d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
44946d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4495d5e616fcSJoe Perches				      $herecurr) &&
4496d5e616fcSJoe Perches			    $fix) {
44976d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4498d5e616fcSJoe Perches			}
44990a920b5bSAndy Whitcroft		}
45000a920b5bSAndy Whitcroft
45011813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
45021813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
45031813087dSJoe Perches			my $tmp = trim($1);
45041813087dSJoe Perches			WARN("MISORDERED_TYPE",
45051813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
45061813087dSJoe Perches		}
45071813087dSJoe Perches
4508809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4509809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4510809e082eSJoe Perches			my $type = trim($1);
4511809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4512809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4513809e082eSJoe Perches			my $new_type = $type;
4514809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4515809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4516809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4517809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4518809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4519809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4520809e082eSJoe Perches			$new_type = trim($new_type);
4521809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4522809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4523809e082eSJoe Perches			    $fix) {
4524809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4525809e082eSJoe Perches			}
4526809e082eSJoe Perches		}
4527809e082eSJoe Perches
4528cb710ecaSJoe Perches# check for static const char * arrays.
4529cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4530000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4531000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4532cb710ecaSJoe Perches				$herecurr);
4533cb710ecaSJoe Perches		}
4534cb710ecaSJoe Perches
453577b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
453677b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
453777b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
453877b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
453977b8c0a8SJoe Perches			    $fix) {
454077b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
454177b8c0a8SJoe Perches			}
454277b8c0a8SJoe Perches		}
454377b8c0a8SJoe Perches
4544cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4545cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4546000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4547000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4548cb710ecaSJoe Perches				$herecurr);
4549cb710ecaSJoe Perches		}
4550cb710ecaSJoe Perches
4551ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4552ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4553ab7e23f3SJoe Perches			my $found = $1;
4554ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4555ab7e23f3SJoe Perches				WARN("CONST_CONST",
4556ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4557ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4558ab7e23f3SJoe Perches				WARN("CONST_CONST",
4559ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4560ab7e23f3SJoe Perches			}
4561ab7e23f3SJoe Perches		}
4562ab7e23f3SJoe Perches
456373169765SJoe Perches# check for const static or static <non ptr type> const declarations
456473169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
456573169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
456673169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
456773169765SJoe Perches			if (WARN("STATIC_CONST",
456873169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
456973169765SJoe Perches			    $fix) {
457073169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
457173169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
457273169765SJoe Perches			}
457373169765SJoe Perches		}
457473169765SJoe Perches
45759b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
45769b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
45779b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
45789b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
45799b0fa60dSJoe Perches				$herecurr);
45809b0fa60dSJoe Perches		}
45819b0fa60dSJoe Perches
4582b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4583b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4584b598b670SJoe Perches			my $array = $1;
4585b598b670SJoe 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*\))@) {
4586b598b670SJoe Perches				my $array_div = $1;
4587b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4588b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4589b598b670SJoe Perches				    $fix) {
4590b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4591b598b670SJoe Perches				}
4592b598b670SJoe Perches			}
4593b598b670SJoe Perches		}
4594b598b670SJoe Perches
4595b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
459616b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4597b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4598b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4599b36190c5SJoe Perches			    $fix) {
4600194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4601b36190c5SJoe Perches			}
4602b36190c5SJoe Perches		}
4603b36190c5SJoe Perches
4604653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4605653d4876SAndy Whitcroft# make sense.
4606653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
46078054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4608c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
46098ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
461046d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4611000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4612000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
46130a920b5bSAndy Whitcroft		}
46140a920b5bSAndy Whitcroft
46150a920b5bSAndy Whitcroft# * goes on variable not on type
461665863862SAndy Whitcroft		# (char*[ const])
4617bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4618bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
46193705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4620d8aaf121SAndy Whitcroft
462165863862SAndy Whitcroft			# Should start with a space.
462265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
462365863862SAndy Whitcroft			# Should not end with a space.
462465863862SAndy Whitcroft			$to =~ s/\s+$//;
462565863862SAndy Whitcroft			# '*'s should not have spaces between.
4626f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
462765863862SAndy Whitcroft			}
4628d8aaf121SAndy Whitcroft
46293705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
463065863862SAndy Whitcroft			if ($from ne $to) {
46313705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
46323705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
46333705ce5bSJoe Perches				    $fix) {
46343705ce5bSJoe Perches					my $sub_from = $ident;
46353705ce5bSJoe Perches					my $sub_to = $ident;
46363705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4637194f66fcSJoe Perches					$fixed[$fixlinenr] =~
46383705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
46393705ce5bSJoe Perches				}
464065863862SAndy Whitcroft			}
4641bfcb2cc7SAndy Whitcroft		}
4642bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4643bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
46443705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4645d8aaf121SAndy Whitcroft
464665863862SAndy Whitcroft			# Should start with a space.
464765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
464865863862SAndy Whitcroft			# Should not end with a space.
464965863862SAndy Whitcroft			$to =~ s/\s+$//;
465065863862SAndy Whitcroft			# '*'s should not have spaces between.
4651f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
465265863862SAndy Whitcroft			}
465365863862SAndy Whitcroft			# Modifiers should have spaces.
465465863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
465565863862SAndy Whitcroft
46563705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4657667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
46583705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
46593705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
46603705ce5bSJoe Perches				    $fix) {
46613705ce5bSJoe Perches
46623705ce5bSJoe Perches					my $sub_from = $match;
46633705ce5bSJoe Perches					my $sub_to = $match;
46643705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4665194f66fcSJoe Perches					$fixed[$fixlinenr] =~
46663705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
46673705ce5bSJoe Perches				}
466865863862SAndy Whitcroft			}
46690a920b5bSAndy Whitcroft		}
46700a920b5bSAndy Whitcroft
46719d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
46729d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
46730675a8fbSJean Delvare			my $msg_level = \&WARN;
46740675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
46750675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
46769d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
46779d3e3c70SJoe Perches		}
46780a920b5bSAndy Whitcroft
46799d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
46808905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4681000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4682000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
46838905a67cSAndy Whitcroft		}
46848905a67cSAndy Whitcroft
468517441227SJoe Perches# check for uses of printk_ratelimit
468617441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4687000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4688000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
468917441227SJoe Perches		}
469017441227SJoe Perches
4691eeef5733SJoe Perches# printk should use KERN_* levels
4692eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4693000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4694eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
469500df344fSAndy Whitcroft		}
46960a920b5bSAndy Whitcroft
4697f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4698f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4699f5eea3b0SJoe Perches			my $printk = $1;
4700f5eea3b0SJoe Perches			my $modifier = $2;
4701f5eea3b0SJoe Perches			my $orig = $3;
4702f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4703243f3803SJoe Perches			my $level = lc($orig);
4704243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
47058f26b837SJoe Perches			my $level2 = $level;
47068f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4707f5eea3b0SJoe Perches			$level .= $modifier;
4708f5eea3b0SJoe Perches			$level2 .= $modifier;
4709243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4710f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4711243f3803SJoe Perches		}
4712243f3803SJoe Perches
4713f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4714dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4715dc139313SJoe Perches			my $orig = $1;
4716dc139313SJoe Perches			my $level = lc($orig);
4717dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4718dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4719dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4720dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4721dc139313SJoe Perches		}
4722dc139313SJoe Perches
47238020b253SNicolas Boichat# trace_printk should not be used in production code.
47248020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
47258020b253SNicolas Boichat			WARN("TRACE_PRINTK",
47268020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
47278020b253SNicolas Boichat		}
47288020b253SNicolas Boichat
472991c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
473091c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
473191c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
473291c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
473391c9afafSAndy Lutomirski			WARN("ENOSYS",
473491c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
473591c9afafSAndy Lutomirski		}
473691c9afafSAndy Lutomirski
47376b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
47386b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
47396b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
47406b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
47416b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
47426b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
47436b9ea5ffSJakub Kicinski			    $fix) {
47446b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
47456b9ea5ffSJakub Kicinski			}
47466b9ea5ffSJakub Kicinski		}
47476b9ea5ffSJakub Kicinski
4748653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4749653d4876SAndy Whitcroft# or if closed on same line
47505b57980dSJoe Perches		if ($perl_version_ok &&
47512d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
47522d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
47532d453e3bSJoe Perches		    $sline !~ /}/) {
47548d182478SJoe Perches			if (ERROR("OPEN_BRACE",
47552d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
47568d182478SJoe Perches			    $fix) {
47578d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
47588d182478SJoe Perches				my $fixed_line = $rawline;
475903f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
47608d182478SJoe Perches				my $line1 = $1;
47618d182478SJoe Perches				my $line2 = $2;
47628d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
47638d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
47648d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
47658d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
47668d182478SJoe Perches				}
47678d182478SJoe Perches			}
47680a920b5bSAndy Whitcroft		}
4769653d4876SAndy Whitcroft
47708905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
47718905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
47728905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
47738d182478SJoe Perches			if (ERROR("OPEN_BRACE",
47748d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
47758d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
47768d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
47778d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
47788d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
47798d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
47808d182478SJoe Perches				$fixedline = $rawline;
47818d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
47828d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
47838d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47848d182478SJoe Perches				}
47858d182478SJoe Perches			}
47868905a67cSAndy Whitcroft		}
47878905a67cSAndy Whitcroft
47880c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
47893705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
47903705ce5bSJoe Perches			if (WARN("SPACING",
47913705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
47923705ce5bSJoe Perches			    $fix) {
4793194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47943705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
47953705ce5bSJoe Perches			}
47960c73b4ebSAndy Whitcroft		}
47970c73b4ebSAndy Whitcroft
479831070b5dSJoe Perches# Function pointer declarations
479931070b5dSJoe Perches# check spacing between type, funcptr, and args
480031070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
480191f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
480231070b5dSJoe Perches			my $declare = $1;
480331070b5dSJoe Perches			my $pre_pointer_space = $2;
480431070b5dSJoe Perches			my $post_pointer_space = $3;
480531070b5dSJoe Perches			my $funcname = $4;
480631070b5dSJoe Perches			my $post_funcname_space = $5;
480731070b5dSJoe Perches			my $pre_args_space = $6;
480831070b5dSJoe Perches
480991f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
481091f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
481191f72e9cSJoe Perches# don't need a space so don't warn for those.
481291f72e9cSJoe Perches			my $post_declare_space = "";
481391f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
481491f72e9cSJoe Perches				$post_declare_space = $1;
481591f72e9cSJoe Perches				$declare = rtrim($declare);
481691f72e9cSJoe Perches			}
481791f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
481831070b5dSJoe Perches				WARN("SPACING",
481931070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
482091f72e9cSJoe Perches				$post_declare_space = " ";
482131070b5dSJoe Perches			}
482231070b5dSJoe Perches
482331070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
482491f72e9cSJoe Perches# This test is not currently implemented because these declarations are
482591f72e9cSJoe Perches# equivalent to
482691f72e9cSJoe Perches#	int  foo(int bar, ...)
482791f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
482891f72e9cSJoe Perches#
482991f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
483091f72e9cSJoe Perches#				WARN("SPACING",
483191f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
483291f72e9cSJoe Perches#			}
483331070b5dSJoe Perches
483431070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
483531070b5dSJoe Perches			if (defined $pre_pointer_space &&
483631070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
483731070b5dSJoe Perches				WARN("SPACING",
483831070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
483931070b5dSJoe Perches			}
484031070b5dSJoe Perches
484131070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
484231070b5dSJoe Perches			if (defined $post_pointer_space &&
484331070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
484431070b5dSJoe Perches				WARN("SPACING",
484531070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
484631070b5dSJoe Perches			}
484731070b5dSJoe Perches
484831070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
484931070b5dSJoe Perches			if (defined $post_funcname_space &&
485031070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
485131070b5dSJoe Perches				WARN("SPACING",
485231070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
485331070b5dSJoe Perches			}
485431070b5dSJoe Perches
485531070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
485631070b5dSJoe Perches			if (defined $pre_args_space &&
485731070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
485831070b5dSJoe Perches				WARN("SPACING",
485931070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
486031070b5dSJoe Perches			}
486131070b5dSJoe Perches
486231070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4863194f66fcSJoe Perches				$fixed[$fixlinenr] =~
486491f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
486531070b5dSJoe Perches			}
486631070b5dSJoe Perches		}
486731070b5dSJoe Perches
48688d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
48698d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4870fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4871fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
48728d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
48738d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
48748d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4875fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
487638dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
48773705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
48783705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
48793705ce5bSJoe Perches				    $fix) {
4880194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
48813705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
48823705ce5bSJoe Perches				}
48838d31cfceSAndy Whitcroft			}
48848d31cfceSAndy Whitcroft		}
48858d31cfceSAndy Whitcroft
4886f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
48876c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4888c2fdda0dSAndy Whitcroft			my $name = $1;
4889773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4890773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4891c2fdda0dSAndy Whitcroft
4892c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4893773647a0SAndy Whitcroft			if ($name =~ /^(?:
4894773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4895773647a0SAndy Whitcroft				volatile|__volatile__|
4896773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4897773647a0SAndy Whitcroft				asm|__asm__)$/x)
4898773647a0SAndy Whitcroft			{
4899c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4900c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4901c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4902c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4903773647a0SAndy Whitcroft
4904773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4905c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4906c2fdda0dSAndy Whitcroft
4907c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4908c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4909773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4910c2fdda0dSAndy Whitcroft
4911c2fdda0dSAndy Whitcroft			} else {
49123705ce5bSJoe Perches				if (WARN("SPACING",
49133705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
49143705ce5bSJoe Perches					     $fix) {
4915194f66fcSJoe Perches					$fixed[$fixlinenr] =~
49163705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
49173705ce5bSJoe Perches				}
4918f0a594c1SAndy Whitcroft			}
49196c72ffaaSAndy Whitcroft		}
49209a4cad4eSEric Nelson
4921653d4876SAndy Whitcroft# Check operator spacing.
49220a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
49233705ce5bSJoe Perches			my $fixed_line = "";
49243705ce5bSJoe Perches			my $line_fixed = 0;
49253705ce5bSJoe Perches
49269c0ca6f9SAndy Whitcroft			my $ops = qr{
49279c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
49289c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
49299c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
49301f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
493184731623SJoe Perches				\?:|\?|:
49329c0ca6f9SAndy Whitcroft			}x;
4933cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
49343705ce5bSJoe Perches
49353705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
49363705ce5bSJoe Perches##			foreach my $el (@elements) {
49373705ce5bSJoe Perches##				print("el: <$el>\n");
49383705ce5bSJoe Perches##			}
49393705ce5bSJoe Perches
49403705ce5bSJoe Perches			my @fix_elements = ();
494100df344fSAndy Whitcroft			my $off = 0;
49426c72ffaaSAndy Whitcroft
49433705ce5bSJoe Perches			foreach my $el (@elements) {
49443705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
49453705ce5bSJoe Perches				$off += length($el);
49463705ce5bSJoe Perches			}
49473705ce5bSJoe Perches
49483705ce5bSJoe Perches			$off = 0;
49493705ce5bSJoe Perches
49506c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4951b34c648bSJoe Perches			my $last_after = -1;
49526c72ffaaSAndy Whitcroft
49530a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
49543705ce5bSJoe Perches
49553705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
49563705ce5bSJoe Perches
49573705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
49583705ce5bSJoe Perches
49594a0df2efSAndy Whitcroft				$off += length($elements[$n]);
49604a0df2efSAndy Whitcroft
496125985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4962773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4963773647a0SAndy Whitcroft				my $cc = '';
4964773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4965773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4966773647a0SAndy Whitcroft				}
4967773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4968773647a0SAndy Whitcroft
49694a0df2efSAndy Whitcroft				my $a = '';
49704a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
49714a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4972cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
49734a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
49744a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4975773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
49764a0df2efSAndy Whitcroft
49770a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
49784a0df2efSAndy Whitcroft
49794a0df2efSAndy Whitcroft				my $c = '';
49800a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
49814a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
49824a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4983cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
49844a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
49854a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
49868b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
49874a0df2efSAndy Whitcroft				} else {
49884a0df2efSAndy Whitcroft					$c = 'E';
49890a920b5bSAndy Whitcroft				}
49900a920b5bSAndy Whitcroft
49914a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
49924a0df2efSAndy Whitcroft
49934a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
49944a0df2efSAndy Whitcroft
49956c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4996de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
49970a920b5bSAndy Whitcroft
499874048ed8SAndy Whitcroft				# Pull out the value of this operator.
49996c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
50000a920b5bSAndy Whitcroft
50011f65f947SAndy Whitcroft				# Get the full operator variant.
50021f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
50031f65f947SAndy Whitcroft
500413214adfSAndy Whitcroft				# Ignore operators passed as parameters.
500513214adfSAndy Whitcroft				if ($op_type ne 'V' &&
5006d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
500713214adfSAndy Whitcroft
5008cf655043SAndy Whitcroft#				# Ignore comments
5009cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
501013214adfSAndy Whitcroft
5011d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
501213214adfSAndy Whitcroft				} elsif ($op eq ';') {
5013cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
5014cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
50153705ce5bSJoe Perches						if (ERROR("SPACING",
50163705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
5017b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
50183705ce5bSJoe Perches							$line_fixed = 1;
50193705ce5bSJoe Perches						}
5020d8aaf121SAndy Whitcroft					}
5021d8aaf121SAndy Whitcroft
5022d8aaf121SAndy Whitcroft				# // is a comment
5023d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
50240a920b5bSAndy Whitcroft
5025b00e4814SJoe Perches				#   :   when part of a bitfield
5026b00e4814SJoe Perches				} elsif ($opv eq ':B') {
5027b00e4814SJoe Perches					# skip the bitfield test for now
5028b00e4814SJoe Perches
50291f65f947SAndy Whitcroft				# No spaces for:
50301f65f947SAndy Whitcroft				#   ->
5031b00e4814SJoe Perches				} elsif ($op eq '->') {
50324a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
50333705ce5bSJoe Perches						if (ERROR("SPACING",
50343705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5035b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50363705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
50373705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
50383705ce5bSJoe Perches							}
5039b34c648bSJoe Perches							$line_fixed = 1;
50403705ce5bSJoe Perches						}
50410a920b5bSAndy Whitcroft					}
50420a920b5bSAndy Whitcroft
50432381097bSJoe Perches				# , must not have a space before and must have a space on the right.
50440a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
50452381097bSJoe Perches					my $rtrim_before = 0;
50462381097bSJoe Perches					my $space_after = 0;
50472381097bSJoe Perches					if ($ctx =~ /Wx./) {
50482381097bSJoe Perches						if (ERROR("SPACING",
50492381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
50502381097bSJoe Perches							$line_fixed = 1;
50512381097bSJoe Perches							$rtrim_before = 1;
50522381097bSJoe Perches						}
50532381097bSJoe Perches					}
5054cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
50553705ce5bSJoe Perches						if (ERROR("SPACING",
50563705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
50573705ce5bSJoe Perches							$line_fixed = 1;
5058b34c648bSJoe Perches							$last_after = $n;
50592381097bSJoe Perches							$space_after = 1;
50602381097bSJoe Perches						}
50612381097bSJoe Perches					}
50622381097bSJoe Perches					if ($rtrim_before || $space_after) {
50632381097bSJoe Perches						if ($rtrim_before) {
50642381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50652381097bSJoe Perches						} else {
50662381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
50672381097bSJoe Perches						}
50682381097bSJoe Perches						if ($space_after) {
50692381097bSJoe Perches							$good .= " ";
50703705ce5bSJoe Perches						}
50710a920b5bSAndy Whitcroft					}
50720a920b5bSAndy Whitcroft
50739c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
507474048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
50759c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
50769c0ca6f9SAndy Whitcroft
50779c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
50789c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
50799c0ca6f9SAndy Whitcroft				# unary operator, or a cast
50809c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
508174048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
50820d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
5083cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
50843705ce5bSJoe Perches						if (ERROR("SPACING",
50853705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
5086b34c648bSJoe Perches							if ($n != $last_after + 2) {
5087b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
50883705ce5bSJoe Perches								$line_fixed = 1;
50893705ce5bSJoe Perches							}
50900a920b5bSAndy Whitcroft						}
5091b34c648bSJoe Perches					}
5092a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
5093171ae1a4SAndy Whitcroft						# A unary '*' may be const
5094171ae1a4SAndy Whitcroft
5095171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
50963705ce5bSJoe Perches						if (ERROR("SPACING",
50973705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5098b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
50993705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51003705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
51013705ce5bSJoe Perches							}
5102b34c648bSJoe Perches							$line_fixed = 1;
51033705ce5bSJoe Perches						}
51040a920b5bSAndy Whitcroft					}
51050a920b5bSAndy Whitcroft
51060a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
51070a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
5108773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
51093705ce5bSJoe Perches						if (ERROR("SPACING",
51103705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
5111b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
51123705ce5bSJoe Perches							$line_fixed = 1;
51133705ce5bSJoe Perches						}
51140a920b5bSAndy Whitcroft					}
5115773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
5116773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
51173705ce5bSJoe Perches						if (ERROR("SPACING",
51183705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5119b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51203705ce5bSJoe Perches							$line_fixed = 1;
51213705ce5bSJoe Perches						}
5122653d4876SAndy Whitcroft					}
5123773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
51243705ce5bSJoe Perches						if (ERROR("SPACING",
51253705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5126b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
51273705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51283705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5129773647a0SAndy Whitcroft							}
5130b34c648bSJoe Perches							$line_fixed = 1;
51313705ce5bSJoe Perches						}
51323705ce5bSJoe Perches					}
51330a920b5bSAndy Whitcroft
51340a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
51359c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
51369c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
51379c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5138c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5139c2fdda0dSAndy Whitcroft					 $op eq '%')
51400a920b5bSAndy Whitcroft				{
5141d2e025f3SJoe Perches					if ($check) {
5142d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5143d2e025f3SJoe Perches							if (CHK("SPACING",
5144d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5145d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5146d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5147d2e025f3SJoe Perches								$line_fixed = 1;
5148d2e025f3SJoe Perches							}
5149d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5150d2e025f3SJoe Perches							if (CHK("SPACING",
5151d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5152d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5153d2e025f3SJoe Perches								$line_fixed = 1;
5154d2e025f3SJoe Perches							}
5155d2e025f3SJoe Perches						}
5156d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
51573705ce5bSJoe Perches						if (ERROR("SPACING",
51583705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5159b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5160b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5161b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5162b34c648bSJoe Perches							}
51633705ce5bSJoe Perches							$line_fixed = 1;
51643705ce5bSJoe Perches						}
51650a920b5bSAndy Whitcroft					}
51660a920b5bSAndy Whitcroft
51671f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
51681f65f947SAndy Whitcroft				# terminating a case value or a label.
51691f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
5170263afd39SChris Down					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
51713705ce5bSJoe Perches						if (ERROR("SPACING",
51723705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5173b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51743705ce5bSJoe Perches							$line_fixed = 1;
51753705ce5bSJoe Perches						}
51761f65f947SAndy Whitcroft					}
51771f65f947SAndy Whitcroft
51780a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5179cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
51801f65f947SAndy Whitcroft					my $ok = 0;
51811f65f947SAndy Whitcroft
518222f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
51831f65f947SAndy Whitcroft					if (($op eq '<' &&
51841f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
51851f65f947SAndy Whitcroft					    ($op eq '>' &&
51861f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
51871f65f947SAndy Whitcroft					{
51881f65f947SAndy Whitcroft						$ok = 1;
51891f65f947SAndy Whitcroft					}
51901f65f947SAndy Whitcroft
5191e0df7e1fSJoe Perches					# for asm volatile statements
5192e0df7e1fSJoe Perches					# ignore a colon with another
5193e0df7e1fSJoe Perches					# colon immediately before or after
5194e0df7e1fSJoe Perches					if (($op eq ':') &&
5195e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5196e0df7e1fSJoe Perches						$ok = 1;
5197e0df7e1fSJoe Perches					}
5198e0df7e1fSJoe Perches
519984731623SJoe Perches					# messages are ERROR, but ?: are CHK
52001f65f947SAndy Whitcroft					if ($ok == 0) {
52010675a8fbSJean Delvare						my $msg_level = \&ERROR;
52020675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
520384731623SJoe Perches
52040675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
52053705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5206b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5207b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5208b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5209b34c648bSJoe Perches							}
52103705ce5bSJoe Perches							$line_fixed = 1;
52113705ce5bSJoe Perches						}
52120a920b5bSAndy Whitcroft					}
521322f2a2efSAndy Whitcroft				}
52144a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
52153705ce5bSJoe Perches
52163705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
52173705ce5bSJoe Perches
52183705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
52190a920b5bSAndy Whitcroft			}
52203705ce5bSJoe Perches
52213705ce5bSJoe Perches			if (($#elements % 2) == 0) {
52223705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
52233705ce5bSJoe Perches			}
52243705ce5bSJoe Perches
5225194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5226194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
52273705ce5bSJoe Perches			}
52283705ce5bSJoe Perches
52293705ce5bSJoe Perches
52300a920b5bSAndy Whitcroft		}
52310a920b5bSAndy Whitcroft
5232786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5233d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5234786b6326SJoe Perches			if (WARN("SPACING",
5235786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5236786b6326SJoe Perches			    $fix) {
5237194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5238786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5239786b6326SJoe Perches			}
5240786b6326SJoe Perches		}
5241786b6326SJoe Perches
5242f0a594c1SAndy Whitcroft# check for multiple assignments
5243f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5244000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5245000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5246f0a594c1SAndy Whitcroft		}
5247f0a594c1SAndy Whitcroft
524822f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
524922f2a2efSAndy Whitcroft## # continuation.
525022f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
525122f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
525222f2a2efSAndy Whitcroft##
525322f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5254e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
525522f2a2efSAndy Whitcroft## 			my $ln = $line;
525622f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
525722f2a2efSAndy Whitcroft## 			}
525822f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5259000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5260000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
526122f2a2efSAndy Whitcroft## 			}
526222f2a2efSAndy Whitcroft## 		}
5263f0a594c1SAndy Whitcroft
52640a920b5bSAndy Whitcroft#need space before brace following if, while, etc
52656b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
52666ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
52673705ce5bSJoe Perches			if (ERROR("SPACING",
52683705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
52693705ce5bSJoe Perches			    $fix) {
52706ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
52713705ce5bSJoe Perches			}
5272de7d4f0eSAndy Whitcroft		}
5273de7d4f0eSAndy Whitcroft
5274c4a62ef9SJoe Perches## # check for blank lines before declarations
5275c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5276c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5277c4a62ef9SJoe Perches##			WARN("SPACING",
5278c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5279c4a62ef9SJoe Perches##		}
5280c4a62ef9SJoe Perches##
5281c4a62ef9SJoe Perches
5282de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5283de7d4f0eSAndy Whitcroft# on the line
528494fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5285d5e616fcSJoe Perches			if (ERROR("SPACING",
5286d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5287d5e616fcSJoe Perches			    $fix) {
5288194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5289d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5290d5e616fcSJoe Perches			}
52910a920b5bSAndy Whitcroft		}
52920a920b5bSAndy Whitcroft
529322f2a2efSAndy Whitcroft# check spacing on square brackets
529422f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
52953705ce5bSJoe Perches			if (ERROR("SPACING",
52963705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
52973705ce5bSJoe Perches			    $fix) {
5298194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52993705ce5bSJoe Perches				    s/\[\s+/\[/;
53003705ce5bSJoe Perches			}
530122f2a2efSAndy Whitcroft		}
530222f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
53033705ce5bSJoe Perches			if (ERROR("SPACING",
53043705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
53053705ce5bSJoe Perches			    $fix) {
5306194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53073705ce5bSJoe Perches				    s/\s+\]/\]/;
53083705ce5bSJoe Perches			}
530922f2a2efSAndy Whitcroft		}
531022f2a2efSAndy Whitcroft
5311c45dcabdSAndy Whitcroft# check spacing on parentheses
53129c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
53139c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
53143705ce5bSJoe Perches			if (ERROR("SPACING",
53153705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
53163705ce5bSJoe Perches			    $fix) {
5317194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53183705ce5bSJoe Perches				    s/\(\s+/\(/;
53193705ce5bSJoe Perches			}
532022f2a2efSAndy Whitcroft		}
532113214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5322c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5323c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
53243705ce5bSJoe Perches			if (ERROR("SPACING",
53253705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
53263705ce5bSJoe Perches			    $fix) {
5327194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53283705ce5bSJoe Perches				    s/\s+\)/\)/;
53293705ce5bSJoe Perches			}
533022f2a2efSAndy Whitcroft		}
533122f2a2efSAndy Whitcroft
5332e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5333e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5334e2826fd0SJoe Perches
5335e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5336ea4acbb1SJoe Perches			my $var = $1;
5337ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5338ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5339ea4acbb1SJoe Perches			    $fix) {
5340ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5341ea4acbb1SJoe Perches			}
5342ea4acbb1SJoe Perches		}
5343ea4acbb1SJoe Perches
5344ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5345ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5346ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5347ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5348ea4acbb1SJoe Perches			my $var = $2;
5349ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5350ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5351ea4acbb1SJoe Perches			    $fix) {
5352ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5353ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5354ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5355ea4acbb1SJoe Perches			}
5356e2826fd0SJoe Perches		}
5357e2826fd0SJoe Perches
535863b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5359a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5360a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
53615b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
536263b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
536363b7c73eSJoe Perches			my $if_stat = $1;
536463b7c73eSJoe Perches			my $test = substr($2, 1, -1);
536563b7c73eSJoe Perches			my $herectx;
536663b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
536763b7c73eSJoe Perches				my $match = $1;
536863b7c73eSJoe Perches				# avoid parentheses around potential macro args
536963b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
537063b7c73eSJoe Perches				if (!defined($herectx)) {
537163b7c73eSJoe Perches					$herectx = $here . "\n";
537263b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
537363b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
537463b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
537563b7c73eSJoe Perches						$herectx .=  $rl . "\n";
537663b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
537763b7c73eSJoe Perches					}
537863b7c73eSJoe Perches				}
537963b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
538063b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
538163b7c73eSJoe Perches			}
538263b7c73eSJoe Perches		}
538363b7c73eSJoe Perches
538469078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation)
538569078651SJoe Perches# and ignore bitfield definitions like foo:1
538669078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the :
538769078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels
538869078651SJoe Perches		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
538969078651SJoe Perches		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
539069078651SJoe Perches		    $sline !~ /^.\s+default:/) {
53913705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
53923705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
53933705ce5bSJoe Perches			    $fix) {
5394194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53953705ce5bSJoe Perches				    s/^(.)\s+/$1/;
53963705ce5bSJoe Perches			}
53970a920b5bSAndy Whitcroft		}
53980a920b5bSAndy Whitcroft
539940873abaSJoe Perches# check if a statement with a comma should be two statements like:
540040873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
540140873abaSJoe Perches#	bar = baz();
540240873abaSJoe Perches		if (defined($stat) &&
540340873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
540440873abaSJoe Perches			my $cnt = statement_rawlines($stat);
540540873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
540640873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
540740873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
540840873abaSJoe Perches		}
540940873abaSJoe Perches
54105b9553abSJoe Perches# return is not a function
5411507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5412c45dcabdSAndy Whitcroft			my $spacing = $1;
54135b57980dSJoe Perches			if ($perl_version_ok &&
54145b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
54155b9553abSJoe Perches				my $value = $1;
54165b9553abSJoe Perches				$value = deparenthesize($value);
54175b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5418000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5419000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
54205b9553abSJoe Perches				}
5421c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5422000d1cc1SJoe Perches				ERROR("SPACING",
5423000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5424c45dcabdSAndy Whitcroft			}
5425c45dcabdSAndy Whitcroft		}
5426507e5141SJoe Perches
5427b43ae21bSJoe Perches# unnecessary return in a void function
5428b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5429b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5430b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5431b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5432b43ae21bSJoe Perches		    $linenr >= 3 &&
5433b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5434b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
54359819cf25SJoe Perches			WARN("RETURN_VOID",
5436b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
54379819cf25SJoe Perches		}
54389819cf25SJoe Perches
5439189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
54405b57980dSJoe Perches		if ($perl_version_ok &&
5441189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5442189248d8SJoe Perches			my $openparens = $1;
5443189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5444189248d8SJoe Perches			my $msg = "";
5445189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5446189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5447189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5448189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5449189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5450189248d8SJoe Perches			}
5451189248d8SJoe Perches		}
5452189248d8SJoe Perches
5453c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5454c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5455c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5456c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
54575b57980dSJoe Perches		if ($perl_version_ok &&
5458c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5459c5595fa2SJoe Perches			my $lead = $1;
5460c5595fa2SJoe Perches			my $const = $2;
5461c5595fa2SJoe Perches			my $comp = $3;
5462c5595fa2SJoe Perches			my $to = $4;
5463c5595fa2SJoe Perches			my $newcomp = $comp;
5464f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5465c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5466c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5467c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5468c5595fa2SJoe Perches			    $fix) {
5469c5595fa2SJoe Perches				if ($comp eq "<") {
5470c5595fa2SJoe Perches					$newcomp = ">";
5471c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5472c5595fa2SJoe Perches					$newcomp = ">=";
5473c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5474c5595fa2SJoe Perches					$newcomp = "<";
5475c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5476c5595fa2SJoe Perches					$newcomp = "<=";
5477c5595fa2SJoe Perches				}
5478c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5479c5595fa2SJoe Perches			}
5480c5595fa2SJoe Perches		}
5481c5595fa2SJoe Perches
5482f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5483f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
548453a3c448SAndy Whitcroft			my $name = $1;
548546b85bf9SGuenter Roeck			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5486000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5487f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
548853a3c448SAndy Whitcroft			}
548953a3c448SAndy Whitcroft		}
5490c45dcabdSAndy Whitcroft
54910a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
54924a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
54933705ce5bSJoe Perches			if (ERROR("SPACING",
54943705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
54953705ce5bSJoe Perches			    $fix) {
5496194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54973705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
54983705ce5bSJoe Perches			}
54990a920b5bSAndy Whitcroft		}
55000a920b5bSAndy Whitcroft
5501f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5502f5fe35ddSAndy Whitcroft# statements after the conditional.
5503170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
55043e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
55053e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
55063e469cdcSAndy Whitcroft					if (!defined $stat);
5507170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5508170d3a22SAndy Whitcroft						$remain_next, $off_next);
5509170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5510170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5511170d3a22SAndy Whitcroft
5512170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5513170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5514170d3a22SAndy Whitcroft				# then count those as offsets.
5515170d3a22SAndy Whitcroft				my ($whitespace) =
5516170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5517170d3a22SAndy Whitcroft				my $offset =
5518170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5519170d3a22SAndy Whitcroft
5520170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5521170d3a22SAndy Whitcroft								$offset} = 1;
5522170d3a22SAndy Whitcroft			}
5523170d3a22SAndy Whitcroft		}
5524170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5525c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5526170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5527171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
55288905a67cSAndy Whitcroft
5529b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
553065b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
553165b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
553265b64b3bSJoe Perches				    $fix && $perl_version_ok) {
553365b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
553465b64b3bSJoe Perches						my $space = $1;
553565b64b3bSJoe Perches						my $not = $2;
553665b64b3bSJoe Perches						my $statement = $3;
553765b64b3bSJoe Perches						my $assigned = $4;
553865b64b3bSJoe Perches						my $test = $8;
553965b64b3bSJoe Perches						my $against = $9;
554065b64b3bSJoe Perches						my $brace = $15;
554165b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
554265b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
554365b64b3bSJoe Perches						my $newline = "${space}if (";
554465b64b3bSJoe Perches						$newline .= '!' if defined($not);
554565b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
554665b64b3bSJoe Perches						$newline .= "$assigned";
554765b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
554865b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
554965b64b3bSJoe Perches						$newline .= ')';
555065b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
555165b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
555265b64b3bSJoe Perches					}
555365b64b3bSJoe Perches				}
55548905a67cSAndy Whitcroft			}
55558905a67cSAndy Whitcroft
55568905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
55578905a67cSAndy Whitcroft			# conditional.
5558773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
55598905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
556013214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
556153210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
556253210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5563773647a0SAndy Whitcroft			{
5564bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5565bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5566bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
556742bdf74cSHidetoshi Seto				my $stat_real = '';
5568bb44ad39SAndy Whitcroft
556942bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
557042bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5571bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5572bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5573bb44ad39SAndy Whitcroft				}
5574bb44ad39SAndy Whitcroft
5575000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5576000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
55778905a67cSAndy Whitcroft			}
55788905a67cSAndy Whitcroft		}
55798905a67cSAndy Whitcroft
558013214adfSAndy Whitcroft# Check for bitwise tests written as boolean
558113214adfSAndy Whitcroft		if ($line =~ /
558213214adfSAndy Whitcroft			(?:
558313214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
558413214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
558513214adfSAndy Whitcroft				(?:\&\&|\|\|)
558613214adfSAndy Whitcroft			|
558713214adfSAndy Whitcroft				(?:\&\&|\|\|)
558813214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
558913214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
559013214adfSAndy Whitcroft			)/x)
559113214adfSAndy Whitcroft		{
5592000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5593000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
559413214adfSAndy Whitcroft		}
559513214adfSAndy Whitcroft
55968905a67cSAndy Whitcroft# if and else should not have general statements after it
559713214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
559813214adfSAndy Whitcroft			my $s = $1;
559913214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
560013214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5601000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5602000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
56030a920b5bSAndy Whitcroft			}
560413214adfSAndy Whitcroft		}
560539667782SAndy Whitcroft# if should not continue a brace
560639667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5607000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5608048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
560939667782SAndy Whitcroft				$herecurr);
561039667782SAndy Whitcroft		}
5611a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5612a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5613a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
56143fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5615a1080bf8SAndy Whitcroft			\s*return\s+
5616a1080bf8SAndy Whitcroft		    )/xg)
5617a1080bf8SAndy Whitcroft		{
5618000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5619000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5620a1080bf8SAndy Whitcroft		}
56210a920b5bSAndy Whitcroft
56220a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
56230a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
56248b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
56250a920b5bSAndy Whitcroft		    $previndent == $indent) {
56268b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
56278b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
56288b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
56298b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
56308b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
56318b8856f4SJoe Perches				my $fixedline = $prevrawline;
56328b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
56338b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
56348b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
56358b8856f4SJoe Perches				}
56368b8856f4SJoe Perches				$fixedline = $rawline;
56378b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
56388b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
56398b8856f4SJoe Perches			}
56400a920b5bSAndy Whitcroft		}
56410a920b5bSAndy Whitcroft
56428b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5643c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5644c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5645c2fdda0dSAndy Whitcroft
5646c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5647c2fdda0dSAndy Whitcroft			# conditional.
5648773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5649c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5650c2fdda0dSAndy Whitcroft
5651c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
56528b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
56538b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
56548b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
56558b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
56568b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
56578b8856f4SJoe Perches					my $fixedline = $prevrawline;
56588b8856f4SJoe Perches					my $trailing = $rawline;
56598b8856f4SJoe Perches					$trailing =~ s/^\+//;
56608b8856f4SJoe Perches					$trailing = trim($trailing);
56618b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
56628b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
56638b8856f4SJoe Perches				}
5664c2fdda0dSAndy Whitcroft			}
5665c2fdda0dSAndy Whitcroft		}
5666c2fdda0dSAndy Whitcroft
566795e2c602SJoe Perches#Specific variable tests
5668323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5669323c1260SJoe Perches			my $var = $1;
567095e2c602SJoe Perches
567195e2c602SJoe Perches#CamelCase
5672807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5673be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
56744104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
56754104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
567622735ce8SJoe Perches#Ignore Page<foo> variants
5677807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5678d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5679d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5680d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5681f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5682f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
56837e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
56847e781f67SJoe Perches					my $word = $1;
56857e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5686d8b07710SJoe Perches					if ($check) {
5687d8b07710SJoe Perches						seed_camelcase_includes();
5688d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5689d8b07710SJoe Perches							seed_camelcase_file($realfile);
5690d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5691d8b07710SJoe Perches						}
5692d8b07710SJoe Perches					}
56937e781f67SJoe Perches					if (!defined $camelcase{$word}) {
56947e781f67SJoe Perches						$camelcase{$word} = 1;
5695be79794bSJoe Perches						CHK("CAMELCASE",
56967e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
56977e781f67SJoe Perches					}
5698323c1260SJoe Perches				}
5699323c1260SJoe Perches			}
57003445686aSJoe Perches		}
57010a920b5bSAndy Whitcroft
57020a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5703d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5704d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5705d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5706d5e616fcSJoe Perches			    $fix) {
5707194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5708d5e616fcSJoe Perches			}
57090a920b5bSAndy Whitcroft		}
57100a920b5bSAndy Whitcroft
57110e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
57120e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5713c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5714e09dec48SAndy Whitcroft			my $file = "$1.h";
5715e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5716e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5717e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
57187840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5719c45dcabdSAndy Whitcroft			{
57200e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
57210e212e0aSFabian Frederick				if ($asminclude > 0) {
5722e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5723000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5724000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5725e09dec48SAndy Whitcroft					} else {
5726000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5727000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5728e09dec48SAndy Whitcroft					}
57290a920b5bSAndy Whitcroft				}
57300a920b5bSAndy Whitcroft			}
57310e212e0aSFabian Frederick		}
57320a920b5bSAndy Whitcroft
5733653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5734653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5735cf655043SAndy Whitcroft# in a known good container
5736b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5737b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5738d8aaf121SAndy Whitcroft			my $ln = $linenr;
5739d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5740c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5741c45dcabdSAndy Whitcroft			my $ctx = '';
574208a2843eSJoe Perches			my $has_flow_statement = 0;
574308a2843eSJoe Perches			my $has_arg_concat = 0;
5744c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5745f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5746f74bd194SAndy Whitcroft			$ctx = $dstat;
5747c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5748a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5749c45dcabdSAndy Whitcroft
575008a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
575162e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
575208a2843eSJoe Perches
5753f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5754f59b64bfSJoe Perches			my $define_args = $1;
5755f59b64bfSJoe Perches			my $define_stmt = $dstat;
5756f59b64bfSJoe Perches			my @def_args = ();
5757f59b64bfSJoe Perches
5758f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5759f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5760f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
57618c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5762f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5763f59b64bfSJoe Perches			}
5764f59b64bfSJoe Perches
5765292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5766c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5767c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5768c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5769c45dcabdSAndy Whitcroft
5770c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
57712e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
57722e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
57732e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5774bf30d6edSAndy Whitcroft			{
5775c45dcabdSAndy Whitcroft			}
5776c45dcabdSAndy Whitcroft
5777342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
577833acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
577933acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5780e45bab8eSAndy Whitcroft			{
5781e45bab8eSAndy Whitcroft			}
5782e45bab8eSAndy Whitcroft
578342e15293SJoe Perches			# Make asm volatile uses seem like a generic function
578442e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
578542e15293SJoe Perches
5786c45dcabdSAndy Whitcroft			my $exceptions = qr{
5787c45dcabdSAndy Whitcroft				$Declare|
5788c45dcabdSAndy Whitcroft				module_param_named|
5789a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5790c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5791c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5792383099fdSAndy Whitcroft				__typeof__\(|
579322fd2d3eSStefani Seibold				union|
579422fd2d3eSStefani Seibold				struct|
5795ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
57966b10df42SVladimir Zapolskiy				^\"|\"$|
57976b10df42SVladimir Zapolskiy				^\[
5798c45dcabdSAndy Whitcroft			}x;
57995eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5800f59b64bfSJoe Perches
5801f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5802f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5803e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5804f59b64bfSJoe Perches
5805f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5806f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5807f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
58083cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5809356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5810f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5811f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5812e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
581372f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
58142e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5815f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5816f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5817f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
58184e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5819f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5820c45dcabdSAndy Whitcroft			{
5821e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5822e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5823e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5824e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5825f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5826f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5827f74bd194SAndy Whitcroft				} else {
5828000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5829388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5830d8aaf121SAndy Whitcroft				}
5831f59b64bfSJoe Perches
5832f59b64bfSJoe Perches			}
58335207649bSJoe Perches
58345207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
58355207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
58365207649bSJoe Perches			my $first = 1;
58375207649bSJoe Perches			$define_stmt = "";
58385207649bSJoe Perches			foreach my $l (@stmt_array) {
58395207649bSJoe Perches				$l =~ s/\\$//;
58405207649bSJoe Perches				if ($first) {
58415207649bSJoe Perches					$define_stmt = $l;
58425207649bSJoe Perches					$first = 0;
58435207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
58445207649bSJoe Perches					$define_stmt .= substr($l, 1);
58455207649bSJoe Perches				}
58465207649bSJoe Perches			}
58475207649bSJoe Perches			$define_stmt =~ s/$;//g;
58485207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
58495207649bSJoe Perches			$define_stmt = trim($define_stmt);
58505207649bSJoe Perches
5851f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5852f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5853f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
58549192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
58557fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
58567b844345SVincent 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;
58577fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
58587fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5859d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5860f59b64bfSJoe Perches				if ($use_cnt > 1) {
5861f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5862f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5863f59b64bfSJoe Perches				    }
58649192d41aSJoe Perches# check if any macro arguments may have other precedence issues
58657fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
58669192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
58679192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
58689192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
58699192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
58709192d41aSJoe Perches				}
58710a920b5bSAndy Whitcroft			}
58725023d347SJoe Perches
587308a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
587408a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
587508a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
587608a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5877e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
587808a2843eSJoe Perches
587908a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
588008a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
588108a2843eSJoe Perches			}
588208a2843eSJoe Perches
5883481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
58845023d347SJoe Perches
58855023d347SJoe Perches		} else {
58865023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5887481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5888481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
58895023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
58905023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
58915023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
58925023d347SJoe Perches			}
5893653d4876SAndy Whitcroft		}
58940a920b5bSAndy Whitcroft
5895b13edf7fSJoe Perches# do {} while (0) macro tests:
5896b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5897b13edf7fSJoe Perches# macro should not end with a semicolon
58985b57980dSJoe Perches		if ($perl_version_ok &&
5899b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5900b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5901b13edf7fSJoe Perches			my $ln = $linenr;
5902b13edf7fSJoe Perches			my $cnt = $realcnt;
5903b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5904b13edf7fSJoe Perches			my $ctx = '';
5905b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5906b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5907b13edf7fSJoe Perches			$ctx = $dstat;
5908b13edf7fSJoe Perches
5909b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
59101b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5911b13edf7fSJoe Perches
5912b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5913b13edf7fSJoe Perches				my $stmts = $2;
5914b13edf7fSJoe Perches				my $semis = $3;
5915b13edf7fSJoe Perches
5916b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5917b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5918e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5919b13edf7fSJoe Perches
5920ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5921ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5922b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5923b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5924b13edf7fSJoe Perches				}
5925b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5926b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5927b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5928b13edf7fSJoe Perches				}
5929f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5930f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5931f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5932e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5933f5ef95b1SJoe Perches
5934f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5935f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5936b13edf7fSJoe Perches			}
5937b13edf7fSJoe Perches		}
5938b13edf7fSJoe Perches
5939f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
594013214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
594113214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5942cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
594313214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5944cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5945cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5946aad4f614SJoe Perches				my @allowed = ();
5947aad4f614SJoe Perches				my $allow = 0;
594813214adfSAndy Whitcroft				my $seen = 0;
5949773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5950cf655043SAndy Whitcroft				my $ln = $linenr - 1;
595113214adfSAndy Whitcroft				for my $chunk (@chunks) {
595213214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
595313214adfSAndy Whitcroft
5954773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5955773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5956773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5957773647a0SAndy Whitcroft
5958aad4f614SJoe Perches					$allowed[$allow] = 0;
5959773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5960773647a0SAndy Whitcroft
5961773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5962773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5963773647a0SAndy Whitcroft
5964773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5965cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5966cf655043SAndy Whitcroft
5967773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
596813214adfSAndy Whitcroft
596913214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
597013214adfSAndy Whitcroft
5971aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5972cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5973cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5974aad4f614SJoe Perches						$allowed[$allow] = 1;
597513214adfSAndy Whitcroft					}
597613214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5977cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5978aad4f614SJoe Perches						$allowed[$allow] = 1;
597913214adfSAndy Whitcroft					}
5980cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5981cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5982aad4f614SJoe Perches						$allowed[$allow] = 1;
598313214adfSAndy Whitcroft					}
5984aad4f614SJoe Perches					$allow++;
598513214adfSAndy Whitcroft				}
5986aad4f614SJoe Perches				if ($seen) {
5987aad4f614SJoe Perches					my $sum_allowed = 0;
5988aad4f614SJoe Perches					foreach (@allowed) {
5989aad4f614SJoe Perches						$sum_allowed += $_;
5990aad4f614SJoe Perches					}
5991aad4f614SJoe Perches					if ($sum_allowed == 0) {
5992000d1cc1SJoe Perches						WARN("BRACES",
5993000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5994aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5995aad4f614SJoe Perches						 $seen != $allow) {
5996aad4f614SJoe Perches						CHK("BRACES",
5997aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5998aad4f614SJoe Perches					}
599913214adfSAndy Whitcroft				}
600013214adfSAndy Whitcroft			}
600113214adfSAndy Whitcroft		}
6002773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
600313214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
6004cf655043SAndy Whitcroft			my $allowed = 0;
6005f0a594c1SAndy Whitcroft
6006cf655043SAndy Whitcroft			# Check the pre-context.
6007cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6008cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
6009cf655043SAndy Whitcroft				$allowed = 1;
6010f0a594c1SAndy Whitcroft			}
6011773647a0SAndy Whitcroft
6012773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
6013773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
6014773647a0SAndy Whitcroft
6015cf655043SAndy Whitcroft			# Check the condition.
6016cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
6017773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
6018cf655043SAndy Whitcroft			if (defined $cond) {
6019773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
6020cf655043SAndy Whitcroft			}
6021cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
6022cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
6023cf655043SAndy Whitcroft				$allowed = 1;
6024cf655043SAndy Whitcroft			}
6025cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
6026cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
6027cf655043SAndy Whitcroft				$allowed = 1;
6028cf655043SAndy Whitcroft			}
6029cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
6030cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
6031cf655043SAndy Whitcroft				$allowed = 1;
6032cf655043SAndy Whitcroft			}
6033cf655043SAndy Whitcroft			# Check the post-context.
6034cf655043SAndy Whitcroft			if (defined $chunks[1]) {
6035cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
6036cf655043SAndy Whitcroft				if (defined $cond) {
6037773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
6038cf655043SAndy Whitcroft				}
6039cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
6040cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6041cf655043SAndy Whitcroft					$allowed = 1;
6042cf655043SAndy Whitcroft				}
6043cf655043SAndy Whitcroft			}
6044cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6045f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
6046e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6047cf655043SAndy Whitcroft
6048000d1cc1SJoe Perches				WARN("BRACES",
6049000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6050f0a594c1SAndy Whitcroft			}
6051f0a594c1SAndy Whitcroft		}
6052f0a594c1SAndy Whitcroft
6053e4c5babdSJoe Perches# check for single line unbalanced braces
605495330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
605595330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
6056e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6057e4c5babdSJoe Perches		}
6058e4c5babdSJoe Perches
60590979ae66SJoe Perches# check for unnecessary blank lines around braces
606077b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6061f8e58219SJoe Perches			if (CHK("BRACES",
6062f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6063f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
6064f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
6065f8e58219SJoe Perches			}
60660979ae66SJoe Perches		}
606777b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
6068f8e58219SJoe Perches			if (CHK("BRACES",
6069f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6070f8e58219SJoe Perches			    $fix) {
6071f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
6072f8e58219SJoe Perches			}
60730979ae66SJoe Perches		}
60740979ae66SJoe Perches
60754a0df2efSAndy Whitcroft# no volatiles please
60766c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
60776c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6078000d1cc1SJoe Perches			WARN("VOLATILE",
60798c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
60804a0df2efSAndy Whitcroft		}
60814a0df2efSAndy Whitcroft
60825e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
60835e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
60845e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
60855e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
608633acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
60875e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
60885e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
60895e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
60905e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
60915e4f6ba5SJoe Perches				     $fix &&
60925e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
60935e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
60945e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
60955e4f6ba5SJoe Perches				my $comma_close = "";
60965e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
60975e4f6ba5SJoe Perches					$comma_close = $1;
60985e4f6ba5SJoe Perches				}
60995e4f6ba5SJoe Perches
61005e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
61015e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
61025e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
61035e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
61045e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
61055e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
61065e4f6ba5SJoe Perches				$fixedline = $rawline;
61075e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
61085e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
61095e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
61105e4f6ba5SJoe Perches				}
61115e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
61125e4f6ba5SJoe Perches			}
61135e4f6ba5SJoe Perches		}
61145e4f6ba5SJoe Perches
61155e4f6ba5SJoe Perches# check for missing a space in a string concatenation
61165e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
61175e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
61185e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
61195e4f6ba5SJoe Perches		}
61205e4f6ba5SJoe Perches
612177cb8546SJoe Perches# check for an embedded function name in a string when the function is known
6122e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
6123e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
6124e4b7d309SJoe Perches# function declarations
612577cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
612677cb8546SJoe Perches		    defined($context_function) &&
6127e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6128e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
612977cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
6130e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
613177cb8546SJoe Perches		}
613277cb8546SJoe Perches
6133adb2da82SJoe Perches# check for unnecessary function tracing like uses
6134adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6135adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6136adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6137adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6138adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6139adb2da82SJoe Perches			    $fix) {
6140adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6141adb2da82SJoe Perches			}
6142adb2da82SJoe Perches		}
6143adb2da82SJoe Perches
61445e4f6ba5SJoe Perches# check for spaces before a quoted newline
61455e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
61465e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
61475e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
61485e4f6ba5SJoe Perches			    $fix) {
61495e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
61505e4f6ba5SJoe Perches			}
61515e4f6ba5SJoe Perches
61525e4f6ba5SJoe Perches		}
61535e4f6ba5SJoe Perches
6154f17dba4fSJoe Perches# concatenated string without spaces between elements
6155d2af5aa6SJoe Perches		if ($line =~ /$String[A-Z_]/ ||
6156d2af5aa6SJoe Perches		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
615779682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
615879682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
615979682c0cSJoe Perches			    $fix) {
616079682c0cSJoe Perches				while ($line =~ /($String)/g) {
616179682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
616279682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
616379682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
616479682c0cSJoe Perches				}
616579682c0cSJoe Perches			}
6166f17dba4fSJoe Perches		}
6167f17dba4fSJoe Perches
616890ad30e5SJoe Perches# uncoalesced string fragments
6169d2af5aa6SJoe Perches		if ($line =~ /$String\s*[Lu]?"/) {
617079682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
617179682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
617279682c0cSJoe Perches			    $fix) {
617379682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
617479682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
617579682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
617679682c0cSJoe Perches				}
617779682c0cSJoe Perches			}
617890ad30e5SJoe Perches		}
617990ad30e5SJoe Perches
6180522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6181522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6182522b837cSAlexey Dobriyan		my $show_Z = 1;
61835e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6184522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
61855e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6186522b837cSAlexey Dobriyan			# check for %L
6187522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
61885e4f6ba5SJoe Perches				WARN("PRINTF_L",
6189522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6190522b837cSAlexey Dobriyan				$show_L = 0;
61915e4f6ba5SJoe Perches			}
6192522b837cSAlexey Dobriyan			# check for %Z
6193522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6194522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6195522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6196522b837cSAlexey Dobriyan				$show_Z = 0;
6197522b837cSAlexey Dobriyan			}
6198522b837cSAlexey Dobriyan			# check for 0x<decimal>
6199522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6200522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
62016e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
62026e300757SJoe Perches			}
62035e4f6ba5SJoe Perches		}
62045e4f6ba5SJoe Perches
62055e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
62063f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
62075e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
62085e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
62095e4f6ba5SJoe Perches		}
62105e4f6ba5SJoe Perches
621100df344fSAndy Whitcroft# warn about #if 0
6212c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
621360f89010SPrakruthi Deepak Heragu			WARN("IF_0",
621460f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
621560f89010SPrakruthi Deepak Heragu		}
621660f89010SPrakruthi Deepak Heragu
621760f89010SPrakruthi Deepak Heragu# warn about #if 1
621860f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
621960f89010SPrakruthi Deepak Heragu			WARN("IF_1",
622060f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
62214a0df2efSAndy Whitcroft		}
62224a0df2efSAndy Whitcroft
622303df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
622403df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6225100425deSJoe Perches			my $tested = quotemeta($1);
6226100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6227100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6228100425deSJoe Perches				my $func = $1;
6229100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6230100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6231100425deSJoe Perches				    $fix) {
6232100425deSJoe Perches					my $do_fix = 1;
6233100425deSJoe Perches					my $leading_tabs = "";
6234100425deSJoe Perches					my $new_leading_tabs = "";
6235100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6236100425deSJoe Perches						$leading_tabs = $1;
6237100425deSJoe Perches					} else {
6238100425deSJoe Perches						$do_fix = 0;
6239100425deSJoe Perches					}
6240100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6241100425deSJoe Perches						$new_leading_tabs = $1;
6242100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6243100425deSJoe Perches							$do_fix = 0;
6244100425deSJoe Perches						}
6245100425deSJoe Perches					} else {
6246100425deSJoe Perches						$do_fix = 0;
6247100425deSJoe Perches					}
6248100425deSJoe Perches					if ($do_fix) {
6249100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6250100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6251100425deSJoe Perches					}
6252100425deSJoe Perches				}
62534c432a8fSGreg Kroah-Hartman			}
62544c432a8fSGreg Kroah-Hartman		}
6255f0a594c1SAndy Whitcroft
6256ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6257ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6258ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6259ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6260ebfdc409SJoe Perches		    $linenr > 3) {
6261ebfdc409SJoe Perches			my $testval = $2;
6262ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6263ebfdc409SJoe Perches
6264ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6265ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6266ebfdc409SJoe Perches
6267e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6268e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6269ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6270ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6271ebfdc409SJoe Perches			}
6272ebfdc409SJoe Perches		}
6273ebfdc409SJoe Perches
6274f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6275dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6276f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6277f78d98f6SJoe Perches			my $level = $1;
6278f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6279f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6280f78d98f6SJoe Perches			    $fix) {
6281f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6282f78d98f6SJoe Perches			}
6283f78d98f6SJoe Perches		}
6284f78d98f6SJoe Perches
628545c55e92SJoe Perches# check for logging continuations
628645c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
628745c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
628845c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
628945c55e92SJoe Perches		}
629045c55e92SJoe Perches
629170eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
629270eb2275SDwaipayan Ray		if (defined $stat &&
629370eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
629470eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
629570eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
629670eb2275SDwaipayan Ray			$lc = $lc + $linenr;
629770eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
629870eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
629970eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
630070eb2275SDwaipayan Ray				my $pspec = $1;
630170eb2275SDwaipayan Ray				my $h = $2;
630270eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
630370eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
630470eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
630570eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
630670eb2275SDwaipayan Ray					my $nspec = $pspec;
630770eb2275SDwaipayan Ray					$nspec =~ s/h//g;
630870eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
630970eb2275SDwaipayan Ray				}
631070eb2275SDwaipayan Ray			}
631170eb2275SDwaipayan Ray		}
631270eb2275SDwaipayan Ray
6313abb08a53SJoe Perches# check for mask then right shift without a parentheses
63145b57980dSJoe Perches		if ($perl_version_ok &&
6315abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6316abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6317abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6318abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6319abb08a53SJoe Perches		}
6320abb08a53SJoe Perches
6321b75ac618SJoe Perches# check for pointer comparisons to NULL
63225b57980dSJoe Perches		if ($perl_version_ok) {
6323b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6324b75ac618SJoe Perches				my $val = $1;
6325b75ac618SJoe Perches				my $equal = "!";
6326b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6327b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6328b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6329b75ac618SJoe Perches					    $fix) {
6330b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6331b75ac618SJoe Perches				}
6332b75ac618SJoe Perches			}
6333b75ac618SJoe Perches		}
6334b75ac618SJoe Perches
63358716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
63368716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
63378716de38SJoe Perches			my $attr = $1;
63388716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
63398716de38SJoe Perches				my $ptr = $1;
63408716de38SJoe Perches				my $var = $2;
63418716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
63428716de38SJoe Perches				      ERROR("MISPLACED_INIT",
63438716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
63448716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
63458716de38SJoe Perches				      WARN("MISPLACED_INIT",
63468716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
63478716de38SJoe Perches				    $fix) {
6348194f66fcSJoe 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;
63498716de38SJoe Perches				}
63508716de38SJoe Perches			}
63518716de38SJoe Perches		}
63528716de38SJoe Perches
6353e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6354e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6355e970b884SJoe Perches			my $attr = $1;
6356e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6357e970b884SJoe Perches			my $attr_prefix = $1;
6358e970b884SJoe Perches			my $attr_type = $2;
6359e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6360e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6361e970b884SJoe Perches			    $fix) {
6362194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6363e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6364e970b884SJoe Perches			}
6365e970b884SJoe Perches		}
6366e970b884SJoe Perches
6367e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6368e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6369e970b884SJoe Perches			my $attr = $1;
6370e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6371e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6372e970b884SJoe Perches			    $fix) {
6373194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6374e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6375e970b884SJoe Perches				$lead = rtrim($1);
6376e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6377e970b884SJoe Perches				$lead = "${lead}const ";
6378194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6379e970b884SJoe Perches			}
6380e970b884SJoe Perches		}
6381e970b884SJoe Perches
6382c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6383c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6384c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6385c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6386c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6387c17893c7SJoe Perches			    $fix) {
6388c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6389c17893c7SJoe Perches			}
6390c17893c7SJoe Perches		}
6391c17893c7SJoe Perches
6392fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6393fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6394fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6395fbdb8138SJoe Perches			my $constant_func = $1;
6396fbdb8138SJoe Perches			my $func = $constant_func;
6397fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6398fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6399fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6400fbdb8138SJoe Perches			    $fix) {
6401194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6402fbdb8138SJoe Perches			}
6403fbdb8138SJoe Perches		}
6404fbdb8138SJoe Perches
64051a15a250SPatrick Pannuto# prefer usleep_range over udelay
640637581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
640743c1d77cSJoe Perches			my $delay = $1;
64081a15a250SPatrick Pannuto			# ignore udelay's < 10, however
640943c1d77cSJoe Perches			if (! ($delay < 10) ) {
6410000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6411458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
641243c1d77cSJoe Perches			}
641343c1d77cSJoe Perches			if ($delay > 2000) {
641443c1d77cSJoe Perches				WARN("LONG_UDELAY",
641543c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
64161a15a250SPatrick Pannuto			}
64171a15a250SPatrick Pannuto		}
64181a15a250SPatrick Pannuto
641909ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
642009ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
642109ef8725SPatrick Pannuto			if ($1 < 20) {
6422000d1cc1SJoe Perches				WARN("MSLEEP",
6423458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
642409ef8725SPatrick Pannuto			}
642509ef8725SPatrick Pannuto		}
642609ef8725SPatrick Pannuto
642736ec1939SJoe Perches# check for comparisons of jiffies
642836ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
642936ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
643036ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
643136ec1939SJoe Perches		}
643236ec1939SJoe Perches
64339d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
64349d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
64359d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
64369d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
64379d7a34a5SJoe Perches		}
64389d7a34a5SJoe Perches
643900df344fSAndy Whitcroft# warn about #ifdefs in C files
6440c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
644100df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
644200df344fSAndy Whitcroft#			print "$herecurr";
644300df344fSAndy Whitcroft#			$clean = 0;
644400df344fSAndy Whitcroft#		}
644500df344fSAndy Whitcroft
644622f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6447c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
64483705ce5bSJoe Perches			if (ERROR("SPACING",
64493705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
64503705ce5bSJoe Perches			    $fix) {
6451194f66fcSJoe Perches				$fixed[$fixlinenr] =~
64523705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
64533705ce5bSJoe Perches			}
64543705ce5bSJoe Perches
645522f2a2efSAndy Whitcroft		}
645622f2a2efSAndy Whitcroft
64574a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6458171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6459171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
64604a0df2efSAndy Whitcroft			my $which = $1;
64614a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6462000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6463000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
64644a0df2efSAndy Whitcroft			}
64654a0df2efSAndy Whitcroft		}
64664a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6467402c2553SMichael S. Tsirkin
6468402c2553SMichael S. Tsirkin		my $barriers = qr{
6469402c2553SMichael S. Tsirkin			mb|
6470402c2553SMichael S. Tsirkin			rmb|
6471ad83ec6cSWill Deacon			wmb
6472402c2553SMichael S. Tsirkin		}x;
6473402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6474402c2553SMichael S. Tsirkin			mb__before_atomic|
6475402c2553SMichael S. Tsirkin			mb__after_atomic|
6476402c2553SMichael S. Tsirkin			store_release|
6477402c2553SMichael S. Tsirkin			load_acquire|
6478402c2553SMichael S. Tsirkin			store_mb|
6479402c2553SMichael S. Tsirkin			(?:$barriers)
6480402c2553SMichael S. Tsirkin		}x;
6481402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6482402c2553SMichael S. Tsirkin			(?:$barriers)|
648343e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
648443e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6485402c2553SMichael S. Tsirkin		}x;
6486402c2553SMichael S. Tsirkin
6487402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
64884a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6489c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6490000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
64914a0df2efSAndy Whitcroft			}
64924a0df2efSAndy Whitcroft		}
64933ad81779SPaul E. McKenney
6494f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6495f4073b0fSMichael S. Tsirkin
6496f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6497f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6498f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6499f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6500f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6501f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6502f4073b0fSMichael S. Tsirkin		}
6503f4073b0fSMichael S. Tsirkin
6504cb426e99SJoe Perches# check for waitqueue_active without a comment.
6505cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6506cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6507cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6508cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6509cb426e99SJoe Perches			}
6510cb426e99SJoe Perches		}
65113ad81779SPaul E. McKenney
65125099a722SMarco Elver# check for data_race without a comment.
65135099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
65145099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
65155099a722SMarco Elver				WARN("DATA_RACE",
65165099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
65175099a722SMarco Elver			}
65185099a722SMarco Elver		}
65195099a722SMarco Elver
65204a0df2efSAndy Whitcroft# check of hardware specific defines
6521c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6522000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6523000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
65240a920b5bSAndy Whitcroft		}
6525653d4876SAndy Whitcroft
6526596ed45bSJoe Perches# check that the storage class is not after a type
6527596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6528000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6529596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6530596ed45bSJoe Perches		}
6531596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6532596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6533596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6534596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6535596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6536596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6537596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6538d4977c78STobias Klauser		}
6539d4977c78STobias Klauser
6540de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6541de7d4f0eSAndy Whitcroft# storage class and type.
65429c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
65439c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6544000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6545000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6546de7d4f0eSAndy Whitcroft		}
6547de7d4f0eSAndy Whitcroft
65488905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
65492b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
65502b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6551d5e616fcSJoe Perches			if (WARN("INLINE",
6552d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6553d5e616fcSJoe Perches			    $fix) {
6554194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6555d5e616fcSJoe Perches
6556d5e616fcSJoe Perches			}
65578905a67cSAndy Whitcroft		}
65588905a67cSAndy Whitcroft
65597ebe1d17SDwaipayan Ray# Check for compiler attributes
65602b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
65617ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
65627ebe1d17SDwaipayan Ray			my $attr = $1;
65637ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
65647ebe1d17SDwaipayan Ray
65657ebe1d17SDwaipayan Ray			my %attr_list = (
65660830aab0SJoe Perches				"alias"				=> "__alias",
65677ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
65687ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
65697ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
65707ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
65717ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
65727ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
65737ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
65747ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
65757ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
65767ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
65777ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
65787ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
65797ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
65807ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
65817ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
65827ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
65837ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
65847ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
65857ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6586339f29d9SJoe Perches				"section"			=> "__section",
65870830aab0SJoe Perches				"used"				=> "__used",
65880830aab0SJoe Perches				"weak"				=> "__weak"
65897ebe1d17SDwaipayan Ray			);
65907ebe1d17SDwaipayan Ray
65917ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6592339f29d9SJoe Perches				my $orig_attr = $1;
65937ebe1d17SDwaipayan Ray				my $params = '';
65947ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6595339f29d9SJoe Perches				my $curr_attr = $orig_attr;
65967ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
65977ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6598339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
65997ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
66007ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6601339f29d9SJoe Perches						$new = "__$1\($2";
66027ebe1d17SDwaipayan Ray					} else {
6603339f29d9SJoe Perches						$new = "$new$params";
66047ebe1d17SDwaipayan Ray					}
66057ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6606339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
66077ebe1d17SDwaipayan Ray					    $fix) {
6608339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6609339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6610339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6611339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6612339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
66137ebe1d17SDwaipayan Ray					}
661439b7e287SJoe Perches				}
6615462811d9SJoe Perches			}
6616462811d9SJoe Perches
66177ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
66187ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
66197ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
66207ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6621d5e616fcSJoe Perches			}
66226061d949SJoe Perches		}
66236061d949SJoe Perches
6624619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
66255b57980dSJoe Perches		if ($perl_version_ok &&
6626619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6627619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6628619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6629619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6630619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6631619a908aSJoe Perches		}
6632619a908aSJoe Perches
6633fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6634e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6635fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6636e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6637e6176fa4SJoe Perches			my $type = $1;
6638e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6639e6176fa4SJoe Perches				$type = $1;
6640e6176fa4SJoe Perches				my $kernel_type = 'u';
6641e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6642e6176fa4SJoe Perches				$type =~ /(\d+)/;
6643e6176fa4SJoe Perches				$kernel_type .= $1;
6644e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6645e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6646e6176fa4SJoe Perches				    $fix) {
6647e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6648e6176fa4SJoe Perches				}
6649e6176fa4SJoe Perches			}
6650e6176fa4SJoe Perches		}
6651e6176fa4SJoe Perches
6652938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6653938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6654938224b5SJoe Perches			my $cast = $1;
6655938224b5SJoe Perches			my $const = $2;
6656938224b5SJoe Perches			my $suffix = "";
6657938224b5SJoe Perches			my $newconst = $const;
6658938224b5SJoe Perches			$newconst =~ s/${Int_type}$//;
6659938224b5SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6660938224b5SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6661938224b5SJoe Perches			    $suffix .= 'LL';
6662938224b5SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6663938224b5SJoe Perches			    $suffix .= 'L';
6664938224b5SJoe Perches			}
66650972b8bfSJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
66660972b8bfSJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
66670972b8bfSJoe Perches			    $fix) {
6668938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6669938224b5SJoe Perches			}
6670938224b5SJoe Perches		}
6671938224b5SJoe Perches
66728f53a9b8SJoe Perches# check for sizeof(&)
66738f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6674000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6675000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
66768f53a9b8SJoe Perches		}
66778f53a9b8SJoe Perches
667866c80b60SJoe Perches# check for sizeof without parenthesis
667966c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6680d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6681d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6682d5e616fcSJoe Perches			    $fix) {
6683194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6684d5e616fcSJoe Perches			}
668566c80b60SJoe Perches		}
668666c80b60SJoe Perches
668788982feaSJoe Perches# check for struct spinlock declarations
668888982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
668988982feaSJoe Perches			WARN("USE_SPINLOCK_T",
669088982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
669188982feaSJoe Perches		}
669288982feaSJoe Perches
6693a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
669406668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6695a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6696caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6697caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6698d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6699d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6700d5e616fcSJoe Perches				    $fix) {
6701194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6702d5e616fcSJoe Perches				}
6703a6962d72SJoe Perches			}
6704a6962d72SJoe Perches		}
6705a6962d72SJoe Perches
67060b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
67075b57980dSJoe Perches		if ($perl_version_ok &&
67080b523769SJoe Perches		    defined $stat &&
67090b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
67100b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6711e3c6bc95STobin C. Harding			my $stat_real;
6712e3c6bc95STobin C. Harding
67130b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
67140b523769SJoe Perches			$lc = $lc + $linenr;
67150b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6716ffe07513SJoe Perches				my $specifier;
6717ffe07513SJoe Perches				my $extension;
67183bd32d6aSSakari Ailus				my $qualifier;
6719ffe07513SJoe Perches				my $bad_specifier = "";
67200b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
67210b523769SJoe Perches				$fmt =~ s/%%//g;
6722e3c6bc95STobin C. Harding
67233bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6724e3c6bc95STobin C. Harding					$specifier = $1;
6725e3c6bc95STobin C. Harding					$extension = $2;
67263bd32d6aSSakari Ailus					$qualifier = $3;
6727af612e43SSakari Ailus					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
67283bd32d6aSSakari Ailus					    ($extension eq "f" &&
6729af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^w/) ||
6730af612e43SSakari Ailus					    ($extension eq "4" &&
6731af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^cc/)) {
6732e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
67330b523769SJoe Perches						last;
67340b523769SJoe Perches					}
6735e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6736e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6737e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
67380b523769SJoe Perches						}
6739e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6740e3c6bc95STobin 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");
6741e3c6bc95STobin C. Harding					}
6742e3c6bc95STobin C. Harding				}
6743e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
67442a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
67451df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
67461df7338aSSergey Senozhatsky					my $use = "";
6747e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
67481df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6749e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
67501df7338aSSergey Senozhatsky					}
67512a9f9d85STobin C. Harding
67520b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6753e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6754e3c6bc95STobin C. Harding				}
67550b523769SJoe Perches			}
67560b523769SJoe Perches		}
67570b523769SJoe Perches
6758554e165cSAndy Whitcroft# Check for misused memsets
67595b57980dSJoe Perches		if ($perl_version_ok &&
6760d1fe9c09SJoe Perches		    defined $stat &&
67619e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6762554e165cSAndy Whitcroft
6763d7c76ba7SJoe Perches			my $ms_addr = $2;
6764d1fe9c09SJoe Perches			my $ms_val = $7;
6765d1fe9c09SJoe Perches			my $ms_size = $12;
6766d7c76ba7SJoe Perches
6767554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6768554e165cSAndy Whitcroft				ERROR("MEMSET",
6769d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6770554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6771554e165cSAndy Whitcroft				WARN("MEMSET",
6772d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6773d7c76ba7SJoe Perches			}
6774d7c76ba7SJoe Perches		}
6775d7c76ba7SJoe Perches
677698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
67775b57980dSJoe Perches#		if ($perl_version_ok &&
6778f333195dSJoe Perches#		    defined $stat &&
6779f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6780f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6781f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6782f333195dSJoe Perches#			    $fix) {
6783f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6784f333195dSJoe Perches#			}
6785f333195dSJoe Perches#		}
678698a9bba5SJoe Perches
6787b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
67885b57980dSJoe Perches#		if ($perl_version_ok &&
6789f333195dSJoe Perches#		    defined $stat &&
6790f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6791f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6792f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6793f333195dSJoe Perches#		}
6794b6117d17SMateusz Kulikowski
67958617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
67968617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
67975b57980dSJoe Perches#		if ($perl_version_ok &&
6798f333195dSJoe Perches#		    defined $stat &&
6799f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6800f333195dSJoe Perches#
6801f333195dSJoe Perches#			my $ms_val = $7;
6802f333195dSJoe Perches#
6803f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6804f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6805f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6806f333195dSJoe Perches#				    $fix) {
6807f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6808f333195dSJoe Perches#				}
6809f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6810f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6811f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6812f333195dSJoe Perches#				    $fix) {
6813f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6814f333195dSJoe Perches#				}
6815f333195dSJoe Perches#			}
6816f333195dSJoe Perches#		}
68178617cd09SMateusz Kulikowski
68185dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
68195dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
68205dbdb2d8SJoe Perches			WARN("STRLCPY",
68215dbdb2d8SJoe Perches			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
68225dbdb2d8SJoe Perches		}
68235dbdb2d8SJoe Perches
6824d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
68255b57980dSJoe Perches		if ($perl_version_ok &&
6826d1fe9c09SJoe Perches		    defined $stat &&
6827d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6828d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6829d7c76ba7SJoe Perches				my $call = $1;
6830d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6831d7c76ba7SJoe Perches				my $arg1 = $3;
6832d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6833d1fe9c09SJoe Perches				my $arg2 = $8;
6834d7c76ba7SJoe Perches				my $cast;
6835d7c76ba7SJoe Perches
6836d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6837d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6838d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6839d7c76ba7SJoe Perches					$cast = $cast1;
6840d7c76ba7SJoe Perches				} else {
6841d7c76ba7SJoe Perches					$cast = $cast2;
6842d7c76ba7SJoe Perches				}
6843d7c76ba7SJoe Perches				WARN("MINMAX",
6844d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6845554e165cSAndy Whitcroft			}
6846554e165cSAndy Whitcroft		}
6847554e165cSAndy Whitcroft
68484a273195SJoe Perches# check usleep_range arguments
68495b57980dSJoe Perches		if ($perl_version_ok &&
68504a273195SJoe Perches		    defined $stat &&
68514a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
68524a273195SJoe Perches			my $min = $1;
68534a273195SJoe Perches			my $max = $7;
68544a273195SJoe Perches			if ($min eq $max) {
68554a273195SJoe Perches				WARN("USLEEP_RANGE",
6856458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
68574a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
68584a273195SJoe Perches				 $min > $max) {
68594a273195SJoe Perches				WARN("USLEEP_RANGE",
6860458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
68614a273195SJoe Perches			}
68624a273195SJoe Perches		}
68634a273195SJoe Perches
6864823b794cSJoe Perches# check for naked sscanf
68655b57980dSJoe Perches		if ($perl_version_ok &&
6866823b794cSJoe Perches		    defined $stat &&
68676c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6868823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6869823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6870823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6871823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6872823b794cSJoe Perches			$lc = $lc + $linenr;
68732a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6874823b794cSJoe Perches			WARN("NAKED_SSCANF",
6875823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6876823b794cSJoe Perches		}
6877823b794cSJoe Perches
6878afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
68795b57980dSJoe Perches		if ($perl_version_ok &&
6880afc819abSJoe Perches		    defined $stat &&
6881afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6882afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6883afc819abSJoe Perches			$lc = $lc + $linenr;
68842a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6885afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6886afc819abSJoe Perches				my $format = $6;
6887afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6888afc819abSJoe Perches				if ($count == 1 &&
6889afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6890afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6891afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6892afc819abSJoe Perches				}
6893afc819abSJoe Perches			}
6894afc819abSJoe Perches		}
6895afc819abSJoe Perches
689670dc8a48SJoe Perches# check for new externs in .h files.
689770dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
689870dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6899d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
690070dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
690170dc8a48SJoe Perches			    $fix) {
6902194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
690370dc8a48SJoe Perches			}
690470dc8a48SJoe Perches		}
690570dc8a48SJoe Perches
6906de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6907171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6908c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6909171ae1a4SAndy Whitcroft		{
6910c45dcabdSAndy Whitcroft			my $function_name = $1;
6911c45dcabdSAndy Whitcroft			my $paren_space = $2;
6912171ae1a4SAndy Whitcroft
6913171ae1a4SAndy Whitcroft			my $s = $stat;
6914171ae1a4SAndy Whitcroft			if (defined $cond) {
6915171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6916171ae1a4SAndy Whitcroft			}
6917d8b44b58SKees Cook			if ($s =~ /^\s*;/)
6918c45dcabdSAndy Whitcroft			{
6919000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6920000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6921de7d4f0eSAndy Whitcroft			}
6922de7d4f0eSAndy Whitcroft
6923171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6924000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6925000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6926171ae1a4SAndy Whitcroft			}
69279c9ba34eSAndy Whitcroft
69289c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
69299c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
69309c9ba34eSAndy Whitcroft		{
6931000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6932000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6933171ae1a4SAndy Whitcroft		}
6934171ae1a4SAndy Whitcroft
6935a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
6936a0ad7596SJoe Perches		if (defined $stat &&
6937d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6938d8b44b58SKees Cook		    $1 ne "void") {
6939d8b44b58SKees Cook			my $args = trim($1);
6940ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6941ca0d8929SJoe Perches				my $arg = trim($1);
6942d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6943ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6944ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6945ca0d8929SJoe Perches				}
6946ca0d8929SJoe Perches			}
6947ca0d8929SJoe Perches		}
6948ca0d8929SJoe Perches
6949a0ad7596SJoe Perches# check for function definitions
69505b57980dSJoe Perches		if ($perl_version_ok &&
6951a0ad7596SJoe Perches		    defined $stat &&
6952a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6953a0ad7596SJoe Perches			$context_function = $1;
6954a0ad7596SJoe Perches
6955a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6956a0ad7596SJoe Perches			my $ok = 0;
6957a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6958a0ad7596SJoe Perches			my $herectx = $here . "\n";
6959a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6960a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6961a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6962a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6963a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6964a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6965a0ad7596SJoe Perches			}
6966a0ad7596SJoe Perches			if (!$ok) {
6967a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6968a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6969a0ad7596SJoe Perches			}
6970a0ad7596SJoe Perches		}
6971a0ad7596SJoe Perches
6972de7d4f0eSAndy Whitcroft# checks for new __setup's
6973de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6974de7d4f0eSAndy Whitcroft			my $name = $1;
6975de7d4f0eSAndy Whitcroft
6976de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6977000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
69782581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
6979de7d4f0eSAndy Whitcroft			}
6980653d4876SAndy Whitcroft		}
69819c0ca6f9SAndy Whitcroft
6982e29a70f1SJoe Perches# check for pointless casting of alloc functions
6983e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6984000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6985000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
69869c0ca6f9SAndy Whitcroft		}
698713214adfSAndy Whitcroft
6988a640d25cSJoe Perches# alloc style
6989a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
69905b57980dSJoe Perches		if ($perl_version_ok &&
6991e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6992a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6993a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6994a640d25cSJoe Perches		}
6995a640d25cSJoe Perches
699660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
69975b57980dSJoe Perches		if ($perl_version_ok &&
69981b4a2ed4SJoe Perches		    defined $stat &&
69991b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
700060a55369SJoe Perches			my $oldfunc = $3;
700160a55369SJoe Perches			my $a1 = $4;
700260a55369SJoe Perches			my $a2 = $10;
700360a55369SJoe Perches			my $newfunc = "kmalloc_array";
700460a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
700560a55369SJoe Perches			my $r1 = $a1;
700660a55369SJoe Perches			my $r2 = $a2;
700760a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
700860a55369SJoe Perches				$r1 = $a2;
700960a55369SJoe Perches				$r2 = $a1;
701060a55369SJoe Perches			}
7011e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
7012e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
70131b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
7014e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
7015e3d95a2aSTobin C. Harding
7016e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
70171b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
70181b4a2ed4SJoe Perches				    $cnt == 1 &&
7019e367455aSJoe Perches				    $fix) {
7020194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
702160a55369SJoe Perches				}
702260a55369SJoe Perches			}
702360a55369SJoe Perches		}
702460a55369SJoe Perches
7025972fdea2SJoe Perches# check for krealloc arg reuse
70265b57980dSJoe Perches		if ($perl_version_ok &&
70274cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
70284cab63ceSJoe Perches		    $1 eq $3) {
7029972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
7030972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7031972fdea2SJoe Perches		}
7032972fdea2SJoe Perches
70335ce59ae0SJoe Perches# check for alloc argument mismatch
70347e6cdd7fSChristophe JAILLET		if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
70355ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
70365ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
70375ce59ae0SJoe Perches		}
70385ce59ae0SJoe Perches
7039caf2a54fSJoe Perches# check for multiple semicolons
7040caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
7041d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
7042d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7043d5e616fcSJoe Perches			    $fix) {
7044194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7045d5e616fcSJoe Perches			}
7046d1e2ad07SJoe Perches		}
7047d1e2ad07SJoe Perches
7048cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7049cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
7050cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
70510ab90191SJoe Perches			my $ull = "";
70520ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
70530ab90191SJoe Perches			if (CHK("BIT_MACRO",
70540ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
70550ab90191SJoe Perches			    $fix) {
70560ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
70570ab90191SJoe Perches			}
70580ab90191SJoe Perches		}
70590ab90191SJoe Perches
706050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
70613e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
706250161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
70633e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
706450161266SJoe Perches		}
706550161266SJoe Perches
70662d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
70673e89ad85SJerome 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*$/) {
70682d632745SJoe Perches			my $config = $1;
70692d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
70703e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
70712d632745SJoe Perches			    $fix) {
70722d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
70732d632745SJoe Perches			}
70742d632745SJoe Perches		}
70752d632745SJoe Perches
7076f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
7077f36d3eb8SJoe Perches		my @fallthroughs = (
7078f36d3eb8SJoe Perches			'fallthrough',
7079f36d3eb8SJoe Perches			'@fallthrough@',
7080f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
7081f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7082f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7083f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7084f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7085f36d3eb8SJoe Perches		    );
7086f36d3eb8SJoe Perches		if ($raw_comment ne '') {
7087f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
7088f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
7089f36d3eb8SJoe Perches					my $msg_level = \&WARN;
7090f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
7091f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
7092f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7093f36d3eb8SJoe Perches					last;
7094f36d3eb8SJoe Perches				}
7095f36d3eb8SJoe Perches			}
7096f36d3eb8SJoe Perches		}
7097f36d3eb8SJoe Perches
7098d1e2ad07SJoe Perches# check for switch/default statements without a break;
70995b57980dSJoe Perches		if ($perl_version_ok &&
7100d1e2ad07SJoe Perches		    defined $stat &&
7101d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7102d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
7103e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
7104e3d95a2aSTobin C. Harding
7105d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
7106d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
7107caf2a54fSJoe Perches		}
7108caf2a54fSJoe Perches
710913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
7110d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
7111d5e616fcSJoe Perches			if (WARN("USE_FUNC",
7112d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
7113d5e616fcSJoe Perches			    $fix) {
7114194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7115d5e616fcSJoe Perches			}
711613214adfSAndy Whitcroft		}
7117773647a0SAndy Whitcroft
711862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
711962ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
712062ec818fSJoe Perches			ERROR("DATE_TIME",
712162ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
712262ec818fSJoe Perches		}
712362ec818fSJoe Perches
71242c92488aSJoe Perches# check for use of yield()
71252c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
71262c92488aSJoe Perches			WARN("YIELD",
71272c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
71282c92488aSJoe Perches		}
71292c92488aSJoe Perches
7130179f8f40SJoe Perches# check for comparisons against true and false
7131179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7132179f8f40SJoe Perches			my $lead = $1;
7133179f8f40SJoe Perches			my $arg = $2;
7134179f8f40SJoe Perches			my $test = $3;
7135179f8f40SJoe Perches			my $otype = $4;
7136179f8f40SJoe Perches			my $trail = $5;
7137179f8f40SJoe Perches			my $op = "!";
7138179f8f40SJoe Perches
7139179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7140179f8f40SJoe Perches
7141179f8f40SJoe Perches			my $type = lc($otype);
7142179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7143179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7144179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7145179f8f40SJoe Perches					$op = "";
7146179f8f40SJoe Perches				}
7147179f8f40SJoe Perches
7148179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7149179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7150179f8f40SJoe Perches
7151179f8f40SJoe Perches## maybe suggesting a correct construct would better
7152179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7153179f8f40SJoe Perches
7154179f8f40SJoe Perches			}
7155179f8f40SJoe Perches		}
7156179f8f40SJoe Perches
71574882720bSThomas Gleixner# check for semaphores initialized locked
71584882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7159000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7160000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7161773647a0SAndy Whitcroft		}
71626712d858SJoe Perches
716367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
716467d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7165000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
716667d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7167773647a0SAndy Whitcroft		}
71686712d858SJoe Perches
7169ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7170f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7171000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7172ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7173f3db6639SMichael Ellerman		}
71746712d858SJoe Perches
71753d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
71763d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
71773d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
71783d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
71793d709ab5SPaul E. McKenney		}
71803d709ab5SPaul E. McKenney
71819189c7e7SJoe Perches# check for deprecated apis
71829189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
71839189c7e7SJoe Perches			my $deprecated_api = $1;
71849189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
71859189c7e7SJoe Perches			WARN("DEPRECATED_API",
71869189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
71879189c7e7SJoe Perches		}
71889189c7e7SJoe Perches
71890f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7190d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7191ced69da1SQuentin Monnet		if (defined($const_structs) &&
7192ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7193d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7194000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7195d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
71962b6db5cbSAndy Whitcroft		}
7197773647a0SAndy Whitcroft
7198773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7199773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
720035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7201773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7202c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7203c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7204171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7205171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
720635cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
720735cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7208773647a0SAndy Whitcroft		{
7209000d1cc1SJoe Perches			WARN("NR_CPUS",
7210000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7211773647a0SAndy Whitcroft		}
72129c9ba34eSAndy Whitcroft
721352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
721452ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
721552ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
721652ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
721752ea8506SJoe Perches		}
721852ea8506SJoe Perches
7219acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
72205b57980dSJoe Perches		if ($perl_version_ok &&
7221acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7222acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7223acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7224acd9362cSJoe Perches		}
7225acd9362cSJoe Perches
7226fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline
7227fbe74541SJoe Perches		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7228fbe74541SJoe Perches		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7229fbe74541SJoe Perches			my $offset = $+[6] - 1;
7230fbe74541SJoe Perches			if (WARN("SYSFS_EMIT",
7231fbe74541SJoe Perches				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7232fbe74541SJoe Perches			    $fix) {
7233fbe74541SJoe Perches				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7234fbe74541SJoe Perches			}
7235fbe74541SJoe Perches		}
7236fbe74541SJoe Perches
7237de3f186fSDenis Efremov# nested likely/unlikely calls
7238de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7239de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7240de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7241de3f186fSDenis Efremov		}
7242de3f186fSDenis Efremov
7243691d77b6SAndy Whitcroft# whine mightly about in_atomic
7244691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7245691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7246000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7247000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7248f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7249000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7250000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7251691d77b6SAndy Whitcroft			}
7252691d77b6SAndy Whitcroft		}
72531704f47bSPeter Zijlstra
72541704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
72551704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
72561704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
72571704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
72581704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
72591704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7260000d1cc1SJoe Perches				ERROR("LOCKDEP",
7261000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
72621704f47bSPeter Zijlstra			}
72631704f47bSPeter Zijlstra		}
726488f8831cSDave Jones
7265b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7266b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7267000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7268000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
726988f8831cSDave Jones		}
72702435880fSJoe Perches
727100180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
727200180468SJoe Perches# and whether or not function naming is typical and if
727300180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
72745b57980dSJoe Perches		if ($perl_version_ok &&
727500180468SJoe Perches		    defined $stat &&
727600180468SJoe 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*\)/) {
727700180468SJoe Perches			my $var = $1;
727800180468SJoe Perches			my $perms = $2;
727900180468SJoe Perches			my $show = $3;
728000180468SJoe Perches			my $store = $4;
728100180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
728200180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
728300180468SJoe Perches			    $store =~ /^${var}_store$/ &&
728400180468SJoe Perches			    $octal_perms eq "0644") {
728500180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
728600180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
728700180468SJoe Perches				    $fix) {
728800180468SJoe 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})/;
728900180468SJoe Perches				}
729000180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
729100180468SJoe Perches				 $store =~ /^NULL$/ &&
729200180468SJoe Perches				 $octal_perms eq "0444") {
729300180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
729400180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
729500180468SJoe Perches				    $fix) {
729600180468SJoe 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})/;
729700180468SJoe Perches				}
729800180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
729900180468SJoe Perches				 $store =~ /^${var}_store$/ &&
730000180468SJoe Perches				 $octal_perms eq "0200") {
730100180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
730200180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
730300180468SJoe Perches				    $fix) {
730400180468SJoe 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})/;
730500180468SJoe Perches				}
730600180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
730700180468SJoe Perches				 $octal_perms eq "0444" ||
730800180468SJoe Perches				 $octal_perms eq "0200") {
730900180468SJoe Perches				my $newshow = "$show";
731000180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
731100180468SJoe Perches				my $newstore = $store;
731200180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
731300180468SJoe Perches				my $rename = "";
731400180468SJoe Perches				if ($show ne $newshow) {
731500180468SJoe Perches					$rename .= " '$show' to '$newshow'";
731600180468SJoe Perches				}
731700180468SJoe Perches				if ($store ne $newstore) {
731800180468SJoe Perches					$rename .= " '$store' to '$newstore'";
731900180468SJoe Perches				}
732000180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
732100180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
732200180468SJoe Perches			} else {
732300180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
732400180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
732500180468SJoe Perches			}
732600180468SJoe Perches		}
732700180468SJoe Perches
7328515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7329515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
733073121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
733173121534SJoe Perches#   specific definition of not visible in sysfs.
733273121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
733373121534SJoe Perches#   use the default permissions
73345b57980dSJoe Perches		if ($perl_version_ok &&
7335459cf0aeSJoe Perches		    defined $stat &&
7336515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
73372435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
73382435880fSJoe Perches				my $func = $entry->[0];
73392435880fSJoe Perches				my $arg_pos = $entry->[1];
73402435880fSJoe Perches
7341459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7342459cf0aeSJoe Perches				$lc = $lc + $linenr;
73432a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7344459cf0aeSJoe Perches
73452435880fSJoe Perches				my $skip_args = "";
73462435880fSJoe Perches				if ($arg_pos > 1) {
73472435880fSJoe Perches					$arg_pos--;
73482435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
73492435880fSJoe Perches				}
7350f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7351459cf0aeSJoe Perches				if ($stat =~ /$test/) {
73522435880fSJoe Perches					my $val = $1;
73532435880fSJoe Perches					$val = $6 if ($skip_args ne "");
735473121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
735573121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
735673121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
73572435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7358459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7359f90774e1SJoe Perches					}
7360f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7361c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7362459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
73632435880fSJoe Perches					}
7364459cf0aeSJoe Perches				}
7365459cf0aeSJoe Perches			}
7366459cf0aeSJoe Perches		}
7367459cf0aeSJoe Perches
7368459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7369bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
737000180468SJoe Perches			my $oval = $1;
737100180468SJoe Perches			my $octal = perms_to_octal($oval);
7372f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7373459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7374f90774e1SJoe Perches			    $fix) {
737500180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
73762435880fSJoe Perches			}
737713214adfSAndy Whitcroft		}
73785a6d20ceSBjorn Andersson
73795a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
73805a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
73815a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
73825a6d20ceSBjorn Andersson			my $valid_licenses = qr{
73835a6d20ceSBjorn Andersson						GPL|
73845a6d20ceSBjorn Andersson						GPL\ v2|
73855a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
73865a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
73875a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
73885a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
73895a6d20ceSBjorn Andersson						Proprietary
73905a6d20ceSBjorn Andersson					}x;
73915a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
73925a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
73935a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
73945a6d20ceSBjorn Andersson			}
73955a6d20ceSBjorn Andersson		}
73966a8d76cbSMatteo Croce
73976a8d76cbSMatteo Croce# check for sysctl duplicate constants
73986a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
73996a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
74006a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
74016a8d76cbSMatteo Croce		}
7402515a235eSJoe Perches	}
740313214adfSAndy Whitcroft
740413214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
740513214adfSAndy Whitcroft	# so just keep quiet.
740613214adfSAndy Whitcroft	if ($#rawlines == -1) {
740713214adfSAndy Whitcroft		exit(0);
74080a920b5bSAndy Whitcroft	}
74090a920b5bSAndy Whitcroft
74108905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
74118905a67cSAndy Whitcroft	# things that appear to be patches.
74128905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
74138905a67cSAndy Whitcroft		exit(0);
74148905a67cSAndy Whitcroft	}
74158905a67cSAndy Whitcroft
7416e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
74178905a67cSAndy Whitcroft	# just keep quiet.
74188905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
74198905a67cSAndy Whitcroft		exit(0);
74208905a67cSAndy Whitcroft	}
74218905a67cSAndy Whitcroft
7422a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7423000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7424000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
74250a920b5bSAndy Whitcroft	}
7426cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7427cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7428000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7429000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
743048ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
743148ca2d8aSDwaipayan Ray			# authorsignoff values:
743248ca2d8aSDwaipayan Ray			# 0 -> missing sign off
743348ca2d8aSDwaipayan Ray			# 1 -> sign off identical
743448ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
743548ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
743648ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
743748ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
743848ca2d8aSDwaipayan Ray
743948ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
744048ca2d8aSDwaipayan Ray
744148ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
744248ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7443cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
744448ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
744548ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
744648ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
744748ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
744848ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
744948ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
745048ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
745148ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
745248ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
745348ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
745448ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
745548ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
745648ca2d8aSDwaipayan Ray			}
7457cd261496SGeert Uytterhoeven		}
74580a920b5bSAndy Whitcroft	}
74590a920b5bSAndy Whitcroft
7460f0a594c1SAndy Whitcroft	print report_dump();
746113214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
746213214adfSAndy Whitcroft		print "$filename " if ($summary_file);
74636c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
74646c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
74656c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
74666c72ffaaSAndy Whitcroft	}
74678905a67cSAndy Whitcroft
7468d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7469ef212196SJoe Perches		# If there were any defects found and not already fixing them
7470ef212196SJoe Perches		if (!$clean and !$fix) {
7471ef212196SJoe Perches			print << "EOM"
7472ef212196SJoe Perches
7473ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7474ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7475ef212196SJoe PerchesEOM
7476ef212196SJoe Perches		}
7477d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7478d2c0a235SAndy Whitcroft		# then suggest that.
7479d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7480b0781216SMike Frysinger			$rpt_cleaners = 0;
7481d8469f16SJoe Perches			print << "EOM"
7482d8469f16SJoe Perches
7483d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7484d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7485d8469f16SJoe PerchesEOM
7486d2c0a235SAndy Whitcroft		}
7487d2c0a235SAndy Whitcroft	}
7488d2c0a235SAndy Whitcroft
7489d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7490d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7491d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
74929624b8d6SJoe Perches		my $newfile = $filename;
74939624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
74943705ce5bSJoe Perches		my $linecount = 0;
74953705ce5bSJoe Perches		my $f;
74963705ce5bSJoe Perches
7497d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7498d752fcc8SJoe Perches
74993705ce5bSJoe Perches		open($f, '>', $newfile)
75003705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
75013705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
75023705ce5bSJoe Perches			$linecount++;
75033705ce5bSJoe Perches			if ($file) {
75043705ce5bSJoe Perches				if ($linecount > 3) {
75053705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
75063705ce5bSJoe Perches					print $f $fixed_line . "\n";
75073705ce5bSJoe Perches				}
75083705ce5bSJoe Perches			} else {
75093705ce5bSJoe Perches				print $f $fixed_line . "\n";
75103705ce5bSJoe Perches			}
75113705ce5bSJoe Perches		}
75123705ce5bSJoe Perches		close($f);
75133705ce5bSJoe Perches
75143705ce5bSJoe Perches		if (!$quiet) {
75153705ce5bSJoe Perches			print << "EOM";
7516d8469f16SJoe Perches
75173705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
75183705ce5bSJoe Perches
75193705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
75203705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
75213705ce5bSJoe Perches
75223705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
75233705ce5bSJoe PerchesNo warranties, expressed or implied...
75243705ce5bSJoe PerchesEOM
75253705ce5bSJoe Perches		}
75263705ce5bSJoe Perches	}
75273705ce5bSJoe Perches
7528d8469f16SJoe Perches	if ($quiet == 0) {
7529d8469f16SJoe Perches		print "\n";
7530d8469f16SJoe Perches		if ($clean == 1) {
7531d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7532d8469f16SJoe Perches		} else {
7533d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
75340a920b5bSAndy Whitcroft		}
75350a920b5bSAndy Whitcroft	}
75360a920b5bSAndy Whitcroft	return $clean;
75370a920b5bSAndy Whitcroft}
7538