xref: /linux-6.15/scripts/checkpatch.pl (revision d2af5aa6)
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?};
504*d2af5aa6SJoe 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
1184d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
1185948b133aSHeinrich Schuchardt		$id = undef;
1186d311cd44SJoe Perches	} else {
1187d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1188d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1189d311cd44SJoe Perches	}
1190d311cd44SJoe Perches
1191d311cd44SJoe Perches	return ($id, $desc);
1192d311cd44SJoe Perches}
1193d311cd44SJoe Perches
11946c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
11950a920b5bSAndy Whitcroft
119600df344fSAndy Whitcroftmy @rawlines = ();
1197c2fdda0dSAndy Whitcroftmy @lines = ();
11983705ce5bSJoe Perchesmy @fixed = ();
1199d752fcc8SJoe Perchesmy @fixed_inserted = ();
1200d752fcc8SJoe Perchesmy @fixed_deleted = ();
1201194f66fcSJoe Perchesmy $fixlinenr = -1;
1202194f66fcSJoe Perches
12034a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
12044a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
12050f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
12064a593c34SDu, Changbin
12074a593c34SDu, Changbinif ($git) {
12084a593c34SDu, Changbin	my @commits = ();
12090dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
12104a593c34SDu, Changbin		my $git_range;
121128898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
121228898fd1SJoe Perches			$git_range = "-$2 $1";
12134a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
12144a593c34SDu, Changbin			$git_range = "$commit_expr";
12154a593c34SDu, Changbin		} else {
12160dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
12170dea9f1eSJoe Perches		}
1218dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
12190dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
122028898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
122128898fd1SJoe Perches			next if (!defined($1) || !defined($2));
12220dea9f1eSJoe Perches			my $sha1 = $1;
12230dea9f1eSJoe Perches			my $subject = $2;
12240dea9f1eSJoe Perches			unshift(@commits, $sha1);
12250dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
12264a593c34SDu, Changbin		}
12274a593c34SDu, Changbin	}
12284a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
12294a593c34SDu, Changbin	@ARGV = @commits;
12304a593c34SDu, Changbin}
12314a593c34SDu, Changbin
1232c2fdda0dSAndy Whitcroftmy $vname;
123398005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
12346c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
123521caa13cSAndy Whitcroft	my $FILE;
1236f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1237f5f61325SJoe Perches	my $oldfile = $file;
1238f5f61325SJoe Perches	$file = 1 if ($is_git_file);
12394a593c34SDu, Changbin	if ($git) {
12404a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
12414a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
12424a593c34SDu, Changbin	} elsif ($file) {
124321caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
12446c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
124521caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
124621caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
12476c72ffaaSAndy Whitcroft	} else {
124821caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
12496c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
12506c72ffaaSAndy Whitcroft	}
1251c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1252c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
12534a593c34SDu, Changbin	} elsif ($git) {
12540dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1255c2fdda0dSAndy Whitcroft	} else {
1256c2fdda0dSAndy Whitcroft		$vname = $filename;
1257c2fdda0dSAndy Whitcroft	}
125821caa13cSAndy Whitcroft	while (<$FILE>) {
12590a920b5bSAndy Whitcroft		chomp;
126000df344fSAndy Whitcroft		push(@rawlines, $_);
1261c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
12626c72ffaaSAndy Whitcroft	}
126321caa13cSAndy Whitcroft	close($FILE);
1264d8469f16SJoe Perches
1265d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1266d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1267d8469f16SJoe Perches		print "$vname\n";
1268d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1269d8469f16SJoe Perches	}
1270d8469f16SJoe Perches
1271c2fdda0dSAndy Whitcroft	if (!process($filename)) {
12720a920b5bSAndy Whitcroft		$exit = 1;
12730a920b5bSAndy Whitcroft	}
127400df344fSAndy Whitcroft	@rawlines = ();
127513214adfSAndy Whitcroft	@lines = ();
12763705ce5bSJoe Perches	@fixed = ();
1277d752fcc8SJoe Perches	@fixed_inserted = ();
1278d752fcc8SJoe Perches	@fixed_deleted = ();
1279194f66fcSJoe Perches	$fixlinenr = -1;
1280485ff23eSAlex Dowad	@modifierListFile = ();
1281485ff23eSAlex Dowad	@typeListFile = ();
1282485ff23eSAlex Dowad	build_types();
1283f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
12840a920b5bSAndy Whitcroft}
12850a920b5bSAndy Whitcroft
1286d8469f16SJoe Perchesif (!$quiet) {
12873c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
12883c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
12893c816e49SJoe Perches
12905b57980dSJoe Perches	if (!$perl_version_ok) {
1291d8469f16SJoe Perches		print << "EOM"
1292d8469f16SJoe Perches
1293d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
12945b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1295d8469f16SJoe PerchesEOM
1296d8469f16SJoe Perches	}
1297d8469f16SJoe Perches	if ($exit) {
1298d8469f16SJoe Perches		print << "EOM"
1299d8469f16SJoe Perches
1300d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1301d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1302d8469f16SJoe PerchesEOM
1303d8469f16SJoe Perches	}
1304d8469f16SJoe Perches}
1305d8469f16SJoe Perches
13060a920b5bSAndy Whitcroftexit($exit);
13070a920b5bSAndy Whitcroft
13080a920b5bSAndy Whitcroftsub top_of_kernel_tree {
13096c72ffaaSAndy Whitcroft	my ($root) = @_;
13106c72ffaaSAndy Whitcroft
13116c72ffaaSAndy Whitcroft	my @tree_check = (
13126c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
13136c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
13146c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
13156c72ffaaSAndy Whitcroft	);
13166c72ffaaSAndy Whitcroft
13176c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
13186c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
13190a920b5bSAndy Whitcroft			return 0;
13200a920b5bSAndy Whitcroft		}
13216c72ffaaSAndy Whitcroft	}
13226c72ffaaSAndy Whitcroft	return 1;
13236c72ffaaSAndy Whitcroft}
13240a920b5bSAndy Whitcroft
132520112475SJoe Perchessub parse_email {
132620112475SJoe Perches	my ($formatted_email) = @_;
132720112475SJoe Perches
132820112475SJoe Perches	my $name = "";
1329fccaebf0SDwaipayan Ray	my $quoted = "";
1330dfa05c28SJoe Perches	my $name_comment = "";
133120112475SJoe Perches	my $address = "";
133220112475SJoe Perches	my $comment = "";
133320112475SJoe Perches
133420112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
133520112475SJoe Perches		$name = $1;
133620112475SJoe Perches		$address = $2;
133720112475SJoe Perches		$comment = $3 if defined $3;
133820112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
133920112475SJoe Perches		$address = $1;
134020112475SJoe Perches		$comment = $2 if defined $2;
134120112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
134220112475SJoe Perches		$address = $1;
134320112475SJoe Perches		$comment = $2 if defined $2;
134485e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
134520112475SJoe Perches		$name = $formatted_email;
13463705ce5bSJoe Perches		$name = trim($name);
134720112475SJoe Perches		$name =~ s/^\"|\"$//g;
134820112475SJoe Perches		# If there's a name left after stripping spaces and
134920112475SJoe Perches		# leading quotes, and the address doesn't have both
135020112475SJoe Perches		# leading and trailing angle brackets, the address
135120112475SJoe Perches		# is invalid. ie:
135220112475SJoe Perches		#   "joe smith [email protected]" bad
135320112475SJoe Perches		#   "joe smith <[email protected]" bad
135420112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
135520112475SJoe Perches			$name = "";
135620112475SJoe Perches			$address = "";
135720112475SJoe Perches			$comment = "";
135820112475SJoe Perches		}
135920112475SJoe Perches	}
136020112475SJoe Perches
1361fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1362fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1363fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1364fccaebf0SDwaipayan Ray		$quoted = $1;
1365dfa05c28SJoe Perches	}
1366fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1367fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1368fccaebf0SDwaipayan Ray	}
1369fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1370fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1371fccaebf0SDwaipayan Ray
13723705ce5bSJoe Perches	$address = trim($address);
137320112475SJoe Perches	$address =~ s/^\<|\>$//g;
1374fccaebf0SDwaipayan Ray	$comment = trim($comment);
137520112475SJoe Perches
137620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
137720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
137820112475SJoe Perches		$name = "\"$name\"";
137920112475SJoe Perches	}
138020112475SJoe Perches
1381dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
138220112475SJoe Perches}
138320112475SJoe Perches
138420112475SJoe Perchessub format_email {
138548ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
138620112475SJoe Perches
138720112475SJoe Perches	my $formatted_email;
138820112475SJoe Perches
1389fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
13903705ce5bSJoe Perches	$address = trim($address);
1391fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
139220112475SJoe Perches
139320112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
139420112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
139520112475SJoe Perches		$name = "\"$name\"";
139620112475SJoe Perches	}
139720112475SJoe Perches
1398fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1399fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1400fccaebf0SDwaipayan Ray	$comment = trim($comment);
1401fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1402fccaebf0SDwaipayan Ray
140320112475SJoe Perches	if ("$name" eq "") {
140420112475SJoe Perches		$formatted_email = "$address";
140520112475SJoe Perches	} else {
140648ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
140720112475SJoe Perches	}
140848ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
140920112475SJoe Perches	return $formatted_email;
141020112475SJoe Perches}
141120112475SJoe Perches
1412dfa05c28SJoe Perchessub reformat_email {
1413dfa05c28SJoe Perches	my ($email) = @_;
1414dfa05c28SJoe Perches
1415dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
141648ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1417dfa05c28SJoe Perches}
1418dfa05c28SJoe Perches
1419dfa05c28SJoe Perchessub same_email_addresses {
1420fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1421dfa05c28SJoe Perches
1422dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1423dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1424dfa05c28SJoe Perches
142548ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
142648ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
142748ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
142848ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
142948ca2d8aSDwaipayan Ray}
1430dfa05c28SJoe Perches
1431d311cd44SJoe Perchessub which {
1432d311cd44SJoe Perches	my ($bin) = @_;
1433d311cd44SJoe Perches
1434d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1435d311cd44SJoe Perches		if (-e "$path/$bin") {
1436d311cd44SJoe Perches			return "$path/$bin";
1437d311cd44SJoe Perches		}
1438d311cd44SJoe Perches	}
1439d311cd44SJoe Perches
1440d311cd44SJoe Perches	return "";
1441d311cd44SJoe Perches}
1442d311cd44SJoe Perches
1443000d1cc1SJoe Perchessub which_conf {
1444000d1cc1SJoe Perches	my ($conf) = @_;
1445000d1cc1SJoe Perches
1446000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1447000d1cc1SJoe Perches		if (-e "$path/$conf") {
1448000d1cc1SJoe Perches			return "$path/$conf";
1449000d1cc1SJoe Perches		}
1450000d1cc1SJoe Perches	}
1451000d1cc1SJoe Perches
1452000d1cc1SJoe Perches	return "";
1453000d1cc1SJoe Perches}
1454000d1cc1SJoe Perches
14550a920b5bSAndy Whitcroftsub expand_tabs {
14560a920b5bSAndy Whitcroft	my ($str) = @_;
14570a920b5bSAndy Whitcroft
14580a920b5bSAndy Whitcroft	my $res = '';
14590a920b5bSAndy Whitcroft	my $n = 0;
14600a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
14610a920b5bSAndy Whitcroft		if ($c eq "\t") {
14620a920b5bSAndy Whitcroft			$res .= ' ';
14630a920b5bSAndy Whitcroft			$n++;
1464713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
14650a920b5bSAndy Whitcroft				$res .= ' ';
14660a920b5bSAndy Whitcroft			}
14670a920b5bSAndy Whitcroft			next;
14680a920b5bSAndy Whitcroft		}
14690a920b5bSAndy Whitcroft		$res .= $c;
14700a920b5bSAndy Whitcroft		$n++;
14710a920b5bSAndy Whitcroft	}
14720a920b5bSAndy Whitcroft
14730a920b5bSAndy Whitcroft	return $res;
14740a920b5bSAndy Whitcroft}
14756c72ffaaSAndy Whitcroftsub copy_spacing {
1476773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
14776c72ffaaSAndy Whitcroft	return $res;
14786c72ffaaSAndy Whitcroft}
14790a920b5bSAndy Whitcroft
14804a0df2efSAndy Whitcroftsub line_stats {
14814a0df2efSAndy Whitcroft	my ($line) = @_;
14824a0df2efSAndy Whitcroft
14834a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
14844a0df2efSAndy Whitcroft	$line =~ s/^.//;
14854a0df2efSAndy Whitcroft	$line = expand_tabs($line);
14864a0df2efSAndy Whitcroft
14874a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
14884a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
14894a0df2efSAndy Whitcroft
14904a0df2efSAndy Whitcroft	return (length($line), length($white));
14914a0df2efSAndy Whitcroft}
14924a0df2efSAndy Whitcroft
1493773647a0SAndy Whitcroftmy $sanitise_quote = '';
1494773647a0SAndy Whitcroft
1495773647a0SAndy Whitcroftsub sanitise_line_reset {
1496773647a0SAndy Whitcroft	my ($in_comment) = @_;
1497773647a0SAndy Whitcroft
1498773647a0SAndy Whitcroft	if ($in_comment) {
1499773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1500773647a0SAndy Whitcroft	} else {
1501773647a0SAndy Whitcroft		$sanitise_quote = '';
1502773647a0SAndy Whitcroft	}
1503773647a0SAndy Whitcroft}
150400df344fSAndy Whitcroftsub sanitise_line {
150500df344fSAndy Whitcroft	my ($line) = @_;
150600df344fSAndy Whitcroft
150700df344fSAndy Whitcroft	my $res = '';
150800df344fSAndy Whitcroft	my $l = '';
150900df344fSAndy Whitcroft
1510c2fdda0dSAndy Whitcroft	my $qlen = 0;
1511773647a0SAndy Whitcroft	my $off = 0;
1512773647a0SAndy Whitcroft	my $c;
151300df344fSAndy Whitcroft
1514773647a0SAndy Whitcroft	# Always copy over the diff marker.
1515773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1516773647a0SAndy Whitcroft
1517773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1518773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1519773647a0SAndy Whitcroft
15208d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1521773647a0SAndy Whitcroft		# and end, all to $;.
1522773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1523773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1524773647a0SAndy Whitcroft
1525773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1526773647a0SAndy Whitcroft			$off++;
152700df344fSAndy Whitcroft			next;
1528773647a0SAndy Whitcroft		}
152981bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1530773647a0SAndy Whitcroft			$sanitise_quote = '';
1531773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1532773647a0SAndy Whitcroft			$off++;
1533773647a0SAndy Whitcroft			next;
1534773647a0SAndy Whitcroft		}
1535113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1536113f04a8SDaniel Walker			$sanitise_quote = '//';
1537113f04a8SDaniel Walker
1538113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1539113f04a8SDaniel Walker			$off++;
1540113f04a8SDaniel Walker			next;
1541113f04a8SDaniel Walker		}
1542773647a0SAndy Whitcroft
1543773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1544773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1545773647a0SAndy Whitcroft		    $c eq "\\") {
1546773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1547773647a0SAndy Whitcroft			$off++;
1548773647a0SAndy Whitcroft			next;
1549773647a0SAndy Whitcroft		}
1550773647a0SAndy Whitcroft		# Regular quotes.
1551773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1552773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1553773647a0SAndy Whitcroft				$sanitise_quote = $c;
1554773647a0SAndy Whitcroft
1555773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1556773647a0SAndy Whitcroft				next;
1557773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1558773647a0SAndy Whitcroft				$sanitise_quote = '';
155900df344fSAndy Whitcroft			}
156000df344fSAndy Whitcroft		}
1561773647a0SAndy Whitcroft
1562fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1563773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1564773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1565113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1566113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1567773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1568773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
156900df344fSAndy Whitcroft		} else {
1570773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
157100df344fSAndy Whitcroft		}
1572c2fdda0dSAndy Whitcroft	}
1573c2fdda0dSAndy Whitcroft
1574113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1575113f04a8SDaniel Walker		$sanitise_quote = '';
1576113f04a8SDaniel Walker	}
1577113f04a8SDaniel Walker
1578c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1579c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1580c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1581c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1582c2fdda0dSAndy Whitcroft
1583c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1584c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1585c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1586c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1587c2fdda0dSAndy Whitcroft	}
1588c2fdda0dSAndy Whitcroft
1589dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1590dadf680dSJoe Perches		my $match = $1;
1591dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1592dadf680dSJoe Perches	}
1593dadf680dSJoe Perches
159400df344fSAndy Whitcroft	return $res;
159500df344fSAndy Whitcroft}
159600df344fSAndy Whitcroft
1597a6962d72SJoe Perchessub get_quoted_string {
1598a6962d72SJoe Perches	my ($line, $rawline) = @_;
1599a6962d72SJoe Perches
1600478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
160133acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1602a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1603a6962d72SJoe Perches}
1604a6962d72SJoe Perches
16058905a67cSAndy Whitcroftsub ctx_statement_block {
16068905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16078905a67cSAndy Whitcroft	my $line = $linenr - 1;
16088905a67cSAndy Whitcroft	my $blk = '';
16098905a67cSAndy Whitcroft	my $soff = $off;
16108905a67cSAndy Whitcroft	my $coff = $off - 1;
1611773647a0SAndy Whitcroft	my $coff_set = 0;
16128905a67cSAndy Whitcroft
161313214adfSAndy Whitcroft	my $loff = 0;
161413214adfSAndy Whitcroft
16158905a67cSAndy Whitcroft	my $type = '';
16168905a67cSAndy Whitcroft	my $level = 0;
1617a2750645SAndy Whitcroft	my @stack = ();
1618cf655043SAndy Whitcroft	my $p;
16198905a67cSAndy Whitcroft	my $c;
16208905a67cSAndy Whitcroft	my $len = 0;
162113214adfSAndy Whitcroft
162213214adfSAndy Whitcroft	my $remainder;
16238905a67cSAndy Whitcroft	while (1) {
1624a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1625a2750645SAndy Whitcroft
1626773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
16278905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
16288905a67cSAndy Whitcroft		# context.
16298905a67cSAndy Whitcroft		if ($off >= $len) {
16308905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1631dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1632c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
16338905a67cSAndy Whitcroft				$remain--;
163413214adfSAndy Whitcroft				$loff = $len;
1635c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
16368905a67cSAndy Whitcroft				$len = length($blk);
16378905a67cSAndy Whitcroft				$line++;
16388905a67cSAndy Whitcroft				last;
16398905a67cSAndy Whitcroft			}
16408905a67cSAndy Whitcroft			# Bail if there is no further context.
16418905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
164213214adfSAndy Whitcroft			if ($off >= $len) {
16438905a67cSAndy Whitcroft				last;
16448905a67cSAndy Whitcroft			}
1645f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1646f74bd194SAndy Whitcroft				$level++;
1647f74bd194SAndy Whitcroft				$type = '#';
1648f74bd194SAndy Whitcroft			}
16498905a67cSAndy Whitcroft		}
1650cf655043SAndy Whitcroft		$p = $c;
16518905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
165213214adfSAndy Whitcroft		$remainder = substr($blk, $off);
16538905a67cSAndy Whitcroft
1654773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
16554635f4fbSAndy Whitcroft
16564635f4fbSAndy Whitcroft		# Handle nested #if/#else.
16574635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
16584635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
16594635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
16604635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
16614635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
16624635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
16634635f4fbSAndy Whitcroft		}
16644635f4fbSAndy Whitcroft
16658905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
16668905a67cSAndy Whitcroft		# outermost level.
16678905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
16688905a67cSAndy Whitcroft			last;
16698905a67cSAndy Whitcroft		}
16708905a67cSAndy Whitcroft
167113214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1672773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1673773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1674773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1675773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1676773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1677773647a0SAndy Whitcroft			$coff_set = 1;
1678773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1679773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
168013214adfSAndy Whitcroft		}
168113214adfSAndy Whitcroft
16828905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
16838905a67cSAndy Whitcroft			$level++;
16848905a67cSAndy Whitcroft			$type = '(';
16858905a67cSAndy Whitcroft		}
16868905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
16878905a67cSAndy Whitcroft			$level--;
16888905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
16898905a67cSAndy Whitcroft
16908905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
16918905a67cSAndy Whitcroft				$coff = $off;
1692773647a0SAndy Whitcroft				$coff_set = 1;
1693773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
16948905a67cSAndy Whitcroft			}
16958905a67cSAndy Whitcroft		}
16968905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
16978905a67cSAndy Whitcroft			$level++;
16988905a67cSAndy Whitcroft			$type = '{';
16998905a67cSAndy Whitcroft		}
17008905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
17018905a67cSAndy Whitcroft			$level--;
17028905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
17038905a67cSAndy Whitcroft
17048905a67cSAndy Whitcroft			if ($level == 0) {
1705b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1706b998e001SPatrick Pannuto					$off++;
1707b998e001SPatrick Pannuto				}
17088905a67cSAndy Whitcroft				last;
17098905a67cSAndy Whitcroft			}
17108905a67cSAndy Whitcroft		}
1711f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1712f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1713f74bd194SAndy Whitcroft			$level--;
1714f74bd194SAndy Whitcroft			$type = '';
1715f74bd194SAndy Whitcroft			$off++;
1716f74bd194SAndy Whitcroft			last;
1717f74bd194SAndy Whitcroft		}
17188905a67cSAndy Whitcroft		$off++;
17198905a67cSAndy Whitcroft	}
1720a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
172113214adfSAndy Whitcroft	if ($off == $len) {
1722a3bb97a7SAndy Whitcroft		$loff = $len + 1;
172313214adfSAndy Whitcroft		$line++;
172413214adfSAndy Whitcroft		$remain--;
172513214adfSAndy Whitcroft	}
17268905a67cSAndy Whitcroft
17278905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
17288905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
17298905a67cSAndy Whitcroft
17308905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
17318905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
17328905a67cSAndy Whitcroft
1733773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
173413214adfSAndy Whitcroft
173513214adfSAndy Whitcroft	return ($statement, $condition,
173613214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
173713214adfSAndy Whitcroft}
173813214adfSAndy Whitcroft
1739cf655043SAndy Whitcroftsub statement_lines {
1740cf655043SAndy Whitcroft	my ($stmt) = @_;
1741cf655043SAndy Whitcroft
1742cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1743cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1744cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1745cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1746cf655043SAndy Whitcroft
1747cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1748cf655043SAndy Whitcroft
1749cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1750cf655043SAndy Whitcroft}
1751cf655043SAndy Whitcroft
1752cf655043SAndy Whitcroftsub statement_rawlines {
1753cf655043SAndy Whitcroft	my ($stmt) = @_;
1754cf655043SAndy Whitcroft
1755cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1756cf655043SAndy Whitcroft
1757cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1758cf655043SAndy Whitcroft}
1759cf655043SAndy Whitcroft
1760cf655043SAndy Whitcroftsub statement_block_size {
1761cf655043SAndy Whitcroft	my ($stmt) = @_;
1762cf655043SAndy Whitcroft
1763cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1764cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1765cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1766cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1767cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1768cf655043SAndy Whitcroft
1769cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1770cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1771cf655043SAndy Whitcroft
1772cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1773cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1774cf655043SAndy Whitcroft
1775cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1776cf655043SAndy Whitcroft		return $stmt_lines;
1777cf655043SAndy Whitcroft	} else {
1778cf655043SAndy Whitcroft		return $stmt_statements;
1779cf655043SAndy Whitcroft	}
1780cf655043SAndy Whitcroft}
1781cf655043SAndy Whitcroft
178213214adfSAndy Whitcroftsub ctx_statement_full {
178313214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
178413214adfSAndy Whitcroft	my ($statement, $condition, $level);
178513214adfSAndy Whitcroft
178613214adfSAndy Whitcroft	my (@chunks);
178713214adfSAndy Whitcroft
1788cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
178913214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
179013214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1791773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
179213214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1793cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1794cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1795cf655043SAndy Whitcroft	}
1796cf655043SAndy Whitcroft
1797cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1798cf655043SAndy Whitcroft	# could continue the statement.
1799cf655043SAndy Whitcroft	for (;;) {
180013214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
180113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1802cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1803773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1804cf655043SAndy Whitcroft		#print "C: push\n";
1805cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
180613214adfSAndy Whitcroft	}
180713214adfSAndy Whitcroft
180813214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
18098905a67cSAndy Whitcroft}
18108905a67cSAndy Whitcroft
18114a0df2efSAndy Whitcroftsub ctx_block_get {
1812f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
18134a0df2efSAndy Whitcroft	my $line;
18144a0df2efSAndy Whitcroft	my $start = $linenr - 1;
18154a0df2efSAndy Whitcroft	my $blk = '';
18164a0df2efSAndy Whitcroft	my @o;
18174a0df2efSAndy Whitcroft	my @c;
18184a0df2efSAndy Whitcroft	my @res = ();
18194a0df2efSAndy Whitcroft
1820f0a594c1SAndy Whitcroft	my $level = 0;
18214635f4fbSAndy Whitcroft	my @stack = ($level);
182200df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
182300df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
182400df344fSAndy Whitcroft		$remain--;
182500df344fSAndy Whitcroft
182600df344fSAndy Whitcroft		$blk .= $rawlines[$line];
18274635f4fbSAndy Whitcroft
18284635f4fbSAndy Whitcroft		# Handle nested #if/#else.
182901464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
18304635f4fbSAndy Whitcroft			push(@stack, $level);
183101464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
18324635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
183301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
18344635f4fbSAndy Whitcroft			$level = pop(@stack);
18354635f4fbSAndy Whitcroft		}
18364635f4fbSAndy Whitcroft
183701464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1838f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1839f0a594c1SAndy Whitcroft			if ($off > 0) {
1840f0a594c1SAndy Whitcroft				$off--;
1841f0a594c1SAndy Whitcroft				next;
1842f0a594c1SAndy Whitcroft			}
18434a0df2efSAndy Whitcroft
1844f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1845f0a594c1SAndy Whitcroft				$level--;
1846f0a594c1SAndy Whitcroft				last if ($level == 0);
1847f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1848f0a594c1SAndy Whitcroft				$level++;
1849f0a594c1SAndy Whitcroft			}
1850f0a594c1SAndy Whitcroft		}
18514a0df2efSAndy Whitcroft
1852f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
185300df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
18544a0df2efSAndy Whitcroft		}
18554a0df2efSAndy Whitcroft
1856f0a594c1SAndy Whitcroft		last if ($level == 0);
18574a0df2efSAndy Whitcroft	}
18584a0df2efSAndy Whitcroft
1859f0a594c1SAndy Whitcroft	return ($level, @res);
18604a0df2efSAndy Whitcroft}
18614a0df2efSAndy Whitcroftsub ctx_block_outer {
18624a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
18634a0df2efSAndy Whitcroft
1864f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1865f0a594c1SAndy Whitcroft	return @r;
18664a0df2efSAndy Whitcroft}
18674a0df2efSAndy Whitcroftsub ctx_block {
18684a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
18694a0df2efSAndy Whitcroft
1870f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1871f0a594c1SAndy Whitcroft	return @r;
1872653d4876SAndy Whitcroft}
1873653d4876SAndy Whitcroftsub ctx_statement {
1874f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1875f0a594c1SAndy Whitcroft
1876f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1877f0a594c1SAndy Whitcroft	return @r;
1878f0a594c1SAndy Whitcroft}
1879f0a594c1SAndy Whitcroftsub ctx_block_level {
1880653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1881653d4876SAndy Whitcroft
1882f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
18834a0df2efSAndy Whitcroft}
18849c0ca6f9SAndy Whitcroftsub ctx_statement_level {
18859c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
18869c0ca6f9SAndy Whitcroft
18879c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
18889c0ca6f9SAndy Whitcroft}
18894a0df2efSAndy Whitcroft
18904a0df2efSAndy Whitcroftsub ctx_locate_comment {
18914a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
18924a0df2efSAndy Whitcroft
1893a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1894a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1895a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1896a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1897a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1898a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1899a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1900a55ee0ccSJoe Perches
19014a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1902a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
19034a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
19044a0df2efSAndy Whitcroft
19054a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
19064a0df2efSAndy Whitcroft	# comment.
19074a0df2efSAndy Whitcroft	my $in_comment = 0;
19084a0df2efSAndy Whitcroft	$current_comment = '';
19094a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
191000df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
191100df344fSAndy Whitcroft		#warn "           $line\n";
19124a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
19134a0df2efSAndy Whitcroft			$in_comment = 1;
19144a0df2efSAndy Whitcroft		}
19154a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
19164a0df2efSAndy Whitcroft			$in_comment = 1;
19174a0df2efSAndy Whitcroft		}
19184a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
19194a0df2efSAndy Whitcroft			$current_comment = '';
19204a0df2efSAndy Whitcroft		}
19214a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
19224a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
19234a0df2efSAndy Whitcroft			$in_comment = 0;
19244a0df2efSAndy Whitcroft		}
19254a0df2efSAndy Whitcroft	}
19264a0df2efSAndy Whitcroft
19274a0df2efSAndy Whitcroft	chomp($current_comment);
19284a0df2efSAndy Whitcroft	return($current_comment);
19294a0df2efSAndy Whitcroft}
19304a0df2efSAndy Whitcroftsub ctx_has_comment {
19314a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19324a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
19334a0df2efSAndy Whitcroft
193400df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
19354a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
19364a0df2efSAndy Whitcroft
19374a0df2efSAndy Whitcroft	return ($cmt ne '');
19384a0df2efSAndy Whitcroft}
19394a0df2efSAndy Whitcroft
19404d001e4dSAndy Whitcroftsub raw_line {
19414d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
19424d001e4dSAndy Whitcroft
19434d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
19444d001e4dSAndy Whitcroft	$cnt++;
19454d001e4dSAndy Whitcroft
19464d001e4dSAndy Whitcroft	my $line;
19474d001e4dSAndy Whitcroft	while ($cnt) {
19484d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
19494d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
19504d001e4dSAndy Whitcroft		$cnt--;
19514d001e4dSAndy Whitcroft	}
19524d001e4dSAndy Whitcroft
19534d001e4dSAndy Whitcroft	return $line;
19544d001e4dSAndy Whitcroft}
19554d001e4dSAndy Whitcroft
19562a9f9d85STobin C. Hardingsub get_stat_real {
19572a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
19582a9f9d85STobin C. Harding
19592a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
19602a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
19612a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
19622a9f9d85STobin C. Harding	}
19632a9f9d85STobin C. Harding
19642a9f9d85STobin C. Harding	return $stat_real;
19652a9f9d85STobin C. Harding}
19662a9f9d85STobin C. Harding
1967e3d95a2aSTobin C. Hardingsub get_stat_here {
1968e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1969e3d95a2aSTobin C. Harding
1970e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1971e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1972e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1973e3d95a2aSTobin C. Harding	}
1974e3d95a2aSTobin C. Harding
1975e3d95a2aSTobin C. Harding	return $herectx;
1976e3d95a2aSTobin C. Harding}
1977e3d95a2aSTobin C. Harding
19780a920b5bSAndy Whitcroftsub cat_vet {
19790a920b5bSAndy Whitcroft	my ($vet) = @_;
19809c0ca6f9SAndy Whitcroft	my ($res, $coded);
19810a920b5bSAndy Whitcroft
19829c0ca6f9SAndy Whitcroft	$res = '';
19836c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
19846c72ffaaSAndy Whitcroft		$res .= $1;
19856c72ffaaSAndy Whitcroft		if ($2 ne '') {
19869c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
19876c72ffaaSAndy Whitcroft			$res .= $coded;
19886c72ffaaSAndy Whitcroft		}
19899c0ca6f9SAndy Whitcroft	}
19909c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
19910a920b5bSAndy Whitcroft
19929c0ca6f9SAndy Whitcroft	return $res;
19930a920b5bSAndy Whitcroft}
19940a920b5bSAndy Whitcroft
1995c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1996cf655043SAndy Whitcroftmy $av_pending;
1997c2fdda0dSAndy Whitcroftmy @av_paren_type;
19981f65f947SAndy Whitcroftmy $av_pend_colon;
1999c2fdda0dSAndy Whitcroft
2000c2fdda0dSAndy Whitcroftsub annotate_reset {
2001c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
2002cf655043SAndy Whitcroft	$av_pending = '_';
2003cf655043SAndy Whitcroft	@av_paren_type = ('E');
20041f65f947SAndy Whitcroft	$av_pend_colon = 'O';
2005c2fdda0dSAndy Whitcroft}
2006c2fdda0dSAndy Whitcroft
20076c72ffaaSAndy Whitcroftsub annotate_values {
20086c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
20096c72ffaaSAndy Whitcroft
20106c72ffaaSAndy Whitcroft	my $res;
20111f65f947SAndy Whitcroft	my $var = '_' x length($stream);
20126c72ffaaSAndy Whitcroft	my $cur = $stream;
20136c72ffaaSAndy Whitcroft
2014c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
20156c72ffaaSAndy Whitcroft
20166c72ffaaSAndy Whitcroft	while (length($cur)) {
2017773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
2018cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
2019171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
20206c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
2021c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
2022c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
2023cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
2024c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
20256c72ffaaSAndy Whitcroft			}
20266c72ffaaSAndy Whitcroft
2027c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
20289446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
20299446ef56SAndy Whitcroft			push(@av_paren_type, $type);
2030addcdceaSAndy Whitcroft			$type = 'c';
20319446ef56SAndy Whitcroft
2032e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2033c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
20346c72ffaaSAndy Whitcroft			$type = 'T';
20356c72ffaaSAndy Whitcroft
2036389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
2037389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
2038389a2fe5SAndy Whitcroft			$type = 'T';
2039389a2fe5SAndy Whitcroft
2040c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2041171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2042c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2043171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
2044171ae1a4SAndy Whitcroft			if ($2 ne '') {
2045cf655043SAndy Whitcroft				$av_pending = 'N';
2046171ae1a4SAndy Whitcroft			}
2047171ae1a4SAndy Whitcroft			$type = 'E';
2048171ae1a4SAndy Whitcroft
2049c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2050171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
2051171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
2052171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
20536c72ffaaSAndy Whitcroft
2054c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2055cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
2056c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2057cf655043SAndy Whitcroft
2058cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2059cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2060171ae1a4SAndy Whitcroft			$type = 'E';
2061cf655043SAndy Whitcroft
2062c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2063cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2064cf655043SAndy Whitcroft			$av_preprocessor = 1;
2065cf655043SAndy Whitcroft
2066cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2067cf655043SAndy Whitcroft
2068171ae1a4SAndy Whitcroft			$type = 'E';
2069cf655043SAndy Whitcroft
2070c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2071cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
2072cf655043SAndy Whitcroft
2073cf655043SAndy Whitcroft			$av_preprocessor = 1;
2074cf655043SAndy Whitcroft
2075cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
2076cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
2077cf655043SAndy Whitcroft			pop(@av_paren_type);
2078cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2079171ae1a4SAndy Whitcroft			$type = 'E';
20806c72ffaaSAndy Whitcroft
20816c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
2082c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
20836c72ffaaSAndy Whitcroft
2084171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2085171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2086171ae1a4SAndy Whitcroft			$av_pending = $type;
2087171ae1a4SAndy Whitcroft			$type = 'N';
2088171ae1a4SAndy Whitcroft
20896c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2090c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
20916c72ffaaSAndy Whitcroft			if (defined $2) {
2092cf655043SAndy Whitcroft				$av_pending = 'V';
20936c72ffaaSAndy Whitcroft			}
20946c72ffaaSAndy Whitcroft			$type = 'N';
20956c72ffaaSAndy Whitcroft
209614b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2097c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
209814b111c1SAndy Whitcroft			$av_pending = 'E';
20996c72ffaaSAndy Whitcroft			$type = 'N';
21006c72ffaaSAndy Whitcroft
21011f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
21021f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
21031f65f947SAndy Whitcroft			$av_pend_colon = 'C';
21041f65f947SAndy Whitcroft			$type = 'N';
21051f65f947SAndy Whitcroft
210614b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2107c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
21086c72ffaaSAndy Whitcroft			$type = 'N';
21096c72ffaaSAndy Whitcroft
21106c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2111c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2112cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2113cf655043SAndy Whitcroft			$av_pending = '_';
21146c72ffaaSAndy Whitcroft			$type = 'N';
21156c72ffaaSAndy Whitcroft
21166c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2117cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2118cf655043SAndy Whitcroft			if ($new_type ne '_') {
2119cf655043SAndy Whitcroft				$type = $new_type;
2120c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2121c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
21226c72ffaaSAndy Whitcroft			} else {
2123c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
21246c72ffaaSAndy Whitcroft			}
21256c72ffaaSAndy Whitcroft
2126c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2127c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2128c8cb2ca3SAndy Whitcroft			$type = 'V';
2129cf655043SAndy Whitcroft			$av_pending = 'V';
21306c72ffaaSAndy Whitcroft
21318e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
21328e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
21331f65f947SAndy Whitcroft				$av_pend_colon = 'B';
21348e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
21358e761b04SAndy Whitcroft				$av_pend_colon = 'L';
21361f65f947SAndy Whitcroft			}
21371f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
21381f65f947SAndy Whitcroft			$type = 'V';
21391f65f947SAndy Whitcroft
21406c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2141c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
21426c72ffaaSAndy Whitcroft			$type = 'V';
21436c72ffaaSAndy Whitcroft
21446c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2145c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
21466c72ffaaSAndy Whitcroft			$type = 'N';
21476c72ffaaSAndy Whitcroft
2148cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2149c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
215013214adfSAndy Whitcroft			$type = 'E';
21511f65f947SAndy Whitcroft			$av_pend_colon = 'O';
215213214adfSAndy Whitcroft
21538e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
21548e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
21558e761b04SAndy Whitcroft			$type = 'C';
21568e761b04SAndy Whitcroft
21571f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
21581f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
21591f65f947SAndy Whitcroft			$type = 'N';
21601f65f947SAndy Whitcroft
21611f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
21621f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
21631f65f947SAndy Whitcroft
21641f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
21651f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
21661f65f947SAndy Whitcroft				$type = 'E';
21671f65f947SAndy Whitcroft			} else {
21681f65f947SAndy Whitcroft				$type = 'N';
21691f65f947SAndy Whitcroft			}
21701f65f947SAndy Whitcroft			$av_pend_colon = 'O';
21711f65f947SAndy Whitcroft
21728e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
217313214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
21746c72ffaaSAndy Whitcroft			$type = 'N';
21756c72ffaaSAndy Whitcroft
21760d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
217774048ed8SAndy Whitcroft			my $variant;
217874048ed8SAndy Whitcroft
217974048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
218074048ed8SAndy Whitcroft			if ($type eq 'V') {
218174048ed8SAndy Whitcroft				$variant = 'B';
218274048ed8SAndy Whitcroft			} else {
218374048ed8SAndy Whitcroft				$variant = 'U';
218474048ed8SAndy Whitcroft			}
218574048ed8SAndy Whitcroft
218674048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
218774048ed8SAndy Whitcroft			$type = 'N';
218874048ed8SAndy Whitcroft
21896c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2190c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
21916c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
21926c72ffaaSAndy Whitcroft				$type = 'N';
21936c72ffaaSAndy Whitcroft			}
21946c72ffaaSAndy Whitcroft
21956c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2196c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
21976c72ffaaSAndy Whitcroft		}
21986c72ffaaSAndy Whitcroft		if (defined $1) {
21996c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
22006c72ffaaSAndy Whitcroft			$res .= $type x length($1);
22016c72ffaaSAndy Whitcroft		}
22026c72ffaaSAndy Whitcroft	}
22036c72ffaaSAndy Whitcroft
22041f65f947SAndy Whitcroft	return ($res, $var);
22056c72ffaaSAndy Whitcroft}
22066c72ffaaSAndy Whitcroft
22078905a67cSAndy Whitcroftsub possible {
220813214adfSAndy Whitcroft	my ($possible, $line) = @_;
22099a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
22100776e594SAndy Whitcroft		^(?:
22110776e594SAndy Whitcroft			$Modifier|
22120776e594SAndy Whitcroft			$Storage|
22130776e594SAndy Whitcroft			$Type|
22149a974fdbSAndy Whitcroft			DEFINE_\S+
22159a974fdbSAndy Whitcroft		)$|
22169a974fdbSAndy Whitcroft		^(?:
22170776e594SAndy Whitcroft			goto|
22180776e594SAndy Whitcroft			return|
22190776e594SAndy Whitcroft			case|
22200776e594SAndy Whitcroft			else|
22210776e594SAndy Whitcroft			asm|__asm__|
222289a88353SAndy Whitcroft			do|
222389a88353SAndy Whitcroft			\#|
222489a88353SAndy Whitcroft			\#\#|
22259a974fdbSAndy Whitcroft		)(?:\s|$)|
22260776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
22279a974fdbSAndy Whitcroft	    )}x;
22289a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
22299a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2230c45dcabdSAndy Whitcroft		# Check for modifiers.
2231c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2232c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2233c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2234c45dcabdSAndy Whitcroft
2235c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2236c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2237d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
22389a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2239d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2240485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2241d2506586SAndy Whitcroft				}
22429a974fdbSAndy Whitcroft			}
2243c45dcabdSAndy Whitcroft
2244c45dcabdSAndy Whitcroft		} else {
224513214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2246485ff23eSAlex Dowad			push(@typeListFile, $possible);
2247c45dcabdSAndy Whitcroft		}
22488905a67cSAndy Whitcroft		build_types();
22490776e594SAndy Whitcroft	} else {
22500776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
22518905a67cSAndy Whitcroft	}
22528905a67cSAndy Whitcroft}
22538905a67cSAndy Whitcroft
22546c72ffaaSAndy Whitcroftmy $prefix = '';
22556c72ffaaSAndy Whitcroft
2256000d1cc1SJoe Perchessub show_type {
2257cbec18afSJoe Perches	my ($type) = @_;
225891bfe484SJoe Perches
2259522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2260522b837cSAlexey Dobriyan
2261cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2262cbec18afSJoe Perches
2263cbec18afSJoe Perches	return !defined $ignore_type{$type};
2264000d1cc1SJoe Perches}
2265000d1cc1SJoe Perches
2266f0a594c1SAndy Whitcroftsub report {
2267cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2268cbec18afSJoe Perches
2269cbec18afSJoe Perches	if (!show_type($type) ||
2270cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2271773647a0SAndy Whitcroft		return 0;
2272773647a0SAndy Whitcroft	}
227357230297SJoe Perches	my $output = '';
2274737c0767SJohn Brooks	if ($color) {
227557230297SJoe Perches		if ($level eq 'ERROR') {
227657230297SJoe Perches			$output .= RED;
227757230297SJoe Perches		} elsif ($level eq 'WARNING') {
227857230297SJoe Perches			$output .= YELLOW;
2279000d1cc1SJoe Perches		} else {
228057230297SJoe Perches			$output .= GREEN;
2281000d1cc1SJoe Perches		}
228257230297SJoe Perches	}
228357230297SJoe Perches	$output .= $prefix . $level . ':';
228457230297SJoe Perches	if ($show_types) {
2285737c0767SJohn Brooks		$output .= BLUE if ($color);
228657230297SJoe Perches		$output .= "$type:";
228757230297SJoe Perches	}
2288737c0767SJohn Brooks	$output .= RESET if ($color);
228957230297SJoe Perches	$output .= ' ' . $msg . "\n";
229034d8815fSJoe Perches
229134d8815fSJoe Perches	if ($showfile) {
229234d8815fSJoe Perches		my @lines = split("\n", $output, -1);
229334d8815fSJoe Perches		splice(@lines, 1, 1);
229434d8815fSJoe Perches		$output = join("\n", @lines);
229534d8815fSJoe Perches	}
229652178ce0SDwaipayan Ray
229752178ce0SDwaipayan Ray	if ($terse) {
229852178ce0SDwaipayan Ray		$output = (split('\n', $output))[0] . "\n";
229952178ce0SDwaipayan Ray	}
230052178ce0SDwaipayan Ray
230152178ce0SDwaipayan Ray	if ($verbose && exists($verbose_messages{$type}) &&
230252178ce0SDwaipayan Ray	    !exists($verbose_emitted{$type})) {
230352178ce0SDwaipayan Ray		$output .= $verbose_messages{$type} . "\n\n";
230452178ce0SDwaipayan Ray		$verbose_emitted{$type} = 1;
230552178ce0SDwaipayan Ray	}
23068905a67cSAndy Whitcroft
230757230297SJoe Perches	push(our @report, $output);
2308773647a0SAndy Whitcroft
2309773647a0SAndy Whitcroft	return 1;
2310f0a594c1SAndy Whitcroft}
2311cbec18afSJoe Perches
2312f0a594c1SAndy Whitcroftsub report_dump {
231313214adfSAndy Whitcroft	our @report;
2314f0a594c1SAndy Whitcroft}
2315000d1cc1SJoe Perches
2316d752fcc8SJoe Perchessub fixup_current_range {
2317d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2318d752fcc8SJoe Perches
2319d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2320d752fcc8SJoe Perches		my $o = $1;
2321d752fcc8SJoe Perches		my $l = $2;
2322d752fcc8SJoe Perches		my $no = $o + $offset;
2323d752fcc8SJoe Perches		my $nl = $l + $length;
2324d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2325d752fcc8SJoe Perches	}
2326d752fcc8SJoe Perches}
2327d752fcc8SJoe Perches
2328d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2329d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2330d752fcc8SJoe Perches
2331d752fcc8SJoe Perches	my $range_last_linenr = 0;
2332d752fcc8SJoe Perches	my $delta_offset = 0;
2333d752fcc8SJoe Perches
2334d752fcc8SJoe Perches	my $old_linenr = 0;
2335d752fcc8SJoe Perches	my $new_linenr = 0;
2336d752fcc8SJoe Perches
2337d752fcc8SJoe Perches	my $next_insert = 0;
2338d752fcc8SJoe Perches	my $next_delete = 0;
2339d752fcc8SJoe Perches
2340d752fcc8SJoe Perches	my @lines = ();
2341d752fcc8SJoe Perches
2342d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2343d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2344d752fcc8SJoe Perches
2345d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2346d752fcc8SJoe Perches		my $save_line = 1;
2347d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2348323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2349d752fcc8SJoe Perches			$delta_offset = 0;
2350d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2351d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2352d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2353d752fcc8SJoe Perches		}
2354d752fcc8SJoe Perches
2355d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2356d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2357d752fcc8SJoe Perches			$save_line = 0;
2358d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2359d752fcc8SJoe Perches		}
2360d752fcc8SJoe Perches
2361d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2362d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2363d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2364d752fcc8SJoe Perches			$new_linenr++;
2365d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2366d752fcc8SJoe Perches		}
2367d752fcc8SJoe Perches
2368d752fcc8SJoe Perches		if ($save_line) {
2369d752fcc8SJoe Perches			push(@lines, $line);
2370d752fcc8SJoe Perches			$new_linenr++;
2371d752fcc8SJoe Perches		}
2372d752fcc8SJoe Perches
2373d752fcc8SJoe Perches		$old_linenr++;
2374d752fcc8SJoe Perches	}
2375d752fcc8SJoe Perches
2376d752fcc8SJoe Perches	return @lines;
2377d752fcc8SJoe Perches}
2378d752fcc8SJoe Perches
2379f2d7e4d4SJoe Perchessub fix_insert_line {
2380f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2381f2d7e4d4SJoe Perches
2382f2d7e4d4SJoe Perches	my $inserted = {
2383f2d7e4d4SJoe Perches		LINENR => $linenr,
2384f2d7e4d4SJoe Perches		LINE => $line,
2385f2d7e4d4SJoe Perches	};
2386f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2387f2d7e4d4SJoe Perches}
2388f2d7e4d4SJoe Perches
2389f2d7e4d4SJoe Perchessub fix_delete_line {
2390f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2391f2d7e4d4SJoe Perches
2392f2d7e4d4SJoe Perches	my $deleted = {
2393f2d7e4d4SJoe Perches		LINENR => $linenr,
2394f2d7e4d4SJoe Perches		LINE => $line,
2395f2d7e4d4SJoe Perches	};
2396f2d7e4d4SJoe Perches
2397f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2398f2d7e4d4SJoe Perches}
2399f2d7e4d4SJoe Perches
2400de7d4f0eSAndy Whitcroftsub ERROR {
2401cbec18afSJoe Perches	my ($type, $msg) = @_;
2402cbec18afSJoe Perches
2403cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2404de7d4f0eSAndy Whitcroft		our $clean = 0;
24056c72ffaaSAndy Whitcroft		our $cnt_error++;
24063705ce5bSJoe Perches		return 1;
2407de7d4f0eSAndy Whitcroft	}
24083705ce5bSJoe Perches	return 0;
2409773647a0SAndy Whitcroft}
2410de7d4f0eSAndy Whitcroftsub WARN {
2411cbec18afSJoe Perches	my ($type, $msg) = @_;
2412cbec18afSJoe Perches
2413cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2414de7d4f0eSAndy Whitcroft		our $clean = 0;
24156c72ffaaSAndy Whitcroft		our $cnt_warn++;
24163705ce5bSJoe Perches		return 1;
2417de7d4f0eSAndy Whitcroft	}
24183705ce5bSJoe Perches	return 0;
2419773647a0SAndy Whitcroft}
2420de7d4f0eSAndy Whitcroftsub CHK {
2421cbec18afSJoe Perches	my ($type, $msg) = @_;
2422cbec18afSJoe Perches
2423cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2424de7d4f0eSAndy Whitcroft		our $clean = 0;
24256c72ffaaSAndy Whitcroft		our $cnt_chk++;
24263705ce5bSJoe Perches		return 1;
24276c72ffaaSAndy Whitcroft	}
24283705ce5bSJoe Perches	return 0;
2429de7d4f0eSAndy Whitcroft}
2430de7d4f0eSAndy Whitcroft
24316ecd9674SAndy Whitcroftsub check_absolute_file {
24326ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
24336ecd9674SAndy Whitcroft	my $file = $absolute;
24346ecd9674SAndy Whitcroft
24356ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
24366ecd9674SAndy Whitcroft
24376ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
24386ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
24396ecd9674SAndy Whitcroft		if (-f "$root/$file") {
24406ecd9674SAndy Whitcroft			##print "file<$file>\n";
24416ecd9674SAndy Whitcroft			last;
24426ecd9674SAndy Whitcroft		}
24436ecd9674SAndy Whitcroft	}
24446ecd9674SAndy Whitcroft	if (! -f _)  {
24456ecd9674SAndy Whitcroft		return 0;
24466ecd9674SAndy Whitcroft	}
24476ecd9674SAndy Whitcroft
24486ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
24496ecd9674SAndy Whitcroft	my $prefix = $absolute;
24506ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
24516ecd9674SAndy Whitcroft
24526ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
24536ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2454000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2455000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
24566ecd9674SAndy Whitcroft	}
24576ecd9674SAndy Whitcroft}
24586ecd9674SAndy Whitcroft
24593705ce5bSJoe Perchessub trim {
24603705ce5bSJoe Perches	my ($string) = @_;
24613705ce5bSJoe Perches
2462b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2463b34c648bSJoe Perches
2464b34c648bSJoe Perches	return $string;
2465b34c648bSJoe Perches}
2466b34c648bSJoe Perches
2467b34c648bSJoe Perchessub ltrim {
2468b34c648bSJoe Perches	my ($string) = @_;
2469b34c648bSJoe Perches
2470b34c648bSJoe Perches	$string =~ s/^\s+//;
2471b34c648bSJoe Perches
2472b34c648bSJoe Perches	return $string;
2473b34c648bSJoe Perches}
2474b34c648bSJoe Perches
2475b34c648bSJoe Perchessub rtrim {
2476b34c648bSJoe Perches	my ($string) = @_;
2477b34c648bSJoe Perches
2478b34c648bSJoe Perches	$string =~ s/\s+$//;
24793705ce5bSJoe Perches
24803705ce5bSJoe Perches	return $string;
24813705ce5bSJoe Perches}
24823705ce5bSJoe Perches
248352ea8506SJoe Perchessub string_find_replace {
248452ea8506SJoe Perches	my ($string, $find, $replace) = @_;
248552ea8506SJoe Perches
248652ea8506SJoe Perches	$string =~ s/$find/$replace/g;
248752ea8506SJoe Perches
248852ea8506SJoe Perches	return $string;
248952ea8506SJoe Perches}
249052ea8506SJoe Perches
24913705ce5bSJoe Perchessub tabify {
24923705ce5bSJoe Perches	my ($leading) = @_;
24933705ce5bSJoe Perches
2494713a09deSAntonio Borneo	my $source_indent = $tabsize;
24953705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
24963705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
24973705ce5bSJoe Perches
24983705ce5bSJoe Perches	#convert leading spaces to tabs
24993705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
25003705ce5bSJoe Perches	#Remove spaces before a tab
25013705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
25023705ce5bSJoe Perches
25033705ce5bSJoe Perches	return "$leading";
25043705ce5bSJoe Perches}
25053705ce5bSJoe Perches
2506d1fe9c09SJoe Perchessub pos_last_openparen {
2507d1fe9c09SJoe Perches	my ($line) = @_;
2508d1fe9c09SJoe Perches
2509d1fe9c09SJoe Perches	my $pos = 0;
2510d1fe9c09SJoe Perches
2511d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2512d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2513d1fe9c09SJoe Perches
2514d1fe9c09SJoe Perches	my $last_openparen = 0;
2515d1fe9c09SJoe Perches
2516d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2517d1fe9c09SJoe Perches		return -1;
2518d1fe9c09SJoe Perches	}
2519d1fe9c09SJoe Perches
2520d1fe9c09SJoe Perches	my $len = length($line);
2521d1fe9c09SJoe Perches
2522d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2523d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2524d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2525d1fe9c09SJoe Perches			$pos += length($1) - 1;
2526d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2527d1fe9c09SJoe Perches			$last_openparen = $pos;
2528d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2529d1fe9c09SJoe Perches			last;
2530d1fe9c09SJoe Perches		}
2531d1fe9c09SJoe Perches	}
2532d1fe9c09SJoe Perches
253391cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2534d1fe9c09SJoe Perches}
2535d1fe9c09SJoe Perches
2536f36d3eb8SJoe Perchessub get_raw_comment {
2537f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2538f36d3eb8SJoe Perches	my $comment = '';
2539f36d3eb8SJoe Perches
2540f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2541f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2542f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2543f36d3eb8SJoe Perches		}
2544f36d3eb8SJoe Perches	}
2545f36d3eb8SJoe Perches
2546f36d3eb8SJoe Perches	return $comment;
2547f36d3eb8SJoe Perches}
2548f36d3eb8SJoe Perches
25495b8f82e1SSong Liusub exclude_global_initialisers {
25505b8f82e1SSong Liu	my ($realfile) = @_;
25515b8f82e1SSong Liu
25525b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
25535b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
25545b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
25555b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
25565b8f82e1SSong Liu}
25575b8f82e1SSong Liu
25580a920b5bSAndy Whitcroftsub process {
25590a920b5bSAndy Whitcroft	my $filename = shift;
25600a920b5bSAndy Whitcroft
25610a920b5bSAndy Whitcroft	my $linenr=0;
25620a920b5bSAndy Whitcroft	my $prevline="";
2563c2fdda0dSAndy Whitcroft	my $prevrawline="";
25640a920b5bSAndy Whitcroft	my $stashline="";
2565c2fdda0dSAndy Whitcroft	my $stashrawline="";
25660a920b5bSAndy Whitcroft
25674a0df2efSAndy Whitcroft	my $length;
25680a920b5bSAndy Whitcroft	my $indent;
25690a920b5bSAndy Whitcroft	my $previndent=0;
25700a920b5bSAndy Whitcroft	my $stashindent=0;
25710a920b5bSAndy Whitcroft
2572de7d4f0eSAndy Whitcroft	our $clean = 1;
25730a920b5bSAndy Whitcroft	my $signoff = 0;
2574cd261496SGeert Uytterhoeven	my $author = '';
2575cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
257648ca2d8aSDwaipayan Ray	my $author_sob = '';
25770a920b5bSAndy Whitcroft	my $is_patch = 0;
2578133712a2SRob Herring	my $is_binding_patch = -1;
257929ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
258015662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
258144d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2582ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2583490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2584bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
25852a076f40SJoe Perches	my $commit_log_long_line = 0;
2586e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
258713f1937eSJoe Perches	my $reported_maintainer_file = 0;
2588fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2589fa64205dSPasi Savanainen
2590365dd4eaSJoe Perches	my $last_blank_line = 0;
25915e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2592365dd4eaSJoe Perches
259313214adfSAndy Whitcroft	our @report = ();
25946c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
25956c72ffaaSAndy Whitcroft	our $cnt_error = 0;
25966c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
25976c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
25986c72ffaaSAndy Whitcroft
25990a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
26000a920b5bSAndy Whitcroft	my $realfile = '';
26010a920b5bSAndy Whitcroft	my $realline = 0;
26020a920b5bSAndy Whitcroft	my $realcnt = 0;
26030a920b5bSAndy Whitcroft	my $here = '';
260477cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
26050a920b5bSAndy Whitcroft	my $in_comment = 0;
2606c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
26070a920b5bSAndy Whitcroft	my $first_line = 0;
26081e855726SWolfram Sang	my $p1_prefix = '';
26090a920b5bSAndy Whitcroft
261013214adfSAndy Whitcroft	my $prev_values = 'E';
261113214adfSAndy Whitcroft
261213214adfSAndy Whitcroft	# suppression flags
2613773647a0SAndy Whitcroft	my %suppress_ifbraces;
2614170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
26152b474a1aSAndy Whitcroft	my %suppress_export;
26163e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2617653d4876SAndy Whitcroft
26187e51f197SJoe Perches	my %signatures = ();
2619323c1260SJoe Perches
2620c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2621de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2622c2fdda0dSAndy Whitcroft	#
2623de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2624de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2625773647a0SAndy Whitcroft
2626d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2627d8b07710SJoe Perches
26289f3a8992SRob Herring	my $checklicenseline = 1;
26299f3a8992SRob Herring
2630773647a0SAndy Whitcroft	sanitise_line_reset();
2631c2fdda0dSAndy Whitcroft	my $line;
2632c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2633773647a0SAndy Whitcroft		$linenr++;
2634773647a0SAndy Whitcroft		$line = $rawline;
2635c2fdda0dSAndy Whitcroft
26363705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
26373705ce5bSJoe Perches
2638773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2639de7d4f0eSAndy Whitcroft			$setup_docs = 0;
26402581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2641de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2642de7d4f0eSAndy Whitcroft			}
2643773647a0SAndy Whitcroft			#next;
2644de7d4f0eSAndy Whitcroft		}
264574fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2646773647a0SAndy Whitcroft			$realline=$1-1;
2647773647a0SAndy Whitcroft			if (defined $2) {
2648773647a0SAndy Whitcroft				$realcnt=$3+1;
2649773647a0SAndy Whitcroft			} else {
2650773647a0SAndy Whitcroft				$realcnt=1+1;
2651773647a0SAndy Whitcroft			}
2652c45dcabdSAndy Whitcroft			$in_comment = 0;
2653773647a0SAndy Whitcroft
2654773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2655773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2656773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2657773647a0SAndy Whitcroft			# at context start.
2658773647a0SAndy Whitcroft			my $edge;
265901fa9147SAndy Whitcroft			my $cnt = $realcnt;
266001fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
266101fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
266201fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
266301fa9147SAndy Whitcroft				$cnt--;
266401fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2665721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2666fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2667fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2668fae17daeSAndy Whitcroft					($edge) = $1;
2669fae17daeSAndy Whitcroft					last;
2670fae17daeSAndy Whitcroft				}
2671773647a0SAndy Whitcroft			}
2672773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2673773647a0SAndy Whitcroft				$in_comment = 1;
2674773647a0SAndy Whitcroft			}
2675773647a0SAndy Whitcroft
2676773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2677773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2678773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2679773647a0SAndy Whitcroft			if (!defined $edge &&
268083242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2681773647a0SAndy Whitcroft			{
2682773647a0SAndy Whitcroft				$in_comment = 1;
2683773647a0SAndy Whitcroft			}
2684773647a0SAndy Whitcroft
2685773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2686773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2687773647a0SAndy Whitcroft
2688171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2689773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2690171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2691773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2692773647a0SAndy Whitcroft		}
2693773647a0SAndy Whitcroft		push(@lines, $line);
2694773647a0SAndy Whitcroft
2695773647a0SAndy Whitcroft		if ($realcnt > 1) {
2696773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2697773647a0SAndy Whitcroft		} else {
2698773647a0SAndy Whitcroft			$realcnt = 0;
2699773647a0SAndy Whitcroft		}
2700773647a0SAndy Whitcroft
2701773647a0SAndy Whitcroft		#print "==>$rawline\n";
2702773647a0SAndy Whitcroft		#print "-->$line\n";
2703de7d4f0eSAndy Whitcroft
2704de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2705de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2706de7d4f0eSAndy Whitcroft		}
2707de7d4f0eSAndy Whitcroft	}
2708de7d4f0eSAndy Whitcroft
27096c72ffaaSAndy Whitcroft	$prefix = '';
27106c72ffaaSAndy Whitcroft
2711773647a0SAndy Whitcroft	$realcnt = 0;
2712773647a0SAndy Whitcroft	$linenr = 0;
2713194f66fcSJoe Perches	$fixlinenr = -1;
27140a920b5bSAndy Whitcroft	foreach my $line (@lines) {
27150a920b5bSAndy Whitcroft		$linenr++;
2716194f66fcSJoe Perches		$fixlinenr++;
27171b5539b1SJoe Perches		my $sline = $line;	#copy of $line
27181b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
27190a920b5bSAndy Whitcroft
2720c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2721f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
27226c72ffaaSAndy Whitcroft
272312c253abSJoe Perches# check if it's a mode change, rename or start of a patch
272412c253abSJoe Perches		if (!$in_commit_log &&
272512c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
272612c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
272712c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
272812c253abSJoe Perches			$is_patch = 1;
272912c253abSJoe Perches		}
273012c253abSJoe Perches
27310a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2732e518e9a5SJoe Perches		if (!$in_commit_log &&
273374fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
273474fd4f34SJoe Perches			my $context = $4;
27350a920b5bSAndy Whitcroft			$is_patch = 1;
27364a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
27370a920b5bSAndy Whitcroft			$realline=$1-1;
27380a920b5bSAndy Whitcroft			if (defined $2) {
27390a920b5bSAndy Whitcroft				$realcnt=$3+1;
27400a920b5bSAndy Whitcroft			} else {
27410a920b5bSAndy Whitcroft				$realcnt=1+1;
27420a920b5bSAndy Whitcroft			}
2743c2fdda0dSAndy Whitcroft			annotate_reset();
274413214adfSAndy Whitcroft			$prev_values = 'E';
274513214adfSAndy Whitcroft
2746773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2747170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
27482b474a1aSAndy Whitcroft			%suppress_export = ();
27493e469cdcSAndy Whitcroft			$suppress_statement = 0;
275074fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
275174fd4f34SJoe Perches				$context_function = $1;
275274fd4f34SJoe Perches			} else {
275374fd4f34SJoe Perches				undef $context_function;
275474fd4f34SJoe Perches			}
27550a920b5bSAndy Whitcroft			next;
27560a920b5bSAndy Whitcroft
27574a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
27584a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
27594a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2760773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
27610a920b5bSAndy Whitcroft			$realline++;
2762d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
27630a920b5bSAndy Whitcroft
27644a0df2efSAndy Whitcroft			# Measure the line length and indent.
2765c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
27660a920b5bSAndy Whitcroft
27670a920b5bSAndy Whitcroft			# Track the previous line.
27680a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
27690a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2770c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2771c2fdda0dSAndy Whitcroft
2772773647a0SAndy Whitcroft			#warn "line<$line>\n";
27736c72ffaaSAndy Whitcroft
2774d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2775d8aaf121SAndy Whitcroft			$realcnt--;
27760a920b5bSAndy Whitcroft		}
27770a920b5bSAndy Whitcroft
2778cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2779cc77cdcaSAndy Whitcroft
27806c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
27816c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2782773647a0SAndy Whitcroft
27832ac73b4fSJoe Perches		my $found_file = 0;
2784773647a0SAndy Whitcroft		# extract the filename as it passes
27853bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
27863bf9a009SRabin Vincent			$realfile = $1;
27872b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2788270c49a0SJoe Perches			$in_commit_log = 0;
27892ac73b4fSJoe Perches			$found_file = 1;
27903bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2791773647a0SAndy Whitcroft			$realfile = $1;
27922b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2793270c49a0SJoe Perches			$in_commit_log = 0;
27941e855726SWolfram Sang
27951e855726SWolfram Sang			$p1_prefix = $1;
2796e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2797e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2798000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2799000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
28001e855726SWolfram Sang			}
2801773647a0SAndy Whitcroft
2802c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2803000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2804000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2805773647a0SAndy Whitcroft			}
28062ac73b4fSJoe Perches			$found_file = 1;
28072ac73b4fSJoe Perches		}
28082ac73b4fSJoe Perches
280934d8815fSJoe Perches#make up the handle for any error we report on this line
281034d8815fSJoe Perches		if ($showfile) {
281134d8815fSJoe Perches			$prefix = "$realfile:$realline: "
281234d8815fSJoe Perches		} elsif ($emacs) {
28137d3a9f67SJoe Perches			if ($file) {
28147d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
28157d3a9f67SJoe Perches			} else {
281634d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
281734d8815fSJoe Perches			}
28187d3a9f67SJoe Perches		}
281934d8815fSJoe Perches
28202ac73b4fSJoe Perches		if ($found_file) {
282185b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
282285b0ee18SJoe Perches				WARN("OBSOLETE",
282385b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
282485b0ee18SJoe Perches			}
28257bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
28262ac73b4fSJoe Perches				$check = 1;
28272ac73b4fSJoe Perches			} else {
28282ac73b4fSJoe Perches				$check = $check_orig;
28292ac73b4fSJoe Perches			}
28309f3a8992SRob Herring			$checklicenseline = 1;
2831133712a2SRob Herring
2832133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2833133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2834133712a2SRob Herring
2835133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2836133712a2SRob Herring
2837133712a2SRob Herring				if (($last_binding_patch != -1) &&
2838133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2839133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2840858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2841133712a2SRob Herring				}
2842133712a2SRob Herring			}
2843133712a2SRob Herring
2844773647a0SAndy Whitcroft			next;
2845773647a0SAndy Whitcroft		}
2846773647a0SAndy Whitcroft
2847389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
28480a920b5bSAndy Whitcroft
2849c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2850c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2851c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
28520a920b5bSAndy Whitcroft
28536c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
28546c72ffaaSAndy Whitcroft
2855490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2856490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2857490b292cSJoe Perches		if ($in_commit_log) {
2858490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2859490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2860490b292cSJoe Perches			}
2861490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2862490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2863490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2864490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2865490b292cSJoe Perches		}
2866490b292cSJoe Perches
2867e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2868e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
286913e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
287013e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2871e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2872e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2873e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2874e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2875e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2876e518e9a5SJoe Perches		}
2877e518e9a5SJoe Perches
28783bf9a009SRabin Vincent# Check for incorrect file permissions
28793bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
28803bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
288104db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
288204db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2883000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2884000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
28853bf9a009SRabin Vincent			}
28863bf9a009SRabin Vincent		}
28873bf9a009SRabin Vincent
2888cd261496SGeert Uytterhoeven# Check the patch for a From:
2889cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2890cd261496SGeert Uytterhoeven			$author = $1;
2891e7f929f3SDwaipayan Ray			my $curline = $linenr;
2892e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2893e7f929f3SDwaipayan Ray				$author .= $1;
2894e7f929f3SDwaipayan Ray			}
2895cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2896cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2897dfa05c28SJoe Perches			$author = reformat_email($author);
2898cd261496SGeert Uytterhoeven		}
2899cd261496SGeert Uytterhoeven
290020112475SJoe Perches# Check the patch for a signoff:
2901dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
29024a0df2efSAndy Whitcroft			$signoff++;
290315662b3eSJoe Perches			$in_commit_log = 0;
290448ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2905fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2906cd261496SGeert Uytterhoeven					$authorsignoff = 1;
290748ca2d8aSDwaipayan Ray				} else {
290848ca2d8aSDwaipayan Ray					my $ctx = $1;
290948ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
291048ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
291148ca2d8aSDwaipayan Ray
291248ca2d8aSDwaipayan Ray					if ($email_address eq $author_address && $email_name eq $author_name) {
291348ca2d8aSDwaipayan Ray						$author_sob = $ctx;
291448ca2d8aSDwaipayan Ray						$authorsignoff = 2;
291548ca2d8aSDwaipayan Ray					} elsif ($email_address eq $author_address) {
291648ca2d8aSDwaipayan Ray						$author_sob = $ctx;
291748ca2d8aSDwaipayan Ray						$authorsignoff = 3;
291848ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
291948ca2d8aSDwaipayan Ray						$author_sob = $ctx;
292048ca2d8aSDwaipayan Ray						$authorsignoff = 4;
292148ca2d8aSDwaipayan Ray
292248ca2d8aSDwaipayan Ray						my $address1 = $email_address;
292348ca2d8aSDwaipayan Ray						my $address2 = $author_address;
292448ca2d8aSDwaipayan Ray
292548ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
292648ca2d8aSDwaipayan Ray							$address1 = "$1$2";
292748ca2d8aSDwaipayan Ray						}
292848ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
292948ca2d8aSDwaipayan Ray							$address2 = "$1$2";
293048ca2d8aSDwaipayan Ray						}
293148ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
293248ca2d8aSDwaipayan Ray							$authorsignoff = 5;
293348ca2d8aSDwaipayan Ray						}
293448ca2d8aSDwaipayan Ray					}
2935cd261496SGeert Uytterhoeven				}
2936cd261496SGeert Uytterhoeven			}
29370a920b5bSAndy Whitcroft		}
293820112475SJoe Perches
293944d303ebSJoe Perches# Check for patch separator
294044d303ebSJoe Perches		if ($line =~ /^---$/) {
294144d303ebSJoe Perches			$has_patch_separator = 1;
294244d303ebSJoe Perches			$in_commit_log = 0;
294344d303ebSJoe Perches		}
294444d303ebSJoe Perches
2945e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2946e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2947e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2948e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2949e0d975b1SJoe Perches		}
2950e0d975b1SJoe Perches
295120112475SJoe Perches# Check signature styles
2952270c49a0SJoe Perches		if (!$in_header_lines &&
2953ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
295420112475SJoe Perches			my $space_before = $1;
295520112475SJoe Perches			my $sign_off = $2;
295620112475SJoe Perches			my $space_after = $3;
295720112475SJoe Perches			my $email = $4;
295820112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
295920112475SJoe Perches
2960ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2961831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
2962831242abSAditya Srivastava				if ($suggested_signature eq "") {
2963ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
2964ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
2965831242abSAditya Srivastava				} else {
2966831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
2967831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2968831242abSAditya Srivastava					    $fix) {
2969831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2970831242abSAditya Srivastava					}
2971831242abSAditya Srivastava				}
2972ce0338dfSJoe Perches			}
297320112475SJoe Perches			if (defined $space_before && $space_before ne "") {
29743705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29753705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
29763705ce5bSJoe Perches				    $fix) {
2977194f66fcSJoe Perches					$fixed[$fixlinenr] =
29783705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29793705ce5bSJoe Perches				}
298020112475SJoe Perches			}
298120112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
29823705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29833705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
29843705ce5bSJoe Perches				    $fix) {
2985194f66fcSJoe Perches					$fixed[$fixlinenr] =
29863705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29873705ce5bSJoe Perches				}
29883705ce5bSJoe Perches
298920112475SJoe Perches			}
299020112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
29913705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
29923705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
29933705ce5bSJoe Perches				    $fix) {
2994194f66fcSJoe Perches					$fixed[$fixlinenr] =
29953705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29963705ce5bSJoe Perches				}
299720112475SJoe Perches			}
299820112475SJoe Perches
2999dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
300048ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
300120112475SJoe Perches			if ($suggested_email eq "") {
3002000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
3003000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
300420112475SJoe Perches			} else {
300520112475SJoe Perches				my $dequoted = $suggested_email;
300620112475SJoe Perches				$dequoted =~ s/^"//;
300720112475SJoe Perches				$dequoted =~ s/" </ </;
300820112475SJoe Perches				# Don't force email to have quotes
300920112475SJoe Perches				# Allow just an angle bracketed address
3010fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
3011fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3012fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3013fccaebf0SDwaipayan Ray					    $fix) {
3014fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3015fccaebf0SDwaipayan Ray					}
3016fccaebf0SDwaipayan Ray				}
3017fccaebf0SDwaipayan Ray
3018fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
3019fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
3020fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
3021fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
3022fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3023fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3024fccaebf0SDwaipayan Ray					    $fix) {
3025fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3026fccaebf0SDwaipayan Ray					}
3027fccaebf0SDwaipayan Ray				}
3028fccaebf0SDwaipayan Ray
3029fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
3030fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3031fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
3032000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
3033fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
3034fccaebf0SDwaipayan Ray				}
3035fccaebf0SDwaipayan Ray
3036fccaebf0SDwaipayan Ray
3037fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
3038e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
3039fccaebf0SDwaipayan Ray				# begin with a #
3040fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3041fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
3042fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
3043fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
3044fccaebf0SDwaipayan Ray						my $new_comment = $comment;
3045fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3046fccaebf0SDwaipayan Ray
3047fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
3048fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
3049fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
3050fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
3051fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
3052fccaebf0SDwaipayan Ray
3053fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3054fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
3055fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
3056fccaebf0SDwaipayan Ray
3057fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3058fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3059fccaebf0SDwaipayan Ray						    $fix) {
3060fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3061fccaebf0SDwaipayan Ray						}
3062fccaebf0SDwaipayan Ray					}
3063fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3064fccaebf0SDwaipayan Ray					my $new_comment = $comment;
3065fccaebf0SDwaipayan Ray
3066fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
3067fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
3068fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
3069fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3070fccaebf0SDwaipayan Ray
3071fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
3072fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3073fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
3074fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3075fccaebf0SDwaipayan Ray
3076fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3077fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3078fccaebf0SDwaipayan Ray					    $fix) {
3079fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3080fccaebf0SDwaipayan Ray					}
308120112475SJoe Perches				}
30820a920b5bSAndy Whitcroft			}
30837e51f197SJoe Perches
30847e51f197SJoe Perches# Check for duplicate signatures
30857e51f197SJoe Perches			my $sig_nospace = $line;
30867e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
30877e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
30887e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
30897e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
30907e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
30917e51f197SJoe Perches			} else {
30927e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
30937e51f197SJoe Perches			}
30946c5d24eeSSean Christopherson
30956c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
30966c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
30976c5d24eeSSean Christopherson				if ($email eq $author) {
30986c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30996c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
31006c5d24eeSSean Christopherson				}
31016c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
31026c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31036c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
31046c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
31056c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31066c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31076c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
31086c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31096c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31106c5d24eeSSean Christopherson				}
31116c5d24eeSSean Christopherson			}
31120a920b5bSAndy Whitcroft		}
31130a920b5bSAndy Whitcroft
3114a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3115a2fe16b9SJoe Perches		if ($in_header_lines &&
3116a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3117a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3118a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3119a2fe16b9SJoe Perches		}
3120a2fe16b9SJoe Perches
312144d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
312244d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
31237580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
31247580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
31257580c5b9SAditya Srivastava			    $fix) {
31267580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
31277580c5b9SAditya Srivastava			}
31287ebd05efSChristopher Covington		}
31297ebd05efSChristopher Covington
3130369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3131369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3132369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3133369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3134369c8dd3SJoe Perches					# timestamp
3135634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3136634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3137634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3138634cffccSJoe Perches					# stack dump address styles
3139369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3140369c8dd3SJoe Perches		}
3141369c8dd3SJoe Perches
31422a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
31432a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3144bf4daf12SJoe Perches		    length($line) > 75 &&
3145bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3146bf4daf12SJoe Perches					# file delta changes
3147bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
3148bf4daf12SJoe Perches					# filename then :
314927b379afSAditya Srivastava		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
315027b379afSAditya Srivastava					# A Fixes: or Link: line or signature tag line
3151bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
31522a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
31532a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
31542a076f40SJoe Perches			$commit_log_long_line = 1;
31552a076f40SJoe Perches		}
31562a076f40SJoe Perches
3157bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3158bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3159bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3160bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3161bf4daf12SJoe Perches		}
3162bf4daf12SJoe Perches
3163084a617aSDwaipayan Ray# Check for lines starting with a #
3164084a617aSDwaipayan Ray		if ($in_commit_log && $line =~ /^#/) {
3165084a617aSDwaipayan Ray			if (WARN("COMMIT_COMMENT_SYMBOL",
3166084a617aSDwaipayan Ray				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3167084a617aSDwaipayan Ray			    $fix) {
3168084a617aSDwaipayan Ray				$fixed[$fixlinenr] =~ s/^/ /;
3169084a617aSDwaipayan Ray			}
3170084a617aSDwaipayan Ray		}
3171084a617aSDwaipayan Ray
31720d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
3173369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3174a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3175e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
3176fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3177aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3178369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3179bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3180fe043ea1SJoe Perches			my $init_char = "c";
3181fe043ea1SJoe Perches			my $orig_commit = "";
31820d7835fcSJoe Perches			my $short = 1;
31830d7835fcSJoe Perches			my $long = 0;
31840d7835fcSJoe Perches			my $case = 1;
31850d7835fcSJoe Perches			my $space = 1;
31860d7835fcSJoe Perches			my $hasdesc = 0;
318719c146a6SJoe Perches			my $hasparens = 0;
31880d7835fcSJoe Perches			my $id = '0123456789ab';
31890d7835fcSJoe Perches			my $orig_desc = "commit description";
31900d7835fcSJoe Perches			my $description = "";
31910d7835fcSJoe Perches
3192fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3193fe043ea1SJoe Perches				$init_char = $1;
3194fe043ea1SJoe Perches				$orig_commit = lc($2);
3195fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
3196fe043ea1SJoe Perches				$orig_commit = lc($1);
3197fe043ea1SJoe Perches			}
3198fe043ea1SJoe Perches
31990d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
32000d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
32010d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
32020d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
32030d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
32040d7835fcSJoe Perches				$orig_desc = $1;
320519c146a6SJoe Perches				$hasparens = 1;
32060d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
32070d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
32080d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
32090d7835fcSJoe Perches				$orig_desc = $1;
321019c146a6SJoe Perches				$hasparens = 1;
3211b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
3212b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
3213b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
3214b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
3215b671fde0SJoe Perches				$orig_desc = $1;
3216b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
3217b671fde0SJoe Perches				$orig_desc .= " " . $1;
321819c146a6SJoe Perches				$hasparens = 1;
32190d7835fcSJoe Perches			}
32200d7835fcSJoe Perches
32210d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
32220d7835fcSJoe Perches							      $id, $orig_desc);
32230d7835fcSJoe Perches
3224948b133aSHeinrich Schuchardt			if (defined($id) &&
3225948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
3226d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
32270d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
32280d7835fcSJoe Perches			}
3229d311cd44SJoe Perches		}
3230d311cd44SJoe Perches
323113f1937eSJoe Perches# Check for added, moved or deleted files
323213f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
323313f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
323413f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
323513f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
323613f1937eSJoe Perches		      (defined($1) || defined($2))))) {
3237a82603a8SAndrew Jeffery			$is_patch = 1;
323813f1937eSJoe Perches			$reported_maintainer_file = 1;
323913f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
324013f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
324113f1937eSJoe Perches		}
324213f1937eSJoe Perches
3243e400edb1SRob Herring# Check for adding new DT bindings not in schema format
3244e400edb1SRob Herring		if (!$in_commit_log &&
3245e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3246e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3247e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
324856ddc4cdSMauro Carvalho Chehab			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3249e400edb1SRob Herring		}
3250e400edb1SRob Herring
325100df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
32528905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3253000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
3254000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
32556c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
3256de7d4f0eSAndy Whitcroft		}
3257de7d4f0eSAndy Whitcroft
3258de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3259de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3260171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
3261171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3262171ae1a4SAndy Whitcroft
3263171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
3264171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3265171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
3266171ae1a4SAndy Whitcroft
326734d99219SJoe Perches			CHK("INVALID_UTF8",
3268000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
326900df344fSAndy Whitcroft		}
32700a920b5bSAndy Whitcroft
327115662b3eSJoe Perches# Check if it's the start of a commit log
327215662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
327315662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
3274eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
3275eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
327615662b3eSJoe Perches			$in_header_lines = 0;
327715662b3eSJoe Perches			$in_commit_log = 1;
3278ed43c4e5SAllen Hubbe			$has_commit_log = 1;
327915662b3eSJoe Perches		}
328015662b3eSJoe Perches
3281fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
3282fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
3283fa64205dSPasi Savanainen		if ($in_header_lines &&
3284fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3285fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
3286fa64205dSPasi Savanainen			$non_utf8_charset = 1;
3287fa64205dSPasi Savanainen		}
3288fa64205dSPasi Savanainen
3289fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
329015662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3291fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
329215662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
329315662b3eSJoe Perches		}
329415662b3eSJoe Perches
3295d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3296d6430f71SJoe Perches		if ($tree && $in_commit_log) {
3297d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3298d6430f71SJoe Perches				my $file = $1;
3299d6430f71SJoe Perches
3300d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3301d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
3302d6430f71SJoe Perches					#
3303d6430f71SJoe Perches				} else {
3304d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
3305d6430f71SJoe Perches				}
3306d6430f71SJoe Perches			}
3307d6430f71SJoe Perches		}
3308d6430f71SJoe Perches
330966b47b4aSKees Cook# Check for various typo / spelling mistakes
331066d7a382SJoe Perches		if (defined($misspellings) &&
331166d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
33127da07c31SDwaipayan Ray			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
331366b47b4aSKees Cook				my $typo = $1;
33147da07c31SDwaipayan Ray				my $blank = copy_spacing($rawline);
33157da07c31SDwaipayan Ray				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
33167da07c31SDwaipayan Ray				my $hereptr = "$hereline$ptr\n";
331766b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
331866b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
331966b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
33200675a8fbSJean Delvare				my $msg_level = \&WARN;
33210675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
33220675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
33237da07c31SDwaipayan Ray						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
332466b47b4aSKees Cook				    $fix) {
332566b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
332666b47b4aSKees Cook				}
332766b47b4aSKees Cook			}
332866b47b4aSKees Cook		}
332966b47b4aSKees Cook
3330a8dd86bfSMatteo Croce# check for invalid commit id
3331a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3332a8dd86bfSMatteo Croce			my $id;
3333a8dd86bfSMatteo Croce			my $description;
3334a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
3335a8dd86bfSMatteo Croce			if (!defined($id)) {
3336a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
3337a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3338a8dd86bfSMatteo Croce			}
3339a8dd86bfSMatteo Croce		}
3340a8dd86bfSMatteo Croce
3341310cd06bSJoe Perches# check for repeated words separated by a single space
33428d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
33438d0325ccSAditya Srivastava		if (($rawline =~ /^\+/ || $in_commit_log) &&
33448d0325ccSAditya Srivastava		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
33451db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3346310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3347310cd06bSJoe Perches
3348310cd06bSJoe Perches				my $first = $1;
3349310cd06bSJoe Perches				my $second = $2;
33501db81a68SDwaipayan Ray				my $start_pos = $-[1];
33511db81a68SDwaipayan Ray				my $end_pos = $+[2];
3352310cd06bSJoe Perches				if ($first =~ /(?:struct|union|enum)/) {
3353310cd06bSJoe Perches					pos($rawline) += length($first) + length($second) + 1;
3354310cd06bSJoe Perches					next;
3355310cd06bSJoe Perches				}
3356310cd06bSJoe Perches
33571db81a68SDwaipayan Ray				next if (lc($first) ne lc($second));
3358310cd06bSJoe Perches				next if ($first eq 'long');
3359310cd06bSJoe Perches
33601db81a68SDwaipayan Ray				# check for character before and after the word matches
33611db81a68SDwaipayan Ray				my $start_char = '';
33621db81a68SDwaipayan Ray				my $end_char = '';
33631db81a68SDwaipayan Ray				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
33641db81a68SDwaipayan Ray				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
33651db81a68SDwaipayan Ray
33661db81a68SDwaipayan Ray				next if ($start_char =~ /^\S$/);
33671db81a68SDwaipayan Ray				next if (index(" \t.,;?!", $end_char) == -1);
33681db81a68SDwaipayan Ray
33698d0325ccSAditya Srivastava				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
33708d0325ccSAditya Srivastava				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
33718d0325ccSAditya Srivastava					next if (!exists($allow_repeated_words{lc($first)}));
33728d0325ccSAditya Srivastava				}
33738d0325ccSAditya Srivastava
3374310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3375310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3376310cd06bSJoe Perches				    $fix) {
3377310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3378310cd06bSJoe Perches				}
3379310cd06bSJoe Perches			}
3380310cd06bSJoe Perches
3381310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3382310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
3383310cd06bSJoe Perches			    $prevrawline =~ /($word_pattern)\s*$/) {
3384310cd06bSJoe Perches				my $last_word = $1;
3385310cd06bSJoe Perches				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3386310cd06bSJoe Perches					if (WARN("REPEATED_WORD",
3387310cd06bSJoe Perches						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3388310cd06bSJoe Perches					    $fix) {
3389310cd06bSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3390310cd06bSJoe Perches					}
3391310cd06bSJoe Perches				}
3392310cd06bSJoe Perches			}
3393310cd06bSJoe Perches		}
3394310cd06bSJoe Perches
339530670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
339630670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
339700df344fSAndy Whitcroft
33980a920b5bSAndy Whitcroft#trailing whitespace
33999c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
3400c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3401d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3402d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
3403d5e616fcSJoe Perches			    $fix) {
3404194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3405d5e616fcSJoe Perches			}
3406c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3407c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34083705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
34093705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
34103705ce5bSJoe Perches			    $fix) {
3411194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
34123705ce5bSJoe Perches			}
34133705ce5bSJoe Perches
3414d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
34150a920b5bSAndy Whitcroft		}
34165368df20SAndy Whitcroft
34174783f894SJosh Triplett# Check for FSF mailing addresses.
3418109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
34191bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
34203e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
34213e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
34224783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34230675a8fbSJean Delvare			my $msg_level = \&ERROR;
34240675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
34250675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
34264783f894SJosh 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)
34274783f894SJosh Triplett		}
34284783f894SJosh Triplett
34293354957aSAndi Kleen# check for Kconfig help text having a real description
34309fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
34319fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
34323354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3433678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3434678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3435678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3436678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
34373354957aSAndi Kleen			my $length = 0;
34389fe287d7SAndy Whitcroft			my $cnt = $realcnt;
34399fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
34409fe287d7SAndy Whitcroft			my $f;
3441a1385803SAndy Whitcroft			my $is_start = 0;
34429fe287d7SAndy Whitcroft			my $is_end = 0;
3443a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
34449fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
34459fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
34469fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
34479fe287d7SAndy Whitcroft
34489fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
34498d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3450a1385803SAndy Whitcroft
345186adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3452a1385803SAndy Whitcroft					$is_start = 1;
345322a4ac02SMasahiro Yamada				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
3454a1385803SAndy Whitcroft					$length = -1;
3455a1385803SAndy Whitcroft				}
3456a1385803SAndy Whitcroft
34579fe287d7SAndy Whitcroft				$f =~ s/^.//;
34583354957aSAndi Kleen				$f =~ s/#.*//;
34593354957aSAndi Kleen				$f =~ s/^\s+//;
34603354957aSAndi Kleen				next if ($f =~ /^$/);
3461678ae162SUlf Magnusson
3462678ae162SUlf Magnusson				# This only checks context lines in the patch
3463678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3464678ae162SUlf Magnusson				# positives, even though some of these are
3465678ae162SUlf Magnusson				# common words in help texts
3466678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3467678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
34689fe287d7SAndy Whitcroft					$is_end = 1;
34699fe287d7SAndy Whitcroft					last;
34709fe287d7SAndy Whitcroft				}
34713354957aSAndi Kleen				$length++;
34723354957aSAndi Kleen			}
347356193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3474000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
347556193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
347656193274SVadim Bendebury			}
3477a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
34783354957aSAndi Kleen		}
34793354957aSAndi Kleen
34807ccf41a8SJoe Perches# check MAINTAINERS entries
34817ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
34827ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
34837ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3484628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3485628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3486628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3487628f91a2SJoe Perches				    $fix) {
3488628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3489628f91a2SJoe Perches				}
3490628f91a2SJoe Perches			}
34917ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
34927ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
34937ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
34947ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
34957ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
34967ccf41a8SJoe Perches				my $cur = $1;
34977ccf41a8SJoe Perches				my $curval = $2;
34987ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
34997ccf41a8SJoe Perches				my $prev = $1;
35007ccf41a8SJoe Perches				my $prevval = $2;
35017ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
35027ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
35037ccf41a8SJoe Perches				if ($curindex < 0) {
35047ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
35057ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
35067ccf41a8SJoe Perches				} else {
35077ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
35087ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
35097ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
35107ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
35117ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
35127ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
35137ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
35147ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
35157ccf41a8SJoe Perches					}
35167ccf41a8SJoe Perches				}
35177ccf41a8SJoe Perches			}
35187ccf41a8SJoe Perches		}
3519628f91a2SJoe Perches
3520c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3521c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3522c68e5878SArnaud Lacombe			my $flag = $1;
3523c68e5878SArnaud Lacombe			my $replacement = {
3524c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3525c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3526c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3527c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3528c68e5878SArnaud Lacombe			};
3529c68e5878SArnaud Lacombe
3530c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3531c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3532c68e5878SArnaud Lacombe		}
3533c68e5878SArnaud Lacombe
3534bff5da43SRob Herring# check for DT compatible documentation
35357dd05b38SFlorian Vaussard		if (defined $root &&
35367dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
35377dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
35387dd05b38SFlorian Vaussard
3539bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3540bff5da43SRob Herring
3541cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3542852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3543cc93319bSFlorian Vaussard
3544bff5da43SRob Herring			foreach my $compat (@compats) {
3545bff5da43SRob Herring				my $compat2 = $compat;
3546185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3547185d566bSRob Herring				my $compat3 = $compat;
3548185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3549185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3550bff5da43SRob Herring				if ( $? >> 8 ) {
3551bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3552bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3553bff5da43SRob Herring				}
3554bff5da43SRob Herring
35554fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
35564fbf32a6SFlorian Vaussard				my $vendor = $1;
3557852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3558bff5da43SRob Herring				if ( $? >> 8 ) {
3559bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3560cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3561bff5da43SRob Herring				}
3562bff5da43SRob Herring			}
3563bff5da43SRob Herring		}
3564bff5da43SRob Herring
35659f3a8992SRob Herring# check for using SPDX license tag at beginning of files
35669f3a8992SRob Herring		if ($realline == $checklicenseline) {
35679f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
35689f3a8992SRob Herring				$checklicenseline = 2;
35699f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
35709f3a8992SRob Herring				my $comment = "";
35719f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
35729f3a8992SRob Herring					$comment = '/*';
35739f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
35749f3a8992SRob Herring					$comment = '//';
3575c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
35769f3a8992SRob Herring					$comment = '#';
35779f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
35789f3a8992SRob Herring					$comment = '..';
35799f3a8992SRob Herring				}
35809f3a8992SRob Herring
3581fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3582fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3583fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3584ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3585fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3586fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3587fdf13693SJoe Perches				}
3588fdf13693SJoe Perches
35899f3a8992SRob Herring				if ($comment !~ /^$/ &&
3590ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
35919f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
35929f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
35933b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
35943b6e8ac9SJoe Perches					my $spdx_license = $1;
35953b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
35963b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
35973b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
35983b6e8ac9SJoe Perches					}
359950c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
360050c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
360150c92900SLubomir Rintel						my $msg_level = \&WARN;
360250c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
360350c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
360450c92900SLubomir Rintel
360550c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
360650c92900SLubomir Rintel						    $fix) {
360750c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
360850c92900SLubomir Rintel						}
360950c92900SLubomir Rintel					}
36109f3a8992SRob Herring				}
36119f3a8992SRob Herring			}
36129f3a8992SRob Herring		}
36139f3a8992SRob Herring
3614a0154cdbSJoe Perches# check for embedded filenames
3615a0154cdbSJoe Perches		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3616a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3617a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3618a0154cdbSJoe Perches		}
3619a0154cdbSJoe Perches
36205368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3621d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
36225368df20SAndy Whitcroft
3623a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3624a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3625a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3626a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3627a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3628a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3629a8da38a9SJoe Perches		}
3630a8da38a9SJoe Perches
363147e0c88bSJoe Perches# line length limit (with some exclusions)
363247e0c88bSJoe Perches#
363347e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
363447e0c88bSJoe Perches#	logging functions like pr_info that end in a string
363547e0c88bSJoe Perches#	lines with a single string
363647e0c88bSJoe Perches#	#defines that are a single string
36372e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
363847e0c88bSJoe Perches#
363947e0c88bSJoe Perches# There are 3 different line length message types:
3640ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
364147e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
364247e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
364347e0c88bSJoe Perches#
364447e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
364547e0c88bSJoe Perches#
364647e0c88bSJoe Perches
3647b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
364847e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
364947e0c88bSJoe Perches
365047e0c88bSJoe Perches			# Check the allowed long line types first
365147e0c88bSJoe Perches
365247e0c88bSJoe Perches			# logging functions that end in a string that starts
365347e0c88bSJoe Perches			# before $max_line_length
365447e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
365547e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
365647e0c88bSJoe Perches				$msg_type = "";
365747e0c88bSJoe Perches
365847e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
365947e0c88bSJoe Perches			# #defines with only strings
366047e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
366147e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
366247e0c88bSJoe Perches				$msg_type = "";
366347e0c88bSJoe Perches
3664cc147506SJoe Perches			# More special cases
3665cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3666cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3667d560a5f8SJoe Perches				$msg_type = "";
3668d560a5f8SJoe Perches
36692e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
36702e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
36712e4bbbc5SAndreas Brauchli				$msg_type = "";
36722e4bbbc5SAndreas Brauchli
367347e0c88bSJoe Perches			# Otherwise set the alternate message types
367447e0c88bSJoe Perches
367547e0c88bSJoe Perches			# a comment starts before $max_line_length
367647e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
367747e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
367847e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
367947e0c88bSJoe Perches
368047e0c88bSJoe Perches			# a quoted string starts before $max_line_length
368147e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
368247e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
368347e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
368447e0c88bSJoe Perches			}
368547e0c88bSJoe Perches
368647e0c88bSJoe Perches			if ($msg_type ne "" &&
368747e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3688bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3689bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3690bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3691bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
36920a920b5bSAndy Whitcroft			}
369347e0c88bSJoe Perches		}
36940a920b5bSAndy Whitcroft
36958905a67cSAndy Whitcroft# check for adding lines without a newline.
36968905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
369747ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
369847ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
369947ca69b8STom Rix			    $fix) {
370047ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
370147ca69b8STom Rix			}
37028905a67cSAndy Whitcroft		}
37038905a67cSAndy Whitcroft
3704de93245cSAditya Srivastava# check for .L prefix local symbols in .S files
3705de93245cSAditya Srivastava		if ($realfile =~ /\.S$/ &&
3706de93245cSAditya Srivastava		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3707de93245cSAditya Srivastava			WARN("AVOID_L_PREFIX",
3708de93245cSAditya 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);
3709de93245cSAditya Srivastava		}
3710de93245cSAditya Srivastava
3711b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3712de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
37130a920b5bSAndy Whitcroft
37140a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3715713a09deSAntonio Borneo# more than $tabsize must use tabs.
3716c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3717c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3718c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3719d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
37203705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
37213705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
37223705ce5bSJoe Perches			    $fix) {
3723194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
37243705ce5bSJoe Perches			}
37250a920b5bSAndy Whitcroft		}
37260a920b5bSAndy Whitcroft
372708e44365SAlberto Panizzo# check for space before tabs.
372808e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
372908e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
37303705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
37313705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
37323705ce5bSJoe Perches			    $fix) {
3733194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3734713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3735194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3736c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
37373705ce5bSJoe Perches			}
373808e44365SAlberto Panizzo		}
373908e44365SAlberto Panizzo
37406a487211SJoe Perches# check for assignments on the start of a line
37416a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3742da7355abSAditya Srivastava			my $operator = $1;
3743da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3744da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3745da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3746da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3747da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3748da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3749da7355abSAditya Srivastava			}
37506a487211SJoe Perches		}
37516a487211SJoe Perches
3752d1fe9c09SJoe Perches# check for && or || at the start of a line
3753d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
37548e08f076SAditya Srivastava			my $operator = $1;
37558e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
37568e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
37578e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
37588e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
37598e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
37608e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
37618e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
37628e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
37638e08f076SAditya Srivastava			}
3764d1fe9c09SJoe Perches		}
3765d1fe9c09SJoe Perches
3766a91e8994SJoe Perches# check indentation starts on a tab stop
37675b57980dSJoe Perches		if ($perl_version_ok &&
3768bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3769a91e8994SJoe Perches			my $indent = length($1);
3770713a09deSAntonio Borneo			if ($indent % $tabsize) {
3771a91e8994SJoe Perches				if (WARN("TABSTOP",
3772a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3773a91e8994SJoe Perches				    $fix) {
3774713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3775a91e8994SJoe Perches				}
3776a91e8994SJoe Perches			}
3777a91e8994SJoe Perches		}
3778a91e8994SJoe Perches
3779d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
37805b57980dSJoe Perches		if ($perl_version_ok &&
3781fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3782d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3783d1fe9c09SJoe Perches			my $oldindent = $1;
3784d1fe9c09SJoe Perches			my $rest = $2;
3785d1fe9c09SJoe Perches
3786d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3787d1fe9c09SJoe Perches			if ($pos >= 0) {
3788b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3789b34a26f3SJoe Perches				my $newindent = $2;
3790d1fe9c09SJoe Perches
3791d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3792713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3793713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3794d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3795d1fe9c09SJoe Perches
3796d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3797d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
37983705ce5bSJoe Perches
37993705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
38003705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
38013705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3802194f66fcSJoe Perches						$fixed[$fixlinenr] =~
38033705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
38043705ce5bSJoe Perches					}
3805d1fe9c09SJoe Perches				}
3806d1fe9c09SJoe Perches			}
3807d1fe9c09SJoe Perches		}
3808d1fe9c09SJoe Perches
38096ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
38106ab3a970SJoe Perches# avoid checking a few false positives:
38116ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
38126ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
38136ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
38146ab3a970SJoe Perches#   multiline macros that define functions
38156ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
38166ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
38176ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
38183705ce5bSJoe Perches			if (CHK("SPACING",
3819f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
38203705ce5bSJoe Perches			    $fix) {
3821194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3822f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
38233705ce5bSJoe Perches			}
3824aad4f614SJoe Perches		}
3825aad4f614SJoe Perches
382686406b1cSJoe Perches# Block comment styles
382786406b1cSJoe Perches# Networking with an initial /*
382805880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3829fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
383085ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
3831c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
383205880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
383305880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
383405880600SJoe Perches		}
383505880600SJoe Perches
383686406b1cSJoe Perches# Block comments use * on subsequent lines
383786406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
383886406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3839a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
384061135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3841a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
384286406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
384386406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3844a605e32eSJoe Perches		}
3845a605e32eSJoe Perches
384686406b1cSJoe Perches# Block comments use */ on trailing lines
384786406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3848c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3849c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3850c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
385186406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
385286406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
385305880600SJoe Perches		}
385405880600SJoe Perches
385508eb9b80SJoe Perches# Block comment * alignment
385608eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3857af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3858af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3859af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
386008eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3861af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3862af207524SJoe Perches			my $oldindent;
386308eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3864af207524SJoe Perches			if (defined($1)) {
3865af207524SJoe Perches				$oldindent = expand_tabs($1);
3866af207524SJoe Perches			} else {
3867af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3868af207524SJoe Perches				$oldindent = expand_tabs($1);
3869af207524SJoe Perches			}
387008eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
387108eb9b80SJoe Perches			my $newindent = $1;
387208eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3873af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
387408eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
387508eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
387608eb9b80SJoe Perches			}
387708eb9b80SJoe Perches		}
387808eb9b80SJoe Perches
38797f619191SJoe Perches# check for missing blank lines after struct/union declarations
38807f619191SJoe Perches# with exceptions for various attributes and macros
38817f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
38827f619191SJoe Perches		    $line =~ /^\+/ &&
38837f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
38847f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
38857f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
38867f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
38877f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
38887f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
38897f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
38900bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
38917f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3892d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3893d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3894d752fcc8SJoe Perches			    $fix) {
3895f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3896d752fcc8SJoe Perches			}
38977f619191SJoe Perches		}
38987f619191SJoe Perches
3899365dd4eaSJoe Perches# check for multiple consecutive blank lines
3900365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3901365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3902365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3903d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3904d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3905d752fcc8SJoe Perches			    $fix) {
3906f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3907d752fcc8SJoe Perches			}
3908d752fcc8SJoe Perches
3909365dd4eaSJoe Perches			$last_blank_line = $linenr;
3910365dd4eaSJoe Perches		}
3911365dd4eaSJoe Perches
39123b617e3bSJoe Perches# check for missing blank lines after declarations
3913b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
3914b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3915b5e8736aSJoe Perches			# use temporaries
3916b5e8736aSJoe Perches			my $sl = $sline;
3917b5e8736aSJoe Perches			my $pl = $prevline;
3918b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
3919b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3920b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3921b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
39225a4e1fd3SJoe Perches			# function pointer declarations
3923b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
39243f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3925b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
39263f7bac03SJoe Perches			# known declaration macros
3927b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
39283f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
3929b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
39303f7bac03SJoe Perches			# other possible extensions of declaration lines
3931b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
39323f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
3933b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
39343f7bac03SJoe Perches			# looks like a declaration
3935b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
39365a4e1fd3SJoe Perches			# function pointer declarations
3937b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
39383f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3939b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
39403f7bac03SJoe Perches			# known declaration macros
3941b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
39423f7bac03SJoe Perches			# start of struct or union or enum
3943b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
39443f7bac03SJoe Perches			# start or end of block or continuation of declaration
3945b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
39463f7bac03SJoe Perches			# bitfield continuation
3947b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
39483f7bac03SJoe Perches			# other possible extensions of declaration lines
3949b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3950d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
3951d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
3952d752fcc8SJoe Perches				    $fix) {
3953f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
3954d752fcc8SJoe Perches				}
39553b617e3bSJoe Perches			}
3956b5e8736aSJoe Perches		}
39573b617e3bSJoe Perches
39585f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
39596b4c5bebSAndy Whitcroft# Exceptions:
39606b4c5bebSAndy Whitcroft#  1) within comments
39616b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
39626b4c5bebSAndy Whitcroft#  3) hanging labels
39633705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
39645f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
39653705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
39663705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
39673705ce5bSJoe Perches			    $fix) {
3968194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
39693705ce5bSJoe Perches			}
39705f7ddae6SRaffaele Recalcati		}
39715f7ddae6SRaffaele Recalcati
3972b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3973b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3974b9ea10d6SAndy Whitcroft
39755751a24eSJoe Perches# check for unusual line ending [ or (
39765751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
39775751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
39785751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
39795751a24eSJoe Perches		}
39805751a24eSJoe Perches
39814dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
39824dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
39834dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
39844dbed76fSJoe Perches			$context_function = $1;
39854dbed76fSJoe Perches		}
39864dbed76fSJoe Perches
39874dbed76fSJoe Perches# check if this appears to be the end of function declaration
39884dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
39894dbed76fSJoe Perches			undef $context_function;
39904dbed76fSJoe Perches		}
39914dbed76fSJoe Perches
3992032a4c0fSJoe Perches# check indentation of any line with a bare else
3993840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3994032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3995032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3996032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3997840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3998840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3999840080a0SJoe Perches			     defined $lines[$linenr] &&
4000840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
4001032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
4002032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
4003032a4c0fSJoe Perches			}
4004032a4c0fSJoe Perches		}
4005032a4c0fSJoe Perches
4006c00df19aSJoe Perches# check indentation of a line with a break;
4007dc58bc55SJoe Perches# if the previous line is a goto, return or break
4008dc58bc55SJoe Perches# and is indented the same # of tabs
4009c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4010c00df19aSJoe Perches			my $tabs = $1;
4011dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4012dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
4013dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
4014dc58bc55SJoe Perches				    $fix) {
4015dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
4016dc58bc55SJoe Perches				}
4017c00df19aSJoe Perches			}
4018c00df19aSJoe Perches		}
4019c00df19aSJoe Perches
4020c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
4021cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4022000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
4023000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4024c2fdda0dSAndy Whitcroft		}
402522f2a2efSAndy Whitcroft
402656e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
402756e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
402856e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
402956e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
403056e77d70SJoe Perches		}
403156e77d70SJoe Perches
40329c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
40332b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
40342b474a1aSAndy Whitcroft		    $realline_next);
40353e469cdcSAndy Whitcroft#print "LINE<$line>\n";
4036ca819864SJoe Perches		if ($linenr > $suppress_statement &&
40371b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
4038170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4039f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4040171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
4041171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
4042171ae1a4SAndy Whitcroft
40433e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
40443e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
40453e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
40463e469cdcSAndy Whitcroft			# until we hit end of it.
40473e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
40483e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
40493e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
40503e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
40513e469cdcSAndy Whitcroft			}
4052f74bd194SAndy Whitcroft
40532b474a1aSAndy Whitcroft			# Find the real next line.
40542b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
40552b474a1aSAndy Whitcroft			if (defined $realline_next &&
40562b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
40572b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
40582b474a1aSAndy Whitcroft				$realline_next++;
40592b474a1aSAndy Whitcroft			}
40602b474a1aSAndy Whitcroft
4061171ae1a4SAndy Whitcroft			my $s = $stat;
4062171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
4063cf655043SAndy Whitcroft
4064c2fdda0dSAndy Whitcroft			# Ignore goto labels.
4065171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
4066c2fdda0dSAndy Whitcroft
4067c2fdda0dSAndy Whitcroft			# Ignore functions being called
4068171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
4069c2fdda0dSAndy Whitcroft
4070463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
4071463f2864SAndy Whitcroft
4072c45dcabdSAndy Whitcroft			# declarations always start with types
4073d2506586SAndy 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) {
4074c45dcabdSAndy Whitcroft				my $type = $1;
4075c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
4076c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
4077c45dcabdSAndy Whitcroft
40786c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
4079a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4080c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
4081c2fdda0dSAndy Whitcroft			}
40828905a67cSAndy Whitcroft
40836c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
408465863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4085c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
40869c0ca6f9SAndy Whitcroft			}
40878905a67cSAndy Whitcroft
40888905a67cSAndy Whitcroft			# Check for any sort of function declaration.
40898905a67cSAndy Whitcroft			# int foo(something bar, other baz);
40908905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
4091171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
40928905a67cSAndy Whitcroft				my ($name_len) = length($1);
40938905a67cSAndy Whitcroft
4094cf655043SAndy Whitcroft				my $ctx = $s;
4095773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
40968905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
4097cf655043SAndy Whitcroft
40988905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4099c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
41008905a67cSAndy Whitcroft
4101c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
41028905a67cSAndy Whitcroft					}
41038905a67cSAndy Whitcroft				}
41048905a67cSAndy Whitcroft			}
41058905a67cSAndy Whitcroft
41069c0ca6f9SAndy Whitcroft		}
41079c0ca6f9SAndy Whitcroft
410800df344fSAndy Whitcroft#
410900df344fSAndy Whitcroft# Checks which may be anchored in the context.
411000df344fSAndy Whitcroft#
411100df344fSAndy Whitcroft
411200df344fSAndy Whitcroft# Check for switch () and associated case and default
411300df344fSAndy Whitcroft# statements should be at the same indent.
411400df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
411500df344fSAndy Whitcroft			my $err = '';
411600df344fSAndy Whitcroft			my $sep = '';
411700df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
411800df344fSAndy Whitcroft			shift(@ctx);
411900df344fSAndy Whitcroft			for my $ctx (@ctx) {
412000df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
412100df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
412200df344fSAndy Whitcroft							$indent != $cindent) {
412300df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
412400df344fSAndy Whitcroft					$sep = '';
412500df344fSAndy Whitcroft				} else {
412600df344fSAndy Whitcroft					$sep = "[...]\n";
412700df344fSAndy Whitcroft				}
412800df344fSAndy Whitcroft			}
412900df344fSAndy Whitcroft			if ($err ne '') {
4130000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4131000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4132de7d4f0eSAndy Whitcroft			}
4133de7d4f0eSAndy Whitcroft		}
4134de7d4f0eSAndy Whitcroft
4135de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4136de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
41370fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4138773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4139773647a0SAndy Whitcroft
41409c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
41418eef05ddSJoe Perches
41428eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
41438eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
41448eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
41458eef05ddSJoe Perches			}
41468eef05ddSJoe Perches
4147de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4148de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4149de7d4f0eSAndy Whitcroft
4150548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4151548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4152de7d4f0eSAndy Whitcroft
4153548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4154548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4155548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4156548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4157548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4158773647a0SAndy Whitcroft				$ctx_ln++;
4159773647a0SAndy Whitcroft			}
4160548596d5SAndy Whitcroft
416153210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
416253210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4163773647a0SAndy Whitcroft
4164773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4165000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4166000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
416701464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
416800df344fSAndy Whitcroft			}
4169773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4170773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4171773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4172773647a0SAndy Whitcroft			{
41739c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
41749c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4175000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4176000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
417701464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
41789c0ca6f9SAndy Whitcroft				}
41799c0ca6f9SAndy Whitcroft			}
418000df344fSAndy Whitcroft		}
418100df344fSAndy Whitcroft
41824d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4183f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
41843e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
41853e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
41863e469cdcSAndy Whitcroft					if (!defined $stat);
41874d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
41884d001e4dSAndy Whitcroft
41894d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
41904d001e4dSAndy Whitcroft
41919f5af480SJoe Perches			# remove inline comments
41929f5af480SJoe Perches			$s =~ s/$;/ /g;
41939f5af480SJoe Perches			$c =~ s/$;/ /g;
41944d001e4dSAndy Whitcroft
41954d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
41966f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
41976f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
41984d001e4dSAndy Whitcroft
41999f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
42009f5af480SJoe Perches			# none on the first line, and are going to readd them
42019f5af480SJoe Perches			# where necessary.
42029f5af480SJoe Perches			$s =~ s/\n./\n/gs;
42039f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
42049f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
42059f5af480SJoe Perches			}
42069f5af480SJoe Perches
42074d001e4dSAndy Whitcroft			# We want to check the first line inside the block
42084d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
42094d001e4dSAndy Whitcroft			#  1) any blank line termination
42104d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
42114d001e4dSAndy Whitcroft			#  3) any do (...) {
42124d001e4dSAndy Whitcroft			my $continuation = 0;
42134d001e4dSAndy Whitcroft			my $check = 0;
42144d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
42154d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
42164d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
42174d001e4dSAndy Whitcroft				$continuation = 1;
42184d001e4dSAndy Whitcroft			}
42199bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
42204d001e4dSAndy Whitcroft				$check = 1;
42214d001e4dSAndy Whitcroft				$cond_lines++;
42224d001e4dSAndy Whitcroft			}
42234d001e4dSAndy Whitcroft
42244d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
42254d001e4dSAndy Whitcroft			# preprocessor statement.
42264d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
42274d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
42284d001e4dSAndy Whitcroft				$check = 0;
42294d001e4dSAndy Whitcroft			}
42304d001e4dSAndy Whitcroft
42319bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4232740504c6SAndy Whitcroft			$continuation = 0;
42339bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
42349bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
42354d001e4dSAndy Whitcroft
4236f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4237f16fa28fSAndy Whitcroft				# is not linear.
4238f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4239f16fa28fSAndy Whitcroft					$check = 0;
4240f16fa28fSAndy Whitcroft				}
4241f16fa28fSAndy Whitcroft
42429bd49efeSAndy Whitcroft				# Ignore:
42439bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
42449bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
42459bd49efeSAndy Whitcroft				#  3) labels.
4246740504c6SAndy Whitcroft				if ($continuation ||
4247740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
42489bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
42499bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4250740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
425130dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
42529bd49efeSAndy Whitcroft						$cond_lines++;
42539bd49efeSAndy Whitcroft					}
42544d001e4dSAndy Whitcroft				}
425530dad6ebSAndy Whitcroft			}
42564d001e4dSAndy Whitcroft
42574d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
42584d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
42594d001e4dSAndy Whitcroft
42604d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
42614d001e4dSAndy Whitcroft			# this is not this patch's fault.
42624d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
42634d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
42644d001e4dSAndy Whitcroft				$check = 0;
42654d001e4dSAndy Whitcroft			}
42664d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
42674d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
42684d001e4dSAndy Whitcroft			}
42694d001e4dSAndy Whitcroft
42709bd49efeSAndy 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";
42714d001e4dSAndy Whitcroft
42729f5af480SJoe Perches			if ($check && $s ne '' &&
4273713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
42749f5af480SJoe Perches			     ($sindent < $indent) ||
4275f6950a73SJoe Perches			     ($sindent == $indent &&
4276f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4277713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4278000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4279000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
42804d001e4dSAndy Whitcroft			}
42814d001e4dSAndy Whitcroft		}
42824d001e4dSAndy Whitcroft
42836c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
42846c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
42851f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
42861f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
42876c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4288c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4289c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4290cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4291cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
42921f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4293c2fdda0dSAndy Whitcroft		}
42946c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
42956c72ffaaSAndy Whitcroft
429600df344fSAndy Whitcroft#ignore lines not being added
42973705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
429800df344fSAndy Whitcroft
429999ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
430099ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
430199ca38c2SJoe Perches#	struct foo bar = *(&(bar));
430299ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
430399ca38c2SJoe Perches			my $var = $1;
430499ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
430599ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
430699ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
430799ca38c2SJoe Perches			}
430899ca38c2SJoe Perches		}
430999ca38c2SJoe Perches
431011ca40a0SJoe Perches# check for dereferences that span multiple lines
431111ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
431211ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
431311ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
431411ca40a0SJoe Perches			my $ref = $1;
431511ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
431611ca40a0SJoe Perches			$ref .= $1;
431711ca40a0SJoe Perches			$ref =~ s/\s//g;
431811ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
431911ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
432011ca40a0SJoe Perches		}
432111ca40a0SJoe Perches
4322a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4323c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4324a1ce18e4SJoe Perches			my $type = $1;
4325a1ce18e4SJoe Perches			my $var = $2;
4326207a8e84SJoe Perches			$var = "" if (!defined $var);
4327207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4328a1ce18e4SJoe Perches				my $sign = $1;
4329a1ce18e4SJoe Perches				my $pointer = $2;
4330a1ce18e4SJoe Perches
4331a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4332a1ce18e4SJoe Perches
4333a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4334a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4335a1ce18e4SJoe Perches				    $fix) {
4336a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4337207a8e84SJoe Perches					my $comp_pointer = $pointer;
4338207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4339207a8e84SJoe Perches					$decl .= $comp_pointer;
4340207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4341207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4342a1ce18e4SJoe Perches				}
4343a1ce18e4SJoe Perches			}
4344a1ce18e4SJoe Perches		}
4345a1ce18e4SJoe Perches
4346653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
43477429c690SAndy Whitcroft		if ($dbg_type) {
43487429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4349000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4350000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
43517429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4352000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4353000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
43547429c690SAndy Whitcroft			}
4355653d4876SAndy Whitcroft			next;
4356653d4876SAndy Whitcroft		}
4357a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4358a1ef277eSAndy Whitcroft		if ($dbg_attr) {
43599360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4360000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4361000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
43629360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4363000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4364000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4365a1ef277eSAndy Whitcroft			}
4366a1ef277eSAndy Whitcroft			next;
4367a1ef277eSAndy Whitcroft		}
4368653d4876SAndy Whitcroft
4369f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
437099423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
437199423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4372d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4373d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4374f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4375f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4376f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4377d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4378d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4379f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4380d752fcc8SJoe Perches				$fixedline = $line;
43818d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4382f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4383d752fcc8SJoe Perches			}
4384f0a594c1SAndy Whitcroft		}
4385f0a594c1SAndy Whitcroft
438600df344fSAndy Whitcroft#
438700df344fSAndy Whitcroft# Checks which are anchored on the added line.
438800df344fSAndy Whitcroft#
438900df344fSAndy Whitcroft
4390653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4391c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4392653d4876SAndy Whitcroft			my $path = $1;
4393653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4394000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4395495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4396495e9d84SJoe Perches			}
4397495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4398495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4399495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4400653d4876SAndy Whitcroft			}
4401653d4876SAndy Whitcroft		}
4402653d4876SAndy Whitcroft
440300df344fSAndy Whitcroft# no C99 // comments
440400df344fSAndy Whitcroft		if ($line =~ m{//}) {
44053705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
44063705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
44073705ce5bSJoe Perches			    $fix) {
4408194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
44093705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
44103705ce5bSJoe Perches					my $comment = trim($1);
4411194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
44123705ce5bSJoe Perches				}
44133705ce5bSJoe Perches			}
441400df344fSAndy Whitcroft		}
441500df344fSAndy Whitcroft		# Remove C99 comments.
44160a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
44176c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
44180a920b5bSAndy Whitcroft
44192b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
44202b474a1aSAndy Whitcroft# the whole statement.
44212b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
44222b474a1aSAndy Whitcroft		if (defined $realline_next &&
44232b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
44242b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
442536794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
44263cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
44273cbf62dfSAndy Whitcroft			# a prefix:
44283cbf62dfSAndy Whitcroft			#   XXX(foo);
44293cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4430653d4876SAndy Whitcroft			my $name = $1;
443187a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
44323cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
44333cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
44343cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
44353cbf62dfSAndy Whitcroft
44363cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
44372b474a1aSAndy Whitcroft				\n.}\s*$|
443848012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
443948012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
444048012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
44412b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
44422b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
444348012058SAndy Whitcroft			    )/x) {
44442b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
44452b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
44462b474a1aSAndy Whitcroft			} else {
44472b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
44480a920b5bSAndy Whitcroft			}
44490a920b5bSAndy Whitcroft		}
44502b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
44512b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
445236794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
44532b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
44542b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
44552b474a1aSAndy Whitcroft		}
44562b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
44572b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4458000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4459000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
44602b474a1aSAndy Whitcroft		}
44610a920b5bSAndy Whitcroft
44625150bda4SJoe Eloff# check for global initialisers.
44635b8f82e1SSong Liu		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
44645b8f82e1SSong Liu		    !exclude_global_initialisers($realfile)) {
4465d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
44666d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4467d5e616fcSJoe Perches			    $fix) {
44686d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4469d5e616fcSJoe Perches			}
4470f0a594c1SAndy Whitcroft		}
44710a920b5bSAndy Whitcroft# check for static initialisers.
44726d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4473d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
44746d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4475d5e616fcSJoe Perches				      $herecurr) &&
4476d5e616fcSJoe Perches			    $fix) {
44776d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4478d5e616fcSJoe Perches			}
44790a920b5bSAndy Whitcroft		}
44800a920b5bSAndy Whitcroft
44811813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
44821813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
44831813087dSJoe Perches			my $tmp = trim($1);
44841813087dSJoe Perches			WARN("MISORDERED_TYPE",
44851813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
44861813087dSJoe Perches		}
44871813087dSJoe Perches
4488809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4489809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4490809e082eSJoe Perches			my $type = trim($1);
4491809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4492809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4493809e082eSJoe Perches			my $new_type = $type;
4494809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4495809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4496809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4497809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4498809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4499809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4500809e082eSJoe Perches			$new_type = trim($new_type);
4501809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4502809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4503809e082eSJoe Perches			    $fix) {
4504809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4505809e082eSJoe Perches			}
4506809e082eSJoe Perches		}
4507809e082eSJoe Perches
4508cb710ecaSJoe Perches# check for static const char * arrays.
4509cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4510000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4511000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4512cb710ecaSJoe Perches				$herecurr);
4513cb710ecaSJoe Perches		}
4514cb710ecaSJoe Perches
451577b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
451677b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
451777b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
451877b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
451977b8c0a8SJoe Perches			    $fix) {
452077b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
452177b8c0a8SJoe Perches			}
452277b8c0a8SJoe Perches		}
452377b8c0a8SJoe Perches
4524cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4525cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4526000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4527000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4528cb710ecaSJoe Perches				$herecurr);
4529cb710ecaSJoe Perches		}
4530cb710ecaSJoe Perches
4531ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4532ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4533ab7e23f3SJoe Perches			my $found = $1;
4534ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4535ab7e23f3SJoe Perches				WARN("CONST_CONST",
4536ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4537ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4538ab7e23f3SJoe Perches				WARN("CONST_CONST",
4539ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4540ab7e23f3SJoe Perches			}
4541ab7e23f3SJoe Perches		}
4542ab7e23f3SJoe Perches
454373169765SJoe Perches# check for const static or static <non ptr type> const declarations
454473169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
454573169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
454673169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
454773169765SJoe Perches			if (WARN("STATIC_CONST",
454873169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
454973169765SJoe Perches			    $fix) {
455073169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
455173169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
455273169765SJoe Perches			}
455373169765SJoe Perches		}
455473169765SJoe Perches
45559b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
45569b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
45579b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
45589b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
45599b0fa60dSJoe Perches				$herecurr);
45609b0fa60dSJoe Perches		}
45619b0fa60dSJoe Perches
4562b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4563b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4564b598b670SJoe Perches			my $array = $1;
4565b598b670SJoe 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*\))@) {
4566b598b670SJoe Perches				my $array_div = $1;
4567b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4568b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4569b598b670SJoe Perches				    $fix) {
4570b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4571b598b670SJoe Perches				}
4572b598b670SJoe Perches			}
4573b598b670SJoe Perches		}
4574b598b670SJoe Perches
4575b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
457616b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4577b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4578b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4579b36190c5SJoe Perches			    $fix) {
4580194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4581b36190c5SJoe Perches			}
4582b36190c5SJoe Perches		}
4583b36190c5SJoe Perches
4584653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4585653d4876SAndy Whitcroft# make sense.
4586653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
45878054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4588c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
45898ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
459046d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4591000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4592000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
45930a920b5bSAndy Whitcroft		}
45940a920b5bSAndy Whitcroft
45950a920b5bSAndy Whitcroft# * goes on variable not on type
459665863862SAndy Whitcroft		# (char*[ const])
4597bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4598bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
45993705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4600d8aaf121SAndy Whitcroft
460165863862SAndy Whitcroft			# Should start with a space.
460265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
460365863862SAndy Whitcroft			# Should not end with a space.
460465863862SAndy Whitcroft			$to =~ s/\s+$//;
460565863862SAndy Whitcroft			# '*'s should not have spaces between.
4606f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
460765863862SAndy Whitcroft			}
4608d8aaf121SAndy Whitcroft
46093705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
461065863862SAndy Whitcroft			if ($from ne $to) {
46113705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
46123705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
46133705ce5bSJoe Perches				    $fix) {
46143705ce5bSJoe Perches					my $sub_from = $ident;
46153705ce5bSJoe Perches					my $sub_to = $ident;
46163705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4617194f66fcSJoe Perches					$fixed[$fixlinenr] =~
46183705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
46193705ce5bSJoe Perches				}
462065863862SAndy Whitcroft			}
4621bfcb2cc7SAndy Whitcroft		}
4622bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4623bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
46243705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4625d8aaf121SAndy Whitcroft
462665863862SAndy Whitcroft			# Should start with a space.
462765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
462865863862SAndy Whitcroft			# Should not end with a space.
462965863862SAndy Whitcroft			$to =~ s/\s+$//;
463065863862SAndy Whitcroft			# '*'s should not have spaces between.
4631f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
463265863862SAndy Whitcroft			}
463365863862SAndy Whitcroft			# Modifiers should have spaces.
463465863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
463565863862SAndy Whitcroft
46363705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4637667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
46383705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
46393705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
46403705ce5bSJoe Perches				    $fix) {
46413705ce5bSJoe Perches
46423705ce5bSJoe Perches					my $sub_from = $match;
46433705ce5bSJoe Perches					my $sub_to = $match;
46443705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4645194f66fcSJoe Perches					$fixed[$fixlinenr] =~
46463705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
46473705ce5bSJoe Perches				}
464865863862SAndy Whitcroft			}
46490a920b5bSAndy Whitcroft		}
46500a920b5bSAndy Whitcroft
46519d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
46529d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
46530675a8fbSJean Delvare			my $msg_level = \&WARN;
46540675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
46550675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
46569d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
46579d3e3c70SJoe Perches		}
46580a920b5bSAndy Whitcroft
46599d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
46608905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4661000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4662000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
46638905a67cSAndy Whitcroft		}
46648905a67cSAndy Whitcroft
466517441227SJoe Perches# check for uses of printk_ratelimit
466617441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4667000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4668000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
466917441227SJoe Perches		}
467017441227SJoe Perches
4671eeef5733SJoe Perches# printk should use KERN_* levels
4672eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4673000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4674eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
467500df344fSAndy Whitcroft		}
46760a920b5bSAndy Whitcroft
4677f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4678f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4679f5eea3b0SJoe Perches			my $printk = $1;
4680f5eea3b0SJoe Perches			my $modifier = $2;
4681f5eea3b0SJoe Perches			my $orig = $3;
4682f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4683243f3803SJoe Perches			my $level = lc($orig);
4684243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
46858f26b837SJoe Perches			my $level2 = $level;
46868f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4687f5eea3b0SJoe Perches			$level .= $modifier;
4688f5eea3b0SJoe Perches			$level2 .= $modifier;
4689243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4690f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4691243f3803SJoe Perches		}
4692243f3803SJoe Perches
4693f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4694dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4695dc139313SJoe Perches			my $orig = $1;
4696dc139313SJoe Perches			my $level = lc($orig);
4697dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4698dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4699dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4700dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4701dc139313SJoe Perches		}
4702dc139313SJoe Perches
47038020b253SNicolas Boichat# trace_printk should not be used in production code.
47048020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
47058020b253SNicolas Boichat			WARN("TRACE_PRINTK",
47068020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
47078020b253SNicolas Boichat		}
47088020b253SNicolas Boichat
470991c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
471091c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
471191c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
471291c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
471391c9afafSAndy Lutomirski			WARN("ENOSYS",
471491c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
471591c9afafSAndy Lutomirski		}
471691c9afafSAndy Lutomirski
47176b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
47186b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
47196b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
47206b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
47216b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
47226b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
47236b9ea5ffSJakub Kicinski			    $fix) {
47246b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
47256b9ea5ffSJakub Kicinski			}
47266b9ea5ffSJakub Kicinski		}
47276b9ea5ffSJakub Kicinski
4728653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4729653d4876SAndy Whitcroft# or if closed on same line
47305b57980dSJoe Perches		if ($perl_version_ok &&
47312d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
47322d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
47332d453e3bSJoe Perches		    $sline !~ /}/) {
47348d182478SJoe Perches			if (ERROR("OPEN_BRACE",
47352d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
47368d182478SJoe Perches			    $fix) {
47378d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
47388d182478SJoe Perches				my $fixed_line = $rawline;
473903f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
47408d182478SJoe Perches				my $line1 = $1;
47418d182478SJoe Perches				my $line2 = $2;
47428d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
47438d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
47448d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
47458d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
47468d182478SJoe Perches				}
47478d182478SJoe Perches			}
47480a920b5bSAndy Whitcroft		}
4749653d4876SAndy Whitcroft
47508905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
47518905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
47528905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
47538d182478SJoe Perches			if (ERROR("OPEN_BRACE",
47548d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
47558d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
47568d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
47578d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
47588d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
47598d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
47608d182478SJoe Perches				$fixedline = $rawline;
47618d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
47628d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
47638d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47648d182478SJoe Perches				}
47658d182478SJoe Perches			}
47668905a67cSAndy Whitcroft		}
47678905a67cSAndy Whitcroft
47680c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
47693705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
47703705ce5bSJoe Perches			if (WARN("SPACING",
47713705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
47723705ce5bSJoe Perches			    $fix) {
4773194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47743705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
47753705ce5bSJoe Perches			}
47760c73b4ebSAndy Whitcroft		}
47770c73b4ebSAndy Whitcroft
477831070b5dSJoe Perches# Function pointer declarations
477931070b5dSJoe Perches# check spacing between type, funcptr, and args
478031070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
478191f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
478231070b5dSJoe Perches			my $declare = $1;
478331070b5dSJoe Perches			my $pre_pointer_space = $2;
478431070b5dSJoe Perches			my $post_pointer_space = $3;
478531070b5dSJoe Perches			my $funcname = $4;
478631070b5dSJoe Perches			my $post_funcname_space = $5;
478731070b5dSJoe Perches			my $pre_args_space = $6;
478831070b5dSJoe Perches
478991f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
479091f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
479191f72e9cSJoe Perches# don't need a space so don't warn for those.
479291f72e9cSJoe Perches			my $post_declare_space = "";
479391f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
479491f72e9cSJoe Perches				$post_declare_space = $1;
479591f72e9cSJoe Perches				$declare = rtrim($declare);
479691f72e9cSJoe Perches			}
479791f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
479831070b5dSJoe Perches				WARN("SPACING",
479931070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
480091f72e9cSJoe Perches				$post_declare_space = " ";
480131070b5dSJoe Perches			}
480231070b5dSJoe Perches
480331070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
480491f72e9cSJoe Perches# This test is not currently implemented because these declarations are
480591f72e9cSJoe Perches# equivalent to
480691f72e9cSJoe Perches#	int  foo(int bar, ...)
480791f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
480891f72e9cSJoe Perches#
480991f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
481091f72e9cSJoe Perches#				WARN("SPACING",
481191f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
481291f72e9cSJoe Perches#			}
481331070b5dSJoe Perches
481431070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
481531070b5dSJoe Perches			if (defined $pre_pointer_space &&
481631070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
481731070b5dSJoe Perches				WARN("SPACING",
481831070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
481931070b5dSJoe Perches			}
482031070b5dSJoe Perches
482131070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
482231070b5dSJoe Perches			if (defined $post_pointer_space &&
482331070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
482431070b5dSJoe Perches				WARN("SPACING",
482531070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
482631070b5dSJoe Perches			}
482731070b5dSJoe Perches
482831070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
482931070b5dSJoe Perches			if (defined $post_funcname_space &&
483031070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
483131070b5dSJoe Perches				WARN("SPACING",
483231070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
483331070b5dSJoe Perches			}
483431070b5dSJoe Perches
483531070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
483631070b5dSJoe Perches			if (defined $pre_args_space &&
483731070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
483831070b5dSJoe Perches				WARN("SPACING",
483931070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
484031070b5dSJoe Perches			}
484131070b5dSJoe Perches
484231070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4843194f66fcSJoe Perches				$fixed[$fixlinenr] =~
484491f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
484531070b5dSJoe Perches			}
484631070b5dSJoe Perches		}
484731070b5dSJoe Perches
48488d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
48498d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4850fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4851fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
48528d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
48538d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
48548d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4855fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
485638dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
48573705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
48583705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
48593705ce5bSJoe Perches				    $fix) {
4860194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
48613705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
48623705ce5bSJoe Perches				}
48638d31cfceSAndy Whitcroft			}
48648d31cfceSAndy Whitcroft		}
48658d31cfceSAndy Whitcroft
4866f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
48676c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4868c2fdda0dSAndy Whitcroft			my $name = $1;
4869773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4870773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4871c2fdda0dSAndy Whitcroft
4872c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4873773647a0SAndy Whitcroft			if ($name =~ /^(?:
4874773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4875773647a0SAndy Whitcroft				volatile|__volatile__|
4876773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4877773647a0SAndy Whitcroft				asm|__asm__)$/x)
4878773647a0SAndy Whitcroft			{
4879c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4880c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4881c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4882c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4883773647a0SAndy Whitcroft
4884773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4885c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4886c2fdda0dSAndy Whitcroft
4887c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4888c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4889773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4890c2fdda0dSAndy Whitcroft
4891c2fdda0dSAndy Whitcroft			} else {
48923705ce5bSJoe Perches				if (WARN("SPACING",
48933705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
48943705ce5bSJoe Perches					     $fix) {
4895194f66fcSJoe Perches					$fixed[$fixlinenr] =~
48963705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
48973705ce5bSJoe Perches				}
4898f0a594c1SAndy Whitcroft			}
48996c72ffaaSAndy Whitcroft		}
49009a4cad4eSEric Nelson
4901653d4876SAndy Whitcroft# Check operator spacing.
49020a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
49033705ce5bSJoe Perches			my $fixed_line = "";
49043705ce5bSJoe Perches			my $line_fixed = 0;
49053705ce5bSJoe Perches
49069c0ca6f9SAndy Whitcroft			my $ops = qr{
49079c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
49089c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
49099c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
49101f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
491184731623SJoe Perches				\?:|\?|:
49129c0ca6f9SAndy Whitcroft			}x;
4913cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
49143705ce5bSJoe Perches
49153705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
49163705ce5bSJoe Perches##			foreach my $el (@elements) {
49173705ce5bSJoe Perches##				print("el: <$el>\n");
49183705ce5bSJoe Perches##			}
49193705ce5bSJoe Perches
49203705ce5bSJoe Perches			my @fix_elements = ();
492100df344fSAndy Whitcroft			my $off = 0;
49226c72ffaaSAndy Whitcroft
49233705ce5bSJoe Perches			foreach my $el (@elements) {
49243705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
49253705ce5bSJoe Perches				$off += length($el);
49263705ce5bSJoe Perches			}
49273705ce5bSJoe Perches
49283705ce5bSJoe Perches			$off = 0;
49293705ce5bSJoe Perches
49306c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4931b34c648bSJoe Perches			my $last_after = -1;
49326c72ffaaSAndy Whitcroft
49330a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
49343705ce5bSJoe Perches
49353705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
49363705ce5bSJoe Perches
49373705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
49383705ce5bSJoe Perches
49394a0df2efSAndy Whitcroft				$off += length($elements[$n]);
49404a0df2efSAndy Whitcroft
494125985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4942773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4943773647a0SAndy Whitcroft				my $cc = '';
4944773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4945773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4946773647a0SAndy Whitcroft				}
4947773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4948773647a0SAndy Whitcroft
49494a0df2efSAndy Whitcroft				my $a = '';
49504a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
49514a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4952cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
49534a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
49544a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4955773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
49564a0df2efSAndy Whitcroft
49570a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
49584a0df2efSAndy Whitcroft
49594a0df2efSAndy Whitcroft				my $c = '';
49600a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
49614a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
49624a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4963cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
49644a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
49654a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
49668b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
49674a0df2efSAndy Whitcroft				} else {
49684a0df2efSAndy Whitcroft					$c = 'E';
49690a920b5bSAndy Whitcroft				}
49700a920b5bSAndy Whitcroft
49714a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
49724a0df2efSAndy Whitcroft
49734a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
49744a0df2efSAndy Whitcroft
49756c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4976de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
49770a920b5bSAndy Whitcroft
497874048ed8SAndy Whitcroft				# Pull out the value of this operator.
49796c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
49800a920b5bSAndy Whitcroft
49811f65f947SAndy Whitcroft				# Get the full operator variant.
49821f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
49831f65f947SAndy Whitcroft
498413214adfSAndy Whitcroft				# Ignore operators passed as parameters.
498513214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4986d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
498713214adfSAndy Whitcroft
4988cf655043SAndy Whitcroft#				# Ignore comments
4989cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
499013214adfSAndy Whitcroft
4991d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
499213214adfSAndy Whitcroft				} elsif ($op eq ';') {
4993cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4994cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
49953705ce5bSJoe Perches						if (ERROR("SPACING",
49963705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4997b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
49983705ce5bSJoe Perches							$line_fixed = 1;
49993705ce5bSJoe Perches						}
5000d8aaf121SAndy Whitcroft					}
5001d8aaf121SAndy Whitcroft
5002d8aaf121SAndy Whitcroft				# // is a comment
5003d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
50040a920b5bSAndy Whitcroft
5005b00e4814SJoe Perches				#   :   when part of a bitfield
5006b00e4814SJoe Perches				} elsif ($opv eq ':B') {
5007b00e4814SJoe Perches					# skip the bitfield test for now
5008b00e4814SJoe Perches
50091f65f947SAndy Whitcroft				# No spaces for:
50101f65f947SAndy Whitcroft				#   ->
5011b00e4814SJoe Perches				} elsif ($op eq '->') {
50124a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
50133705ce5bSJoe Perches						if (ERROR("SPACING",
50143705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5015b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50163705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
50173705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
50183705ce5bSJoe Perches							}
5019b34c648bSJoe Perches							$line_fixed = 1;
50203705ce5bSJoe Perches						}
50210a920b5bSAndy Whitcroft					}
50220a920b5bSAndy Whitcroft
50232381097bSJoe Perches				# , must not have a space before and must have a space on the right.
50240a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
50252381097bSJoe Perches					my $rtrim_before = 0;
50262381097bSJoe Perches					my $space_after = 0;
50272381097bSJoe Perches					if ($ctx =~ /Wx./) {
50282381097bSJoe Perches						if (ERROR("SPACING",
50292381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
50302381097bSJoe Perches							$line_fixed = 1;
50312381097bSJoe Perches							$rtrim_before = 1;
50322381097bSJoe Perches						}
50332381097bSJoe Perches					}
5034cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
50353705ce5bSJoe Perches						if (ERROR("SPACING",
50363705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
50373705ce5bSJoe Perches							$line_fixed = 1;
5038b34c648bSJoe Perches							$last_after = $n;
50392381097bSJoe Perches							$space_after = 1;
50402381097bSJoe Perches						}
50412381097bSJoe Perches					}
50422381097bSJoe Perches					if ($rtrim_before || $space_after) {
50432381097bSJoe Perches						if ($rtrim_before) {
50442381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50452381097bSJoe Perches						} else {
50462381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
50472381097bSJoe Perches						}
50482381097bSJoe Perches						if ($space_after) {
50492381097bSJoe Perches							$good .= " ";
50503705ce5bSJoe Perches						}
50510a920b5bSAndy Whitcroft					}
50520a920b5bSAndy Whitcroft
50539c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
505474048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
50559c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
50569c0ca6f9SAndy Whitcroft
50579c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
50589c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
50599c0ca6f9SAndy Whitcroft				# unary operator, or a cast
50609c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
506174048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
50620d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
5063cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
50643705ce5bSJoe Perches						if (ERROR("SPACING",
50653705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
5066b34c648bSJoe Perches							if ($n != $last_after + 2) {
5067b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
50683705ce5bSJoe Perches								$line_fixed = 1;
50693705ce5bSJoe Perches							}
50700a920b5bSAndy Whitcroft						}
5071b34c648bSJoe Perches					}
5072a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
5073171ae1a4SAndy Whitcroft						# A unary '*' may be const
5074171ae1a4SAndy Whitcroft
5075171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
50763705ce5bSJoe Perches						if (ERROR("SPACING",
50773705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5078b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
50793705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
50803705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
50813705ce5bSJoe Perches							}
5082b34c648bSJoe Perches							$line_fixed = 1;
50833705ce5bSJoe Perches						}
50840a920b5bSAndy Whitcroft					}
50850a920b5bSAndy Whitcroft
50860a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
50870a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
5088773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
50893705ce5bSJoe Perches						if (ERROR("SPACING",
50903705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
5091b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
50923705ce5bSJoe Perches							$line_fixed = 1;
50933705ce5bSJoe Perches						}
50940a920b5bSAndy Whitcroft					}
5095773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
5096773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
50973705ce5bSJoe Perches						if (ERROR("SPACING",
50983705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5099b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51003705ce5bSJoe Perches							$line_fixed = 1;
51013705ce5bSJoe Perches						}
5102653d4876SAndy Whitcroft					}
5103773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
51043705ce5bSJoe Perches						if (ERROR("SPACING",
51053705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5106b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
51073705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51083705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5109773647a0SAndy Whitcroft							}
5110b34c648bSJoe Perches							$line_fixed = 1;
51113705ce5bSJoe Perches						}
51123705ce5bSJoe Perches					}
51130a920b5bSAndy Whitcroft
51140a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
51159c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
51169c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
51179c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5118c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5119c2fdda0dSAndy Whitcroft					 $op eq '%')
51200a920b5bSAndy Whitcroft				{
5121d2e025f3SJoe Perches					if ($check) {
5122d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5123d2e025f3SJoe Perches							if (CHK("SPACING",
5124d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5125d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5126d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5127d2e025f3SJoe Perches								$line_fixed = 1;
5128d2e025f3SJoe Perches							}
5129d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5130d2e025f3SJoe Perches							if (CHK("SPACING",
5131d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5132d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5133d2e025f3SJoe Perches								$line_fixed = 1;
5134d2e025f3SJoe Perches							}
5135d2e025f3SJoe Perches						}
5136d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
51373705ce5bSJoe Perches						if (ERROR("SPACING",
51383705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5139b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5140b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5141b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5142b34c648bSJoe Perches							}
51433705ce5bSJoe Perches							$line_fixed = 1;
51443705ce5bSJoe Perches						}
51450a920b5bSAndy Whitcroft					}
51460a920b5bSAndy Whitcroft
51471f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
51481f65f947SAndy Whitcroft				# terminating a case value or a label.
51491f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
5150263afd39SChris Down					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
51513705ce5bSJoe Perches						if (ERROR("SPACING",
51523705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5153b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51543705ce5bSJoe Perches							$line_fixed = 1;
51553705ce5bSJoe Perches						}
51561f65f947SAndy Whitcroft					}
51571f65f947SAndy Whitcroft
51580a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5159cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
51601f65f947SAndy Whitcroft					my $ok = 0;
51611f65f947SAndy Whitcroft
516222f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
51631f65f947SAndy Whitcroft					if (($op eq '<' &&
51641f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
51651f65f947SAndy Whitcroft					    ($op eq '>' &&
51661f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
51671f65f947SAndy Whitcroft					{
51681f65f947SAndy Whitcroft						$ok = 1;
51691f65f947SAndy Whitcroft					}
51701f65f947SAndy Whitcroft
5171e0df7e1fSJoe Perches					# for asm volatile statements
5172e0df7e1fSJoe Perches					# ignore a colon with another
5173e0df7e1fSJoe Perches					# colon immediately before or after
5174e0df7e1fSJoe Perches					if (($op eq ':') &&
5175e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5176e0df7e1fSJoe Perches						$ok = 1;
5177e0df7e1fSJoe Perches					}
5178e0df7e1fSJoe Perches
517984731623SJoe Perches					# messages are ERROR, but ?: are CHK
51801f65f947SAndy Whitcroft					if ($ok == 0) {
51810675a8fbSJean Delvare						my $msg_level = \&ERROR;
51820675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
518384731623SJoe Perches
51840675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
51853705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5186b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5187b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5188b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5189b34c648bSJoe Perches							}
51903705ce5bSJoe Perches							$line_fixed = 1;
51913705ce5bSJoe Perches						}
51920a920b5bSAndy Whitcroft					}
519322f2a2efSAndy Whitcroft				}
51944a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
51953705ce5bSJoe Perches
51963705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
51973705ce5bSJoe Perches
51983705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
51990a920b5bSAndy Whitcroft			}
52003705ce5bSJoe Perches
52013705ce5bSJoe Perches			if (($#elements % 2) == 0) {
52023705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
52033705ce5bSJoe Perches			}
52043705ce5bSJoe Perches
5205194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5206194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
52073705ce5bSJoe Perches			}
52083705ce5bSJoe Perches
52093705ce5bSJoe Perches
52100a920b5bSAndy Whitcroft		}
52110a920b5bSAndy Whitcroft
5212786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5213d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5214786b6326SJoe Perches			if (WARN("SPACING",
5215786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5216786b6326SJoe Perches			    $fix) {
5217194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5218786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5219786b6326SJoe Perches			}
5220786b6326SJoe Perches		}
5221786b6326SJoe Perches
5222f0a594c1SAndy Whitcroft# check for multiple assignments
5223f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5224000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5225000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5226f0a594c1SAndy Whitcroft		}
5227f0a594c1SAndy Whitcroft
522822f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
522922f2a2efSAndy Whitcroft## # continuation.
523022f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
523122f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
523222f2a2efSAndy Whitcroft##
523322f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5234e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
523522f2a2efSAndy Whitcroft## 			my $ln = $line;
523622f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
523722f2a2efSAndy Whitcroft## 			}
523822f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5239000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5240000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
524122f2a2efSAndy Whitcroft## 			}
524222f2a2efSAndy Whitcroft## 		}
5243f0a594c1SAndy Whitcroft
52440a920b5bSAndy Whitcroft#need space before brace following if, while, etc
52456b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
52466ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
52473705ce5bSJoe Perches			if (ERROR("SPACING",
52483705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
52493705ce5bSJoe Perches			    $fix) {
52506ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
52513705ce5bSJoe Perches			}
5252de7d4f0eSAndy Whitcroft		}
5253de7d4f0eSAndy Whitcroft
5254c4a62ef9SJoe Perches## # check for blank lines before declarations
5255c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5256c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5257c4a62ef9SJoe Perches##			WARN("SPACING",
5258c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5259c4a62ef9SJoe Perches##		}
5260c4a62ef9SJoe Perches##
5261c4a62ef9SJoe Perches
5262de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5263de7d4f0eSAndy Whitcroft# on the line
526494fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5265d5e616fcSJoe Perches			if (ERROR("SPACING",
5266d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5267d5e616fcSJoe Perches			    $fix) {
5268194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5269d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5270d5e616fcSJoe Perches			}
52710a920b5bSAndy Whitcroft		}
52720a920b5bSAndy Whitcroft
527322f2a2efSAndy Whitcroft# check spacing on square brackets
527422f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
52753705ce5bSJoe Perches			if (ERROR("SPACING",
52763705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
52773705ce5bSJoe Perches			    $fix) {
5278194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52793705ce5bSJoe Perches				    s/\[\s+/\[/;
52803705ce5bSJoe Perches			}
528122f2a2efSAndy Whitcroft		}
528222f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
52833705ce5bSJoe Perches			if (ERROR("SPACING",
52843705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
52853705ce5bSJoe Perches			    $fix) {
5286194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52873705ce5bSJoe Perches				    s/\s+\]/\]/;
52883705ce5bSJoe Perches			}
528922f2a2efSAndy Whitcroft		}
529022f2a2efSAndy Whitcroft
5291c45dcabdSAndy Whitcroft# check spacing on parentheses
52929c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
52939c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
52943705ce5bSJoe Perches			if (ERROR("SPACING",
52953705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
52963705ce5bSJoe Perches			    $fix) {
5297194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52983705ce5bSJoe Perches				    s/\(\s+/\(/;
52993705ce5bSJoe Perches			}
530022f2a2efSAndy Whitcroft		}
530113214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5302c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5303c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
53043705ce5bSJoe Perches			if (ERROR("SPACING",
53053705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
53063705ce5bSJoe Perches			    $fix) {
5307194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53083705ce5bSJoe Perches				    s/\s+\)/\)/;
53093705ce5bSJoe Perches			}
531022f2a2efSAndy Whitcroft		}
531122f2a2efSAndy Whitcroft
5312e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5313e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5314e2826fd0SJoe Perches
5315e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5316ea4acbb1SJoe Perches			my $var = $1;
5317ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5318ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5319ea4acbb1SJoe Perches			    $fix) {
5320ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5321ea4acbb1SJoe Perches			}
5322ea4acbb1SJoe Perches		}
5323ea4acbb1SJoe Perches
5324ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5325ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5326ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5327ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5328ea4acbb1SJoe Perches			my $var = $2;
5329ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5330ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5331ea4acbb1SJoe Perches			    $fix) {
5332ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5333ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5334ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5335ea4acbb1SJoe Perches			}
5336e2826fd0SJoe Perches		}
5337e2826fd0SJoe Perches
533863b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5339a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5340a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
53415b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
534263b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
534363b7c73eSJoe Perches			my $if_stat = $1;
534463b7c73eSJoe Perches			my $test = substr($2, 1, -1);
534563b7c73eSJoe Perches			my $herectx;
534663b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
534763b7c73eSJoe Perches				my $match = $1;
534863b7c73eSJoe Perches				# avoid parentheses around potential macro args
534963b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
535063b7c73eSJoe Perches				if (!defined($herectx)) {
535163b7c73eSJoe Perches					$herectx = $here . "\n";
535263b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
535363b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
535463b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
535563b7c73eSJoe Perches						$herectx .=  $rl . "\n";
535663b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
535763b7c73eSJoe Perches					}
535863b7c73eSJoe Perches				}
535963b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
536063b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
536163b7c73eSJoe Perches			}
536263b7c73eSJoe Perches		}
536363b7c73eSJoe Perches
536469078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation)
536569078651SJoe Perches# and ignore bitfield definitions like foo:1
536669078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the :
536769078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels
536869078651SJoe Perches		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
536969078651SJoe Perches		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
537069078651SJoe Perches		    $sline !~ /^.\s+default:/) {
53713705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
53723705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
53733705ce5bSJoe Perches			    $fix) {
5374194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53753705ce5bSJoe Perches				    s/^(.)\s+/$1/;
53763705ce5bSJoe Perches			}
53770a920b5bSAndy Whitcroft		}
53780a920b5bSAndy Whitcroft
537940873abaSJoe Perches# check if a statement with a comma should be two statements like:
538040873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
538140873abaSJoe Perches#	bar = baz();
538240873abaSJoe Perches		if (defined($stat) &&
538340873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
538440873abaSJoe Perches			my $cnt = statement_rawlines($stat);
538540873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
538640873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
538740873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
538840873abaSJoe Perches		}
538940873abaSJoe Perches
53905b9553abSJoe Perches# return is not a function
5391507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5392c45dcabdSAndy Whitcroft			my $spacing = $1;
53935b57980dSJoe Perches			if ($perl_version_ok &&
53945b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
53955b9553abSJoe Perches				my $value = $1;
53965b9553abSJoe Perches				$value = deparenthesize($value);
53975b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5398000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5399000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
54005b9553abSJoe Perches				}
5401c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5402000d1cc1SJoe Perches				ERROR("SPACING",
5403000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5404c45dcabdSAndy Whitcroft			}
5405c45dcabdSAndy Whitcroft		}
5406507e5141SJoe Perches
5407b43ae21bSJoe Perches# unnecessary return in a void function
5408b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5409b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5410b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5411b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5412b43ae21bSJoe Perches		    $linenr >= 3 &&
5413b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5414b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
54159819cf25SJoe Perches			WARN("RETURN_VOID",
5416b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
54179819cf25SJoe Perches		}
54189819cf25SJoe Perches
5419189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
54205b57980dSJoe Perches		if ($perl_version_ok &&
5421189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5422189248d8SJoe Perches			my $openparens = $1;
5423189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5424189248d8SJoe Perches			my $msg = "";
5425189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5426189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5427189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5428189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5429189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5430189248d8SJoe Perches			}
5431189248d8SJoe Perches		}
5432189248d8SJoe Perches
5433c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5434c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5435c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5436c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
54375b57980dSJoe Perches		if ($perl_version_ok &&
5438c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5439c5595fa2SJoe Perches			my $lead = $1;
5440c5595fa2SJoe Perches			my $const = $2;
5441c5595fa2SJoe Perches			my $comp = $3;
5442c5595fa2SJoe Perches			my $to = $4;
5443c5595fa2SJoe Perches			my $newcomp = $comp;
5444f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5445c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5446c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5447c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5448c5595fa2SJoe Perches			    $fix) {
5449c5595fa2SJoe Perches				if ($comp eq "<") {
5450c5595fa2SJoe Perches					$newcomp = ">";
5451c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5452c5595fa2SJoe Perches					$newcomp = ">=";
5453c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5454c5595fa2SJoe Perches					$newcomp = "<";
5455c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5456c5595fa2SJoe Perches					$newcomp = "<=";
5457c5595fa2SJoe Perches				}
5458c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5459c5595fa2SJoe Perches			}
5460c5595fa2SJoe Perches		}
5461c5595fa2SJoe Perches
5462f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5463f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
546453a3c448SAndy Whitcroft			my $name = $1;
546546b85bf9SGuenter Roeck			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5466000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5467f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
546853a3c448SAndy Whitcroft			}
546953a3c448SAndy Whitcroft		}
5470c45dcabdSAndy Whitcroft
54710a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
54724a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
54733705ce5bSJoe Perches			if (ERROR("SPACING",
54743705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
54753705ce5bSJoe Perches			    $fix) {
5476194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54773705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
54783705ce5bSJoe Perches			}
54790a920b5bSAndy Whitcroft		}
54800a920b5bSAndy Whitcroft
5481f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5482f5fe35ddSAndy Whitcroft# statements after the conditional.
5483170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
54843e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
54853e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
54863e469cdcSAndy Whitcroft					if (!defined $stat);
5487170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5488170d3a22SAndy Whitcroft						$remain_next, $off_next);
5489170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5490170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5491170d3a22SAndy Whitcroft
5492170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5493170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5494170d3a22SAndy Whitcroft				# then count those as offsets.
5495170d3a22SAndy Whitcroft				my ($whitespace) =
5496170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5497170d3a22SAndy Whitcroft				my $offset =
5498170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5499170d3a22SAndy Whitcroft
5500170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5501170d3a22SAndy Whitcroft								$offset} = 1;
5502170d3a22SAndy Whitcroft			}
5503170d3a22SAndy Whitcroft		}
5504170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5505c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5506170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5507171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
55088905a67cSAndy Whitcroft
5509b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
551065b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
551165b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
551265b64b3bSJoe Perches				    $fix && $perl_version_ok) {
551365b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
551465b64b3bSJoe Perches						my $space = $1;
551565b64b3bSJoe Perches						my $not = $2;
551665b64b3bSJoe Perches						my $statement = $3;
551765b64b3bSJoe Perches						my $assigned = $4;
551865b64b3bSJoe Perches						my $test = $8;
551965b64b3bSJoe Perches						my $against = $9;
552065b64b3bSJoe Perches						my $brace = $15;
552165b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
552265b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
552365b64b3bSJoe Perches						my $newline = "${space}if (";
552465b64b3bSJoe Perches						$newline .= '!' if defined($not);
552565b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
552665b64b3bSJoe Perches						$newline .= "$assigned";
552765b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
552865b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
552965b64b3bSJoe Perches						$newline .= ')';
553065b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
553165b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
553265b64b3bSJoe Perches					}
553365b64b3bSJoe Perches				}
55348905a67cSAndy Whitcroft			}
55358905a67cSAndy Whitcroft
55368905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
55378905a67cSAndy Whitcroft			# conditional.
5538773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
55398905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
554013214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
554153210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
554253210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5543773647a0SAndy Whitcroft			{
5544bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5545bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5546bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
554742bdf74cSHidetoshi Seto				my $stat_real = '';
5548bb44ad39SAndy Whitcroft
554942bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
555042bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5551bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5552bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5553bb44ad39SAndy Whitcroft				}
5554bb44ad39SAndy Whitcroft
5555000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5556000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
55578905a67cSAndy Whitcroft			}
55588905a67cSAndy Whitcroft		}
55598905a67cSAndy Whitcroft
556013214adfSAndy Whitcroft# Check for bitwise tests written as boolean
556113214adfSAndy Whitcroft		if ($line =~ /
556213214adfSAndy Whitcroft			(?:
556313214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
556413214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
556513214adfSAndy Whitcroft				(?:\&\&|\|\|)
556613214adfSAndy Whitcroft			|
556713214adfSAndy Whitcroft				(?:\&\&|\|\|)
556813214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
556913214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
557013214adfSAndy Whitcroft			)/x)
557113214adfSAndy Whitcroft		{
5572000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5573000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
557413214adfSAndy Whitcroft		}
557513214adfSAndy Whitcroft
55768905a67cSAndy Whitcroft# if and else should not have general statements after it
557713214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
557813214adfSAndy Whitcroft			my $s = $1;
557913214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
558013214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5581000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5582000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
55830a920b5bSAndy Whitcroft			}
558413214adfSAndy Whitcroft		}
558539667782SAndy Whitcroft# if should not continue a brace
558639667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5587000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5588048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
558939667782SAndy Whitcroft				$herecurr);
559039667782SAndy Whitcroft		}
5591a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5592a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5593a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
55943fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5595a1080bf8SAndy Whitcroft			\s*return\s+
5596a1080bf8SAndy Whitcroft		    )/xg)
5597a1080bf8SAndy Whitcroft		{
5598000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5599000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5600a1080bf8SAndy Whitcroft		}
56010a920b5bSAndy Whitcroft
56020a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
56030a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
56048b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
56050a920b5bSAndy Whitcroft		    $previndent == $indent) {
56068b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
56078b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
56088b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
56098b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
56108b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
56118b8856f4SJoe Perches				my $fixedline = $prevrawline;
56128b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
56138b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
56148b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
56158b8856f4SJoe Perches				}
56168b8856f4SJoe Perches				$fixedline = $rawline;
56178b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
56188b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
56198b8856f4SJoe Perches			}
56200a920b5bSAndy Whitcroft		}
56210a920b5bSAndy Whitcroft
56228b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5623c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5624c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5625c2fdda0dSAndy Whitcroft
5626c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5627c2fdda0dSAndy Whitcroft			# conditional.
5628773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5629c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5630c2fdda0dSAndy Whitcroft
5631c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
56328b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
56338b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
56348b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
56358b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
56368b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
56378b8856f4SJoe Perches					my $fixedline = $prevrawline;
56388b8856f4SJoe Perches					my $trailing = $rawline;
56398b8856f4SJoe Perches					$trailing =~ s/^\+//;
56408b8856f4SJoe Perches					$trailing = trim($trailing);
56418b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
56428b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
56438b8856f4SJoe Perches				}
5644c2fdda0dSAndy Whitcroft			}
5645c2fdda0dSAndy Whitcroft		}
5646c2fdda0dSAndy Whitcroft
564795e2c602SJoe Perches#Specific variable tests
5648323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5649323c1260SJoe Perches			my $var = $1;
565095e2c602SJoe Perches
565195e2c602SJoe Perches#CamelCase
5652807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5653be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
56544104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
56554104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
565622735ce8SJoe Perches#Ignore Page<foo> variants
5657807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5658d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5659d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5660d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5661f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5662f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
56637e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
56647e781f67SJoe Perches					my $word = $1;
56657e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5666d8b07710SJoe Perches					if ($check) {
5667d8b07710SJoe Perches						seed_camelcase_includes();
5668d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5669d8b07710SJoe Perches							seed_camelcase_file($realfile);
5670d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5671d8b07710SJoe Perches						}
5672d8b07710SJoe Perches					}
56737e781f67SJoe Perches					if (!defined $camelcase{$word}) {
56747e781f67SJoe Perches						$camelcase{$word} = 1;
5675be79794bSJoe Perches						CHK("CAMELCASE",
56767e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
56777e781f67SJoe Perches					}
5678323c1260SJoe Perches				}
5679323c1260SJoe Perches			}
56803445686aSJoe Perches		}
56810a920b5bSAndy Whitcroft
56820a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5683d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5684d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5685d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5686d5e616fcSJoe Perches			    $fix) {
5687194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5688d5e616fcSJoe Perches			}
56890a920b5bSAndy Whitcroft		}
56900a920b5bSAndy Whitcroft
56910e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
56920e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5693c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5694e09dec48SAndy Whitcroft			my $file = "$1.h";
5695e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5696e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5697e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
56987840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5699c45dcabdSAndy Whitcroft			{
57000e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
57010e212e0aSFabian Frederick				if ($asminclude > 0) {
5702e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5703000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5704000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5705e09dec48SAndy Whitcroft					} else {
5706000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5707000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5708e09dec48SAndy Whitcroft					}
57090a920b5bSAndy Whitcroft				}
57100a920b5bSAndy Whitcroft			}
57110e212e0aSFabian Frederick		}
57120a920b5bSAndy Whitcroft
5713653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5714653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5715cf655043SAndy Whitcroft# in a known good container
5716b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5717b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5718d8aaf121SAndy Whitcroft			my $ln = $linenr;
5719d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5720c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5721c45dcabdSAndy Whitcroft			my $ctx = '';
572208a2843eSJoe Perches			my $has_flow_statement = 0;
572308a2843eSJoe Perches			my $has_arg_concat = 0;
5724c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5725f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5726f74bd194SAndy Whitcroft			$ctx = $dstat;
5727c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5728a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5729c45dcabdSAndy Whitcroft
573008a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
573162e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
573208a2843eSJoe Perches
5733f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5734f59b64bfSJoe Perches			my $define_args = $1;
5735f59b64bfSJoe Perches			my $define_stmt = $dstat;
5736f59b64bfSJoe Perches			my @def_args = ();
5737f59b64bfSJoe Perches
5738f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5739f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5740f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
57418c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5742f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5743f59b64bfSJoe Perches			}
5744f59b64bfSJoe Perches
5745292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5746c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5747c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5748c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5749c45dcabdSAndy Whitcroft
5750c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
57512e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
57522e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
57532e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5754bf30d6edSAndy Whitcroft			{
5755c45dcabdSAndy Whitcroft			}
5756c45dcabdSAndy Whitcroft
5757342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
575833acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
575933acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5760e45bab8eSAndy Whitcroft			{
5761e45bab8eSAndy Whitcroft			}
5762e45bab8eSAndy Whitcroft
576342e15293SJoe Perches			# Make asm volatile uses seem like a generic function
576442e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
576542e15293SJoe Perches
5766c45dcabdSAndy Whitcroft			my $exceptions = qr{
5767c45dcabdSAndy Whitcroft				$Declare|
5768c45dcabdSAndy Whitcroft				module_param_named|
5769a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5770c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5771c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5772383099fdSAndy Whitcroft				__typeof__\(|
577322fd2d3eSStefani Seibold				union|
577422fd2d3eSStefani Seibold				struct|
5775ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
57766b10df42SVladimir Zapolskiy				^\"|\"$|
57776b10df42SVladimir Zapolskiy				^\[
5778c45dcabdSAndy Whitcroft			}x;
57795eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5780f59b64bfSJoe Perches
5781f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5782f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5783e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5784f59b64bfSJoe Perches
5785f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5786f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5787f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
57883cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5789356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5790f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5791f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5792e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
579372f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
57942e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5795f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5796f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5797f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
57984e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5799f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5800c45dcabdSAndy Whitcroft			{
5801e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5802e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5803e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5804e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5805f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5806f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5807f74bd194SAndy Whitcroft				} else {
5808000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5809388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5810d8aaf121SAndy Whitcroft				}
5811f59b64bfSJoe Perches
5812f59b64bfSJoe Perches			}
58135207649bSJoe Perches
58145207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
58155207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
58165207649bSJoe Perches			my $first = 1;
58175207649bSJoe Perches			$define_stmt = "";
58185207649bSJoe Perches			foreach my $l (@stmt_array) {
58195207649bSJoe Perches				$l =~ s/\\$//;
58205207649bSJoe Perches				if ($first) {
58215207649bSJoe Perches					$define_stmt = $l;
58225207649bSJoe Perches					$first = 0;
58235207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
58245207649bSJoe Perches					$define_stmt .= substr($l, 1);
58255207649bSJoe Perches				}
58265207649bSJoe Perches			}
58275207649bSJoe Perches			$define_stmt =~ s/$;//g;
58285207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
58295207649bSJoe Perches			$define_stmt = trim($define_stmt);
58305207649bSJoe Perches
5831f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5832f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5833f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
58349192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
58357fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
58367b844345SVincent 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;
58377fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
58387fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5839d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5840f59b64bfSJoe Perches				if ($use_cnt > 1) {
5841f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5842f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5843f59b64bfSJoe Perches				    }
58449192d41aSJoe Perches# check if any macro arguments may have other precedence issues
58457fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
58469192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
58479192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
58489192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
58499192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
58509192d41aSJoe Perches				}
58510a920b5bSAndy Whitcroft			}
58525023d347SJoe Perches
585308a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
585408a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
585508a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
585608a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5857e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
585808a2843eSJoe Perches
585908a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
586008a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
586108a2843eSJoe Perches			}
586208a2843eSJoe Perches
5863481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
58645023d347SJoe Perches
58655023d347SJoe Perches		} else {
58665023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5867481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5868481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
58695023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
58705023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
58715023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
58725023d347SJoe Perches			}
5873653d4876SAndy Whitcroft		}
58740a920b5bSAndy Whitcroft
5875b13edf7fSJoe Perches# do {} while (0) macro tests:
5876b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5877b13edf7fSJoe Perches# macro should not end with a semicolon
58785b57980dSJoe Perches		if ($perl_version_ok &&
5879b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5880b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5881b13edf7fSJoe Perches			my $ln = $linenr;
5882b13edf7fSJoe Perches			my $cnt = $realcnt;
5883b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5884b13edf7fSJoe Perches			my $ctx = '';
5885b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5886b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5887b13edf7fSJoe Perches			$ctx = $dstat;
5888b13edf7fSJoe Perches
5889b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
58901b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5891b13edf7fSJoe Perches
5892b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5893b13edf7fSJoe Perches				my $stmts = $2;
5894b13edf7fSJoe Perches				my $semis = $3;
5895b13edf7fSJoe Perches
5896b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5897b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5898e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5899b13edf7fSJoe Perches
5900ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5901ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5902b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5903b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5904b13edf7fSJoe Perches				}
5905b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5906b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5907b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5908b13edf7fSJoe Perches				}
5909f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5910f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5911f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5912e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5913f5ef95b1SJoe Perches
5914f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5915f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5916b13edf7fSJoe Perches			}
5917b13edf7fSJoe Perches		}
5918b13edf7fSJoe Perches
5919f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
592013214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
592113214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5922cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
592313214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5924cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5925cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5926aad4f614SJoe Perches				my @allowed = ();
5927aad4f614SJoe Perches				my $allow = 0;
592813214adfSAndy Whitcroft				my $seen = 0;
5929773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5930cf655043SAndy Whitcroft				my $ln = $linenr - 1;
593113214adfSAndy Whitcroft				for my $chunk (@chunks) {
593213214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
593313214adfSAndy Whitcroft
5934773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5935773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5936773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5937773647a0SAndy Whitcroft
5938aad4f614SJoe Perches					$allowed[$allow] = 0;
5939773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5940773647a0SAndy Whitcroft
5941773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5942773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5943773647a0SAndy Whitcroft
5944773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5945cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5946cf655043SAndy Whitcroft
5947773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
594813214adfSAndy Whitcroft
594913214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
595013214adfSAndy Whitcroft
5951aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5952cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5953cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5954aad4f614SJoe Perches						$allowed[$allow] = 1;
595513214adfSAndy Whitcroft					}
595613214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5957cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5958aad4f614SJoe Perches						$allowed[$allow] = 1;
595913214adfSAndy Whitcroft					}
5960cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5961cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5962aad4f614SJoe Perches						$allowed[$allow] = 1;
596313214adfSAndy Whitcroft					}
5964aad4f614SJoe Perches					$allow++;
596513214adfSAndy Whitcroft				}
5966aad4f614SJoe Perches				if ($seen) {
5967aad4f614SJoe Perches					my $sum_allowed = 0;
5968aad4f614SJoe Perches					foreach (@allowed) {
5969aad4f614SJoe Perches						$sum_allowed += $_;
5970aad4f614SJoe Perches					}
5971aad4f614SJoe Perches					if ($sum_allowed == 0) {
5972000d1cc1SJoe Perches						WARN("BRACES",
5973000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5974aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5975aad4f614SJoe Perches						 $seen != $allow) {
5976aad4f614SJoe Perches						CHK("BRACES",
5977aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5978aad4f614SJoe Perches					}
597913214adfSAndy Whitcroft				}
598013214adfSAndy Whitcroft			}
598113214adfSAndy Whitcroft		}
5982773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
598313214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5984cf655043SAndy Whitcroft			my $allowed = 0;
5985f0a594c1SAndy Whitcroft
5986cf655043SAndy Whitcroft			# Check the pre-context.
5987cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5988cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5989cf655043SAndy Whitcroft				$allowed = 1;
5990f0a594c1SAndy Whitcroft			}
5991773647a0SAndy Whitcroft
5992773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5993773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5994773647a0SAndy Whitcroft
5995cf655043SAndy Whitcroft			# Check the condition.
5996cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5997773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5998cf655043SAndy Whitcroft			if (defined $cond) {
5999773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
6000cf655043SAndy Whitcroft			}
6001cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
6002cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
6003cf655043SAndy Whitcroft				$allowed = 1;
6004cf655043SAndy Whitcroft			}
6005cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
6006cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
6007cf655043SAndy Whitcroft				$allowed = 1;
6008cf655043SAndy Whitcroft			}
6009cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
6010cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
6011cf655043SAndy Whitcroft				$allowed = 1;
6012cf655043SAndy Whitcroft			}
6013cf655043SAndy Whitcroft			# Check the post-context.
6014cf655043SAndy Whitcroft			if (defined $chunks[1]) {
6015cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
6016cf655043SAndy Whitcroft				if (defined $cond) {
6017773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
6018cf655043SAndy Whitcroft				}
6019cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
6020cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6021cf655043SAndy Whitcroft					$allowed = 1;
6022cf655043SAndy Whitcroft				}
6023cf655043SAndy Whitcroft			}
6024cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6025f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
6026e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6027cf655043SAndy Whitcroft
6028000d1cc1SJoe Perches				WARN("BRACES",
6029000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6030f0a594c1SAndy Whitcroft			}
6031f0a594c1SAndy Whitcroft		}
6032f0a594c1SAndy Whitcroft
6033e4c5babdSJoe Perches# check for single line unbalanced braces
603495330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
603595330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
6036e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6037e4c5babdSJoe Perches		}
6038e4c5babdSJoe Perches
60390979ae66SJoe Perches# check for unnecessary blank lines around braces
604077b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6041f8e58219SJoe Perches			if (CHK("BRACES",
6042f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6043f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
6044f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
6045f8e58219SJoe Perches			}
60460979ae66SJoe Perches		}
604777b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
6048f8e58219SJoe Perches			if (CHK("BRACES",
6049f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6050f8e58219SJoe Perches			    $fix) {
6051f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
6052f8e58219SJoe Perches			}
60530979ae66SJoe Perches		}
60540979ae66SJoe Perches
60554a0df2efSAndy Whitcroft# no volatiles please
60566c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
60576c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6058000d1cc1SJoe Perches			WARN("VOLATILE",
60598c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
60604a0df2efSAndy Whitcroft		}
60614a0df2efSAndy Whitcroft
60625e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
60635e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
60645e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
60655e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
606633acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
60675e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
60685e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
60695e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
60705e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
60715e4f6ba5SJoe Perches				     $fix &&
60725e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
60735e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
60745e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
60755e4f6ba5SJoe Perches				my $comma_close = "";
60765e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
60775e4f6ba5SJoe Perches					$comma_close = $1;
60785e4f6ba5SJoe Perches				}
60795e4f6ba5SJoe Perches
60805e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
60815e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
60825e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
60835e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
60845e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
60855e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
60865e4f6ba5SJoe Perches				$fixedline = $rawline;
60875e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
60885e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
60895e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
60905e4f6ba5SJoe Perches				}
60915e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
60925e4f6ba5SJoe Perches			}
60935e4f6ba5SJoe Perches		}
60945e4f6ba5SJoe Perches
60955e4f6ba5SJoe Perches# check for missing a space in a string concatenation
60965e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
60975e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
60985e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
60995e4f6ba5SJoe Perches		}
61005e4f6ba5SJoe Perches
610177cb8546SJoe Perches# check for an embedded function name in a string when the function is known
6102e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
6103e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
6104e4b7d309SJoe Perches# function declarations
610577cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
610677cb8546SJoe Perches		    defined($context_function) &&
6107e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6108e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
610977cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
6110e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
611177cb8546SJoe Perches		}
611277cb8546SJoe Perches
6113adb2da82SJoe Perches# check for unnecessary function tracing like uses
6114adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6115adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6116adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6117adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6118adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6119adb2da82SJoe Perches			    $fix) {
6120adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6121adb2da82SJoe Perches			}
6122adb2da82SJoe Perches		}
6123adb2da82SJoe Perches
61245e4f6ba5SJoe Perches# check for spaces before a quoted newline
61255e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
61265e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
61275e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
61285e4f6ba5SJoe Perches			    $fix) {
61295e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
61305e4f6ba5SJoe Perches			}
61315e4f6ba5SJoe Perches
61325e4f6ba5SJoe Perches		}
61335e4f6ba5SJoe Perches
6134f17dba4fSJoe Perches# concatenated string without spaces between elements
6135*d2af5aa6SJoe Perches		if ($line =~ /$String[A-Z_]/ ||
6136*d2af5aa6SJoe Perches		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
613779682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
613879682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
613979682c0cSJoe Perches			    $fix) {
614079682c0cSJoe Perches				while ($line =~ /($String)/g) {
614179682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
614279682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
614379682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
614479682c0cSJoe Perches				}
614579682c0cSJoe Perches			}
6146f17dba4fSJoe Perches		}
6147f17dba4fSJoe Perches
614890ad30e5SJoe Perches# uncoalesced string fragments
6149*d2af5aa6SJoe Perches		if ($line =~ /$String\s*[Lu]?"/) {
615079682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
615179682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
615279682c0cSJoe Perches			    $fix) {
615379682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
615479682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
615579682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
615679682c0cSJoe Perches				}
615779682c0cSJoe Perches			}
615890ad30e5SJoe Perches		}
615990ad30e5SJoe Perches
6160522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6161522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6162522b837cSAlexey Dobriyan		my $show_Z = 1;
61635e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6164522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
61655e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6166522b837cSAlexey Dobriyan			# check for %L
6167522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
61685e4f6ba5SJoe Perches				WARN("PRINTF_L",
6169522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6170522b837cSAlexey Dobriyan				$show_L = 0;
61715e4f6ba5SJoe Perches			}
6172522b837cSAlexey Dobriyan			# check for %Z
6173522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6174522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6175522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6176522b837cSAlexey Dobriyan				$show_Z = 0;
6177522b837cSAlexey Dobriyan			}
6178522b837cSAlexey Dobriyan			# check for 0x<decimal>
6179522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6180522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
61816e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
61826e300757SJoe Perches			}
61835e4f6ba5SJoe Perches		}
61845e4f6ba5SJoe Perches
61855e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
61863f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
61875e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
61885e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
61895e4f6ba5SJoe Perches		}
61905e4f6ba5SJoe Perches
619100df344fSAndy Whitcroft# warn about #if 0
6192c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
619360f89010SPrakruthi Deepak Heragu			WARN("IF_0",
619460f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
619560f89010SPrakruthi Deepak Heragu		}
619660f89010SPrakruthi Deepak Heragu
619760f89010SPrakruthi Deepak Heragu# warn about #if 1
619860f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
619960f89010SPrakruthi Deepak Heragu			WARN("IF_1",
620060f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
62014a0df2efSAndy Whitcroft		}
62024a0df2efSAndy Whitcroft
620303df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
620403df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6205100425deSJoe Perches			my $tested = quotemeta($1);
6206100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6207100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6208100425deSJoe Perches				my $func = $1;
6209100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6210100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6211100425deSJoe Perches				    $fix) {
6212100425deSJoe Perches					my $do_fix = 1;
6213100425deSJoe Perches					my $leading_tabs = "";
6214100425deSJoe Perches					my $new_leading_tabs = "";
6215100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6216100425deSJoe Perches						$leading_tabs = $1;
6217100425deSJoe Perches					} else {
6218100425deSJoe Perches						$do_fix = 0;
6219100425deSJoe Perches					}
6220100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6221100425deSJoe Perches						$new_leading_tabs = $1;
6222100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6223100425deSJoe Perches							$do_fix = 0;
6224100425deSJoe Perches						}
6225100425deSJoe Perches					} else {
6226100425deSJoe Perches						$do_fix = 0;
6227100425deSJoe Perches					}
6228100425deSJoe Perches					if ($do_fix) {
6229100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6230100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6231100425deSJoe Perches					}
6232100425deSJoe Perches				}
62334c432a8fSGreg Kroah-Hartman			}
62344c432a8fSGreg Kroah-Hartman		}
6235f0a594c1SAndy Whitcroft
6236ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6237ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6238ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6239ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6240ebfdc409SJoe Perches		    $linenr > 3) {
6241ebfdc409SJoe Perches			my $testval = $2;
6242ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6243ebfdc409SJoe Perches
6244ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6245ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6246ebfdc409SJoe Perches
6247e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6248e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6249ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6250ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6251ebfdc409SJoe Perches			}
6252ebfdc409SJoe Perches		}
6253ebfdc409SJoe Perches
6254f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6255dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6256f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6257f78d98f6SJoe Perches			my $level = $1;
6258f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6259f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6260f78d98f6SJoe Perches			    $fix) {
6261f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6262f78d98f6SJoe Perches			}
6263f78d98f6SJoe Perches		}
6264f78d98f6SJoe Perches
626545c55e92SJoe Perches# check for logging continuations
626645c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
626745c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
626845c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
626945c55e92SJoe Perches		}
627045c55e92SJoe Perches
627170eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
627270eb2275SDwaipayan Ray		if (defined $stat &&
627370eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
627470eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
627570eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
627670eb2275SDwaipayan Ray			$lc = $lc + $linenr;
627770eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
627870eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
627970eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
628070eb2275SDwaipayan Ray				my $pspec = $1;
628170eb2275SDwaipayan Ray				my $h = $2;
628270eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
628370eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
628470eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
628570eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
628670eb2275SDwaipayan Ray					my $nspec = $pspec;
628770eb2275SDwaipayan Ray					$nspec =~ s/h//g;
628870eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
628970eb2275SDwaipayan Ray				}
629070eb2275SDwaipayan Ray			}
629170eb2275SDwaipayan Ray		}
629270eb2275SDwaipayan Ray
6293abb08a53SJoe Perches# check for mask then right shift without a parentheses
62945b57980dSJoe Perches		if ($perl_version_ok &&
6295abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6296abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6297abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6298abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6299abb08a53SJoe Perches		}
6300abb08a53SJoe Perches
6301b75ac618SJoe Perches# check for pointer comparisons to NULL
63025b57980dSJoe Perches		if ($perl_version_ok) {
6303b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6304b75ac618SJoe Perches				my $val = $1;
6305b75ac618SJoe Perches				my $equal = "!";
6306b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6307b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6308b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6309b75ac618SJoe Perches					    $fix) {
6310b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6311b75ac618SJoe Perches				}
6312b75ac618SJoe Perches			}
6313b75ac618SJoe Perches		}
6314b75ac618SJoe Perches
63158716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
63168716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
63178716de38SJoe Perches			my $attr = $1;
63188716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
63198716de38SJoe Perches				my $ptr = $1;
63208716de38SJoe Perches				my $var = $2;
63218716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
63228716de38SJoe Perches				      ERROR("MISPLACED_INIT",
63238716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
63248716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
63258716de38SJoe Perches				      WARN("MISPLACED_INIT",
63268716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
63278716de38SJoe Perches				    $fix) {
6328194f66fcSJoe 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;
63298716de38SJoe Perches				}
63308716de38SJoe Perches			}
63318716de38SJoe Perches		}
63328716de38SJoe Perches
6333e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6334e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6335e970b884SJoe Perches			my $attr = $1;
6336e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6337e970b884SJoe Perches			my $attr_prefix = $1;
6338e970b884SJoe Perches			my $attr_type = $2;
6339e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6340e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6341e970b884SJoe Perches			    $fix) {
6342194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6343e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6344e970b884SJoe Perches			}
6345e970b884SJoe Perches		}
6346e970b884SJoe Perches
6347e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6348e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6349e970b884SJoe Perches			my $attr = $1;
6350e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6351e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6352e970b884SJoe Perches			    $fix) {
6353194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6354e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6355e970b884SJoe Perches				$lead = rtrim($1);
6356e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6357e970b884SJoe Perches				$lead = "${lead}const ";
6358194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6359e970b884SJoe Perches			}
6360e970b884SJoe Perches		}
6361e970b884SJoe Perches
6362c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6363c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6364c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6365c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6366c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6367c17893c7SJoe Perches			    $fix) {
6368c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6369c17893c7SJoe Perches			}
6370c17893c7SJoe Perches		}
6371c17893c7SJoe Perches
6372fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6373fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6374fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6375fbdb8138SJoe Perches			my $constant_func = $1;
6376fbdb8138SJoe Perches			my $func = $constant_func;
6377fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6378fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6379fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6380fbdb8138SJoe Perches			    $fix) {
6381194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6382fbdb8138SJoe Perches			}
6383fbdb8138SJoe Perches		}
6384fbdb8138SJoe Perches
63851a15a250SPatrick Pannuto# prefer usleep_range over udelay
638637581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
638743c1d77cSJoe Perches			my $delay = $1;
63881a15a250SPatrick Pannuto			# ignore udelay's < 10, however
638943c1d77cSJoe Perches			if (! ($delay < 10) ) {
6390000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6391458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
639243c1d77cSJoe Perches			}
639343c1d77cSJoe Perches			if ($delay > 2000) {
639443c1d77cSJoe Perches				WARN("LONG_UDELAY",
639543c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
63961a15a250SPatrick Pannuto			}
63971a15a250SPatrick Pannuto		}
63981a15a250SPatrick Pannuto
639909ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
640009ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
640109ef8725SPatrick Pannuto			if ($1 < 20) {
6402000d1cc1SJoe Perches				WARN("MSLEEP",
6403458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
640409ef8725SPatrick Pannuto			}
640509ef8725SPatrick Pannuto		}
640609ef8725SPatrick Pannuto
640736ec1939SJoe Perches# check for comparisons of jiffies
640836ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
640936ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
641036ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
641136ec1939SJoe Perches		}
641236ec1939SJoe Perches
64139d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
64149d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
64159d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
64169d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
64179d7a34a5SJoe Perches		}
64189d7a34a5SJoe Perches
641900df344fSAndy Whitcroft# warn about #ifdefs in C files
6420c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
642100df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
642200df344fSAndy Whitcroft#			print "$herecurr";
642300df344fSAndy Whitcroft#			$clean = 0;
642400df344fSAndy Whitcroft#		}
642500df344fSAndy Whitcroft
642622f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6427c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
64283705ce5bSJoe Perches			if (ERROR("SPACING",
64293705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
64303705ce5bSJoe Perches			    $fix) {
6431194f66fcSJoe Perches				$fixed[$fixlinenr] =~
64323705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
64333705ce5bSJoe Perches			}
64343705ce5bSJoe Perches
643522f2a2efSAndy Whitcroft		}
643622f2a2efSAndy Whitcroft
64374a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6438171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6439171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
64404a0df2efSAndy Whitcroft			my $which = $1;
64414a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6442000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6443000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
64444a0df2efSAndy Whitcroft			}
64454a0df2efSAndy Whitcroft		}
64464a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6447402c2553SMichael S. Tsirkin
6448402c2553SMichael S. Tsirkin		my $barriers = qr{
6449402c2553SMichael S. Tsirkin			mb|
6450402c2553SMichael S. Tsirkin			rmb|
6451ad83ec6cSWill Deacon			wmb
6452402c2553SMichael S. Tsirkin		}x;
6453402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6454402c2553SMichael S. Tsirkin			mb__before_atomic|
6455402c2553SMichael S. Tsirkin			mb__after_atomic|
6456402c2553SMichael S. Tsirkin			store_release|
6457402c2553SMichael S. Tsirkin			load_acquire|
6458402c2553SMichael S. Tsirkin			store_mb|
6459402c2553SMichael S. Tsirkin			(?:$barriers)
6460402c2553SMichael S. Tsirkin		}x;
6461402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6462402c2553SMichael S. Tsirkin			(?:$barriers)|
646343e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
646443e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6465402c2553SMichael S. Tsirkin		}x;
6466402c2553SMichael S. Tsirkin
6467402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
64684a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6469c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6470000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
64714a0df2efSAndy Whitcroft			}
64724a0df2efSAndy Whitcroft		}
64733ad81779SPaul E. McKenney
6474f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6475f4073b0fSMichael S. Tsirkin
6476f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6477f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6478f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6479f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6480f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6481f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6482f4073b0fSMichael S. Tsirkin		}
6483f4073b0fSMichael S. Tsirkin
6484cb426e99SJoe Perches# check for waitqueue_active without a comment.
6485cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6486cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6487cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6488cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6489cb426e99SJoe Perches			}
6490cb426e99SJoe Perches		}
64913ad81779SPaul E. McKenney
64925099a722SMarco Elver# check for data_race without a comment.
64935099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
64945099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
64955099a722SMarco Elver				WARN("DATA_RACE",
64965099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
64975099a722SMarco Elver			}
64985099a722SMarco Elver		}
64995099a722SMarco Elver
65004a0df2efSAndy Whitcroft# check of hardware specific defines
6501c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6502000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6503000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
65040a920b5bSAndy Whitcroft		}
6505653d4876SAndy Whitcroft
6506596ed45bSJoe Perches# check that the storage class is not after a type
6507596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6508000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6509596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6510596ed45bSJoe Perches		}
6511596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6512596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6513596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6514596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6515596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6516596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6517596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6518d4977c78STobias Klauser		}
6519d4977c78STobias Klauser
6520de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6521de7d4f0eSAndy Whitcroft# storage class and type.
65229c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
65239c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6524000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6525000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6526de7d4f0eSAndy Whitcroft		}
6527de7d4f0eSAndy Whitcroft
65288905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
65292b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
65302b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6531d5e616fcSJoe Perches			if (WARN("INLINE",
6532d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6533d5e616fcSJoe Perches			    $fix) {
6534194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6535d5e616fcSJoe Perches
6536d5e616fcSJoe Perches			}
65378905a67cSAndy Whitcroft		}
65388905a67cSAndy Whitcroft
65397ebe1d17SDwaipayan Ray# Check for compiler attributes
65402b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
65417ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
65427ebe1d17SDwaipayan Ray			my $attr = $1;
65437ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
65447ebe1d17SDwaipayan Ray
65457ebe1d17SDwaipayan Ray			my %attr_list = (
65460830aab0SJoe Perches				"alias"				=> "__alias",
65477ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
65487ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
65497ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
65507ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
65517ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
65527ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
65537ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
65547ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
65557ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
65567ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
65577ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
65587ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
65597ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
65607ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
65617ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
65627ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
65637ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
65647ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
65657ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6566339f29d9SJoe Perches				"section"			=> "__section",
65670830aab0SJoe Perches				"used"				=> "__used",
65680830aab0SJoe Perches				"weak"				=> "__weak"
65697ebe1d17SDwaipayan Ray			);
65707ebe1d17SDwaipayan Ray
65717ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6572339f29d9SJoe Perches				my $orig_attr = $1;
65737ebe1d17SDwaipayan Ray				my $params = '';
65747ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6575339f29d9SJoe Perches				my $curr_attr = $orig_attr;
65767ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
65777ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6578339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
65797ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
65807ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6581339f29d9SJoe Perches						$new = "__$1\($2";
65827ebe1d17SDwaipayan Ray					} else {
6583339f29d9SJoe Perches						$new = "$new$params";
65847ebe1d17SDwaipayan Ray					}
65857ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6586339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
65877ebe1d17SDwaipayan Ray					    $fix) {
6588339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6589339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6590339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6591339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6592339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
65937ebe1d17SDwaipayan Ray					}
659439b7e287SJoe Perches				}
6595462811d9SJoe Perches			}
6596462811d9SJoe Perches
65977ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
65987ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
65997ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
66007ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6601d5e616fcSJoe Perches			}
66026061d949SJoe Perches		}
66036061d949SJoe Perches
6604619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
66055b57980dSJoe Perches		if ($perl_version_ok &&
6606619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6607619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6608619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6609619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6610619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6611619a908aSJoe Perches		}
6612619a908aSJoe Perches
6613fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6614e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6615fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6616e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6617e6176fa4SJoe Perches			my $type = $1;
6618e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6619e6176fa4SJoe Perches				$type = $1;
6620e6176fa4SJoe Perches				my $kernel_type = 'u';
6621e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6622e6176fa4SJoe Perches				$type =~ /(\d+)/;
6623e6176fa4SJoe Perches				$kernel_type .= $1;
6624e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6625e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6626e6176fa4SJoe Perches				    $fix) {
6627e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6628e6176fa4SJoe Perches				}
6629e6176fa4SJoe Perches			}
6630e6176fa4SJoe Perches		}
6631e6176fa4SJoe Perches
6632938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6633938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6634938224b5SJoe Perches			my $cast = $1;
6635938224b5SJoe Perches			my $const = $2;
6636938224b5SJoe Perches			my $suffix = "";
6637938224b5SJoe Perches			my $newconst = $const;
6638938224b5SJoe Perches			$newconst =~ s/${Int_type}$//;
6639938224b5SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6640938224b5SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6641938224b5SJoe Perches			    $suffix .= 'LL';
6642938224b5SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6643938224b5SJoe Perches			    $suffix .= 'L';
6644938224b5SJoe Perches			}
66450972b8bfSJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
66460972b8bfSJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
66470972b8bfSJoe Perches			    $fix) {
6648938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6649938224b5SJoe Perches			}
6650938224b5SJoe Perches		}
6651938224b5SJoe Perches
66528f53a9b8SJoe Perches# check for sizeof(&)
66538f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6654000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6655000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
66568f53a9b8SJoe Perches		}
66578f53a9b8SJoe Perches
665866c80b60SJoe Perches# check for sizeof without parenthesis
665966c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6660d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6661d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6662d5e616fcSJoe Perches			    $fix) {
6663194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6664d5e616fcSJoe Perches			}
666566c80b60SJoe Perches		}
666666c80b60SJoe Perches
666788982feaSJoe Perches# check for struct spinlock declarations
666888982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
666988982feaSJoe Perches			WARN("USE_SPINLOCK_T",
667088982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
667188982feaSJoe Perches		}
667288982feaSJoe Perches
6673a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
667406668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6675a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6676caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6677caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6678d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6679d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6680d5e616fcSJoe Perches				    $fix) {
6681194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6682d5e616fcSJoe Perches				}
6683a6962d72SJoe Perches			}
6684a6962d72SJoe Perches		}
6685a6962d72SJoe Perches
66860b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
66875b57980dSJoe Perches		if ($perl_version_ok &&
66880b523769SJoe Perches		    defined $stat &&
66890b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
66900b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6691e3c6bc95STobin C. Harding			my $stat_real;
6692e3c6bc95STobin C. Harding
66930b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
66940b523769SJoe Perches			$lc = $lc + $linenr;
66950b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6696ffe07513SJoe Perches				my $specifier;
6697ffe07513SJoe Perches				my $extension;
66983bd32d6aSSakari Ailus				my $qualifier;
6699ffe07513SJoe Perches				my $bad_specifier = "";
67000b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
67010b523769SJoe Perches				$fmt =~ s/%%//g;
6702e3c6bc95STobin C. Harding
67033bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6704e3c6bc95STobin C. Harding					$specifier = $1;
6705e3c6bc95STobin C. Harding					$extension = $2;
67063bd32d6aSSakari Ailus					$qualifier = $3;
6707af612e43SSakari Ailus					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
67083bd32d6aSSakari Ailus					    ($extension eq "f" &&
6709af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^w/) ||
6710af612e43SSakari Ailus					    ($extension eq "4" &&
6711af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^cc/)) {
6712e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
67130b523769SJoe Perches						last;
67140b523769SJoe Perches					}
6715e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6716e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6717e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
67180b523769SJoe Perches						}
6719e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6720e3c6bc95STobin 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");
6721e3c6bc95STobin C. Harding					}
6722e3c6bc95STobin C. Harding				}
6723e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
67242a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
67251df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
67261df7338aSSergey Senozhatsky					my $use = "";
6727e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
67281df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6729e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
67301df7338aSSergey Senozhatsky					}
67312a9f9d85STobin C. Harding
67320b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6733e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6734e3c6bc95STobin C. Harding				}
67350b523769SJoe Perches			}
67360b523769SJoe Perches		}
67370b523769SJoe Perches
6738554e165cSAndy Whitcroft# Check for misused memsets
67395b57980dSJoe Perches		if ($perl_version_ok &&
6740d1fe9c09SJoe Perches		    defined $stat &&
67419e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6742554e165cSAndy Whitcroft
6743d7c76ba7SJoe Perches			my $ms_addr = $2;
6744d1fe9c09SJoe Perches			my $ms_val = $7;
6745d1fe9c09SJoe Perches			my $ms_size = $12;
6746d7c76ba7SJoe Perches
6747554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6748554e165cSAndy Whitcroft				ERROR("MEMSET",
6749d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6750554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6751554e165cSAndy Whitcroft				WARN("MEMSET",
6752d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6753d7c76ba7SJoe Perches			}
6754d7c76ba7SJoe Perches		}
6755d7c76ba7SJoe Perches
675698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
67575b57980dSJoe Perches#		if ($perl_version_ok &&
6758f333195dSJoe Perches#		    defined $stat &&
6759f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6760f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6761f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6762f333195dSJoe Perches#			    $fix) {
6763f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6764f333195dSJoe Perches#			}
6765f333195dSJoe Perches#		}
676698a9bba5SJoe Perches
6767b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
67685b57980dSJoe Perches#		if ($perl_version_ok &&
6769f333195dSJoe Perches#		    defined $stat &&
6770f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6771f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6772f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6773f333195dSJoe Perches#		}
6774b6117d17SMateusz Kulikowski
67758617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
67768617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
67775b57980dSJoe Perches#		if ($perl_version_ok &&
6778f333195dSJoe Perches#		    defined $stat &&
6779f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6780f333195dSJoe Perches#
6781f333195dSJoe Perches#			my $ms_val = $7;
6782f333195dSJoe Perches#
6783f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6784f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6785f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6786f333195dSJoe Perches#				    $fix) {
6787f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6788f333195dSJoe Perches#				}
6789f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6790f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6791f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6792f333195dSJoe Perches#				    $fix) {
6793f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6794f333195dSJoe Perches#				}
6795f333195dSJoe Perches#			}
6796f333195dSJoe Perches#		}
67978617cd09SMateusz Kulikowski
67985dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
67995dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
68005dbdb2d8SJoe Perches			WARN("STRLCPY",
68015dbdb2d8SJoe Perches			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
68025dbdb2d8SJoe Perches		}
68035dbdb2d8SJoe Perches
6804d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
68055b57980dSJoe Perches		if ($perl_version_ok &&
6806d1fe9c09SJoe Perches		    defined $stat &&
6807d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6808d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6809d7c76ba7SJoe Perches				my $call = $1;
6810d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6811d7c76ba7SJoe Perches				my $arg1 = $3;
6812d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6813d1fe9c09SJoe Perches				my $arg2 = $8;
6814d7c76ba7SJoe Perches				my $cast;
6815d7c76ba7SJoe Perches
6816d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6817d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6818d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6819d7c76ba7SJoe Perches					$cast = $cast1;
6820d7c76ba7SJoe Perches				} else {
6821d7c76ba7SJoe Perches					$cast = $cast2;
6822d7c76ba7SJoe Perches				}
6823d7c76ba7SJoe Perches				WARN("MINMAX",
6824d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6825554e165cSAndy Whitcroft			}
6826554e165cSAndy Whitcroft		}
6827554e165cSAndy Whitcroft
68284a273195SJoe Perches# check usleep_range arguments
68295b57980dSJoe Perches		if ($perl_version_ok &&
68304a273195SJoe Perches		    defined $stat &&
68314a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
68324a273195SJoe Perches			my $min = $1;
68334a273195SJoe Perches			my $max = $7;
68344a273195SJoe Perches			if ($min eq $max) {
68354a273195SJoe Perches				WARN("USLEEP_RANGE",
6836458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
68374a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
68384a273195SJoe Perches				 $min > $max) {
68394a273195SJoe Perches				WARN("USLEEP_RANGE",
6840458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
68414a273195SJoe Perches			}
68424a273195SJoe Perches		}
68434a273195SJoe Perches
6844823b794cSJoe Perches# check for naked sscanf
68455b57980dSJoe Perches		if ($perl_version_ok &&
6846823b794cSJoe Perches		    defined $stat &&
68476c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6848823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6849823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6850823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6851823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6852823b794cSJoe Perches			$lc = $lc + $linenr;
68532a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6854823b794cSJoe Perches			WARN("NAKED_SSCANF",
6855823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6856823b794cSJoe Perches		}
6857823b794cSJoe Perches
6858afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
68595b57980dSJoe Perches		if ($perl_version_ok &&
6860afc819abSJoe Perches		    defined $stat &&
6861afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6862afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6863afc819abSJoe Perches			$lc = $lc + $linenr;
68642a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6865afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6866afc819abSJoe Perches				my $format = $6;
6867afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6868afc819abSJoe Perches				if ($count == 1 &&
6869afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6870afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6871afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6872afc819abSJoe Perches				}
6873afc819abSJoe Perches			}
6874afc819abSJoe Perches		}
6875afc819abSJoe Perches
687670dc8a48SJoe Perches# check for new externs in .h files.
687770dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
687870dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6879d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
688070dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
688170dc8a48SJoe Perches			    $fix) {
6882194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
688370dc8a48SJoe Perches			}
688470dc8a48SJoe Perches		}
688570dc8a48SJoe Perches
6886de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6887171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6888c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6889171ae1a4SAndy Whitcroft		{
6890c45dcabdSAndy Whitcroft			my $function_name = $1;
6891c45dcabdSAndy Whitcroft			my $paren_space = $2;
6892171ae1a4SAndy Whitcroft
6893171ae1a4SAndy Whitcroft			my $s = $stat;
6894171ae1a4SAndy Whitcroft			if (defined $cond) {
6895171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6896171ae1a4SAndy Whitcroft			}
6897d8b44b58SKees Cook			if ($s =~ /^\s*;/)
6898c45dcabdSAndy Whitcroft			{
6899000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6900000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6901de7d4f0eSAndy Whitcroft			}
6902de7d4f0eSAndy Whitcroft
6903171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6904000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6905000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6906171ae1a4SAndy Whitcroft			}
69079c9ba34eSAndy Whitcroft
69089c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
69099c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
69109c9ba34eSAndy Whitcroft		{
6911000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6912000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6913171ae1a4SAndy Whitcroft		}
6914171ae1a4SAndy Whitcroft
6915a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
6916a0ad7596SJoe Perches		if (defined $stat &&
6917d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6918d8b44b58SKees Cook		    $1 ne "void") {
6919d8b44b58SKees Cook			my $args = trim($1);
6920ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6921ca0d8929SJoe Perches				my $arg = trim($1);
6922d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6923ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6924ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6925ca0d8929SJoe Perches				}
6926ca0d8929SJoe Perches			}
6927ca0d8929SJoe Perches		}
6928ca0d8929SJoe Perches
6929a0ad7596SJoe Perches# check for function definitions
69305b57980dSJoe Perches		if ($perl_version_ok &&
6931a0ad7596SJoe Perches		    defined $stat &&
6932a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6933a0ad7596SJoe Perches			$context_function = $1;
6934a0ad7596SJoe Perches
6935a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6936a0ad7596SJoe Perches			my $ok = 0;
6937a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6938a0ad7596SJoe Perches			my $herectx = $here . "\n";
6939a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6940a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6941a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6942a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6943a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6944a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6945a0ad7596SJoe Perches			}
6946a0ad7596SJoe Perches			if (!$ok) {
6947a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6948a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6949a0ad7596SJoe Perches			}
6950a0ad7596SJoe Perches		}
6951a0ad7596SJoe Perches
6952de7d4f0eSAndy Whitcroft# checks for new __setup's
6953de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6954de7d4f0eSAndy Whitcroft			my $name = $1;
6955de7d4f0eSAndy Whitcroft
6956de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6957000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
69582581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
6959de7d4f0eSAndy Whitcroft			}
6960653d4876SAndy Whitcroft		}
69619c0ca6f9SAndy Whitcroft
6962e29a70f1SJoe Perches# check for pointless casting of alloc functions
6963e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6964000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6965000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
69669c0ca6f9SAndy Whitcroft		}
696713214adfSAndy Whitcroft
6968a640d25cSJoe Perches# alloc style
6969a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
69705b57980dSJoe Perches		if ($perl_version_ok &&
6971e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6972a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6973a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6974a640d25cSJoe Perches		}
6975a640d25cSJoe Perches
697660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
69775b57980dSJoe Perches		if ($perl_version_ok &&
69781b4a2ed4SJoe Perches		    defined $stat &&
69791b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
698060a55369SJoe Perches			my $oldfunc = $3;
698160a55369SJoe Perches			my $a1 = $4;
698260a55369SJoe Perches			my $a2 = $10;
698360a55369SJoe Perches			my $newfunc = "kmalloc_array";
698460a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
698560a55369SJoe Perches			my $r1 = $a1;
698660a55369SJoe Perches			my $r2 = $a2;
698760a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
698860a55369SJoe Perches				$r1 = $a2;
698960a55369SJoe Perches				$r2 = $a1;
699060a55369SJoe Perches			}
6991e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6992e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
69931b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6994e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6995e3d95a2aSTobin C. Harding
6996e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
69971b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
69981b4a2ed4SJoe Perches				    $cnt == 1 &&
6999e367455aSJoe Perches				    $fix) {
7000194f66fcSJoe 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;
700160a55369SJoe Perches				}
700260a55369SJoe Perches			}
700360a55369SJoe Perches		}
700460a55369SJoe Perches
7005972fdea2SJoe Perches# check for krealloc arg reuse
70065b57980dSJoe Perches		if ($perl_version_ok &&
70074cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
70084cab63ceSJoe Perches		    $1 eq $3) {
7009972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
7010972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7011972fdea2SJoe Perches		}
7012972fdea2SJoe Perches
70135ce59ae0SJoe Perches# check for alloc argument mismatch
70147e6cdd7fSChristophe JAILLET		if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
70155ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
70165ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
70175ce59ae0SJoe Perches		}
70185ce59ae0SJoe Perches
7019caf2a54fSJoe Perches# check for multiple semicolons
7020caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
7021d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
7022d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7023d5e616fcSJoe Perches			    $fix) {
7024194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7025d5e616fcSJoe Perches			}
7026d1e2ad07SJoe Perches		}
7027d1e2ad07SJoe Perches
7028cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7029cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
7030cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
70310ab90191SJoe Perches			my $ull = "";
70320ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
70330ab90191SJoe Perches			if (CHK("BIT_MACRO",
70340ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
70350ab90191SJoe Perches			    $fix) {
70360ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
70370ab90191SJoe Perches			}
70380ab90191SJoe Perches		}
70390ab90191SJoe Perches
704050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
70413e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
704250161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
70433e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
704450161266SJoe Perches		}
704550161266SJoe Perches
70462d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
70473e89ad85SJerome 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*$/) {
70482d632745SJoe Perches			my $config = $1;
70492d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
70503e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
70512d632745SJoe Perches			    $fix) {
70522d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
70532d632745SJoe Perches			}
70542d632745SJoe Perches		}
70552d632745SJoe Perches
7056f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
7057f36d3eb8SJoe Perches		my @fallthroughs = (
7058f36d3eb8SJoe Perches			'fallthrough',
7059f36d3eb8SJoe Perches			'@fallthrough@',
7060f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
7061f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7062f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7063f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7064f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7065f36d3eb8SJoe Perches		    );
7066f36d3eb8SJoe Perches		if ($raw_comment ne '') {
7067f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
7068f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
7069f36d3eb8SJoe Perches					my $msg_level = \&WARN;
7070f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
7071f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
7072f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7073f36d3eb8SJoe Perches					last;
7074f36d3eb8SJoe Perches				}
7075f36d3eb8SJoe Perches			}
7076f36d3eb8SJoe Perches		}
7077f36d3eb8SJoe Perches
7078d1e2ad07SJoe Perches# check for switch/default statements without a break;
70795b57980dSJoe Perches		if ($perl_version_ok &&
7080d1e2ad07SJoe Perches		    defined $stat &&
7081d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7082d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
7083e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
7084e3d95a2aSTobin C. Harding
7085d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
7086d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
7087caf2a54fSJoe Perches		}
7088caf2a54fSJoe Perches
708913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
7090d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
7091d5e616fcSJoe Perches			if (WARN("USE_FUNC",
7092d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
7093d5e616fcSJoe Perches			    $fix) {
7094194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7095d5e616fcSJoe Perches			}
709613214adfSAndy Whitcroft		}
7097773647a0SAndy Whitcroft
709862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
709962ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
710062ec818fSJoe Perches			ERROR("DATE_TIME",
710162ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
710262ec818fSJoe Perches		}
710362ec818fSJoe Perches
71042c92488aSJoe Perches# check for use of yield()
71052c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
71062c92488aSJoe Perches			WARN("YIELD",
71072c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
71082c92488aSJoe Perches		}
71092c92488aSJoe Perches
7110179f8f40SJoe Perches# check for comparisons against true and false
7111179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7112179f8f40SJoe Perches			my $lead = $1;
7113179f8f40SJoe Perches			my $arg = $2;
7114179f8f40SJoe Perches			my $test = $3;
7115179f8f40SJoe Perches			my $otype = $4;
7116179f8f40SJoe Perches			my $trail = $5;
7117179f8f40SJoe Perches			my $op = "!";
7118179f8f40SJoe Perches
7119179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7120179f8f40SJoe Perches
7121179f8f40SJoe Perches			my $type = lc($otype);
7122179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7123179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7124179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7125179f8f40SJoe Perches					$op = "";
7126179f8f40SJoe Perches				}
7127179f8f40SJoe Perches
7128179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7129179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7130179f8f40SJoe Perches
7131179f8f40SJoe Perches## maybe suggesting a correct construct would better
7132179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7133179f8f40SJoe Perches
7134179f8f40SJoe Perches			}
7135179f8f40SJoe Perches		}
7136179f8f40SJoe Perches
71374882720bSThomas Gleixner# check for semaphores initialized locked
71384882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7139000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7140000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7141773647a0SAndy Whitcroft		}
71426712d858SJoe Perches
714367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
714467d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7145000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
714667d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7147773647a0SAndy Whitcroft		}
71486712d858SJoe Perches
7149ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7150f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7151000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7152ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7153f3db6639SMichael Ellerman		}
71546712d858SJoe Perches
71553d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
71563d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
71573d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
71583d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
71593d709ab5SPaul E. McKenney		}
71603d709ab5SPaul E. McKenney
71619189c7e7SJoe Perches# check for deprecated apis
71629189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
71639189c7e7SJoe Perches			my $deprecated_api = $1;
71649189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
71659189c7e7SJoe Perches			WARN("DEPRECATED_API",
71669189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
71679189c7e7SJoe Perches		}
71689189c7e7SJoe Perches
71690f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7170d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7171ced69da1SQuentin Monnet		if (defined($const_structs) &&
7172ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7173d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7174000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7175d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
71762b6db5cbSAndy Whitcroft		}
7177773647a0SAndy Whitcroft
7178773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7179773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
718035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7181773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7182c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7183c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7184171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7185171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
718635cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
718735cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7188773647a0SAndy Whitcroft		{
7189000d1cc1SJoe Perches			WARN("NR_CPUS",
7190000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7191773647a0SAndy Whitcroft		}
71929c9ba34eSAndy Whitcroft
719352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
719452ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
719552ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
719652ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
719752ea8506SJoe Perches		}
719852ea8506SJoe Perches
7199acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
72005b57980dSJoe Perches		if ($perl_version_ok &&
7201acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7202acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7203acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7204acd9362cSJoe Perches		}
7205acd9362cSJoe Perches
7206fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline
7207fbe74541SJoe Perches		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7208fbe74541SJoe Perches		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7209fbe74541SJoe Perches			my $offset = $+[6] - 1;
7210fbe74541SJoe Perches			if (WARN("SYSFS_EMIT",
7211fbe74541SJoe Perches				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7212fbe74541SJoe Perches			    $fix) {
7213fbe74541SJoe Perches				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7214fbe74541SJoe Perches			}
7215fbe74541SJoe Perches		}
7216fbe74541SJoe Perches
7217de3f186fSDenis Efremov# nested likely/unlikely calls
7218de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7219de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7220de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7221de3f186fSDenis Efremov		}
7222de3f186fSDenis Efremov
7223691d77b6SAndy Whitcroft# whine mightly about in_atomic
7224691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7225691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7226000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7227000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7228f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7229000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7230000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7231691d77b6SAndy Whitcroft			}
7232691d77b6SAndy Whitcroft		}
72331704f47bSPeter Zijlstra
72341704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
72351704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
72361704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
72371704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
72381704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
72391704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7240000d1cc1SJoe Perches				ERROR("LOCKDEP",
7241000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
72421704f47bSPeter Zijlstra			}
72431704f47bSPeter Zijlstra		}
724488f8831cSDave Jones
7245b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7246b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7247000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7248000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
724988f8831cSDave Jones		}
72502435880fSJoe Perches
725100180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
725200180468SJoe Perches# and whether or not function naming is typical and if
725300180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
72545b57980dSJoe Perches		if ($perl_version_ok &&
725500180468SJoe Perches		    defined $stat &&
725600180468SJoe 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*\)/) {
725700180468SJoe Perches			my $var = $1;
725800180468SJoe Perches			my $perms = $2;
725900180468SJoe Perches			my $show = $3;
726000180468SJoe Perches			my $store = $4;
726100180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
726200180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
726300180468SJoe Perches			    $store =~ /^${var}_store$/ &&
726400180468SJoe Perches			    $octal_perms eq "0644") {
726500180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
726600180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
726700180468SJoe Perches				    $fix) {
726800180468SJoe 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})/;
726900180468SJoe Perches				}
727000180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
727100180468SJoe Perches				 $store =~ /^NULL$/ &&
727200180468SJoe Perches				 $octal_perms eq "0444") {
727300180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
727400180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
727500180468SJoe Perches				    $fix) {
727600180468SJoe 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})/;
727700180468SJoe Perches				}
727800180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
727900180468SJoe Perches				 $store =~ /^${var}_store$/ &&
728000180468SJoe Perches				 $octal_perms eq "0200") {
728100180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
728200180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
728300180468SJoe Perches				    $fix) {
728400180468SJoe 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})/;
728500180468SJoe Perches				}
728600180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
728700180468SJoe Perches				 $octal_perms eq "0444" ||
728800180468SJoe Perches				 $octal_perms eq "0200") {
728900180468SJoe Perches				my $newshow = "$show";
729000180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
729100180468SJoe Perches				my $newstore = $store;
729200180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
729300180468SJoe Perches				my $rename = "";
729400180468SJoe Perches				if ($show ne $newshow) {
729500180468SJoe Perches					$rename .= " '$show' to '$newshow'";
729600180468SJoe Perches				}
729700180468SJoe Perches				if ($store ne $newstore) {
729800180468SJoe Perches					$rename .= " '$store' to '$newstore'";
729900180468SJoe Perches				}
730000180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
730100180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
730200180468SJoe Perches			} else {
730300180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
730400180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
730500180468SJoe Perches			}
730600180468SJoe Perches		}
730700180468SJoe Perches
7308515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7309515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
731073121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
731173121534SJoe Perches#   specific definition of not visible in sysfs.
731273121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
731373121534SJoe Perches#   use the default permissions
73145b57980dSJoe Perches		if ($perl_version_ok &&
7315459cf0aeSJoe Perches		    defined $stat &&
7316515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
73172435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
73182435880fSJoe Perches				my $func = $entry->[0];
73192435880fSJoe Perches				my $arg_pos = $entry->[1];
73202435880fSJoe Perches
7321459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7322459cf0aeSJoe Perches				$lc = $lc + $linenr;
73232a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7324459cf0aeSJoe Perches
73252435880fSJoe Perches				my $skip_args = "";
73262435880fSJoe Perches				if ($arg_pos > 1) {
73272435880fSJoe Perches					$arg_pos--;
73282435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
73292435880fSJoe Perches				}
7330f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7331459cf0aeSJoe Perches				if ($stat =~ /$test/) {
73322435880fSJoe Perches					my $val = $1;
73332435880fSJoe Perches					$val = $6 if ($skip_args ne "");
733473121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
733573121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
733673121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
73372435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7338459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7339f90774e1SJoe Perches					}
7340f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7341c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7342459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
73432435880fSJoe Perches					}
7344459cf0aeSJoe Perches				}
7345459cf0aeSJoe Perches			}
7346459cf0aeSJoe Perches		}
7347459cf0aeSJoe Perches
7348459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7349bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
735000180468SJoe Perches			my $oval = $1;
735100180468SJoe Perches			my $octal = perms_to_octal($oval);
7352f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7353459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7354f90774e1SJoe Perches			    $fix) {
735500180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
73562435880fSJoe Perches			}
735713214adfSAndy Whitcroft		}
73585a6d20ceSBjorn Andersson
73595a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
73605a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
73615a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
73625a6d20ceSBjorn Andersson			my $valid_licenses = qr{
73635a6d20ceSBjorn Andersson						GPL|
73645a6d20ceSBjorn Andersson						GPL\ v2|
73655a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
73665a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
73675a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
73685a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
73695a6d20ceSBjorn Andersson						Proprietary
73705a6d20ceSBjorn Andersson					}x;
73715a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
73725a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
73735a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
73745a6d20ceSBjorn Andersson			}
73755a6d20ceSBjorn Andersson		}
73766a8d76cbSMatteo Croce
73776a8d76cbSMatteo Croce# check for sysctl duplicate constants
73786a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
73796a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
73806a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
73816a8d76cbSMatteo Croce		}
7382515a235eSJoe Perches	}
738313214adfSAndy Whitcroft
738413214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
738513214adfSAndy Whitcroft	# so just keep quiet.
738613214adfSAndy Whitcroft	if ($#rawlines == -1) {
738713214adfSAndy Whitcroft		exit(0);
73880a920b5bSAndy Whitcroft	}
73890a920b5bSAndy Whitcroft
73908905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
73918905a67cSAndy Whitcroft	# things that appear to be patches.
73928905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
73938905a67cSAndy Whitcroft		exit(0);
73948905a67cSAndy Whitcroft	}
73958905a67cSAndy Whitcroft
7396e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
73978905a67cSAndy Whitcroft	# just keep quiet.
73988905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
73998905a67cSAndy Whitcroft		exit(0);
74008905a67cSAndy Whitcroft	}
74018905a67cSAndy Whitcroft
7402a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7403000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7404000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
74050a920b5bSAndy Whitcroft	}
7406cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7407cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7408000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7409000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
741048ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
741148ca2d8aSDwaipayan Ray			# authorsignoff values:
741248ca2d8aSDwaipayan Ray			# 0 -> missing sign off
741348ca2d8aSDwaipayan Ray			# 1 -> sign off identical
741448ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
741548ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
741648ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
741748ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
741848ca2d8aSDwaipayan Ray
741948ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
742048ca2d8aSDwaipayan Ray
742148ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
742248ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7423cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
742448ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
742548ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
742648ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
742748ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
742848ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
742948ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
743048ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
743148ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
743248ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
743348ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
743448ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
743548ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
743648ca2d8aSDwaipayan Ray			}
7437cd261496SGeert Uytterhoeven		}
74380a920b5bSAndy Whitcroft	}
74390a920b5bSAndy Whitcroft
7440f0a594c1SAndy Whitcroft	print report_dump();
744113214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
744213214adfSAndy Whitcroft		print "$filename " if ($summary_file);
74436c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
74446c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
74456c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
74466c72ffaaSAndy Whitcroft	}
74478905a67cSAndy Whitcroft
7448d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7449ef212196SJoe Perches		# If there were any defects found and not already fixing them
7450ef212196SJoe Perches		if (!$clean and !$fix) {
7451ef212196SJoe Perches			print << "EOM"
7452ef212196SJoe Perches
7453ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7454ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7455ef212196SJoe PerchesEOM
7456ef212196SJoe Perches		}
7457d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7458d2c0a235SAndy Whitcroft		# then suggest that.
7459d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7460b0781216SMike Frysinger			$rpt_cleaners = 0;
7461d8469f16SJoe Perches			print << "EOM"
7462d8469f16SJoe Perches
7463d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7464d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7465d8469f16SJoe PerchesEOM
7466d2c0a235SAndy Whitcroft		}
7467d2c0a235SAndy Whitcroft	}
7468d2c0a235SAndy Whitcroft
7469d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7470d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7471d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
74729624b8d6SJoe Perches		my $newfile = $filename;
74739624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
74743705ce5bSJoe Perches		my $linecount = 0;
74753705ce5bSJoe Perches		my $f;
74763705ce5bSJoe Perches
7477d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7478d752fcc8SJoe Perches
74793705ce5bSJoe Perches		open($f, '>', $newfile)
74803705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
74813705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
74823705ce5bSJoe Perches			$linecount++;
74833705ce5bSJoe Perches			if ($file) {
74843705ce5bSJoe Perches				if ($linecount > 3) {
74853705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
74863705ce5bSJoe Perches					print $f $fixed_line . "\n";
74873705ce5bSJoe Perches				}
74883705ce5bSJoe Perches			} else {
74893705ce5bSJoe Perches				print $f $fixed_line . "\n";
74903705ce5bSJoe Perches			}
74913705ce5bSJoe Perches		}
74923705ce5bSJoe Perches		close($f);
74933705ce5bSJoe Perches
74943705ce5bSJoe Perches		if (!$quiet) {
74953705ce5bSJoe Perches			print << "EOM";
7496d8469f16SJoe Perches
74973705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
74983705ce5bSJoe Perches
74993705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
75003705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
75013705ce5bSJoe Perches
75023705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
75033705ce5bSJoe PerchesNo warranties, expressed or implied...
75043705ce5bSJoe PerchesEOM
75053705ce5bSJoe Perches		}
75063705ce5bSJoe Perches	}
75073705ce5bSJoe Perches
7508d8469f16SJoe Perches	if ($quiet == 0) {
7509d8469f16SJoe Perches		print "\n";
7510d8469f16SJoe Perches		if ($clean == 1) {
7511d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7512d8469f16SJoe Perches		} else {
7513d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
75140a920b5bSAndy Whitcroft		}
75150a920b5bSAndy Whitcroft	}
75160a920b5bSAndy Whitcroft	return $clean;
75170a920b5bSAndy Whitcroft}
7518