xref: /linux-6.15/scripts/checkpatch.pl (revision bc2f19d6)
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;
31d5d6281aSDan Carpentermy $chk_fixes_tag = 1;
320a920b5bSAndy Whitcroftmy $chk_patch = 1;
33773647a0SAndy Whitcroftmy $tst_only;
346c72ffaaSAndy Whitcroftmy $emacs = 0;
358905a67cSAndy Whitcroftmy $terse = 0;
3634d8815fSJoe Perchesmy $showfile = 0;
376c72ffaaSAndy Whitcroftmy $file = 0;
384a593c34SDu, Changbinmy $git = 0;
390dea9f1eSJoe Perchesmy %git_commits = ();
406c72ffaaSAndy Whitcroftmy $check = 0;
412ac73b4fSJoe Perchesmy $check_orig = 0;
428905a67cSAndy Whitcroftmy $summary = 1;
438905a67cSAndy Whitcroftmy $mailback = 0;
4413214adfSAndy Whitcroftmy $summary_file = 0;
45000d1cc1SJoe Perchesmy $show_types = 0;
463beb42ecSJoe Perchesmy $list_types = 0;
473705ce5bSJoe Perchesmy $fix = 0;
489624b8d6SJoe Perchesmy $fix_inplace = 0;
496c72ffaaSAndy Whitcroftmy $root;
500f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'};
510f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot);
52c2fdda0dSAndy Whitcroftmy %debug;
533445686aSJoe Perchesmy %camelcase = ();
5491bfe484SJoe Perchesmy %use_type = ();
5591bfe484SJoe Perchesmy @use = ();
5691bfe484SJoe Perchesmy %ignore_type = ();
57000d1cc1SJoe Perchesmy @ignore = ();
5877f5b10aSHannes Edermy $help = 0;
59000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
60bdc48fa1SJoe Perchesmy $max_line_length = 100;
61d62a201fSDave Hansenmy $ignore_perl_version = 0;
62d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
6356193274SVadim Bendeburymy $min_conf_desc_length = 4;
6466b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
65ebfd7d62SJoe Perchesmy $codespell = 0;
66f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
670ee3e7b8SPeter Ujfalusimy $user_codespellfile = "";
68bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
6952178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
70ced69da1SQuentin Monnetmy $typedefsfile;
71737c0767SJohn Brooksmy $color = "auto";
7298005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
73dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
74dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
75713a09deSAntonio Borneomy $tabsize = 8;
763e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_";
7777f5b10aSHannes Eder
785b2c7334SJim Cromiemy %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h
795b2c7334SJim Cromie
8077f5b10aSHannes Edersub help {
8177f5b10aSHannes Eder	my ($exitcode) = @_;
8277f5b10aSHannes Eder
8377f5b10aSHannes Eder	print << "EOM";
8477f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
8577f5b10aSHannes EderVersion: $V
8677f5b10aSHannes Eder
8777f5b10aSHannes EderOptions:
8877f5b10aSHannes Eder  -q, --quiet                quiet
8952178ce0SDwaipayan Ray  -v, --verbose              verbose mode
9077f5b10aSHannes Eder  --no-tree                  run without a kernel tree
9177f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
92d5d6281aSDan Carpenter  --no-fixes-tag             do not check for 'Fixes:' tag
9377f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
9477f5b10aSHannes Eder  --emacs                    emacs compile window format
9577f5b10aSHannes Eder  --terse                    one line per report
9634d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
974a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
984a593c34SDu, Changbin                             single git commit with:
994a593c34SDu, Changbin                               <rev>
1004a593c34SDu, Changbin                               <rev>^
1014a593c34SDu, Changbin                               <rev>~n
1024a593c34SDu, Changbin                             multiple git commits with:
1034a593c34SDu, Changbin                               <rev1>..<rev2>
1044a593c34SDu, Changbin                               <rev1>...<rev2>
1054a593c34SDu, Changbin                               <rev>-<count>
1064a593c34SDu, Changbin                             git merges are ignored
10777f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
10877f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
1093beb42ecSJoe Perches  --list-types               list the possible message types
11091bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
111000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1123beb42ecSJoe Perches  --show-types               show the specific message type in the output
113bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
114bdc48fa1SJoe Perches                             if exceeded, warn on patches
115bdc48fa1SJoe Perches                             requires --strict for use with --file
116*bc2f19d6SPhilipp Hahn  --min-conf-desc-length=n   set the minimum description length for config symbols
117*bc2f19d6SPhilipp Hahn                             in lines, if shorter, warn (default $min_conf_desc_length)
118bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
11977f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
12077f5b10aSHannes Eder  --no-summary               suppress the per-file summary
12177f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
12277f5b10aSHannes Eder  --summary-file             include the filename in summary
12377f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
12477f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
12577f5b10aSHannes Eder                             is all off)
12677f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
12777f5b10aSHannes Eder                             literally
1283705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1293705ce5bSJoe Perches                             If correctable single-line errors exist, create
1303705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1313705ce5bSJoe Perches                             with potential errors corrected to the preferred
1323705ce5bSJoe Perches                             checkpatch style
1339624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1349624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1359624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
136d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
137d62a201fSDave Hansen                             runtime errors.
138ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
1390ee3e7b8SPeter Ujfalusi                             (default:$codespellfile)
140ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
14175ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
142737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
143737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
1443e89ad85SJerome Forissier  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1453e89ad85SJerome Forissier                             ${CONFIG_})
14677f5b10aSHannes Eder  -h, --help, --version      display this help and exit
14777f5b10aSHannes Eder
14877f5b10aSHannes EderWhen FILE is - read standard input.
14977f5b10aSHannes EderEOM
15077f5b10aSHannes Eder
15177f5b10aSHannes Eder	exit($exitcode);
15277f5b10aSHannes Eder}
15377f5b10aSHannes Eder
1543beb42ecSJoe Perchessub uniq {
1553beb42ecSJoe Perches	my %seen;
1563beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1573beb42ecSJoe Perches}
1583beb42ecSJoe Perches
1593beb42ecSJoe Perchessub list_types {
1603beb42ecSJoe Perches	my ($exitcode) = @_;
1613beb42ecSJoe Perches
1623beb42ecSJoe Perches	my $count = 0;
1633beb42ecSJoe Perches
1643beb42ecSJoe Perches	local $/ = undef;
1653beb42ecSJoe Perches
1663beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1673beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1683beb42ecSJoe Perches
1693beb42ecSJoe Perches	my $text = <$script>;
1703beb42ecSJoe Perches	close($script);
1713beb42ecSJoe Perches
17252178ce0SDwaipayan Ray	my %types = ();
1730547fa58SJean Delvare	# Also catch when type or level is passed through a variable
17452178ce0SDwaipayan Ray	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
17552178ce0SDwaipayan Ray		if (defined($1)) {
17652178ce0SDwaipayan Ray			if (exists($types{$2})) {
17752178ce0SDwaipayan Ray				$types{$2} .= ",$1" if ($types{$2} ne $1);
17852178ce0SDwaipayan Ray			} else {
17952178ce0SDwaipayan Ray				$types{$2} = $1;
1803beb42ecSJoe Perches			}
18152178ce0SDwaipayan Ray		} else {
18252178ce0SDwaipayan Ray			$types{$2} = "UNDETERMINED";
18352178ce0SDwaipayan Ray		}
18452178ce0SDwaipayan Ray	}
18552178ce0SDwaipayan Ray
1863beb42ecSJoe Perches	print("#\tMessage type\n\n");
18752178ce0SDwaipayan Ray	if ($color) {
18852178ce0SDwaipayan Ray		print(" ( Color coding: ");
18952178ce0SDwaipayan Ray		print(RED . "ERROR" . RESET);
19052178ce0SDwaipayan Ray		print(" | ");
19152178ce0SDwaipayan Ray		print(YELLOW . "WARNING" . RESET);
19252178ce0SDwaipayan Ray		print(" | ");
19352178ce0SDwaipayan Ray		print(GREEN . "CHECK" . RESET);
19452178ce0SDwaipayan Ray		print(" | ");
19552178ce0SDwaipayan Ray		print("Multiple levels / Undetermined");
19652178ce0SDwaipayan Ray		print(" )\n\n");
19752178ce0SDwaipayan Ray	}
19852178ce0SDwaipayan Ray
19952178ce0SDwaipayan Ray	foreach my $type (sort keys %types) {
20052178ce0SDwaipayan Ray		my $orig_type = $type;
20152178ce0SDwaipayan Ray		if ($color) {
20252178ce0SDwaipayan Ray			my $level = $types{$type};
20352178ce0SDwaipayan Ray			if ($level eq "ERROR") {
20452178ce0SDwaipayan Ray				$type = RED . $type . RESET;
20552178ce0SDwaipayan Ray			} elsif ($level eq "WARN") {
20652178ce0SDwaipayan Ray				$type = YELLOW . $type . RESET;
20752178ce0SDwaipayan Ray			} elsif ($level eq "CHK") {
20852178ce0SDwaipayan Ray				$type = GREEN . $type . RESET;
20952178ce0SDwaipayan Ray			}
21052178ce0SDwaipayan Ray		}
2113beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
21252178ce0SDwaipayan Ray		if ($verbose && exists($verbose_messages{$orig_type})) {
21352178ce0SDwaipayan Ray			my $message = $verbose_messages{$orig_type};
21452178ce0SDwaipayan Ray			$message =~ s/\n/\n\t/g;
21552178ce0SDwaipayan Ray			print("\t" . $message . "\n\n");
21652178ce0SDwaipayan Ray		}
2173beb42ecSJoe Perches	}
2183beb42ecSJoe Perches
2193beb42ecSJoe Perches	exit($exitcode);
2203beb42ecSJoe Perches}
2213beb42ecSJoe Perches
222000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
223000d1cc1SJoe Perchesif (-f $conf) {
224000d1cc1SJoe Perches	my @conf_args;
225000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
226000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
227000d1cc1SJoe Perches
228000d1cc1SJoe Perches	while (<$conffile>) {
229000d1cc1SJoe Perches		my $line = $_;
230000d1cc1SJoe Perches
231000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
232000d1cc1SJoe Perches		$line =~ s/^\s*//g;
233000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
234000d1cc1SJoe Perches
235000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
236000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
237000d1cc1SJoe Perches
238000d1cc1SJoe Perches		my @words = split(" ", $line);
239000d1cc1SJoe Perches		foreach my $word (@words) {
240000d1cc1SJoe Perches			last if ($word =~ m/^#/);
241000d1cc1SJoe Perches			push (@conf_args, $word);
242000d1cc1SJoe Perches		}
243000d1cc1SJoe Perches	}
244000d1cc1SJoe Perches	close($conffile);
245000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
246000d1cc1SJoe Perches}
247000d1cc1SJoe Perches
24852178ce0SDwaipayan Raysub load_docs {
24952178ce0SDwaipayan Ray	open(my $docs, '<', "$docsfile")
25052178ce0SDwaipayan Ray	    or warn "$P: Can't read the documentation file $docsfile $!\n";
25152178ce0SDwaipayan Ray
25252178ce0SDwaipayan Ray	my $type = '';
25352178ce0SDwaipayan Ray	my $desc = '';
25452178ce0SDwaipayan Ray	my $in_desc = 0;
25552178ce0SDwaipayan Ray
25652178ce0SDwaipayan Ray	while (<$docs>) {
25752178ce0SDwaipayan Ray		chomp;
25852178ce0SDwaipayan Ray		my $line = $_;
25952178ce0SDwaipayan Ray		$line =~ s/\s+$//;
26052178ce0SDwaipayan Ray
26152178ce0SDwaipayan Ray		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
26252178ce0SDwaipayan Ray			if ($desc ne '') {
26352178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
26452178ce0SDwaipayan Ray			}
26552178ce0SDwaipayan Ray			$type = $1;
26652178ce0SDwaipayan Ray			$desc = '';
26752178ce0SDwaipayan Ray			$in_desc = 1;
26852178ce0SDwaipayan Ray		} elsif ($in_desc) {
26952178ce0SDwaipayan Ray			if ($line =~ /^(?:\s{4,}|$)/) {
27052178ce0SDwaipayan Ray				$line =~ s/^\s{4}//;
27152178ce0SDwaipayan Ray				$desc .= $line;
27252178ce0SDwaipayan Ray				$desc .= "\n";
27352178ce0SDwaipayan Ray			} else {
27452178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
27552178ce0SDwaipayan Ray				$type = '';
27652178ce0SDwaipayan Ray				$desc = '';
27752178ce0SDwaipayan Ray				$in_desc = 0;
27852178ce0SDwaipayan Ray			}
27952178ce0SDwaipayan Ray		}
28052178ce0SDwaipayan Ray	}
28152178ce0SDwaipayan Ray
28252178ce0SDwaipayan Ray	if ($desc ne '') {
28352178ce0SDwaipayan Ray		$verbose_messages{$type} = trim($desc);
28452178ce0SDwaipayan Ray	}
28552178ce0SDwaipayan Ray	close($docs);
28652178ce0SDwaipayan Ray}
28752178ce0SDwaipayan Ray
288737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
289737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
290737c0767SJohn Brooksforeach (@ARGV) {
291737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
292737c0767SJohn Brooks		$_ = "--color=$color";
293737c0767SJohn Brooks	}
294737c0767SJohn Brooks}
295737c0767SJohn Brooks
2960a920b5bSAndy WhitcroftGetOptions(
2976c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
29852178ce0SDwaipayan Ray	'v|verbose!'	=> \$verbose,
2990a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
3000a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
301d5d6281aSDan Carpenter	'fixes-tag!'	=> \$chk_fixes_tag,
3020a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
3036c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
3048905a67cSAndy Whitcroft	'terse!'	=> \$terse,
30534d8815fSJoe Perches	'showfile!'	=> \$showfile,
30677f5b10aSHannes Eder	'f|file!'	=> \$file,
3074a593c34SDu, Changbin	'g|git!'	=> \$git,
3086c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
3096c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
310000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
31191bfe484SJoe Perches	'types=s'	=> \@use,
312000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
3133beb42ecSJoe Perches	'list-types!'	=> \$list_types,
3146cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
31556193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
316713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
3176c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
3188905a67cSAndy Whitcroft	'summary!'	=> \$summary,
3198905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
32013214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
3213705ce5bSJoe Perches	'fix!'		=> \$fix,
3229624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
323d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
324c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
325773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
326ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
3270ee3e7b8SPeter Ujfalusi	'codespellfile=s'	=> \$user_codespellfile,
32875ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
329737c0767SJohn Brooks	'color=s'	=> \$color,
330737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
331737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
3323e89ad85SJerome Forissier	'kconfig-prefix=s'	=> \${CONFIG_},
33377f5b10aSHannes Eder	'h|help'	=> \$help,
33477f5b10aSHannes Eder	'version'	=> \$help
3350ee3e7b8SPeter Ujfalusi) or $help = 2;
33677f5b10aSHannes Eder
3370ee3e7b8SPeter Ujfalusiif ($user_codespellfile) {
3380ee3e7b8SPeter Ujfalusi	# Use the user provided codespell file unconditionally
3390ee3e7b8SPeter Ujfalusi	$codespellfile = $user_codespellfile;
3400ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) {
3410ee3e7b8SPeter Ujfalusi	# If /usr/share/codespell/dictionary.txt is not present, try to find it
3420ee3e7b8SPeter Ujfalusi	# under codespell's install directory: <codespell_root>/data/dictionary.txt
343c882c6b1SSagar Patel	if (($codespell || $help) && which("python3") ne "") {
3440ee3e7b8SPeter Ujfalusi		my $python_codespell_dict = << "EOF";
3450ee3e7b8SPeter Ujfalusi
3460ee3e7b8SPeter Ujfalusiimport os.path as op
3470ee3e7b8SPeter Ujfalusiimport codespell_lib
3480ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__)
3490ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
3500ee3e7b8SPeter Ujfalusiprint(codespell_file, end='')
3510ee3e7b8SPeter UjfalusiEOF
3520ee3e7b8SPeter Ujfalusi
353c882c6b1SSagar Patel		my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`;
3540ee3e7b8SPeter Ujfalusi		$codespellfile = $codespell_dict if (-f $codespell_dict);
3550ee3e7b8SPeter Ujfalusi	}
3560ee3e7b8SPeter Ujfalusi}
3570ee3e7b8SPeter Ujfalusi
3580ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0
3590ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1
3600ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help);
3610a920b5bSAndy Whitcroft
36252178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
36352178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
36452178ce0SDwaipayan Ray
36552178ce0SDwaipayan Rayif ($color =~ /^[01]$/) {
36652178ce0SDwaipayan Ray	$color = !$color;
36752178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) {
36852178ce0SDwaipayan Ray	$color = 1;
36952178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) {
37052178ce0SDwaipayan Ray	$color = 0;
37152178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) {
37252178ce0SDwaipayan Ray	$color = (-t STDOUT);
37352178ce0SDwaipayan Ray} else {
37452178ce0SDwaipayan Ray	die "$P: Invalid color mode: $color\n";
37552178ce0SDwaipayan Ray}
37652178ce0SDwaipayan Ray
37752178ce0SDwaipayan Rayload_docs() if ($verbose);
3783beb42ecSJoe Percheslist_types(0) if ($list_types);
3793beb42ecSJoe Perches
3809624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
3812ac73b4fSJoe Perches$check_orig = $check;
3829624b8d6SJoe Perches
3830a920b5bSAndy Whitcroftmy $exit = 0;
3840a920b5bSAndy Whitcroft
3855b57980dSJoe Perchesmy $perl_version_ok = 1;
386d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
3875b57980dSJoe Perches	$perl_version_ok = 0;
388d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
3895b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
390d62a201fSDave Hansen}
391d62a201fSDave Hansen
39245107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
3930a920b5bSAndy Whitcroftif ($#ARGV < 0) {
39445107ff6SAllen Hubbe	push(@ARGV, '-');
3950a920b5bSAndy Whitcroft}
3960a920b5bSAndy Whitcroft
397713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
39832f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
399713a09deSAntonio Borneo
40091bfe484SJoe Perchessub hash_save_array_words {
40191bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
40291bfe484SJoe Perches
40391bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
40491bfe484SJoe Perches	foreach my $word (@array) {
405000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
406000d1cc1SJoe Perches		$word =~ s/^\s*//g;
407000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
408000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
409000d1cc1SJoe Perches
410000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
411000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
412000d1cc1SJoe Perches
41391bfe484SJoe Perches		$hashRef->{$word}++;
414000d1cc1SJoe Perches	}
41591bfe484SJoe Perches}
41691bfe484SJoe Perches
41791bfe484SJoe Perchessub hash_show_words {
41891bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
41991bfe484SJoe Perches
4203c816e49SJoe Perches	if (keys %$hashRef) {
421d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
42258cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
42391bfe484SJoe Perches			print " $word";
42491bfe484SJoe Perches		}
425d8469f16SJoe Perches		print "\n";
42691bfe484SJoe Perches	}
42791bfe484SJoe Perches}
42891bfe484SJoe Perches
42991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
43091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
431000d1cc1SJoe Perches
432c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
433c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
4347429c690SAndy Whitcroftmy $dbg_type = 0;
435a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
436c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
43721caa13cSAndy Whitcroft	## no critic
43821caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
43921caa13cSAndy Whitcroft	die "$@" if ($@);
440c2fdda0dSAndy Whitcroft}
441c2fdda0dSAndy Whitcroft
442d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
443d2c0a235SAndy Whitcroft
4448905a67cSAndy Whitcroftif ($terse) {
4458905a67cSAndy Whitcroft	$emacs = 1;
4468905a67cSAndy Whitcroft	$quiet++;
4478905a67cSAndy Whitcroft}
4488905a67cSAndy Whitcroft
4496c72ffaaSAndy Whitcroftif ($tree) {
4506c72ffaaSAndy Whitcroft	if (defined $root) {
4516c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
4526c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
4536c72ffaaSAndy Whitcroft		}
4546c72ffaaSAndy Whitcroft	} else {
4556c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
4566c72ffaaSAndy Whitcroft			$root = '.';
4576c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
4586c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
4596c72ffaaSAndy Whitcroft			$root = $1;
4606c72ffaaSAndy Whitcroft		}
4616c72ffaaSAndy Whitcroft	}
4626c72ffaaSAndy Whitcroft
4636c72ffaaSAndy Whitcroft	if (!defined $root) {
4640a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
4650a920b5bSAndy Whitcroft		exit(2);
4660a920b5bSAndy Whitcroft	}
4676c72ffaaSAndy Whitcroft}
4686c72ffaaSAndy Whitcroft
4696c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
4706c72ffaaSAndy Whitcroft
4712ceb532bSAndy Whitcroftour $Ident	= qr{
4722ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
4732ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
4742ceb532bSAndy Whitcroft		}x;
4756c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
4766c72ffaaSAndy Whitcroftour $Sparse	= qr{
4776c72ffaaSAndy Whitcroft			__user|
4786c72ffaaSAndy Whitcroft			__kernel|
4796c72ffaaSAndy Whitcroft			__force|
4806c72ffaaSAndy Whitcroft			__iomem|
4816c72ffaaSAndy Whitcroft			__must_check|
482417495edSAndy Whitcroft			__kprobes|
483165e72a6SSven Eckelmann			__ref|
48433aa4597SGeert Uytterhoeven			__refconst|
48533aa4597SGeert Uytterhoeven			__refdata|
486ad315455SBoqun Feng			__rcu|
487ad315455SBoqun Feng			__private
4886c72ffaaSAndy Whitcroft		}x;
489e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
490e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
491e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
492e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
493e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
4948716de38SJoe Perches
49552131292SWolfram Sang# Notes to $Attribute:
49652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
4976c72ffaaSAndy Whitcroftour $Attribute	= qr{
4986c72ffaaSAndy Whitcroft			const|
499b5e8736aSJoe Perches			volatile|
50003f1df7dSJoe Perches			__percpu|
50103f1df7dSJoe Perches			__nocast|
50203f1df7dSJoe Perches			__safe|
50346d832f5SMichael S. Tsirkin			__bitwise|
50403f1df7dSJoe Perches			__packed__|
50503f1df7dSJoe Perches			__packed2__|
50603f1df7dSJoe Perches			__naked|
50703f1df7dSJoe Perches			__maybe_unused|
50803f1df7dSJoe Perches			__always_unused|
50903f1df7dSJoe Perches			__noreturn|
51003f1df7dSJoe Perches			__used|
51103f1df7dSJoe Perches			__cold|
512e23ef1f3SJoe Perches			__pure|
51303f1df7dSJoe Perches			__noclone|
51403f1df7dSJoe Perches			__deprecated|
5156c72ffaaSAndy Whitcroft			__read_mostly|
516c5967e98SJoe Perches			__ro_after_init|
5176c72ffaaSAndy Whitcroft			__kprobes|
5188716de38SJoe Perches			$InitAttribute|
5192f9dadbaSMarcelo Schmitt			__aligned\s*\(.*\)|
52024e1d81aSAndy Whitcroft			____cacheline_aligned|
52124e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
5225fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
52386cffecdSKees Cook			__weak|
52486cffecdSKees Cook			__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
5256c72ffaaSAndy Whitcroft		  }x;
526c45dcabdSAndy Whitcroftour $Modifier;
52791cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
5286c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
5296c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
5306c72ffaaSAndy Whitcroft
53195e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
53295e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
53395e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
53495e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
5352435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
536d2af5aa6SJoe Perchesour $String	= qr{(?:\b[Lu])?"[X\t]*"};
537326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
538326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
539326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
54074349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
5412435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
542326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
543447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
54423f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
5456c72ffaaSAndy Whitcroftour $Operators	= qr{
5466c72ffaaSAndy Whitcroft			<=|>=|==|!=|
5476c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
54823f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
5496c72ffaaSAndy Whitcroft		  }x;
5506c72ffaaSAndy Whitcroft
55191cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
55291cb5195SJoe Perches
553ab7e23f3SJoe Perchesour $BasicType;
5548905a67cSAndy Whitcroftour $NonptrType;
5551813087dSJoe Perchesour $NonptrTypeMisordered;
5568716de38SJoe Perchesour $NonptrTypeWithAttr;
5578905a67cSAndy Whitcroftour $Type;
5581813087dSJoe Perchesour $TypeMisordered;
5598905a67cSAndy Whitcroftour $Declare;
5601813087dSJoe Perchesour $DeclareMisordered;
5618905a67cSAndy Whitcroft
56215662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
56315662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
564171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
565171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
566171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
567171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
568171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
569171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
570171ae1a4SAndy Whitcroft}x;
571171ae1a4SAndy Whitcroft
57215662b3eSJoe Perchesour $UTF8	= qr{
57315662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
57415662b3eSJoe Perches	| $NON_ASCII_UTF8
57515662b3eSJoe Perches}x;
57615662b3eSJoe Perches
577e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
578021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
579021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
580021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
581021158b4SJoe Perches)};
582e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
583fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
5848ed22cadSAndy Whitcroft	atomic_t
5858ed22cadSAndy Whitcroft)};
5868ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x:
5878ea0114eSMickaël Salaün	FILE
5888ea0114eSMickaël Salaün)};
589e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
590e6176fa4SJoe Perches	$typeC99Typedefs\b|
591e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
5928ea0114eSMickaël Salaün	$typeKernelTypedefs\b|
5938ea0114eSMickaël Salaün	$typeStdioTypedefs\b
594e6176fa4SJoe Perches)};
5958ed22cadSAndy Whitcroft
5966d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
5976d32f7a3SJoe Perches
598691e669bSJoe Perchesour $logFunctions = qr{(?x:
599758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
6007d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
60187bd499aSJoe Perches	TP_printk|
6026e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
603b0531722SJoe Perches	panic|
60406668727SJoe Perches	MODULE_[A-Z_]+|
60506668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
606691e669bSJoe Perches)};
607691e669bSJoe Perches
608e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
609e29a70f1SJoe Perches	(?:(?:devm_)?
61058f02267SJoe Perches		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
611e29a70f1SJoe Perches		kstrdup(?:_const)? |
612e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
613461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
614e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
615e29a70f1SJoe Perches	dma_alloc_coherent
616e29a70f1SJoe Perches)};
617e29a70f1SJoe Perches
61820112475SJoe Perchesour $signature_tags = qr{(?xi:
61920112475SJoe Perches	Signed-off-by:|
620d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
62120112475SJoe Perches	Acked-by:|
62220112475SJoe Perches	Tested-by:|
62320112475SJoe Perches	Reviewed-by:|
62420112475SJoe Perches	Reported-by:|
6258543ae12SMugunthan V N	Suggested-by:|
62620112475SJoe Perches	To:|
62720112475SJoe Perches	Cc:
62820112475SJoe Perches)};
62920112475SJoe Perches
63044c31888SMatthieu Baertsour @link_tags = qw(Link Closes);
631f94e40eaSMatthieu Baerts
632f94e40eaSMatthieu Baerts#Create a search and print patterns for all these strings to be used directly below
633f94e40eaSMatthieu Baertsour $link_tags_search = "";
634f94e40eaSMatthieu Baertsour $link_tags_print = "";
635f94e40eaSMatthieu Baertsforeach my $entry (@link_tags) {
636f94e40eaSMatthieu Baerts	if ($link_tags_search ne "") {
637f94e40eaSMatthieu Baerts		$link_tags_search .= '|';
638f94e40eaSMatthieu Baerts		$link_tags_print .= ' or ';
639f94e40eaSMatthieu Baerts	}
640f94e40eaSMatthieu Baerts	$entry .= ':';
641f94e40eaSMatthieu Baerts	$link_tags_search .= $entry;
642f94e40eaSMatthieu Baerts	$link_tags_print .= "'$entry'";
643f94e40eaSMatthieu Baerts}
644f94e40eaSMatthieu Baerts$link_tags_search = "(?:${link_tags_search})";
645f94e40eaSMatthieu Baerts
646adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
647adb2da82SJoe Perches	[=-]*> |
648adb2da82SJoe Perches	<[=-]* |
649adb2da82SJoe Perches	\[ |
650adb2da82SJoe Perches	\] |
651adb2da82SJoe Perches	start |
652adb2da82SJoe Perches	called |
653adb2da82SJoe Perches	entered |
654adb2da82SJoe Perches	entry |
655adb2da82SJoe Perches	enter |
656adb2da82SJoe Perches	in |
657adb2da82SJoe Perches	inside |
658adb2da82SJoe Perches	here |
659adb2da82SJoe Perches	begin |
660adb2da82SJoe Perches	exit |
661adb2da82SJoe Perches	end |
662adb2da82SJoe Perches	done |
663adb2da82SJoe Perches	leave |
664adb2da82SJoe Perches	completed |
665adb2da82SJoe Perches	out |
666adb2da82SJoe Perches	return |
667adb2da82SJoe Perches	[\.\!:\s]*
668adb2da82SJoe Perches)};
669adb2da82SJoe Perches
670831242abSAditya Srivastavasub edit_distance_min {
671831242abSAditya Srivastava	my (@arr) = @_;
672831242abSAditya Srivastava	my $len = scalar @arr;
673831242abSAditya Srivastava	if ((scalar @arr) < 1) {
674831242abSAditya Srivastava		# if underflow, return
675831242abSAditya Srivastava		return;
676831242abSAditya Srivastava	}
677831242abSAditya Srivastava	my $min = $arr[0];
678831242abSAditya Srivastava	for my $i (0 .. ($len-1)) {
679831242abSAditya Srivastava		if ($arr[$i] < $min) {
680831242abSAditya Srivastava			$min = $arr[$i];
681831242abSAditya Srivastava		}
682831242abSAditya Srivastava	}
683831242abSAditya Srivastava	return $min;
684831242abSAditya Srivastava}
685831242abSAditya Srivastava
686831242abSAditya Srivastavasub get_edit_distance {
687831242abSAditya Srivastava	my ($str1, $str2) = @_;
688831242abSAditya Srivastava	$str1 = lc($str1);
689831242abSAditya Srivastava	$str2 = lc($str2);
690831242abSAditya Srivastava	$str1 =~ s/-//g;
691831242abSAditya Srivastava	$str2 =~ s/-//g;
692831242abSAditya Srivastava	my $len1 = length($str1);
693831242abSAditya Srivastava	my $len2 = length($str2);
694831242abSAditya Srivastava	# two dimensional array storing minimum edit distance
695831242abSAditya Srivastava	my @distance;
696831242abSAditya Srivastava	for my $i (0 .. $len1) {
697831242abSAditya Srivastava		for my $j (0 .. $len2) {
698831242abSAditya Srivastava			if ($i == 0) {
699831242abSAditya Srivastava				$distance[$i][$j] = $j;
700831242abSAditya Srivastava			} elsif ($j == 0) {
701831242abSAditya Srivastava				$distance[$i][$j] = $i;
702831242abSAditya Srivastava			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
703831242abSAditya Srivastava				$distance[$i][$j] = $distance[$i - 1][$j - 1];
704831242abSAditya Srivastava			} else {
705831242abSAditya Srivastava				my $dist1 = $distance[$i][$j - 1]; #insert distance
706831242abSAditya Srivastava				my $dist2 = $distance[$i - 1][$j]; # remove
707831242abSAditya Srivastava				my $dist3 = $distance[$i - 1][$j - 1]; #replace
708831242abSAditya Srivastava				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
709831242abSAditya Srivastava			}
710831242abSAditya Srivastava		}
711831242abSAditya Srivastava	}
712831242abSAditya Srivastava	return $distance[$len1][$len2];
713831242abSAditya Srivastava}
714831242abSAditya Srivastava
715831242abSAditya Srivastavasub find_standard_signature {
716831242abSAditya Srivastava	my ($sign_off) = @_;
717831242abSAditya Srivastava	my @standard_signature_tags = (
718831242abSAditya Srivastava		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
719831242abSAditya Srivastava		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
720831242abSAditya Srivastava	);
721831242abSAditya Srivastava	foreach my $signature (@standard_signature_tags) {
722831242abSAditya Srivastava		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
723831242abSAditya Srivastava	}
724831242abSAditya Srivastava
725831242abSAditya Srivastava	return "";
726831242abSAditya Srivastava}
727831242abSAditya Srivastava
7289b71f79fSBjorn Helgaasour $obsolete_archives = qr{(?xi:
7299b71f79fSBjorn Helgaas	\Qfreedesktop.org/archives/dri-devel\E |
7309b71f79fSBjorn Helgaas	\Qlists.infradead.org\E |
7319b71f79fSBjorn Helgaas	\Qlkml.org\E |
7329b71f79fSBjorn Helgaas	\Qmail-archive.com\E |
7339b71f79fSBjorn Helgaas	\Qmailman.alsa-project.org/pipermail\E |
7349b71f79fSBjorn Helgaas	\Qmarc.info\E |
7359b71f79fSBjorn Helgaas	\Qozlabs.org/pipermail\E |
7369b71f79fSBjorn Helgaas	\Qspinics.net\E
7379b71f79fSBjorn Helgaas)};
7389b71f79fSBjorn Helgaas
7391813087dSJoe Perchesour @typeListMisordered = (
7401813087dSJoe Perches	qr{char\s+(?:un)?signed},
7411813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
7421813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
7431813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
7441813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
7451813087dSJoe Perches	qr{short\s+(?:un)?signed},
7461813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
7471813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
7481813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
7491813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
7501813087dSJoe Perches	qr{int\s+(?:un)?signed},
7511813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
7521813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
7531813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
7541813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
7551813087dSJoe Perches	qr{long\s+(?:un)?signed},
7561813087dSJoe Perches);
7571813087dSJoe Perches
7588905a67cSAndy Whitcroftour @typeList = (
7598905a67cSAndy Whitcroft	qr{void},
7600c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
7610c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
7620c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
7630c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
7640c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
7650c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
7660c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
7670c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
7680c773d9dSJoe Perches	qr{(?:un)?signed},
7698905a67cSAndy Whitcroft	qr{float},
7708905a67cSAndy Whitcroft	qr{double},
7718905a67cSAndy Whitcroft	qr{bool},
7728905a67cSAndy Whitcroft	qr{struct\s+$Ident},
7738905a67cSAndy Whitcroft	qr{union\s+$Ident},
7748905a67cSAndy Whitcroft	qr{enum\s+$Ident},
7758905a67cSAndy Whitcroft	qr{${Ident}_t},
7768905a67cSAndy Whitcroft	qr{${Ident}_handler},
7778905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
7781813087dSJoe Perches	@typeListMisordered,
7798905a67cSAndy Whitcroft);
780938224b5SJoe Perches
781938224b5SJoe Perchesour $C90_int_types = qr{(?x:
782938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
783938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
784938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
785938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
786938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
787938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
788938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
789938224b5SJoe Perches
790938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
791938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
792938224b5SJoe Perches	long\s+(?:un)?signed|
793938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
794938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
795938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
796938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
797938224b5SJoe Perches
798938224b5SJoe Perches	int\s+(?:un)?signed|
799938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
800938224b5SJoe Perches)};
801938224b5SJoe Perches
802485ff23eSAlex Dowadour @typeListFile = ();
8038716de38SJoe Perchesour @typeListWithAttr = (
8048716de38SJoe Perches	@typeList,
8058716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
8068716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
8078716de38SJoe Perches);
8088716de38SJoe Perches
809c45dcabdSAndy Whitcroftour @modifierList = (
810c45dcabdSAndy Whitcroft	qr{fastcall},
811c45dcabdSAndy Whitcroft);
812485ff23eSAlex Dowadour @modifierListFile = ();
8138905a67cSAndy Whitcroft
8142435880fSJoe Perchesour @mode_permission_funcs = (
8152435880fSJoe Perches	["module_param", 3],
8162435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
8172435880fSJoe Perches	["module_param_array_named", 5],
8182435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
8192435880fSJoe Perches	["proc_create(?:_data|)", 2],
820459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
821459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
822459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
823459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
824459cf0aeSJoe Perches	["__ATTR", 2],
8252435880fSJoe Perches);
8262435880fSJoe Perches
8271a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
8281a3dcf2eSJoe Perches
829515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
830515a235eSJoe Perchesour $mode_perms_search = "";
831515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
832515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
833515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
834515a235eSJoe Perches}
83500180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
836515a235eSJoe Perches
8379189c7e7SJoe Perchesour %deprecated_apis = (
838defdaff1SIra Weiny	"kmap"					=> "kmap_local_page",
839a3ea42ffSIra Weiny	"kunmap"				=> "kunmap_local",
840defdaff1SIra Weiny	"kmap_atomic"				=> "kmap_local_page",
841a3ea42ffSIra Weiny	"kunmap_atomic"				=> "kunmap_local",
8429189c7e7SJoe Perches);
8439189c7e7SJoe Perches
8449189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
8459189c7e7SJoe Perchesour $deprecated_apis_search = "";
8469189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
8479189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
8489189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
8499189c7e7SJoe Perches}
8509189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
8519189c7e7SJoe Perches
852b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
853b392c64fSJoe Perches	S_IWUGO		|
854b392c64fSJoe Perches	S_IWOTH		|
855b392c64fSJoe Perches	S_IRWXUGO	|
856b392c64fSJoe Perches	S_IALLUGO	|
857b392c64fSJoe Perches	0[0-7][0-7][2367]
858b392c64fSJoe Perches}x;
859b392c64fSJoe Perches
860f90774e1SJoe Perchesour %mode_permission_string_types = (
861f90774e1SJoe Perches	"S_IRWXU" => 0700,
862f90774e1SJoe Perches	"S_IRUSR" => 0400,
863f90774e1SJoe Perches	"S_IWUSR" => 0200,
864f90774e1SJoe Perches	"S_IXUSR" => 0100,
865f90774e1SJoe Perches	"S_IRWXG" => 0070,
866f90774e1SJoe Perches	"S_IRGRP" => 0040,
867f90774e1SJoe Perches	"S_IWGRP" => 0020,
868f90774e1SJoe Perches	"S_IXGRP" => 0010,
869f90774e1SJoe Perches	"S_IRWXO" => 0007,
870f90774e1SJoe Perches	"S_IROTH" => 0004,
871f90774e1SJoe Perches	"S_IWOTH" => 0002,
872f90774e1SJoe Perches	"S_IXOTH" => 0001,
873f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
874f90774e1SJoe Perches	"S_IRUGO" => 0444,
875f90774e1SJoe Perches	"S_IWUGO" => 0222,
876f90774e1SJoe Perches	"S_IXUGO" => 0111,
877f90774e1SJoe Perches);
878f90774e1SJoe Perches
879f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
880f90774e1SJoe Perchesour $mode_perms_string_search = "";
881f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
882f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
883f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
884f90774e1SJoe Perches}
88500180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
88600180468SJoe Perchesour $multi_mode_perms_string_search = qr{
88700180468SJoe Perches	${single_mode_perms_string_search}
88800180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
88900180468SJoe Perches}x;
89000180468SJoe Perches
89100180468SJoe Perchessub perms_to_octal {
89200180468SJoe Perches	my ($string) = @_;
89300180468SJoe Perches
89400180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
89500180468SJoe Perches
89600180468SJoe Perches	my $val = "";
89700180468SJoe Perches	my $oval = "";
89800180468SJoe Perches	my $to = 0;
89900180468SJoe Perches	my $curpos = 0;
90000180468SJoe Perches	my $lastpos = 0;
90100180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
90200180468SJoe Perches		$curpos = pos($string);
90300180468SJoe Perches		my $match = $2;
90400180468SJoe Perches		my $omatch = $1;
90500180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
90600180468SJoe Perches		$lastpos = $curpos;
90700180468SJoe Perches		$to |= $mode_permission_string_types{$match};
90800180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
90900180468SJoe Perches		$val .= $match;
91000180468SJoe Perches		$oval .= $omatch;
91100180468SJoe Perches	}
91200180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
91300180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
91400180468SJoe Perches	return sprintf("%04o", $to);
91500180468SJoe Perches}
916f90774e1SJoe Perches
9177840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
9187840a94cSWolfram Sang	irq|
919cdcee686SSergey Ryazanov	memory|
920cdcee686SSergey Ryazanov	time|
921cdcee686SSergey Ryazanov	reboot
9227840a94cSWolfram Sang)};
9237840a94cSWolfram Sang# memory.h: ARM has a custom one
9247840a94cSWolfram Sang
92566b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
92666b47b4aSKees Cookmy $misspellings;
92766b47b4aSKees Cookmy %spelling_fix;
92836061e38SJoe Perches
92936061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
93066b47b4aSKees Cook	while (<$spelling>) {
93166b47b4aSKees Cook		my $line = $_;
93266b47b4aSKees Cook
93366b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
93466b47b4aSKees Cook		$line =~ s/^\s*//g;
93566b47b4aSKees Cook
93666b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
93766b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
93866b47b4aSKees Cook
93966b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
94066b47b4aSKees Cook
94166b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
94266b47b4aSKees Cook	}
94366b47b4aSKees Cook	close($spelling);
94436061e38SJoe Perches} else {
94536061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
94636061e38SJoe Perches}
94766b47b4aSKees Cook
948ebfd7d62SJoe Perchesif ($codespell) {
949ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
950ebfd7d62SJoe Perches		while (<$spelling>) {
951ebfd7d62SJoe Perches			my $line = $_;
952ebfd7d62SJoe Perches
953ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
954ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
955ebfd7d62SJoe Perches
956ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
957ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
958ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
959ebfd7d62SJoe Perches
960ebfd7d62SJoe Perches			$line =~ s/,.*$//;
961ebfd7d62SJoe Perches
962ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
963ebfd7d62SJoe Perches
964ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
965ebfd7d62SJoe Perches		}
966ebfd7d62SJoe Perches		close($spelling);
967ebfd7d62SJoe Perches	} else {
968ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
969ebfd7d62SJoe Perches	}
970ebfd7d62SJoe Perches}
971ebfd7d62SJoe Perches
972ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
973ebfd7d62SJoe Perches
97475ad8c57SJerome Forissiersub read_words {
97575ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
97675ad8c57SJerome Forissier
97775ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
97875ad8c57SJerome Forissier		while (<$words>) {
979bf1fa1daSJoe Perches			my $line = $_;
980bf1fa1daSJoe Perches
981bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
982bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
983bf1fa1daSJoe Perches
984bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
985bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
986bf1fa1daSJoe Perches			if ($line =~ /\s/) {
98775ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
988bf1fa1daSJoe Perches				next;
989bf1fa1daSJoe Perches			}
990bf1fa1daSJoe Perches
991ced69da1SQuentin Monnet			$$wordsRef .= '|' if (defined $$wordsRef);
99275ad8c57SJerome Forissier			$$wordsRef .= $line;
993bf1fa1daSJoe Perches		}
99475ad8c57SJerome Forissier		close($file);
99575ad8c57SJerome Forissier		return 1;
996bf1fa1daSJoe Perches	}
997bf1fa1daSJoe Perches
99875ad8c57SJerome Forissier	return 0;
99975ad8c57SJerome Forissier}
100075ad8c57SJerome Forissier
1001ced69da1SQuentin Monnetmy $const_structs;
1002ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) {
100375ad8c57SJerome Forissier	read_words(\$const_structs, $conststructsfile)
100475ad8c57SJerome Forissier	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
1005ced69da1SQuentin Monnet}
100675ad8c57SJerome Forissier
1007ced69da1SQuentin Monnetif (defined($typedefsfile)) {
1008ced69da1SQuentin Monnet	my $typeOtherTypedefs;
100975ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
101075ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
1011ced69da1SQuentin Monnet	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
101275ad8c57SJerome Forissier}
101375ad8c57SJerome Forissier
10148905a67cSAndy Whitcroftsub build_types {
1015485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
1016485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
10171813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
10188716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
1019c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
1020ab7e23f3SJoe Perches	$BasicType	= qr{
1021ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
1022ab7e23f3SJoe Perches				(?:${all}\b)
1023ab7e23f3SJoe Perches		}x;
10248905a67cSAndy Whitcroft	$NonptrType	= qr{
1025d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
1026cf655043SAndy Whitcroft			(?:
10276b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
10288ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
1029c45dcabdSAndy Whitcroft				(?:${all}\b)
1030cf655043SAndy Whitcroft			)
1031c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
10328905a67cSAndy Whitcroft		  }x;
10331813087dSJoe Perches	$NonptrTypeMisordered	= qr{
10341813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
10351813087dSJoe Perches			(?:
10361813087dSJoe Perches				(?:${Misordered}\b)
10371813087dSJoe Perches			)
10381813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
10391813087dSJoe Perches		  }x;
10408716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
10418716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
10428716de38SJoe Perches			(?:
10438716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
10448716de38SJoe Perches				(?:$typeTypedefs\b)|
10458716de38SJoe Perches				(?:${allWithAttr}\b)
10468716de38SJoe Perches			)
10478716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
10488716de38SJoe Perches		  }x;
10498905a67cSAndy Whitcroft	$Type	= qr{
1050c45dcabdSAndy Whitcroft			$NonptrType
10517b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
1052c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
10538905a67cSAndy Whitcroft		  }x;
10541813087dSJoe Perches	$TypeMisordered	= qr{
10551813087dSJoe Perches			$NonptrTypeMisordered
10567b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
10571813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
10581813087dSJoe Perches		  }x;
105991cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
10601813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
10618905a67cSAndy Whitcroft}
10628905a67cSAndy Whitcroftbuild_types();
10636c72ffaaSAndy Whitcroft
10647d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
1065d1fe9c09SJoe Perches
1066d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1067d1fe9c09SJoe Perches# requires at least perl version v5.10.0
1068d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
1069d1fe9c09SJoe Perches
1070d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
10712435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
1072c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
10737d2367afSJoe Perches
1074f8422308SJoe Perchesour $declaration_macros = qr{(?x:
10753e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
1076fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
1077dcea7964SJoe Perches	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(|
1078dcea7964SJoe Perches	(?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\(
1079f8422308SJoe Perches)};
1080f8422308SJoe Perches
10818d0325ccSAditya Srivastavaour %allow_repeated_words = (
10828d0325ccSAditya Srivastava	add => '',
10838d0325ccSAditya Srivastava	added => '',
10848d0325ccSAditya Srivastava	bad => '',
10858d0325ccSAditya Srivastava	be => '',
10868d0325ccSAditya Srivastava);
10878d0325ccSAditya Srivastava
10887d2367afSJoe Perchessub deparenthesize {
10897d2367afSJoe Perches	my ($string) = @_;
10907d2367afSJoe Perches	return "" if (!defined($string));
10915b9553abSJoe Perches
10925b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
10935b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
10945b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
10955b9553abSJoe Perches	}
10965b9553abSJoe Perches
10977d2367afSJoe Perches	$string =~ s@\s+@ @g;
10985b9553abSJoe Perches
10997d2367afSJoe Perches	return $string;
11007d2367afSJoe Perches}
11017d2367afSJoe Perches
11023445686aSJoe Perchessub seed_camelcase_file {
11033445686aSJoe Perches	my ($file) = @_;
11043445686aSJoe Perches
11053445686aSJoe Perches	return if (!(-f $file));
11063445686aSJoe Perches
11073445686aSJoe Perches	local $/;
11083445686aSJoe Perches
11093445686aSJoe Perches	open(my $include_file, '<', "$file")
11103445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
11113445686aSJoe Perches	my $text = <$include_file>;
11123445686aSJoe Perches	close($include_file);
11133445686aSJoe Perches
11143445686aSJoe Perches	my @lines = split('\n', $text);
11153445686aSJoe Perches
11163445686aSJoe Perches	foreach my $line (@lines) {
11173445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
11183445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
11193445686aSJoe Perches			$camelcase{$1} = 1;
112011ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
112111ea516aSJoe Perches			$camelcase{$1} = 1;
112211ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
11233445686aSJoe Perches			$camelcase{$1} = 1;
11243445686aSJoe Perches		}
11253445686aSJoe Perches	}
11263445686aSJoe Perches}
11273445686aSJoe Perches
1128cd28b119SJoe Perchesour %maintained_status = ();
1129cd28b119SJoe Perches
113085b0ee18SJoe Perchessub is_maintained_obsolete {
113185b0ee18SJoe Perches	my ($filename) = @_;
113285b0ee18SJoe Perches
1133f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
113485b0ee18SJoe Perches
1135cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
1136cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1137cd28b119SJoe Perches	}
113885b0ee18SJoe Perches
1139cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
114085b0ee18SJoe Perches}
114185b0ee18SJoe Perches
11423b6e8ac9SJoe Perchessub is_SPDX_License_valid {
11433b6e8ac9SJoe Perches	my ($license) = @_;
11443b6e8ac9SJoe Perches
1145f9363b31SGuenter Roeck	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
11463b6e8ac9SJoe Perches
114756294112SJoe Perches	my $root_path = abs_path($root);
1148f9363b31SGuenter Roeck	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
11493b6e8ac9SJoe Perches	return 0 if ($status ne "");
11503b6e8ac9SJoe Perches	return 1;
11513b6e8ac9SJoe Perches}
11523b6e8ac9SJoe Perches
11533445686aSJoe Perchesmy $camelcase_seeded = 0;
11543445686aSJoe Perchessub seed_camelcase_includes {
11553445686aSJoe Perches	return if ($camelcase_seeded);
11563445686aSJoe Perches
11573445686aSJoe Perches	my $files;
1158c707a81dSJoe Perches	my $camelcase_cache = "";
1159c707a81dSJoe Perches	my @include_files = ();
1160c707a81dSJoe Perches
1161c707a81dSJoe Perches	$camelcase_seeded = 1;
1162351b2a1fSJoe Perches
11630f7f635bSJoe Perches	if (-e "$gitroot") {
1164dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1165351b2a1fSJoe Perches		chomp $git_last_include_commit;
1166c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1167c707a81dSJoe Perches	} else {
1168c707a81dSJoe Perches		my $last_mod_date = 0;
1169c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
1170c707a81dSJoe Perches		@include_files = split('\n', $files);
1171c707a81dSJoe Perches		foreach my $file (@include_files) {
1172c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
1173c707a81dSJoe Perches						   localtime((stat $file)[9]));
1174c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
1175c707a81dSJoe Perches		}
1176c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1177c707a81dSJoe Perches	}
1178c707a81dSJoe Perches
1179c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1180c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
1181c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1182351b2a1fSJoe Perches		while (<$camelcase_file>) {
1183351b2a1fSJoe Perches			chomp;
1184351b2a1fSJoe Perches			$camelcase{$_} = 1;
1185351b2a1fSJoe Perches		}
1186351b2a1fSJoe Perches		close($camelcase_file);
1187351b2a1fSJoe Perches
1188351b2a1fSJoe Perches		return;
1189351b2a1fSJoe Perches	}
1190c707a81dSJoe Perches
11910f7f635bSJoe Perches	if (-e "$gitroot") {
1192dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
1193c707a81dSJoe Perches		@include_files = split('\n', $files);
11943445686aSJoe Perches	}
1195c707a81dSJoe Perches
11963445686aSJoe Perches	foreach my $file (@include_files) {
11973445686aSJoe Perches		seed_camelcase_file($file);
11983445686aSJoe Perches	}
1199351b2a1fSJoe Perches
1200c707a81dSJoe Perches	if ($camelcase_cache ne "") {
1201351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
1202c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
1203c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1204351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1205351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
1206351b2a1fSJoe Perches		}
1207351b2a1fSJoe Perches		close($camelcase_file);
1208351b2a1fSJoe Perches	}
12093445686aSJoe Perches}
12103445686aSJoe Perches
1211f5f61325SJoe Perchessub git_is_single_file {
1212f5f61325SJoe Perches	my ($filename) = @_;
1213f5f61325SJoe Perches
1214f5f61325SJoe Perches	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1215f5f61325SJoe Perches
1216f5f61325SJoe Perches	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1217f5f61325SJoe Perches	my $count = $output =~ tr/\n//;
1218f5f61325SJoe Perches	return $count eq 1 && $output =~ m{^${filename}$};
1219f5f61325SJoe Perches}
1220f5f61325SJoe Perches
1221d311cd44SJoe Perchessub git_commit_info {
1222d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
1223d311cd44SJoe Perches
12240f7f635bSJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1225d311cd44SJoe Perches
1226dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1227d311cd44SJoe Perches	$output =~ s/^\s*//gm;
1228d311cd44SJoe Perches	my @lines = split("\n", $output);
1229d311cd44SJoe Perches
12300d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
12310d7835fcSJoe Perches
12325a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1233d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
1234d311cd44SJoe Perches# all matching commit ids, but it's very slow...
1235d311cd44SJoe Perches#
1236d311cd44SJoe Perches#		echo "checking commits $1..."
1237d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
1238d311cd44SJoe Perches#		while read line ; do
1239d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
1240d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
1241d311cd44SJoe Perches#		done
12424ce9f970SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
12434ce9f970SJoe Perches		 $lines[0] =~ /^fatal: bad object $commit/) {
1244948b133aSHeinrich Schuchardt		$id = undef;
1245d311cd44SJoe Perches	} else {
1246d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1247d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1248d311cd44SJoe Perches	}
1249d311cd44SJoe Perches
1250d311cd44SJoe Perches	return ($id, $desc);
1251d311cd44SJoe Perches}
1252d311cd44SJoe Perches
12536c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
1254d5d6281aSDan Carpenter$chk_fixes_tag = 0 if ($file);
12550a920b5bSAndy Whitcroft
125600df344fSAndy Whitcroftmy @rawlines = ();
1257c2fdda0dSAndy Whitcroftmy @lines = ();
12583705ce5bSJoe Perchesmy @fixed = ();
1259d752fcc8SJoe Perchesmy @fixed_inserted = ();
1260d752fcc8SJoe Perchesmy @fixed_deleted = ();
1261194f66fcSJoe Perchesmy $fixlinenr = -1;
1262194f66fcSJoe Perches
12634a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
12644a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
12650f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
12664a593c34SDu, Changbin
12674a593c34SDu, Changbinif ($git) {
12684a593c34SDu, Changbin	my @commits = ();
12690dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
12704a593c34SDu, Changbin		my $git_range;
127128898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
127228898fd1SJoe Perches			$git_range = "-$2 $1";
12734a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
12744a593c34SDu, Changbin			$git_range = "$commit_expr";
12754a593c34SDu, Changbin		} else {
12760dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
12770dea9f1eSJoe Perches		}
1278dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
12790dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
128028898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
128128898fd1SJoe Perches			next if (!defined($1) || !defined($2));
12820dea9f1eSJoe Perches			my $sha1 = $1;
12830dea9f1eSJoe Perches			my $subject = $2;
12840dea9f1eSJoe Perches			unshift(@commits, $sha1);
12850dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
12864a593c34SDu, Changbin		}
12874a593c34SDu, Changbin	}
12884a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
12894a593c34SDu, Changbin	@ARGV = @commits;
12904a593c34SDu, Changbin}
12914a593c34SDu, Changbin
1292c2fdda0dSAndy Whitcroftmy $vname;
129398005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
12946c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
129521caa13cSAndy Whitcroft	my $FILE;
1296f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1297f5f61325SJoe Perches	my $oldfile = $file;
1298f5f61325SJoe Perches	$file = 1 if ($is_git_file);
12994a593c34SDu, Changbin	if ($git) {
13004a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
13014a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
13024a593c34SDu, Changbin	} elsif ($file) {
130321caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
13046c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
130521caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
130621caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
13076c72ffaaSAndy Whitcroft	} else {
130821caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
13096c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
13106c72ffaaSAndy Whitcroft	}
1311c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1312c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
13134a593c34SDu, Changbin	} elsif ($git) {
13140dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1315c2fdda0dSAndy Whitcroft	} else {
1316c2fdda0dSAndy Whitcroft		$vname = $filename;
1317c2fdda0dSAndy Whitcroft	}
131821caa13cSAndy Whitcroft	while (<$FILE>) {
13190a920b5bSAndy Whitcroft		chomp;
132000df344fSAndy Whitcroft		push(@rawlines, $_);
1321c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
13226c72ffaaSAndy Whitcroft	}
132321caa13cSAndy Whitcroft	close($FILE);
1324d8469f16SJoe Perches
1325d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1326d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1327d8469f16SJoe Perches		print "$vname\n";
1328d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1329d8469f16SJoe Perches	}
1330d8469f16SJoe Perches
1331c2fdda0dSAndy Whitcroft	if (!process($filename)) {
13320a920b5bSAndy Whitcroft		$exit = 1;
13330a920b5bSAndy Whitcroft	}
133400df344fSAndy Whitcroft	@rawlines = ();
133513214adfSAndy Whitcroft	@lines = ();
13363705ce5bSJoe Perches	@fixed = ();
1337d752fcc8SJoe Perches	@fixed_inserted = ();
1338d752fcc8SJoe Perches	@fixed_deleted = ();
1339194f66fcSJoe Perches	$fixlinenr = -1;
1340485ff23eSAlex Dowad	@modifierListFile = ();
1341485ff23eSAlex Dowad	@typeListFile = ();
1342485ff23eSAlex Dowad	build_types();
1343f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
13440a920b5bSAndy Whitcroft}
13450a920b5bSAndy Whitcroft
1346d8469f16SJoe Perchesif (!$quiet) {
13473c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
13483c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
13493c816e49SJoe Perches
13505b57980dSJoe Perches	if (!$perl_version_ok) {
1351d8469f16SJoe Perches		print << "EOM"
1352d8469f16SJoe Perches
1353d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
13545b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1355d8469f16SJoe PerchesEOM
1356d8469f16SJoe Perches	}
1357d8469f16SJoe Perches	if ($exit) {
1358d8469f16SJoe Perches		print << "EOM"
1359d8469f16SJoe Perches
1360d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1361d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1362d8469f16SJoe PerchesEOM
1363d8469f16SJoe Perches	}
1364d8469f16SJoe Perches}
1365d8469f16SJoe Perches
13660a920b5bSAndy Whitcroftexit($exit);
13670a920b5bSAndy Whitcroft
13680a920b5bSAndy Whitcroftsub top_of_kernel_tree {
13696c72ffaaSAndy Whitcroft	my ($root) = @_;
13706c72ffaaSAndy Whitcroft
13716c72ffaaSAndy Whitcroft	my @tree_check = (
13726c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
13736c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
13746c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
13756c72ffaaSAndy Whitcroft	);
13766c72ffaaSAndy Whitcroft
13776c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
13786c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
13790a920b5bSAndy Whitcroft			return 0;
13800a920b5bSAndy Whitcroft		}
13816c72ffaaSAndy Whitcroft	}
13826c72ffaaSAndy Whitcroft	return 1;
13836c72ffaaSAndy Whitcroft}
13840a920b5bSAndy Whitcroft
138520112475SJoe Perchessub parse_email {
138620112475SJoe Perches	my ($formatted_email) = @_;
138720112475SJoe Perches
138820112475SJoe Perches	my $name = "";
1389fccaebf0SDwaipayan Ray	my $quoted = "";
1390dfa05c28SJoe Perches	my $name_comment = "";
139120112475SJoe Perches	my $address = "";
139220112475SJoe Perches	my $comment = "";
139320112475SJoe Perches
139420112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
139520112475SJoe Perches		$name = $1;
139620112475SJoe Perches		$address = $2;
139720112475SJoe Perches		$comment = $3 if defined $3;
139820112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
139920112475SJoe Perches		$address = $1;
140020112475SJoe Perches		$comment = $2 if defined $2;
140120112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
140220112475SJoe Perches		$address = $1;
140320112475SJoe Perches		$comment = $2 if defined $2;
140485e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
140520112475SJoe Perches		$name = $formatted_email;
14063705ce5bSJoe Perches		$name = trim($name);
140720112475SJoe Perches		$name =~ s/^\"|\"$//g;
140820112475SJoe Perches		# If there's a name left after stripping spaces and
140920112475SJoe Perches		# leading quotes, and the address doesn't have both
141020112475SJoe Perches		# leading and trailing angle brackets, the address
141120112475SJoe Perches		# is invalid. ie:
141220112475SJoe Perches		#   "joe smith [email protected]" bad
141320112475SJoe Perches		#   "joe smith <[email protected]" bad
141420112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
141520112475SJoe Perches			$name = "";
141620112475SJoe Perches			$address = "";
141720112475SJoe Perches			$comment = "";
141820112475SJoe Perches		}
141920112475SJoe Perches	}
142020112475SJoe Perches
1421fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1422fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1423fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1424fccaebf0SDwaipayan Ray		$quoted = $1;
1425dfa05c28SJoe Perches	}
1426fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1427fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1428fccaebf0SDwaipayan Ray	}
1429fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1430fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1431fccaebf0SDwaipayan Ray
14323705ce5bSJoe Perches	$address = trim($address);
143320112475SJoe Perches	$address =~ s/^\<|\>$//g;
1434fccaebf0SDwaipayan Ray	$comment = trim($comment);
143520112475SJoe Perches
143620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
143720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
143820112475SJoe Perches		$name = "\"$name\"";
143920112475SJoe Perches	}
144020112475SJoe Perches
1441dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
144220112475SJoe Perches}
144320112475SJoe Perches
144420112475SJoe Perchessub format_email {
144548ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
144620112475SJoe Perches
144720112475SJoe Perches	my $formatted_email;
144820112475SJoe Perches
1449fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
14503705ce5bSJoe Perches	$address = trim($address);
1451fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
145220112475SJoe Perches
145320112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
145420112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
145520112475SJoe Perches		$name = "\"$name\"";
145620112475SJoe Perches	}
145720112475SJoe Perches
1458fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1459fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1460fccaebf0SDwaipayan Ray	$comment = trim($comment);
1461fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1462fccaebf0SDwaipayan Ray
146320112475SJoe Perches	if ("$name" eq "") {
146420112475SJoe Perches		$formatted_email = "$address";
146520112475SJoe Perches	} else {
146648ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
146720112475SJoe Perches	}
146848ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
146920112475SJoe Perches	return $formatted_email;
147020112475SJoe Perches}
147120112475SJoe Perches
1472dfa05c28SJoe Perchessub reformat_email {
1473dfa05c28SJoe Perches	my ($email) = @_;
1474dfa05c28SJoe Perches
1475dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
147648ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1477dfa05c28SJoe Perches}
1478dfa05c28SJoe Perches
1479dfa05c28SJoe Perchessub same_email_addresses {
1480fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1481dfa05c28SJoe Perches
1482dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1483dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1484dfa05c28SJoe Perches
148548ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
148648ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
148748ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
148848ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
148948ca2d8aSDwaipayan Ray}
1490dfa05c28SJoe Perches
1491d311cd44SJoe Perchessub which {
1492d311cd44SJoe Perches	my ($bin) = @_;
1493d311cd44SJoe Perches
1494d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1495d311cd44SJoe Perches		if (-e "$path/$bin") {
1496d311cd44SJoe Perches			return "$path/$bin";
1497d311cd44SJoe Perches		}
1498d311cd44SJoe Perches	}
1499d311cd44SJoe Perches
1500d311cd44SJoe Perches	return "";
1501d311cd44SJoe Perches}
1502d311cd44SJoe Perches
1503000d1cc1SJoe Perchessub which_conf {
1504000d1cc1SJoe Perches	my ($conf) = @_;
1505000d1cc1SJoe Perches
1506000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1507000d1cc1SJoe Perches		if (-e "$path/$conf") {
1508000d1cc1SJoe Perches			return "$path/$conf";
1509000d1cc1SJoe Perches		}
1510000d1cc1SJoe Perches	}
1511000d1cc1SJoe Perches
1512000d1cc1SJoe Perches	return "";
1513000d1cc1SJoe Perches}
1514000d1cc1SJoe Perches
15150a920b5bSAndy Whitcroftsub expand_tabs {
15160a920b5bSAndy Whitcroft	my ($str) = @_;
15170a920b5bSAndy Whitcroft
15180a920b5bSAndy Whitcroft	my $res = '';
15190a920b5bSAndy Whitcroft	my $n = 0;
15200a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
15210a920b5bSAndy Whitcroft		if ($c eq "\t") {
15220a920b5bSAndy Whitcroft			$res .= ' ';
15230a920b5bSAndy Whitcroft			$n++;
1524713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
15250a920b5bSAndy Whitcroft				$res .= ' ';
15260a920b5bSAndy Whitcroft			}
15270a920b5bSAndy Whitcroft			next;
15280a920b5bSAndy Whitcroft		}
15290a920b5bSAndy Whitcroft		$res .= $c;
15300a920b5bSAndy Whitcroft		$n++;
15310a920b5bSAndy Whitcroft	}
15320a920b5bSAndy Whitcroft
15330a920b5bSAndy Whitcroft	return $res;
15340a920b5bSAndy Whitcroft}
15356c72ffaaSAndy Whitcroftsub copy_spacing {
1536773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
15376c72ffaaSAndy Whitcroft	return $res;
15386c72ffaaSAndy Whitcroft}
15390a920b5bSAndy Whitcroft
15404a0df2efSAndy Whitcroftsub line_stats {
15414a0df2efSAndy Whitcroft	my ($line) = @_;
15424a0df2efSAndy Whitcroft
15434a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
15444a0df2efSAndy Whitcroft	$line =~ s/^.//;
15454a0df2efSAndy Whitcroft	$line = expand_tabs($line);
15464a0df2efSAndy Whitcroft
15474a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
15484a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
15494a0df2efSAndy Whitcroft
15504a0df2efSAndy Whitcroft	return (length($line), length($white));
15514a0df2efSAndy Whitcroft}
15524a0df2efSAndy Whitcroft
1553773647a0SAndy Whitcroftmy $sanitise_quote = '';
1554773647a0SAndy Whitcroft
1555773647a0SAndy Whitcroftsub sanitise_line_reset {
1556773647a0SAndy Whitcroft	my ($in_comment) = @_;
1557773647a0SAndy Whitcroft
1558773647a0SAndy Whitcroft	if ($in_comment) {
1559773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1560773647a0SAndy Whitcroft	} else {
1561773647a0SAndy Whitcroft		$sanitise_quote = '';
1562773647a0SAndy Whitcroft	}
1563773647a0SAndy Whitcroft}
156400df344fSAndy Whitcroftsub sanitise_line {
156500df344fSAndy Whitcroft	my ($line) = @_;
156600df344fSAndy Whitcroft
156700df344fSAndy Whitcroft	my $res = '';
156800df344fSAndy Whitcroft	my $l = '';
156900df344fSAndy Whitcroft
1570c2fdda0dSAndy Whitcroft	my $qlen = 0;
1571773647a0SAndy Whitcroft	my $off = 0;
1572773647a0SAndy Whitcroft	my $c;
157300df344fSAndy Whitcroft
1574773647a0SAndy Whitcroft	# Always copy over the diff marker.
1575773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1576773647a0SAndy Whitcroft
1577773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1578773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1579773647a0SAndy Whitcroft
15808d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1581773647a0SAndy Whitcroft		# and end, all to $;.
1582773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1583773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1584773647a0SAndy Whitcroft
1585773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1586773647a0SAndy Whitcroft			$off++;
158700df344fSAndy Whitcroft			next;
1588773647a0SAndy Whitcroft		}
158981bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1590773647a0SAndy Whitcroft			$sanitise_quote = '';
1591773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1592773647a0SAndy Whitcroft			$off++;
1593773647a0SAndy Whitcroft			next;
1594773647a0SAndy Whitcroft		}
1595113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1596113f04a8SDaniel Walker			$sanitise_quote = '//';
1597113f04a8SDaniel Walker
1598113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1599113f04a8SDaniel Walker			$off++;
1600113f04a8SDaniel Walker			next;
1601113f04a8SDaniel Walker		}
1602773647a0SAndy Whitcroft
1603773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1604773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1605773647a0SAndy Whitcroft		    $c eq "\\") {
1606773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1607773647a0SAndy Whitcroft			$off++;
1608773647a0SAndy Whitcroft			next;
1609773647a0SAndy Whitcroft		}
1610773647a0SAndy Whitcroft		# Regular quotes.
1611773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1612773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1613773647a0SAndy Whitcroft				$sanitise_quote = $c;
1614773647a0SAndy Whitcroft
1615773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1616773647a0SAndy Whitcroft				next;
1617773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1618773647a0SAndy Whitcroft				$sanitise_quote = '';
161900df344fSAndy Whitcroft			}
162000df344fSAndy Whitcroft		}
1621773647a0SAndy Whitcroft
1622fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1623773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1624773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1625113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1626113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1627773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1628773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
162900df344fSAndy Whitcroft		} else {
1630773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
163100df344fSAndy Whitcroft		}
1632c2fdda0dSAndy Whitcroft	}
1633c2fdda0dSAndy Whitcroft
1634113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1635113f04a8SDaniel Walker		$sanitise_quote = '';
1636113f04a8SDaniel Walker	}
1637113f04a8SDaniel Walker
1638c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1639c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1640c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1641c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1642c2fdda0dSAndy Whitcroft
1643c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1644c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1645c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1646c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1647c2fdda0dSAndy Whitcroft	}
1648c2fdda0dSAndy Whitcroft
1649dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1650dadf680dSJoe Perches		my $match = $1;
1651dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1652dadf680dSJoe Perches	}
1653dadf680dSJoe Perches
165400df344fSAndy Whitcroft	return $res;
165500df344fSAndy Whitcroft}
165600df344fSAndy Whitcroft
1657a6962d72SJoe Perchessub get_quoted_string {
1658a6962d72SJoe Perches	my ($line, $rawline) = @_;
1659a6962d72SJoe Perches
1660478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
166133acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1662a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1663a6962d72SJoe Perches}
1664a6962d72SJoe Perches
16658905a67cSAndy Whitcroftsub ctx_statement_block {
16668905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16678905a67cSAndy Whitcroft	my $line = $linenr - 1;
16688905a67cSAndy Whitcroft	my $blk = '';
16698905a67cSAndy Whitcroft	my $soff = $off;
16708905a67cSAndy Whitcroft	my $coff = $off - 1;
1671773647a0SAndy Whitcroft	my $coff_set = 0;
16728905a67cSAndy Whitcroft
167313214adfSAndy Whitcroft	my $loff = 0;
167413214adfSAndy Whitcroft
16758905a67cSAndy Whitcroft	my $type = '';
16768905a67cSAndy Whitcroft	my $level = 0;
1677a2750645SAndy Whitcroft	my @stack = ();
1678cf655043SAndy Whitcroft	my $p;
16798905a67cSAndy Whitcroft	my $c;
16808905a67cSAndy Whitcroft	my $len = 0;
168113214adfSAndy Whitcroft
168213214adfSAndy Whitcroft	my $remainder;
16838905a67cSAndy Whitcroft	while (1) {
1684a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1685a2750645SAndy Whitcroft
1686773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
16878905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
16888905a67cSAndy Whitcroft		# context.
16898905a67cSAndy Whitcroft		if ($off >= $len) {
16908905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1691dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1692c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
16938905a67cSAndy Whitcroft				$remain--;
169413214adfSAndy Whitcroft				$loff = $len;
1695c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
16968905a67cSAndy Whitcroft				$len = length($blk);
16978905a67cSAndy Whitcroft				$line++;
16988905a67cSAndy Whitcroft				last;
16998905a67cSAndy Whitcroft			}
17008905a67cSAndy Whitcroft			# Bail if there is no further context.
17018905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
170213214adfSAndy Whitcroft			if ($off >= $len) {
17038905a67cSAndy Whitcroft				last;
17048905a67cSAndy Whitcroft			}
1705f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1706f74bd194SAndy Whitcroft				$level++;
1707f74bd194SAndy Whitcroft				$type = '#';
1708f74bd194SAndy Whitcroft			}
17098905a67cSAndy Whitcroft		}
1710cf655043SAndy Whitcroft		$p = $c;
17118905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
171213214adfSAndy Whitcroft		$remainder = substr($blk, $off);
17138905a67cSAndy Whitcroft
1714773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
17154635f4fbSAndy Whitcroft
17164635f4fbSAndy Whitcroft		# Handle nested #if/#else.
17174635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
17184635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
17194635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
17204635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
17214635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
17224635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
17234635f4fbSAndy Whitcroft		}
17244635f4fbSAndy Whitcroft
17258905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
17268905a67cSAndy Whitcroft		# outermost level.
17278905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
17288905a67cSAndy Whitcroft			last;
17298905a67cSAndy Whitcroft		}
17308905a67cSAndy Whitcroft
173113214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1732773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1733773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1734773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1735773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1736773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1737773647a0SAndy Whitcroft			$coff_set = 1;
1738773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1739773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
174013214adfSAndy Whitcroft		}
174113214adfSAndy Whitcroft
17428905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
17438905a67cSAndy Whitcroft			$level++;
17448905a67cSAndy Whitcroft			$type = '(';
17458905a67cSAndy Whitcroft		}
17468905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
17478905a67cSAndy Whitcroft			$level--;
17488905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
17498905a67cSAndy Whitcroft
17508905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
17518905a67cSAndy Whitcroft				$coff = $off;
1752773647a0SAndy Whitcroft				$coff_set = 1;
1753773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
17548905a67cSAndy Whitcroft			}
17558905a67cSAndy Whitcroft		}
17568905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
17578905a67cSAndy Whitcroft			$level++;
17588905a67cSAndy Whitcroft			$type = '{';
17598905a67cSAndy Whitcroft		}
17608905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
17618905a67cSAndy Whitcroft			$level--;
17628905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
17638905a67cSAndy Whitcroft
17648905a67cSAndy Whitcroft			if ($level == 0) {
1765b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1766b998e001SPatrick Pannuto					$off++;
1767b998e001SPatrick Pannuto				}
17688905a67cSAndy Whitcroft				last;
17698905a67cSAndy Whitcroft			}
17708905a67cSAndy Whitcroft		}
1771f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1772f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1773f74bd194SAndy Whitcroft			$level--;
1774f74bd194SAndy Whitcroft			$type = '';
1775f74bd194SAndy Whitcroft			$off++;
1776f74bd194SAndy Whitcroft			last;
1777f74bd194SAndy Whitcroft		}
17788905a67cSAndy Whitcroft		$off++;
17798905a67cSAndy Whitcroft	}
1780a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
178113214adfSAndy Whitcroft	if ($off == $len) {
1782a3bb97a7SAndy Whitcroft		$loff = $len + 1;
178313214adfSAndy Whitcroft		$line++;
178413214adfSAndy Whitcroft		$remain--;
178513214adfSAndy Whitcroft	}
17868905a67cSAndy Whitcroft
17878905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
17888905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
17898905a67cSAndy Whitcroft
17908905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
17918905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
17928905a67cSAndy Whitcroft
1793773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
179413214adfSAndy Whitcroft
179513214adfSAndy Whitcroft	return ($statement, $condition,
179613214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
179713214adfSAndy Whitcroft}
179813214adfSAndy Whitcroft
1799cf655043SAndy Whitcroftsub statement_lines {
1800cf655043SAndy Whitcroft	my ($stmt) = @_;
1801cf655043SAndy Whitcroft
1802cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1803cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1804cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1805cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1806cf655043SAndy Whitcroft
1807cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1808cf655043SAndy Whitcroft
1809cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1810cf655043SAndy Whitcroft}
1811cf655043SAndy Whitcroft
1812cf655043SAndy Whitcroftsub statement_rawlines {
1813cf655043SAndy Whitcroft	my ($stmt) = @_;
1814cf655043SAndy Whitcroft
1815cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1816cf655043SAndy Whitcroft
1817cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1818cf655043SAndy Whitcroft}
1819cf655043SAndy Whitcroft
1820cf655043SAndy Whitcroftsub statement_block_size {
1821cf655043SAndy Whitcroft	my ($stmt) = @_;
1822cf655043SAndy Whitcroft
1823cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1824cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1825cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1826cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1827cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1828cf655043SAndy Whitcroft
1829cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1830cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1831cf655043SAndy Whitcroft
1832cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1833cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1834cf655043SAndy Whitcroft
1835cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1836cf655043SAndy Whitcroft		return $stmt_lines;
1837cf655043SAndy Whitcroft	} else {
1838cf655043SAndy Whitcroft		return $stmt_statements;
1839cf655043SAndy Whitcroft	}
1840cf655043SAndy Whitcroft}
1841cf655043SAndy Whitcroft
184213214adfSAndy Whitcroftsub ctx_statement_full {
184313214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
184413214adfSAndy Whitcroft	my ($statement, $condition, $level);
184513214adfSAndy Whitcroft
184613214adfSAndy Whitcroft	my (@chunks);
184713214adfSAndy Whitcroft
1848cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
184913214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
185013214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1851773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
185213214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1853cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1854cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1855cf655043SAndy Whitcroft	}
1856cf655043SAndy Whitcroft
1857cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1858cf655043SAndy Whitcroft	# could continue the statement.
1859cf655043SAndy Whitcroft	for (;;) {
186013214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
186113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1862cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1863773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1864cf655043SAndy Whitcroft		#print "C: push\n";
1865cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
186613214adfSAndy Whitcroft	}
186713214adfSAndy Whitcroft
186813214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
18698905a67cSAndy Whitcroft}
18708905a67cSAndy Whitcroft
18714a0df2efSAndy Whitcroftsub ctx_block_get {
1872f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
18734a0df2efSAndy Whitcroft	my $line;
18744a0df2efSAndy Whitcroft	my $start = $linenr - 1;
18754a0df2efSAndy Whitcroft	my $blk = '';
18764a0df2efSAndy Whitcroft	my @o;
18774a0df2efSAndy Whitcroft	my @c;
18784a0df2efSAndy Whitcroft	my @res = ();
18794a0df2efSAndy Whitcroft
1880f0a594c1SAndy Whitcroft	my $level = 0;
18814635f4fbSAndy Whitcroft	my @stack = ($level);
188200df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
188300df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
188400df344fSAndy Whitcroft		$remain--;
188500df344fSAndy Whitcroft
188600df344fSAndy Whitcroft		$blk .= $rawlines[$line];
18874635f4fbSAndy Whitcroft
18884635f4fbSAndy Whitcroft		# Handle nested #if/#else.
188901464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
18904635f4fbSAndy Whitcroft			push(@stack, $level);
189101464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
18924635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
189301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
18944635f4fbSAndy Whitcroft			$level = pop(@stack);
18954635f4fbSAndy Whitcroft		}
18964635f4fbSAndy Whitcroft
189701464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1898f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1899f0a594c1SAndy Whitcroft			if ($off > 0) {
1900f0a594c1SAndy Whitcroft				$off--;
1901f0a594c1SAndy Whitcroft				next;
1902f0a594c1SAndy Whitcroft			}
19034a0df2efSAndy Whitcroft
1904f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1905f0a594c1SAndy Whitcroft				$level--;
1906f0a594c1SAndy Whitcroft				last if ($level == 0);
1907f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1908f0a594c1SAndy Whitcroft				$level++;
1909f0a594c1SAndy Whitcroft			}
1910f0a594c1SAndy Whitcroft		}
19114a0df2efSAndy Whitcroft
1912f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
191300df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
19144a0df2efSAndy Whitcroft		}
19154a0df2efSAndy Whitcroft
1916f0a594c1SAndy Whitcroft		last if ($level == 0);
19174a0df2efSAndy Whitcroft	}
19184a0df2efSAndy Whitcroft
1919f0a594c1SAndy Whitcroft	return ($level, @res);
19204a0df2efSAndy Whitcroft}
19214a0df2efSAndy Whitcroftsub ctx_block_outer {
19224a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
19234a0df2efSAndy Whitcroft
1924f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1925f0a594c1SAndy Whitcroft	return @r;
19264a0df2efSAndy Whitcroft}
19274a0df2efSAndy Whitcroftsub ctx_block {
19284a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
19294a0df2efSAndy Whitcroft
1930f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1931f0a594c1SAndy Whitcroft	return @r;
1932653d4876SAndy Whitcroft}
1933653d4876SAndy Whitcroftsub ctx_statement {
1934f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1935f0a594c1SAndy Whitcroft
1936f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1937f0a594c1SAndy Whitcroft	return @r;
1938f0a594c1SAndy Whitcroft}
1939f0a594c1SAndy Whitcroftsub ctx_block_level {
1940653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1941653d4876SAndy Whitcroft
1942f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
19434a0df2efSAndy Whitcroft}
19449c0ca6f9SAndy Whitcroftsub ctx_statement_level {
19459c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
19469c0ca6f9SAndy Whitcroft
19479c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
19489c0ca6f9SAndy Whitcroft}
19494a0df2efSAndy Whitcroft
19504a0df2efSAndy Whitcroftsub ctx_locate_comment {
19514a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19524a0df2efSAndy Whitcroft
1953a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1954a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1955a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1956a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1957a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1958a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1959a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1960a55ee0ccSJoe Perches
19614a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1962a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
19634a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
19644a0df2efSAndy Whitcroft
19654a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
19664a0df2efSAndy Whitcroft	# comment.
19674a0df2efSAndy Whitcroft	my $in_comment = 0;
19684a0df2efSAndy Whitcroft	$current_comment = '';
19694a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
197000df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
197100df344fSAndy Whitcroft		#warn "           $line\n";
19724a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
19734a0df2efSAndy Whitcroft			$in_comment = 1;
19744a0df2efSAndy Whitcroft		}
19754a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
19764a0df2efSAndy Whitcroft			$in_comment = 1;
19774a0df2efSAndy Whitcroft		}
19784a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
19794a0df2efSAndy Whitcroft			$current_comment = '';
19804a0df2efSAndy Whitcroft		}
19814a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
19824a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
19834a0df2efSAndy Whitcroft			$in_comment = 0;
19844a0df2efSAndy Whitcroft		}
19854a0df2efSAndy Whitcroft	}
19864a0df2efSAndy Whitcroft
19874a0df2efSAndy Whitcroft	chomp($current_comment);
19884a0df2efSAndy Whitcroft	return($current_comment);
19894a0df2efSAndy Whitcroft}
19904a0df2efSAndy Whitcroftsub ctx_has_comment {
19914a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19924a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
19934a0df2efSAndy Whitcroft
199400df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
19954a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
19964a0df2efSAndy Whitcroft
19974a0df2efSAndy Whitcroft	return ($cmt ne '');
19984a0df2efSAndy Whitcroft}
19994a0df2efSAndy Whitcroft
20004d001e4dSAndy Whitcroftsub raw_line {
20014d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
20024d001e4dSAndy Whitcroft
20034d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
20044d001e4dSAndy Whitcroft	$cnt++;
20054d001e4dSAndy Whitcroft
20064d001e4dSAndy Whitcroft	my $line;
20074d001e4dSAndy Whitcroft	while ($cnt) {
20084d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
20094d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
20104d001e4dSAndy Whitcroft		$cnt--;
20114d001e4dSAndy Whitcroft	}
20124d001e4dSAndy Whitcroft
20134d001e4dSAndy Whitcroft	return $line;
20144d001e4dSAndy Whitcroft}
20154d001e4dSAndy Whitcroft
20162a9f9d85STobin C. Hardingsub get_stat_real {
20172a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
20182a9f9d85STobin C. Harding
20192a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
20202a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
20212a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
20222a9f9d85STobin C. Harding	}
20232a9f9d85STobin C. Harding
20242a9f9d85STobin C. Harding	return $stat_real;
20252a9f9d85STobin C. Harding}
20262a9f9d85STobin C. Harding
2027e3d95a2aSTobin C. Hardingsub get_stat_here {
2028e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
2029e3d95a2aSTobin C. Harding
2030e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
2031e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
2032e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
2033e3d95a2aSTobin C. Harding	}
2034e3d95a2aSTobin C. Harding
2035e3d95a2aSTobin C. Harding	return $herectx;
2036e3d95a2aSTobin C. Harding}
2037e3d95a2aSTobin C. Harding
20380a920b5bSAndy Whitcroftsub cat_vet {
20390a920b5bSAndy Whitcroft	my ($vet) = @_;
20409c0ca6f9SAndy Whitcroft	my ($res, $coded);
20410a920b5bSAndy Whitcroft
20429c0ca6f9SAndy Whitcroft	$res = '';
20436c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
20446c72ffaaSAndy Whitcroft		$res .= $1;
20456c72ffaaSAndy Whitcroft		if ($2 ne '') {
20469c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
20476c72ffaaSAndy Whitcroft			$res .= $coded;
20486c72ffaaSAndy Whitcroft		}
20499c0ca6f9SAndy Whitcroft	}
20509c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
20510a920b5bSAndy Whitcroft
20529c0ca6f9SAndy Whitcroft	return $res;
20530a920b5bSAndy Whitcroft}
20540a920b5bSAndy Whitcroft
2055c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
2056cf655043SAndy Whitcroftmy $av_pending;
2057c2fdda0dSAndy Whitcroftmy @av_paren_type;
20581f65f947SAndy Whitcroftmy $av_pend_colon;
2059c2fdda0dSAndy Whitcroft
2060c2fdda0dSAndy Whitcroftsub annotate_reset {
2061c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
2062cf655043SAndy Whitcroft	$av_pending = '_';
2063cf655043SAndy Whitcroft	@av_paren_type = ('E');
20641f65f947SAndy Whitcroft	$av_pend_colon = 'O';
2065c2fdda0dSAndy Whitcroft}
2066c2fdda0dSAndy Whitcroft
20676c72ffaaSAndy Whitcroftsub annotate_values {
20686c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
20696c72ffaaSAndy Whitcroft
20706c72ffaaSAndy Whitcroft	my $res;
20711f65f947SAndy Whitcroft	my $var = '_' x length($stream);
20726c72ffaaSAndy Whitcroft	my $cur = $stream;
20736c72ffaaSAndy Whitcroft
2074c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
20756c72ffaaSAndy Whitcroft
20766c72ffaaSAndy Whitcroft	while (length($cur)) {
2077773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
2078cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
2079171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
20806c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
2081c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
2082c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
2083cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
2084c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
20856c72ffaaSAndy Whitcroft			}
20866c72ffaaSAndy Whitcroft
2087c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
20889446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
20899446ef56SAndy Whitcroft			push(@av_paren_type, $type);
2090addcdceaSAndy Whitcroft			$type = 'c';
20919446ef56SAndy Whitcroft
2092e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2093c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
20946c72ffaaSAndy Whitcroft			$type = 'T';
20956c72ffaaSAndy Whitcroft
2096389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
2097389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
2098389a2fe5SAndy Whitcroft			$type = 'T';
2099389a2fe5SAndy Whitcroft
2100c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2101171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2102c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2103171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
2104171ae1a4SAndy Whitcroft			if ($2 ne '') {
2105cf655043SAndy Whitcroft				$av_pending = 'N';
2106171ae1a4SAndy Whitcroft			}
2107171ae1a4SAndy Whitcroft			$type = 'E';
2108171ae1a4SAndy Whitcroft
2109c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2110171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
2111171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
2112171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
21136c72ffaaSAndy Whitcroft
2114c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2115cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
2116c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2117cf655043SAndy Whitcroft
2118cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2119cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2120171ae1a4SAndy Whitcroft			$type = 'E';
2121cf655043SAndy Whitcroft
2122c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2123cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2124cf655043SAndy Whitcroft			$av_preprocessor = 1;
2125cf655043SAndy Whitcroft
2126cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2127cf655043SAndy Whitcroft
2128171ae1a4SAndy Whitcroft			$type = 'E';
2129cf655043SAndy Whitcroft
2130c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2131cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
2132cf655043SAndy Whitcroft
2133cf655043SAndy Whitcroft			$av_preprocessor = 1;
2134cf655043SAndy Whitcroft
2135cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
2136cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
2137cf655043SAndy Whitcroft			pop(@av_paren_type);
2138cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2139171ae1a4SAndy Whitcroft			$type = 'E';
21406c72ffaaSAndy Whitcroft
21416c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
2142c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
21436c72ffaaSAndy Whitcroft
2144171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2145171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2146171ae1a4SAndy Whitcroft			$av_pending = $type;
2147171ae1a4SAndy Whitcroft			$type = 'N';
2148171ae1a4SAndy Whitcroft
21496c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2150c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
21516c72ffaaSAndy Whitcroft			if (defined $2) {
2152cf655043SAndy Whitcroft				$av_pending = 'V';
21536c72ffaaSAndy Whitcroft			}
21546c72ffaaSAndy Whitcroft			$type = 'N';
21556c72ffaaSAndy Whitcroft
215614b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2157c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
215814b111c1SAndy Whitcroft			$av_pending = 'E';
21596c72ffaaSAndy Whitcroft			$type = 'N';
21606c72ffaaSAndy Whitcroft
21611f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
21621f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
21631f65f947SAndy Whitcroft			$av_pend_colon = 'C';
21641f65f947SAndy Whitcroft			$type = 'N';
21651f65f947SAndy Whitcroft
216614b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2167c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
21686c72ffaaSAndy Whitcroft			$type = 'N';
21696c72ffaaSAndy Whitcroft
21706c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2171c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2172cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2173cf655043SAndy Whitcroft			$av_pending = '_';
21746c72ffaaSAndy Whitcroft			$type = 'N';
21756c72ffaaSAndy Whitcroft
21766c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2177cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2178cf655043SAndy Whitcroft			if ($new_type ne '_') {
2179cf655043SAndy Whitcroft				$type = $new_type;
2180c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2181c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
21826c72ffaaSAndy Whitcroft			} else {
2183c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
21846c72ffaaSAndy Whitcroft			}
21856c72ffaaSAndy Whitcroft
2186c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2187c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2188c8cb2ca3SAndy Whitcroft			$type = 'V';
2189cf655043SAndy Whitcroft			$av_pending = 'V';
21906c72ffaaSAndy Whitcroft
21918e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
21928e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
21931f65f947SAndy Whitcroft				$av_pend_colon = 'B';
21948e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
21958e761b04SAndy Whitcroft				$av_pend_colon = 'L';
21961f65f947SAndy Whitcroft			}
21971f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
21981f65f947SAndy Whitcroft			$type = 'V';
21991f65f947SAndy Whitcroft
22006c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2201c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
22026c72ffaaSAndy Whitcroft			$type = 'V';
22036c72ffaaSAndy Whitcroft
22046c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2205c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
22066c72ffaaSAndy Whitcroft			$type = 'N';
22076c72ffaaSAndy Whitcroft
2208cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2209c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
221013214adfSAndy Whitcroft			$type = 'E';
22111f65f947SAndy Whitcroft			$av_pend_colon = 'O';
221213214adfSAndy Whitcroft
22138e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
22148e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
22158e761b04SAndy Whitcroft			$type = 'C';
22168e761b04SAndy Whitcroft
22171f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
22181f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
22191f65f947SAndy Whitcroft			$type = 'N';
22201f65f947SAndy Whitcroft
22211f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
22221f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
22231f65f947SAndy Whitcroft
22241f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
22251f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
22261f65f947SAndy Whitcroft				$type = 'E';
22271f65f947SAndy Whitcroft			} else {
22281f65f947SAndy Whitcroft				$type = 'N';
22291f65f947SAndy Whitcroft			}
22301f65f947SAndy Whitcroft			$av_pend_colon = 'O';
22311f65f947SAndy Whitcroft
22328e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
223313214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
22346c72ffaaSAndy Whitcroft			$type = 'N';
22356c72ffaaSAndy Whitcroft
22360d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
223774048ed8SAndy Whitcroft			my $variant;
223874048ed8SAndy Whitcroft
223974048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
224074048ed8SAndy Whitcroft			if ($type eq 'V') {
224174048ed8SAndy Whitcroft				$variant = 'B';
224274048ed8SAndy Whitcroft			} else {
224374048ed8SAndy Whitcroft				$variant = 'U';
224474048ed8SAndy Whitcroft			}
224574048ed8SAndy Whitcroft
224674048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
224774048ed8SAndy Whitcroft			$type = 'N';
224874048ed8SAndy Whitcroft
22496c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2250c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
22516c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
22526c72ffaaSAndy Whitcroft				$type = 'N';
22536c72ffaaSAndy Whitcroft			}
22546c72ffaaSAndy Whitcroft
22556c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2256c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
22576c72ffaaSAndy Whitcroft		}
22586c72ffaaSAndy Whitcroft		if (defined $1) {
22596c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
22606c72ffaaSAndy Whitcroft			$res .= $type x length($1);
22616c72ffaaSAndy Whitcroft		}
22626c72ffaaSAndy Whitcroft	}
22636c72ffaaSAndy Whitcroft
22641f65f947SAndy Whitcroft	return ($res, $var);
22656c72ffaaSAndy Whitcroft}
22666c72ffaaSAndy Whitcroft
22678905a67cSAndy Whitcroftsub possible {
226813214adfSAndy Whitcroft	my ($possible, $line) = @_;
22699a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
22700776e594SAndy Whitcroft		^(?:
22710776e594SAndy Whitcroft			$Modifier|
22720776e594SAndy Whitcroft			$Storage|
22730776e594SAndy Whitcroft			$Type|
22749a974fdbSAndy Whitcroft			DEFINE_\S+
22759a974fdbSAndy Whitcroft		)$|
22769a974fdbSAndy Whitcroft		^(?:
22770776e594SAndy Whitcroft			goto|
22780776e594SAndy Whitcroft			return|
22790776e594SAndy Whitcroft			case|
22800776e594SAndy Whitcroft			else|
22810776e594SAndy Whitcroft			asm|__asm__|
228289a88353SAndy Whitcroft			do|
228389a88353SAndy Whitcroft			\#|
228489a88353SAndy Whitcroft			\#\#|
22859a974fdbSAndy Whitcroft		)(?:\s|$)|
22860776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
22879a974fdbSAndy Whitcroft	    )}x;
22889a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
22899a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2290c45dcabdSAndy Whitcroft		# Check for modifiers.
2291c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2292c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2293c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2294c45dcabdSAndy Whitcroft
2295c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2296c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2297d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
22989a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2299d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2300485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2301d2506586SAndy Whitcroft				}
23029a974fdbSAndy Whitcroft			}
2303c45dcabdSAndy Whitcroft
2304c45dcabdSAndy Whitcroft		} else {
230513214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2306485ff23eSAlex Dowad			push(@typeListFile, $possible);
2307c45dcabdSAndy Whitcroft		}
23088905a67cSAndy Whitcroft		build_types();
23090776e594SAndy Whitcroft	} else {
23100776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
23118905a67cSAndy Whitcroft	}
23128905a67cSAndy Whitcroft}
23138905a67cSAndy Whitcroft
23146c72ffaaSAndy Whitcroftmy $prefix = '';
23156c72ffaaSAndy Whitcroft
2316000d1cc1SJoe Perchessub show_type {
2317cbec18afSJoe Perches	my ($type) = @_;
231891bfe484SJoe Perches
2319522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2320522b837cSAlexey Dobriyan
2321cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2322cbec18afSJoe Perches
2323cbec18afSJoe Perches	return !defined $ignore_type{$type};
2324000d1cc1SJoe Perches}
2325000d1cc1SJoe Perches
2326f0a594c1SAndy Whitcroftsub report {
2327cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2328cbec18afSJoe Perches
2329cbec18afSJoe Perches	if (!show_type($type) ||
2330cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2331773647a0SAndy Whitcroft		return 0;
2332773647a0SAndy Whitcroft	}
233357230297SJoe Perches	my $output = '';
2334737c0767SJohn Brooks	if ($color) {
233557230297SJoe Perches		if ($level eq 'ERROR') {
233657230297SJoe Perches			$output .= RED;
233757230297SJoe Perches		} elsif ($level eq 'WARNING') {
233857230297SJoe Perches			$output .= YELLOW;
2339000d1cc1SJoe Perches		} else {
234057230297SJoe Perches			$output .= GREEN;
2341000d1cc1SJoe Perches		}
234257230297SJoe Perches	}
234357230297SJoe Perches	$output .= $prefix . $level . ':';
234457230297SJoe Perches	if ($show_types) {
2345737c0767SJohn Brooks		$output .= BLUE if ($color);
234657230297SJoe Perches		$output .= "$type:";
234757230297SJoe Perches	}
2348737c0767SJohn Brooks	$output .= RESET if ($color);
234957230297SJoe Perches	$output .= ' ' . $msg . "\n";
235034d8815fSJoe Perches
235134d8815fSJoe Perches	if ($showfile) {
235234d8815fSJoe Perches		my @lines = split("\n", $output, -1);
235334d8815fSJoe Perches		splice(@lines, 1, 1);
235434d8815fSJoe Perches		$output = join("\n", @lines);
235534d8815fSJoe Perches	}
235652178ce0SDwaipayan Ray
235752178ce0SDwaipayan Ray	if ($terse) {
235852178ce0SDwaipayan Ray		$output = (split('\n', $output))[0] . "\n";
235952178ce0SDwaipayan Ray	}
236052178ce0SDwaipayan Ray
236152178ce0SDwaipayan Ray	if ($verbose && exists($verbose_messages{$type}) &&
236252178ce0SDwaipayan Ray	    !exists($verbose_emitted{$type})) {
236352178ce0SDwaipayan Ray		$output .= $verbose_messages{$type} . "\n\n";
236452178ce0SDwaipayan Ray		$verbose_emitted{$type} = 1;
236552178ce0SDwaipayan Ray	}
23668905a67cSAndy Whitcroft
236757230297SJoe Perches	push(our @report, $output);
2368773647a0SAndy Whitcroft
2369773647a0SAndy Whitcroft	return 1;
2370f0a594c1SAndy Whitcroft}
2371cbec18afSJoe Perches
2372f0a594c1SAndy Whitcroftsub report_dump {
237313214adfSAndy Whitcroft	our @report;
2374f0a594c1SAndy Whitcroft}
2375000d1cc1SJoe Perches
2376d752fcc8SJoe Perchessub fixup_current_range {
2377d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2378d752fcc8SJoe Perches
2379d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2380d752fcc8SJoe Perches		my $o = $1;
2381d752fcc8SJoe Perches		my $l = $2;
2382d752fcc8SJoe Perches		my $no = $o + $offset;
2383d752fcc8SJoe Perches		my $nl = $l + $length;
2384d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2385d752fcc8SJoe Perches	}
2386d752fcc8SJoe Perches}
2387d752fcc8SJoe Perches
2388d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2389d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2390d752fcc8SJoe Perches
2391d752fcc8SJoe Perches	my $range_last_linenr = 0;
2392d752fcc8SJoe Perches	my $delta_offset = 0;
2393d752fcc8SJoe Perches
2394d752fcc8SJoe Perches	my $old_linenr = 0;
2395d752fcc8SJoe Perches	my $new_linenr = 0;
2396d752fcc8SJoe Perches
2397d752fcc8SJoe Perches	my $next_insert = 0;
2398d752fcc8SJoe Perches	my $next_delete = 0;
2399d752fcc8SJoe Perches
2400d752fcc8SJoe Perches	my @lines = ();
2401d752fcc8SJoe Perches
2402d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2403d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2404d752fcc8SJoe Perches
2405d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2406d752fcc8SJoe Perches		my $save_line = 1;
2407d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2408323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2409d752fcc8SJoe Perches			$delta_offset = 0;
2410d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2411d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2412d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2413d752fcc8SJoe Perches		}
2414d752fcc8SJoe Perches
2415d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2416d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2417d752fcc8SJoe Perches			$save_line = 0;
2418d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2419d752fcc8SJoe Perches		}
2420d752fcc8SJoe Perches
2421d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2422d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2423d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2424d752fcc8SJoe Perches			$new_linenr++;
2425d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2426d752fcc8SJoe Perches		}
2427d752fcc8SJoe Perches
2428d752fcc8SJoe Perches		if ($save_line) {
2429d752fcc8SJoe Perches			push(@lines, $line);
2430d752fcc8SJoe Perches			$new_linenr++;
2431d752fcc8SJoe Perches		}
2432d752fcc8SJoe Perches
2433d752fcc8SJoe Perches		$old_linenr++;
2434d752fcc8SJoe Perches	}
2435d752fcc8SJoe Perches
2436d752fcc8SJoe Perches	return @lines;
2437d752fcc8SJoe Perches}
2438d752fcc8SJoe Perches
2439f2d7e4d4SJoe Perchessub fix_insert_line {
2440f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2441f2d7e4d4SJoe Perches
2442f2d7e4d4SJoe Perches	my $inserted = {
2443f2d7e4d4SJoe Perches		LINENR => $linenr,
2444f2d7e4d4SJoe Perches		LINE => $line,
2445f2d7e4d4SJoe Perches	};
2446f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2447f2d7e4d4SJoe Perches}
2448f2d7e4d4SJoe Perches
2449f2d7e4d4SJoe Perchessub fix_delete_line {
2450f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2451f2d7e4d4SJoe Perches
2452f2d7e4d4SJoe Perches	my $deleted = {
2453f2d7e4d4SJoe Perches		LINENR => $linenr,
2454f2d7e4d4SJoe Perches		LINE => $line,
2455f2d7e4d4SJoe Perches	};
2456f2d7e4d4SJoe Perches
2457f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2458f2d7e4d4SJoe Perches}
2459f2d7e4d4SJoe Perches
2460de7d4f0eSAndy Whitcroftsub ERROR {
2461cbec18afSJoe Perches	my ($type, $msg) = @_;
2462cbec18afSJoe Perches
2463cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2464de7d4f0eSAndy Whitcroft		our $clean = 0;
24656c72ffaaSAndy Whitcroft		our $cnt_error++;
24663705ce5bSJoe Perches		return 1;
2467de7d4f0eSAndy Whitcroft	}
24683705ce5bSJoe Perches	return 0;
2469773647a0SAndy Whitcroft}
2470de7d4f0eSAndy Whitcroftsub WARN {
2471cbec18afSJoe Perches	my ($type, $msg) = @_;
2472cbec18afSJoe Perches
2473cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2474de7d4f0eSAndy Whitcroft		our $clean = 0;
24756c72ffaaSAndy Whitcroft		our $cnt_warn++;
24763705ce5bSJoe Perches		return 1;
2477de7d4f0eSAndy Whitcroft	}
24783705ce5bSJoe Perches	return 0;
2479773647a0SAndy Whitcroft}
2480de7d4f0eSAndy Whitcroftsub CHK {
2481cbec18afSJoe Perches	my ($type, $msg) = @_;
2482cbec18afSJoe Perches
2483cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2484de7d4f0eSAndy Whitcroft		our $clean = 0;
24856c72ffaaSAndy Whitcroft		our $cnt_chk++;
24863705ce5bSJoe Perches		return 1;
24876c72ffaaSAndy Whitcroft	}
24883705ce5bSJoe Perches	return 0;
2489de7d4f0eSAndy Whitcroft}
2490de7d4f0eSAndy Whitcroft
24916ecd9674SAndy Whitcroftsub check_absolute_file {
24926ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
24936ecd9674SAndy Whitcroft	my $file = $absolute;
24946ecd9674SAndy Whitcroft
24956ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
24966ecd9674SAndy Whitcroft
24976ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
24986ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
24996ecd9674SAndy Whitcroft		if (-f "$root/$file") {
25006ecd9674SAndy Whitcroft			##print "file<$file>\n";
25016ecd9674SAndy Whitcroft			last;
25026ecd9674SAndy Whitcroft		}
25036ecd9674SAndy Whitcroft	}
25046ecd9674SAndy Whitcroft	if (! -f _)  {
25056ecd9674SAndy Whitcroft		return 0;
25066ecd9674SAndy Whitcroft	}
25076ecd9674SAndy Whitcroft
25086ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
25096ecd9674SAndy Whitcroft	my $prefix = $absolute;
25106ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
25116ecd9674SAndy Whitcroft
25126ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
25136ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2514000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2515000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
25166ecd9674SAndy Whitcroft	}
25176ecd9674SAndy Whitcroft}
25186ecd9674SAndy Whitcroft
25193705ce5bSJoe Perchessub trim {
25203705ce5bSJoe Perches	my ($string) = @_;
25213705ce5bSJoe Perches
2522b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2523b34c648bSJoe Perches
2524b34c648bSJoe Perches	return $string;
2525b34c648bSJoe Perches}
2526b34c648bSJoe Perches
2527b34c648bSJoe Perchessub ltrim {
2528b34c648bSJoe Perches	my ($string) = @_;
2529b34c648bSJoe Perches
2530b34c648bSJoe Perches	$string =~ s/^\s+//;
2531b34c648bSJoe Perches
2532b34c648bSJoe Perches	return $string;
2533b34c648bSJoe Perches}
2534b34c648bSJoe Perches
2535b34c648bSJoe Perchessub rtrim {
2536b34c648bSJoe Perches	my ($string) = @_;
2537b34c648bSJoe Perches
2538b34c648bSJoe Perches	$string =~ s/\s+$//;
25393705ce5bSJoe Perches
25403705ce5bSJoe Perches	return $string;
25413705ce5bSJoe Perches}
25423705ce5bSJoe Perches
254352ea8506SJoe Perchessub string_find_replace {
254452ea8506SJoe Perches	my ($string, $find, $replace) = @_;
254552ea8506SJoe Perches
254652ea8506SJoe Perches	$string =~ s/$find/$replace/g;
254752ea8506SJoe Perches
254852ea8506SJoe Perches	return $string;
254952ea8506SJoe Perches}
255052ea8506SJoe Perches
25513705ce5bSJoe Perchessub tabify {
25523705ce5bSJoe Perches	my ($leading) = @_;
25533705ce5bSJoe Perches
2554713a09deSAntonio Borneo	my $source_indent = $tabsize;
25553705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
25563705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
25573705ce5bSJoe Perches
25583705ce5bSJoe Perches	#convert leading spaces to tabs
25593705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
25603705ce5bSJoe Perches	#Remove spaces before a tab
25613705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
25623705ce5bSJoe Perches
25633705ce5bSJoe Perches	return "$leading";
25643705ce5bSJoe Perches}
25653705ce5bSJoe Perches
2566d1fe9c09SJoe Perchessub pos_last_openparen {
2567d1fe9c09SJoe Perches	my ($line) = @_;
2568d1fe9c09SJoe Perches
2569d1fe9c09SJoe Perches	my $pos = 0;
2570d1fe9c09SJoe Perches
2571d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2572d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2573d1fe9c09SJoe Perches
2574d1fe9c09SJoe Perches	my $last_openparen = 0;
2575d1fe9c09SJoe Perches
2576d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2577d1fe9c09SJoe Perches		return -1;
2578d1fe9c09SJoe Perches	}
2579d1fe9c09SJoe Perches
2580d1fe9c09SJoe Perches	my $len = length($line);
2581d1fe9c09SJoe Perches
2582d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2583d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2584d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2585d1fe9c09SJoe Perches			$pos += length($1) - 1;
2586d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2587d1fe9c09SJoe Perches			$last_openparen = $pos;
2588d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2589d1fe9c09SJoe Perches			last;
2590d1fe9c09SJoe Perches		}
2591d1fe9c09SJoe Perches	}
2592d1fe9c09SJoe Perches
259391cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2594d1fe9c09SJoe Perches}
2595d1fe9c09SJoe Perches
2596f36d3eb8SJoe Perchessub get_raw_comment {
2597f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2598f36d3eb8SJoe Perches	my $comment = '';
2599f36d3eb8SJoe Perches
2600f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2601f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2602f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2603f36d3eb8SJoe Perches		}
2604f36d3eb8SJoe Perches	}
2605f36d3eb8SJoe Perches
2606f36d3eb8SJoe Perches	return $comment;
2607f36d3eb8SJoe Perches}
2608f36d3eb8SJoe Perches
26095b8f82e1SSong Liusub exclude_global_initialisers {
26105b8f82e1SSong Liu	my ($realfile) = @_;
26115b8f82e1SSong Liu
26125b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
26135b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
26145b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
26155b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
26165b8f82e1SSong Liu}
26175b8f82e1SSong Liu
26180a920b5bSAndy Whitcroftsub process {
26190a920b5bSAndy Whitcroft	my $filename = shift;
26200a920b5bSAndy Whitcroft
26210a920b5bSAndy Whitcroft	my $linenr=0;
26220a920b5bSAndy Whitcroft	my $prevline="";
2623c2fdda0dSAndy Whitcroft	my $prevrawline="";
26240a920b5bSAndy Whitcroft	my $stashline="";
2625c2fdda0dSAndy Whitcroft	my $stashrawline="";
26260a920b5bSAndy Whitcroft
26274a0df2efSAndy Whitcroft	my $length;
26280a920b5bSAndy Whitcroft	my $indent;
26290a920b5bSAndy Whitcroft	my $previndent=0;
26300a920b5bSAndy Whitcroft	my $stashindent=0;
26310a920b5bSAndy Whitcroft
2632de7d4f0eSAndy Whitcroft	our $clean = 1;
26330a920b5bSAndy Whitcroft	my $signoff = 0;
2634d5d6281aSDan Carpenter	my $fixes_tag = 0;
2635d5d6281aSDan Carpenter	my $is_revert = 0;
2636d5d6281aSDan Carpenter	my $needs_fixes_tag = "";
2637cd261496SGeert Uytterhoeven	my $author = '';
2638cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
263948ca2d8aSDwaipayan Ray	my $author_sob = '';
26400a920b5bSAndy Whitcroft	my $is_patch = 0;
2641133712a2SRob Herring	my $is_binding_patch = -1;
264229ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
264315662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
264444d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2645ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2646490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2647bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
26482a076f40SJoe Perches	my $commit_log_long_line = 0;
2649e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
265013f1937eSJoe Perches	my $reported_maintainer_file = 0;
2651fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2652fa64205dSPasi Savanainen
26534ce9f970SJoe Perches	my $last_git_commit_id_linenr = -1;
26544ce9f970SJoe Perches
2655365dd4eaSJoe Perches	my $last_blank_line = 0;
26565e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2657365dd4eaSJoe Perches
265813214adfSAndy Whitcroft	our @report = ();
26596c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
26606c72ffaaSAndy Whitcroft	our $cnt_error = 0;
26616c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
26626c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
26636c72ffaaSAndy Whitcroft
26640a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
26650a920b5bSAndy Whitcroft	my $realfile = '';
26660a920b5bSAndy Whitcroft	my $realline = 0;
26670a920b5bSAndy Whitcroft	my $realcnt = 0;
26680a920b5bSAndy Whitcroft	my $here = '';
266977cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
26700a920b5bSAndy Whitcroft	my $in_comment = 0;
2671c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
26720a920b5bSAndy Whitcroft	my $first_line = 0;
26731e855726SWolfram Sang	my $p1_prefix = '';
26740a920b5bSAndy Whitcroft
267513214adfSAndy Whitcroft	my $prev_values = 'E';
267613214adfSAndy Whitcroft
267713214adfSAndy Whitcroft	# suppression flags
2678773647a0SAndy Whitcroft	my %suppress_ifbraces;
2679170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
26802b474a1aSAndy Whitcroft	my %suppress_export;
26813e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2682653d4876SAndy Whitcroft
26837e51f197SJoe Perches	my %signatures = ();
2684323c1260SJoe Perches
2685c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2686de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2687c2fdda0dSAndy Whitcroft	#
2688de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2689de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2690773647a0SAndy Whitcroft
2691d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2692d8b07710SJoe Perches
26939f3a8992SRob Herring	my $checklicenseline = 1;
26949f3a8992SRob Herring
2695773647a0SAndy Whitcroft	sanitise_line_reset();
2696c2fdda0dSAndy Whitcroft	my $line;
2697c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2698773647a0SAndy Whitcroft		$linenr++;
2699773647a0SAndy Whitcroft		$line = $rawline;
2700c2fdda0dSAndy Whitcroft
27013705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
27023705ce5bSJoe Perches
2703773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2704de7d4f0eSAndy Whitcroft			$setup_docs = 0;
27052581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2706de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2707de7d4f0eSAndy Whitcroft			}
2708773647a0SAndy Whitcroft			#next;
2709de7d4f0eSAndy Whitcroft		}
271074fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2711773647a0SAndy Whitcroft			$realline=$1-1;
2712773647a0SAndy Whitcroft			if (defined $2) {
2713773647a0SAndy Whitcroft				$realcnt=$3+1;
2714773647a0SAndy Whitcroft			} else {
2715773647a0SAndy Whitcroft				$realcnt=1+1;
2716773647a0SAndy Whitcroft			}
2717c45dcabdSAndy Whitcroft			$in_comment = 0;
2718773647a0SAndy Whitcroft
2719773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2720773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2721773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2722773647a0SAndy Whitcroft			# at context start.
2723773647a0SAndy Whitcroft			my $edge;
272401fa9147SAndy Whitcroft			my $cnt = $realcnt;
272501fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
272601fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
272701fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
272801fa9147SAndy Whitcroft				$cnt--;
272901fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2730721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2731fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2732fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2733fae17daeSAndy Whitcroft					($edge) = $1;
2734fae17daeSAndy Whitcroft					last;
2735fae17daeSAndy Whitcroft				}
2736773647a0SAndy Whitcroft			}
2737773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2738773647a0SAndy Whitcroft				$in_comment = 1;
2739773647a0SAndy Whitcroft			}
2740773647a0SAndy Whitcroft
2741773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2742773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2743773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2744773647a0SAndy Whitcroft			if (!defined $edge &&
274583242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2746773647a0SAndy Whitcroft			{
2747773647a0SAndy Whitcroft				$in_comment = 1;
2748773647a0SAndy Whitcroft			}
2749773647a0SAndy Whitcroft
2750773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2751773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2752773647a0SAndy Whitcroft
2753171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2754773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2755171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2756773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2757773647a0SAndy Whitcroft		}
2758773647a0SAndy Whitcroft		push(@lines, $line);
2759773647a0SAndy Whitcroft
2760773647a0SAndy Whitcroft		if ($realcnt > 1) {
2761773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2762773647a0SAndy Whitcroft		} else {
2763773647a0SAndy Whitcroft			$realcnt = 0;
2764773647a0SAndy Whitcroft		}
2765773647a0SAndy Whitcroft
2766773647a0SAndy Whitcroft		#print "==>$rawline\n";
2767773647a0SAndy Whitcroft		#print "-->$line\n";
2768de7d4f0eSAndy Whitcroft
2769de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2770de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2771de7d4f0eSAndy Whitcroft		}
2772de7d4f0eSAndy Whitcroft	}
2773de7d4f0eSAndy Whitcroft
27746c72ffaaSAndy Whitcroft	$prefix = '';
27756c72ffaaSAndy Whitcroft
2776773647a0SAndy Whitcroft	$realcnt = 0;
2777773647a0SAndy Whitcroft	$linenr = 0;
2778194f66fcSJoe Perches	$fixlinenr = -1;
27790a920b5bSAndy Whitcroft	foreach my $line (@lines) {
27800a920b5bSAndy Whitcroft		$linenr++;
2781194f66fcSJoe Perches		$fixlinenr++;
27821b5539b1SJoe Perches		my $sline = $line;	#copy of $line
27831b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
27840a920b5bSAndy Whitcroft
2785c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2786f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
27876c72ffaaSAndy Whitcroft
278812c253abSJoe Perches# check if it's a mode change, rename or start of a patch
278912c253abSJoe Perches		if (!$in_commit_log &&
279012c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
279112c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
279212c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
279312c253abSJoe Perches			$is_patch = 1;
279412c253abSJoe Perches		}
279512c253abSJoe Perches
27960a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2797e518e9a5SJoe Perches		if (!$in_commit_log &&
279874fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
279974fd4f34SJoe Perches			my $context = $4;
28000a920b5bSAndy Whitcroft			$is_patch = 1;
28014a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
28020a920b5bSAndy Whitcroft			$realline=$1-1;
28030a920b5bSAndy Whitcroft			if (defined $2) {
28040a920b5bSAndy Whitcroft				$realcnt=$3+1;
28050a920b5bSAndy Whitcroft			} else {
28060a920b5bSAndy Whitcroft				$realcnt=1+1;
28070a920b5bSAndy Whitcroft			}
2808c2fdda0dSAndy Whitcroft			annotate_reset();
280913214adfSAndy Whitcroft			$prev_values = 'E';
281013214adfSAndy Whitcroft
2811773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2812170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
28132b474a1aSAndy Whitcroft			%suppress_export = ();
28143e469cdcSAndy Whitcroft			$suppress_statement = 0;
281574fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
281674fd4f34SJoe Perches				$context_function = $1;
281774fd4f34SJoe Perches			} else {
281874fd4f34SJoe Perches				undef $context_function;
281974fd4f34SJoe Perches			}
28200a920b5bSAndy Whitcroft			next;
28210a920b5bSAndy Whitcroft
28224a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
28234a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
28244a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2825773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
28260a920b5bSAndy Whitcroft			$realline++;
2827d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
28280a920b5bSAndy Whitcroft
28294a0df2efSAndy Whitcroft			# Measure the line length and indent.
2830c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
28310a920b5bSAndy Whitcroft
28320a920b5bSAndy Whitcroft			# Track the previous line.
28330a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
28340a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2835c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2836c2fdda0dSAndy Whitcroft
2837773647a0SAndy Whitcroft			#warn "line<$line>\n";
28386c72ffaaSAndy Whitcroft
2839d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2840d8aaf121SAndy Whitcroft			$realcnt--;
28410a920b5bSAndy Whitcroft		}
28420a920b5bSAndy Whitcroft
2843cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2844cc77cdcaSAndy Whitcroft
28456c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
28466c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2847773647a0SAndy Whitcroft
28482ac73b4fSJoe Perches		my $found_file = 0;
2849773647a0SAndy Whitcroft		# extract the filename as it passes
28503bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
28513bf9a009SRabin Vincent			$realfile = $1;
28522b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2853270c49a0SJoe Perches			$in_commit_log = 0;
28542ac73b4fSJoe Perches			$found_file = 1;
28553bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2856773647a0SAndy Whitcroft			$realfile = $1;
28572b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2858270c49a0SJoe Perches			$in_commit_log = 0;
28591e855726SWolfram Sang
28601e855726SWolfram Sang			$p1_prefix = $1;
2861e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2862e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2863000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2864000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
28651e855726SWolfram Sang			}
2866773647a0SAndy Whitcroft
2867c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2868000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
286910d27111SGeert Uytterhoeven				      "do not modify files in include/asm, change architecture specific files in arch/<architecture>/include/asm\n" . "$here$rawline\n");
2870773647a0SAndy Whitcroft			}
28712ac73b4fSJoe Perches			$found_file = 1;
28722ac73b4fSJoe Perches		}
28732ac73b4fSJoe Perches
287434d8815fSJoe Perches#make up the handle for any error we report on this line
287534d8815fSJoe Perches		if ($showfile) {
287634d8815fSJoe Perches			$prefix = "$realfile:$realline: "
287734d8815fSJoe Perches		} elsif ($emacs) {
28787d3a9f67SJoe Perches			if ($file) {
28797d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
28807d3a9f67SJoe Perches			} else {
288134d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
288234d8815fSJoe Perches			}
28837d3a9f67SJoe Perches		}
288434d8815fSJoe Perches
28852ac73b4fSJoe Perches		if ($found_file) {
288685b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
288785b0ee18SJoe Perches				WARN("OBSOLETE",
288885b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
288985b0ee18SJoe Perches			}
28907bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
28912ac73b4fSJoe Perches				$check = 1;
28922ac73b4fSJoe Perches			} else {
28932ac73b4fSJoe Perches				$check = $check_orig;
28942ac73b4fSJoe Perches			}
28959f3a8992SRob Herring			$checklicenseline = 1;
2896133712a2SRob Herring
2897133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2898133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2899133712a2SRob Herring
2900133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2901133712a2SRob Herring
2902133712a2SRob Herring				if (($last_binding_patch != -1) &&
2903133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2904133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2905858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2906133712a2SRob Herring				}
2907133712a2SRob Herring			}
2908133712a2SRob Herring
2909773647a0SAndy Whitcroft			next;
2910773647a0SAndy Whitcroft		}
2911773647a0SAndy Whitcroft
2912389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
29130a920b5bSAndy Whitcroft
2914c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2915c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2916c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
29170a920b5bSAndy Whitcroft
29186c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
29196c72ffaaSAndy Whitcroft
2920490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2921490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2922490b292cSJoe Perches		if ($in_commit_log) {
2923490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2924490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2925490b292cSJoe Perches			}
2926490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2927490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2928490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2929490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2930490b292cSJoe Perches		}
2931490b292cSJoe Perches
2932e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2933e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
293413e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
293513e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2936e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2937e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2938e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2939e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2940e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2941e518e9a5SJoe Perches		}
2942e518e9a5SJoe Perches
29433bf9a009SRabin Vincent# Check for incorrect file permissions
29443bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
29453bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
294604db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
294704db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2948000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2949000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
29503bf9a009SRabin Vincent			}
29513bf9a009SRabin Vincent		}
29523bf9a009SRabin Vincent
2953cd261496SGeert Uytterhoeven# Check the patch for a From:
2954cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2955cd261496SGeert Uytterhoeven			$author = $1;
2956e7f929f3SDwaipayan Ray			my $curline = $linenr;
2957e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2958e7f929f3SDwaipayan Ray				$author .= $1;
2959e7f929f3SDwaipayan Ray			}
2960cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2961cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2962dfa05c28SJoe Perches			$author = reformat_email($author);
2963cd261496SGeert Uytterhoeven		}
2964cd261496SGeert Uytterhoeven
296520112475SJoe Perches# Check the patch for a signoff:
2966dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
29674a0df2efSAndy Whitcroft			$signoff++;
296815662b3eSJoe Perches			$in_commit_log = 0;
296948ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2970fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2971cd261496SGeert Uytterhoeven					$authorsignoff = 1;
297248ca2d8aSDwaipayan Ray				} else {
297348ca2d8aSDwaipayan Ray					my $ctx = $1;
297448ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
297548ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
297648ca2d8aSDwaipayan Ray
2977046fc741SMimi Zohar					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
297848ca2d8aSDwaipayan Ray						$author_sob = $ctx;
297948ca2d8aSDwaipayan Ray						$authorsignoff = 2;
2980046fc741SMimi Zohar					} elsif (lc $email_address eq lc $author_address) {
298148ca2d8aSDwaipayan Ray						$author_sob = $ctx;
298248ca2d8aSDwaipayan Ray						$authorsignoff = 3;
298348ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
298448ca2d8aSDwaipayan Ray						$author_sob = $ctx;
298548ca2d8aSDwaipayan Ray						$authorsignoff = 4;
298648ca2d8aSDwaipayan Ray
298748ca2d8aSDwaipayan Ray						my $address1 = $email_address;
298848ca2d8aSDwaipayan Ray						my $address2 = $author_address;
298948ca2d8aSDwaipayan Ray
299048ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
299148ca2d8aSDwaipayan Ray							$address1 = "$1$2";
299248ca2d8aSDwaipayan Ray						}
299348ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
299448ca2d8aSDwaipayan Ray							$address2 = "$1$2";
299548ca2d8aSDwaipayan Ray						}
299648ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
299748ca2d8aSDwaipayan Ray							$authorsignoff = 5;
299848ca2d8aSDwaipayan Ray						}
299948ca2d8aSDwaipayan Ray					}
3000cd261496SGeert Uytterhoeven				}
3001cd261496SGeert Uytterhoeven			}
30020a920b5bSAndy Whitcroft		}
300320112475SJoe Perches
300444d303ebSJoe Perches# Check for patch separator
300544d303ebSJoe Perches		if ($line =~ /^---$/) {
300644d303ebSJoe Perches			$has_patch_separator = 1;
300744d303ebSJoe Perches			$in_commit_log = 0;
300844d303ebSJoe Perches		}
300944d303ebSJoe Perches
3010e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
3011e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
3012e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
3013e0d975b1SJoe Perches			$reported_maintainer_file = 1;
3014e0d975b1SJoe Perches		}
3015e0d975b1SJoe Perches
301620112475SJoe Perches# Check signature styles
3017270c49a0SJoe Perches		if (!$in_header_lines &&
3018ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
301920112475SJoe Perches			my $space_before = $1;
302020112475SJoe Perches			my $sign_off = $2;
302120112475SJoe Perches			my $space_after = $3;
302220112475SJoe Perches			my $email = $4;
302320112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
302420112475SJoe Perches
3025ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
3026831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
3027831242abSAditya Srivastava				if ($suggested_signature eq "") {
3028ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
3029ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
3030831242abSAditya Srivastava				} else {
3031831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
3032831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
3033831242abSAditya Srivastava					    $fix) {
3034831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
3035831242abSAditya Srivastava					}
3036831242abSAditya Srivastava				}
3037ce0338dfSJoe Perches			}
303820112475SJoe Perches			if (defined $space_before && $space_before ne "") {
30393705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30403705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
30413705ce5bSJoe Perches				    $fix) {
3042194f66fcSJoe Perches					$fixed[$fixlinenr] =
30433705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30443705ce5bSJoe Perches				}
304520112475SJoe Perches			}
304620112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
30473705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30483705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
30493705ce5bSJoe Perches				    $fix) {
3050194f66fcSJoe Perches					$fixed[$fixlinenr] =
30513705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30523705ce5bSJoe Perches				}
30533705ce5bSJoe Perches
305420112475SJoe Perches			}
305520112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
30563705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30573705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
30583705ce5bSJoe Perches				    $fix) {
3059194f66fcSJoe Perches					$fixed[$fixlinenr] =
30603705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30613705ce5bSJoe Perches				}
306220112475SJoe Perches			}
306320112475SJoe Perches
3064dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
306548ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
306620112475SJoe Perches			if ($suggested_email eq "") {
3067000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
3068000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
306920112475SJoe Perches			} else {
307020112475SJoe Perches				my $dequoted = $suggested_email;
307120112475SJoe Perches				$dequoted =~ s/^"//;
307220112475SJoe Perches				$dequoted =~ s/" </ </;
307320112475SJoe Perches				# Don't force email to have quotes
307420112475SJoe Perches				# Allow just an angle bracketed address
3075fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
3076fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3077fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3078fccaebf0SDwaipayan Ray					    $fix) {
3079fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3080fccaebf0SDwaipayan Ray					}
3081fccaebf0SDwaipayan Ray				}
3082fccaebf0SDwaipayan Ray
3083fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
3084fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
3085fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
3086fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
3087fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3088fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3089fccaebf0SDwaipayan Ray					    $fix) {
3090fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3091fccaebf0SDwaipayan Ray					}
3092fccaebf0SDwaipayan Ray				}
3093fccaebf0SDwaipayan Ray
3094fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
3095fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3096fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
3097000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
3098fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
3099fccaebf0SDwaipayan Ray				}
3100fccaebf0SDwaipayan Ray
3101fccaebf0SDwaipayan Ray
3102fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
3103e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
3104fccaebf0SDwaipayan Ray				# begin with a #
3105fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3106fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
3107fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
3108fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
3109fccaebf0SDwaipayan Ray						my $new_comment = $comment;
3110fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3111fccaebf0SDwaipayan Ray
3112fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
3113fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
3114fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
3115fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
3116fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
3117fccaebf0SDwaipayan Ray
3118fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3119fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
3120fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
3121fccaebf0SDwaipayan Ray
3122fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3123fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3124fccaebf0SDwaipayan Ray						    $fix) {
3125fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3126fccaebf0SDwaipayan Ray						}
3127fccaebf0SDwaipayan Ray					}
3128fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3129fccaebf0SDwaipayan Ray					my $new_comment = $comment;
3130fccaebf0SDwaipayan Ray
3131fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
3132fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
3133fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
3134fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3135fccaebf0SDwaipayan Ray
3136fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
3137fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3138fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
3139fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3140fccaebf0SDwaipayan Ray
3141fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3142fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3143fccaebf0SDwaipayan Ray					    $fix) {
3144fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3145fccaebf0SDwaipayan Ray					}
314620112475SJoe Perches				}
31470a920b5bSAndy Whitcroft			}
31487e51f197SJoe Perches
31497e51f197SJoe Perches# Check for duplicate signatures
31507e51f197SJoe Perches			my $sig_nospace = $line;
31517e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
31527e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
31537e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
31547e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
31557e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
31567e51f197SJoe Perches			} else {
31577e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
31587e51f197SJoe Perches			}
31596c5d24eeSSean Christopherson
31606c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
31616c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
31626c5d24eeSSean Christopherson				if ($email eq $author) {
31636c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31641916f777SThorsten Leemhuis					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr);
31656c5d24eeSSean Christopherson				}
31666c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
31676c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31681916f777SThorsten Leemhuis					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
31691916f777SThorsten Leemhuis				} elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
31706c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31711916f777SThorsten Leemhuis					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n");
31726c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
31736c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31741916f777SThorsten Leemhuis					     "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n");
31756c5d24eeSSean Christopherson				}
31766c5d24eeSSean Christopherson			}
3177d7f1d71eSKai Wasserbäch
317844c31888SMatthieu Baerts# check if Reported-by: is followed by a Closes: tag
3179d7f1d71eSKai Wasserbäch			if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) {
3180d7f1d71eSKai Wasserbäch				if (!defined $lines[$linenr]) {
3181d7f1d71eSKai Wasserbäch					WARN("BAD_REPORTED_BY_LINK",
318244c31888SMatthieu Baerts					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n");
3183d6ccdd67SMatthieu Baerts				} elsif ($rawlines[$linenr] !~ /^closes:\s*/i) {
3184d7f1d71eSKai Wasserbäch					WARN("BAD_REPORTED_BY_LINK",
318544c31888SMatthieu Baerts					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
31860a920b5bSAndy Whitcroft				}
3187d7f1d71eSKai Wasserbäch			}
3188d7f1d71eSKai Wasserbäch		}
3189d7f1d71eSKai Wasserbäch
3190d5d6281aSDan Carpenter# These indicate a bug fix
3191d5d6281aSDan Carpenter		if (!$in_header_lines && !$is_patch &&
3192d5d6281aSDan Carpenter			$line =~ /^This reverts commit/) {
3193d5d6281aSDan Carpenter			$is_revert = 1;
3194d5d6281aSDan Carpenter		}
3195d5d6281aSDan Carpenter
3196d5d6281aSDan Carpenter		if (!$in_header_lines && !$is_patch &&
3197d5d6281aSDan Carpenter		    $line =~ /((?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller))/) {
3198d5d6281aSDan Carpenter			$needs_fixes_tag = $1;
3199d5d6281aSDan Carpenter		}
32000a920b5bSAndy Whitcroft
3201bd17e036SNiklas Söderlund# Check Fixes: styles is correct
3202bd17e036SNiklas Söderlund		if (!$in_header_lines &&
32032f07b652STamir Duberstein		    $line =~ /^\s*(fixes:?)\s*(?:commit\s*)?([0-9a-f]{5,40})(?:\s*($balanced_parens))?/i) {
32042f07b652STamir Duberstein			my $tag = $1;
32052f07b652STamir Duberstein			my $orig_commit = $2;
32062f07b652STamir Duberstein			my $title;
3207bd17e036SNiklas Söderlund			my $title_has_quotes = 0;
3208d5d6281aSDan Carpenter			$fixes_tag = 1;
32092f07b652STamir Duberstein			if (defined $3) {
3210bd17e036SNiklas Söderlund				# Always strip leading/trailing parens then double quotes if existing
32112f07b652STamir Duberstein				$title = substr($3, 1, -1);
3212bd17e036SNiklas Söderlund				if ($title =~ /^".*"$/) {
3213bd17e036SNiklas Söderlund					$title = substr($title, 1, -1);
3214bd17e036SNiklas Söderlund					$title_has_quotes = 1;
3215bd17e036SNiklas Söderlund				}
32162f07b652STamir Duberstein			} else {
32172f07b652STamir Duberstein				$title = "commit title"
3218bd17e036SNiklas Söderlund			}
3219bd17e036SNiklas Söderlund
32202f07b652STamir Duberstein
32212f07b652STamir Duberstein			my $tag_case = not ($tag eq "Fixes:");
32222f07b652STamir Duberstein			my $tag_space = not ($line =~ /^fixes:? [0-9a-f]{5,40} ($balanced_parens)/i);
32232f07b652STamir Duberstein
32246356f18fSGeert Uytterhoeven			my $id_length = not ($orig_commit =~ /^[0-9a-f]{12,40}$/i);
32252f07b652STamir Duberstein			my $id_case = not ($orig_commit !~ /[A-F]/);
32262f07b652STamir Duberstein
32272f07b652STamir Duberstein			my $id = "0123456789ab";
3228bd17e036SNiklas Söderlund			my ($cid, $ctitle) = git_commit_info($orig_commit, $id,
3229bd17e036SNiklas Söderlund							     $title);
3230bd17e036SNiklas Söderlund
32313735c522STamir Duberstein			if (defined($cid) && ($ctitle ne $title || $tag_case || $tag_space || $id_length || $id_case || !$title_has_quotes)) {
32323735c522STamir Duberstein				my $fixed = "Fixes: $cid (\"$ctitle\")";
3233bd17e036SNiklas Söderlund				if (WARN("BAD_FIXES_TAG",
32343735c522STamir Duberstein				     "Please use correct Fixes: style 'Fixes: <12+ chars of sha1> (\"<title line>\")' - ie: '$fixed'\n" . $herecurr) &&
3235bd17e036SNiklas Söderlund				    $fix) {
32363735c522STamir Duberstein					$fixed[$fixlinenr] = $fixed;
3237bd17e036SNiklas Söderlund				}
3238bd17e036SNiklas Söderlund			}
3239bd17e036SNiklas Söderlund		}
3240bd17e036SNiklas Söderlund
3241a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3242a2fe16b9SJoe Perches		if ($in_header_lines &&
3243a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3244a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3245a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3246a2fe16b9SJoe Perches		}
3247a2fe16b9SJoe Perches
324844d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
324944d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
32507580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
32517580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
32527580c5b9SAditya Srivastava			    $fix) {
32537580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
32547580c5b9SAditya Srivastava			}
32557ebd05efSChristopher Covington		}
32567ebd05efSChristopher Covington
3257369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3258369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3259369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3260369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3261369c8dd3SJoe Perches					# timestamp
3262634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3263634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3264634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3265634cffccSJoe Perches					# stack dump address styles
3266369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3267369c8dd3SJoe Perches		}
3268369c8dd3SJoe Perches
32692a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
32702a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3271bf4daf12SJoe Perches		    length($line) > 75 &&
3272bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3273bf4daf12SJoe Perches					# file delta changes
327436f8b348SJerome Forissier		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
3275bf4daf12SJoe Perches					# filename then :
3276f94e40eaSMatthieu Baerts		      $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i ||
3277f94e40eaSMatthieu Baerts					# A Fixes:, link or signature tag line
3278bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
32792a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
32808e7b7ffbSJim Cromie			     "Prefer a maximum 75 chars per line (possible unwrapped commit description?)\n" . $herecurr);
32812a076f40SJoe Perches			$commit_log_long_line = 1;
32822a076f40SJoe Perches		}
32832a076f40SJoe Perches
3284bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3285bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3286bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3287bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3288bf4daf12SJoe Perches		}
3289bf4daf12SJoe Perches
329076f381bbSKai Wasserbäch# Check for odd tags before a URI/URL
329176f381bbSKai Wasserbäch		if ($in_commit_log &&
3292f94e40eaSMatthieu Baerts		    $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) {
329376f381bbSKai Wasserbäch			if ($1 =~ /^v(?:ersion)?\d+/i) {
329476f381bbSKai Wasserbäch				WARN("COMMIT_LOG_VERSIONING",
329576f381bbSKai Wasserbäch				     "Patch version information should be after the --- line\n" . $herecurr);
329676f381bbSKai Wasserbäch			} else {
329776f381bbSKai Wasserbäch				WARN("COMMIT_LOG_USE_LINK",
3298f94e40eaSMatthieu Baerts				     "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr);
329976f381bbSKai Wasserbäch			}
330076f381bbSKai Wasserbäch		}
330176f381bbSKai Wasserbäch
3302d6ccdd67SMatthieu Baerts# Check for misuse of the link tags
3303d6ccdd67SMatthieu Baerts		if ($in_commit_log &&
3304d6ccdd67SMatthieu Baerts		    $line =~ /^\s*(\w+:)\s*(\S+)/) {
3305d6ccdd67SMatthieu Baerts			my $tag = $1;
3306d6ccdd67SMatthieu Baerts			my $value = $2;
3307d6ccdd67SMatthieu Baerts			if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) {
3308d6ccdd67SMatthieu Baerts				WARN("COMMIT_LOG_WRONG_LINK",
3309d6ccdd67SMatthieu Baerts				     "'$tag' should be followed by a public http(s) link\n" . $herecurr);
33100d7835fcSJoe Perches			}
33114ce9f970SJoe Perches		}
33124ce9f970SJoe Perches
33134ce9f970SJoe Perches# Check for lines starting with a #
33144ce9f970SJoe Perches		if ($in_commit_log && $line =~ /^#/) {
33154ce9f970SJoe Perches			if (WARN("COMMIT_COMMENT_SYMBOL",
33164ce9f970SJoe Perches				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
33174ce9f970SJoe Perches			    $fix) {
33184ce9f970SJoe Perches				$fixed[$fixlinenr] =~ s/^/ /;
33194ce9f970SJoe Perches			}
33204ce9f970SJoe Perches		}
3321a8972573SJohn Hubbard
3322e882dbfcSWei Wang# Check for git id commit length and improperly formed commit descriptions
33234ce9f970SJoe Perches# A correctly formed commit description is:
33244ce9f970SJoe Perches#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
3325aab38f51SJoe Perches# with the commit subject '("' prefix and '")' suffix
3326369c8dd3SJoe Perches# This is a fairly compilicated block as it tests for what appears to be
3327bf4daf12SJoe Perches# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
3328fe043ea1SJoe Perches# possible SHA-1 matches.
3329fe043ea1SJoe Perches# A commit match can span multiple lines so this block attempts to find a
33300d7835fcSJoe Perches# complete typical commit on a maximum of 3 lines
33310d7835fcSJoe Perches		if ($perl_version_ok &&
33320d7835fcSJoe Perches		    $in_commit_log && !$commit_log_possible_stack_dump &&
33330d7835fcSJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
33340d7835fcSJoe Perches		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
33350d7835fcSJoe Perches		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
33360d7835fcSJoe Perches		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
33374ce9f970SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
33384ce9f970SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
33394ce9f970SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
33400d7835fcSJoe Perches			my $init_char = "c";
33414ce9f970SJoe Perches			my $orig_commit = "";
33424ce9f970SJoe Perches			my $short = 1;
33434ce9f970SJoe Perches			my $long = 0;
33444ce9f970SJoe Perches			my $case = 1;
33454ce9f970SJoe Perches			my $space = 1;
33464ce9f970SJoe Perches			my $id = '0123456789ab';
33474ce9f970SJoe Perches			my $orig_desc = "commit description";
33484ce9f970SJoe Perches			my $description = "";
33494ce9f970SJoe Perches			my $herectx = $herecurr;
33504ce9f970SJoe Perches			my $has_parens = 0;
33514ce9f970SJoe Perches			my $has_quotes = 0;
33524ce9f970SJoe Perches
33534ce9f970SJoe Perches			my $input = $line;
33544ce9f970SJoe Perches			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
33554ce9f970SJoe Perches				for (my $n = 0; $n < 2; $n++) {
33564ce9f970SJoe Perches					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
33574ce9f970SJoe Perches						$orig_desc = $1;
33584ce9f970SJoe Perches						$has_parens = 1;
33594ce9f970SJoe Perches						# Always strip leading/trailing parens then double quotes if existing
3360fe043ea1SJoe Perches						$orig_desc = substr($orig_desc, 1, -1);
3361fe043ea1SJoe Perches						if ($orig_desc =~ /^".*"$/) {
33624ce9f970SJoe Perches							$orig_desc = substr($orig_desc, 1, -1);
33634ce9f970SJoe Perches							$has_quotes = 1;
33644ce9f970SJoe Perches						}
33654ce9f970SJoe Perches						last;
33664ce9f970SJoe Perches					}
33674ce9f970SJoe Perches					last if ($#lines < $linenr + $n);
33684ce9f970SJoe Perches					$input .= " " . trim($rawlines[$linenr + $n]);
33694ce9f970SJoe Perches					$herectx .= "$rawlines[$linenr + $n]\n";
33704ce9f970SJoe Perches				}
33710d7835fcSJoe Perches				$herectx = $herecurr if (!$has_parens);
33720d7835fcSJoe Perches			}
33730d7835fcSJoe Perches
33740d7835fcSJoe Perches			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
33750d7835fcSJoe Perches				$init_char = $1;
3376948b133aSHeinrich Schuchardt				$orig_commit = lc($2);
33774ce9f970SJoe Perches				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
33784ce9f970SJoe Perches				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
3379d311cd44SJoe Perches				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
33804ce9f970SJoe Perches				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
33810d7835fcSJoe Perches			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
33824ce9f970SJoe Perches				$orig_commit = lc($1);
33834ce9f970SJoe Perches			}
3384d311cd44SJoe Perches
3385d311cd44SJoe Perches			($id, $description) = git_commit_info($orig_commit,
33869b71f79fSBjorn Helgaas							      $id, $orig_desc);
33879b71f79fSBjorn Helgaas
33889b71f79fSBjorn Helgaas			if (defined($id) &&
33899b71f79fSBjorn Helgaas			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
33909b71f79fSBjorn Helgaas			    $last_git_commit_id_linenr != $linenr - 1) {
33919b71f79fSBjorn Helgaas				ERROR("GIT_COMMIT_ID",
339213f1937eSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
339313f1937eSJoe Perches			}
339413f1937eSJoe Perches			#don't report the next line if this line ends in commit and the sha1 hash is the next line
339513f1937eSJoe Perches			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
339613f1937eSJoe Perches		}
339713f1937eSJoe Perches
3398a82603a8SAndrew Jeffery# Check for mailing list archives other than lore.kernel.org
339913f1937eSJoe Perches		if ($rawline =~ m{http.*\b$obsolete_archives}) {
340013f1937eSJoe Perches			WARN("PREFER_LORE_ARCHIVE",
340113f1937eSJoe Perches			     "Use lore.kernel.org archive links when possible - see https://lore.kernel.org/lists.html\n" . $herecurr);
340213f1937eSJoe Perches		}
340313f1937eSJoe Perches
3404e400edb1SRob Herring# Check for added, moved or deleted files
3405e400edb1SRob Herring		if (!$reported_maintainer_file && !$in_commit_log &&
3406e400edb1SRob Herring		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
3407e400edb1SRob Herring		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
3408e400edb1SRob Herring		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
340956ddc4cdSMauro Carvalho Chehab		      (defined($1) || defined($2))))) {
3410e400edb1SRob Herring			$is_patch = 1;
3411e400edb1SRob Herring			$reported_maintainer_file = 1;
341200df344fSAndy Whitcroft			WARN("FILE_PATH_CHANGES",
34138905a67cSAndy Whitcroft			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
3414000d1cc1SJoe Perches		}
3415000d1cc1SJoe Perches
34166c72ffaaSAndy Whitcroft# Check for adding new DT bindings not in schema format
3417de7d4f0eSAndy Whitcroft		if (!$in_commit_log &&
3418de7d4f0eSAndy Whitcroft		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3419de7d4f0eSAndy Whitcroft		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3420de7d4f0eSAndy Whitcroft			WARN("DT_SCHEMA_BINDING_PATCH",
3421171ae1a4SAndy Whitcroft			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3422171ae1a4SAndy Whitcroft		}
3423171ae1a4SAndy Whitcroft
3424171ae1a4SAndy Whitcroft# Check for wrappage within a valid hunk of the file
3425171ae1a4SAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3426171ae1a4SAndy Whitcroft			ERROR("CORRUPTED_PATCH",
3427171ae1a4SAndy Whitcroft			      "patch seems to be corrupt (line wrapped?)\n" .
342834d99219SJoe Perches				$herecurr) if (!$emitted_corrupt++);
3429000d1cc1SJoe Perches		}
343000df344fSAndy Whitcroft
34310a920b5bSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
343215662b3eSJoe Perches		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
343315662b3eSJoe Perches		    $rawline !~ m/^$UTF8*$/) {
343415662b3eSJoe Perches			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3435eb3a58deSJoe Perches
3436eb3a58deSJoe Perches			my $blank = copy_spacing($rawline);
343715662b3eSJoe Perches			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
343815662b3eSJoe Perches			my $hereptr = "$hereline$ptr\n";
3439ed43c4e5SAllen Hubbe
344015662b3eSJoe Perches			CHK("INVALID_UTF8",
344115662b3eSJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
3442fa64205dSPasi Savanainen		}
3443fa64205dSPasi Savanainen
3444fa64205dSPasi Savanainen# Check if it's the start of a commit log
3445fa64205dSPasi Savanainen# (not a header line and we haven't seen the patch filename)
3446fa64205dSPasi Savanainen		if ($in_header_lines && $realfile =~ /^$/ &&
3447fa64205dSPasi Savanainen		    !($rawline =~ /^\s+(?:\S|$)/ ||
3448fa64205dSPasi Savanainen		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
3449fa64205dSPasi Savanainen			$in_header_lines = 0;
3450fa64205dSPasi Savanainen			$in_commit_log = 1;
345115662b3eSJoe Perches			$has_commit_log = 1;
3452fa64205dSPasi Savanainen		}
345315662b3eSJoe Perches
345415662b3eSJoe Perches# Check if there is UTF-8 in a commit log when a mail header has explicitly
345515662b3eSJoe Perches# declined it, i.e defined some charset where it is missing.
3456d6430f71SJoe Perches		if ($in_header_lines &&
3457d6430f71SJoe Perches		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3458d6430f71SJoe Perches		    $1 !~ /utf-8/i) {
3459d6430f71SJoe Perches			$non_utf8_charset = 1;
3460d6430f71SJoe Perches		}
3461d6430f71SJoe Perches
3462d6430f71SJoe Perches		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
3463d6430f71SJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3464d6430f71SJoe Perches			WARN("UTF8_BEFORE_PATCH",
3465d6430f71SJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
3466d6430f71SJoe Perches		}
3467d6430f71SJoe Perches
3468d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3469d6430f71SJoe Perches		if ($tree && $in_commit_log) {
347066b47b4aSKees Cook			while ($line =~ m{(?:^|\s)(/\S*)}g) {
347166d7a382SJoe Perches				my $file = $1;
347266d7a382SJoe Perches
34737da07c31SDwaipayan Ray				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
347466b47b4aSKees Cook				    check_absolute_file($1, $herecurr)) {
34757da07c31SDwaipayan Ray					#
34767da07c31SDwaipayan Ray				} else {
34777da07c31SDwaipayan Ray					check_absolute_file($file, $herecurr);
347866b47b4aSKees Cook				}
347966b47b4aSKees Cook			}
348066b47b4aSKees Cook		}
34810675a8fbSJean Delvare
34820675a8fbSJean Delvare# Check for various typo / spelling mistakes
34830675a8fbSJean Delvare		if (defined($misspellings) &&
34847da07c31SDwaipayan Ray		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
348566b47b4aSKees Cook			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
348666b47b4aSKees Cook				my $typo = $1;
348766b47b4aSKees Cook				my $blank = copy_spacing($rawline);
348866b47b4aSKees Cook				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
348966b47b4aSKees Cook				my $hereptr = "$hereline$ptr\n";
349066b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
3491a8dd86bfSMatteo Croce				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
3492a8dd86bfSMatteo Croce				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
3493a8dd86bfSMatteo Croce				my $msg_level = \&WARN;
3494a8dd86bfSMatteo Croce				$msg_level = \&CHK if ($file);
3495a8dd86bfSMatteo Croce				if (&{$msg_level}("TYPO_SPELLING",
3496a8dd86bfSMatteo Croce						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
3497a8dd86bfSMatteo Croce				    $fix) {
3498a8dd86bfSMatteo Croce					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
3499a8dd86bfSMatteo Croce				}
3500a8dd86bfSMatteo Croce			}
3501a8dd86bfSMatteo Croce		}
3502310cd06bSJoe Perches
35038d0325ccSAditya Srivastava# check for invalid commit id
35048d0325ccSAditya Srivastava		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
35058d0325ccSAditya Srivastava			my $id;
35061db81a68SDwaipayan Ray			my $description;
3507310cd06bSJoe Perches			($id, $description) = git_commit_info($2, undef, undef);
3508310cd06bSJoe Perches			if (!defined($id)) {
3509310cd06bSJoe Perches				WARN("UNKNOWN_COMMIT_ID",
3510310cd06bSJoe Perches				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
35111db81a68SDwaipayan Ray			}
35121db81a68SDwaipayan Ray		}
3513310cd06bSJoe Perches
3514310cd06bSJoe Perches# check for repeated words separated by a single space
3515310cd06bSJoe Perches# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
3516310cd06bSJoe Perches		if (($rawline =~ /^\+/ || $in_commit_log) &&
3517310cd06bSJoe Perches		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
35181db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3519310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3520310cd06bSJoe Perches
35211db81a68SDwaipayan Ray				my $first = $1;
35221db81a68SDwaipayan Ray				my $second = $2;
35231db81a68SDwaipayan Ray				my $start_pos = $-[1];
35241db81a68SDwaipayan Ray				my $end_pos = $+[2];
35251db81a68SDwaipayan Ray				if ($first =~ /(?:struct|union|enum)/) {
35261db81a68SDwaipayan Ray					pos($rawline) += length($first) + length($second) + 1;
35271db81a68SDwaipayan Ray					next;
35281db81a68SDwaipayan Ray				}
35291db81a68SDwaipayan Ray
35308d0325ccSAditya Srivastava				next if (lc($first) ne lc($second));
35318d0325ccSAditya Srivastava				next if ($first eq 'long');
35328d0325ccSAditya Srivastava
35338d0325ccSAditya Srivastava				# check for character before and after the word matches
35348d0325ccSAditya Srivastava				my $start_char = '';
3535310cd06bSJoe Perches				my $end_char = '';
3536310cd06bSJoe Perches				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
3537310cd06bSJoe Perches				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
3538310cd06bSJoe Perches
3539310cd06bSJoe Perches				next if ($start_char =~ /^\S$/);
3540310cd06bSJoe Perches				next if (index(" \t.,;?!", $end_char) == -1);
3541310cd06bSJoe Perches
3542310cd06bSJoe Perches				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
3543310cd06bSJoe Perches				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
3544310cd06bSJoe Perches					next if (!exists($allow_repeated_words{lc($first)}));
3545310cd06bSJoe Perches				}
3546310cd06bSJoe Perches
3547310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3548310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3549310cd06bSJoe Perches				    $fix) {
3550310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3551310cd06bSJoe Perches				}
3552310cd06bSJoe Perches			}
3553310cd06bSJoe Perches
3554310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3555310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
355630670854SAndy Whitcroft			    $prevrawline =~ /($word_pattern)\s*$/) {
355730670854SAndy Whitcroft				my $last_word = $1;
355800df344fSAndy Whitcroft				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
35590a920b5bSAndy Whitcroft					if (WARN("REPEATED_WORD",
35609c0ca6f9SAndy Whitcroft						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3561c2fdda0dSAndy Whitcroft					    $fix) {
3562d5e616fcSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3563d5e616fcSJoe Perches					}
3564d5e616fcSJoe Perches				}
3565194f66fcSJoe Perches			}
3566d5e616fcSJoe Perches		}
3567c2fdda0dSAndy Whitcroft
3568c2fdda0dSAndy Whitcroft# ignore non-hunk lines and lines being removed
35693705ce5bSJoe Perches		next if (!$hunk_line || $line =~ /^-/);
35703705ce5bSJoe Perches
35713705ce5bSJoe Perches#trailing whitespace
3572194f66fcSJoe Perches		if ($line =~ /^\+.*\015/) {
35733705ce5bSJoe Perches			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35743705ce5bSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3575d2c0a235SAndy Whitcroft				  "DOS line endings\n" . $herevet) &&
35760a920b5bSAndy Whitcroft			    $fix) {
35775368df20SAndy Whitcroft				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
35784783f894SJosh Triplett			}
3579109d8cb2SAlexander Duyck		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
35801bde561eSMatthew Wilcox			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35813e2232f2SJoe Perches			if (ERROR("TRAILING_WHITESPACE",
35823e2232f2SJoe Perches				  "trailing whitespace\n" . $herevet) &&
35834783f894SJosh Triplett			    $fix) {
35840675a8fbSJean Delvare				$fixed[$fixlinenr] =~ s/\s+$//;
35850675a8fbSJean Delvare			}
35860675a8fbSJean Delvare
35874783f894SJosh Triplett			$rpt_cleaners = 1;
35884783f894SJosh Triplett		}
35894783f894SJosh Triplett
35903354957aSAndi Kleen# Check for FSF mailing addresses.
35919fe287d7SAndy Whitcroft		if ($rawline =~ /\bwrite to the Free/i ||
35929fe287d7SAndy Whitcroft		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
35933354957aSAndi Kleen		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
3594678ae162SUlf Magnusson		    $rawline =~ /\b51\s+Franklin\s+St/i) {
3595678ae162SUlf Magnusson			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3596678ae162SUlf Magnusson			my $msg_level = \&ERROR;
3597678ae162SUlf Magnusson			$msg_level = \&CHK if ($file);
3598b8709bceSJoe Perches			&{$msg_level}("FSF_MAILING_ADDRESS",
3599b8709bceSJoe Perches				      "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
3600b8709bceSJoe Perches		}
3601b8709bceSJoe Perches
3602b8709bceSJoe Perches# check for Kconfig help text having a real description
3603b8709bceSJoe Perches# Only applies when adding the entry originally, after that we do not have
36049fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
36059fe287d7SAndy Whitcroft		if ($realfile =~ /Kconfig/ &&
3606b8709bceSJoe Perches		    # 'choice' is usually the last thing on the line (though
3607a1385803SAndy Whitcroft		    # Kconfig supports named choices), so use a word boundary
3608b8709bceSJoe Perches		    # (\b) rather than a whitespace character (\s)
3609b8709bceSJoe Perches		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
3610b8709bceSJoe Perches			my $ln = $linenr;
3611b8709bceSJoe Perches			my $needs_help = 0;
3612b8709bceSJoe Perches			my $has_help = 0;
3613b8709bceSJoe Perches			my $help_length = 0;
3614b8709bceSJoe Perches			while (defined $lines[$ln]) {
3615a1385803SAndy Whitcroft				my $f = $lines[$ln++];
3616a1385803SAndy Whitcroft
3617b8709bceSJoe Perches				next if ($f =~ /^-/);
3618b8709bceSJoe Perches				last if ($f !~ /^[\+ ]/);	# !patch context
3619b8709bceSJoe Perches
3620b8709bceSJoe Perches				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3621678ae162SUlf Magnusson					$needs_help = 1;
3622b8709bceSJoe Perches					next;
3623678ae162SUlf Magnusson				}
3624678ae162SUlf Magnusson				if ($f =~ /^\+\s*help\s*$/) {
3625678ae162SUlf Magnusson					$has_help = 1;
3626678ae162SUlf Magnusson					next;
3627b8709bceSJoe Perches				}
3628678ae162SUlf Magnusson
36299fe287d7SAndy Whitcroft				$f =~ s/^.//;	# strip patch context [+ ]
36309fe287d7SAndy Whitcroft				$f =~ s/#.*//;	# strip # directives
3631b8709bceSJoe Perches				$f =~ s/^\s+//;	# strip leading blanks
36323354957aSAndi Kleen				next if ($f =~ /^$/);	# skip blank lines
3633b8709bceSJoe Perches
3634b8709bceSJoe Perches				# At the end of this Kconfig block:
3635b8709bceSJoe Perches				# This only checks context lines in the patch
3636000d1cc1SJoe Perches				# and so hopefully shouldn't trigger false
3637b8709bceSJoe Perches				# positives, even though some of these are
363856193274SVadim Bendebury				# common words in help texts
36393354957aSAndi Kleen				if ($f =~ /^(?:config|menuconfig|choice|endchoice|
36403354957aSAndi Kleen					       if|endif|menu|endmenu|source)\b/x) {
36417ccf41a8SJoe Perches					last;
36427ccf41a8SJoe Perches				}
36437ccf41a8SJoe Perches				$help_length++ if ($has_help);
36447ccf41a8SJoe Perches			}
3645628f91a2SJoe Perches			if ($needs_help &&
3646628f91a2SJoe Perches			    $help_length < $min_conf_desc_length) {
3647628f91a2SJoe Perches				my $stat_real = get_stat_real($linenr, $ln - 1);
3648628f91a2SJoe Perches				WARN("CONFIG_DESCRIPTION",
3649*bc2f19d6SPhilipp Hahn				     "please write a help paragraph that fully describes the config symbol with at least $min_conf_desc_length lines\n" . "$here\n$stat_real\n");
36501ba8dfd1SKees Cook			}
36511ba8dfd1SKees Cook		}
36521ba8dfd1SKees Cook
36531ba8dfd1SKees Cook# check MAINTAINERS entries
3654628f91a2SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
3655628f91a2SJoe Perches# check MAINTAINERS entries for the right form
3656628f91a2SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3657628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3658628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3659628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3660628f91a2SJoe Perches				    $fix) {
3661628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3662628f91a2SJoe Perches				}
3663628f91a2SJoe Perches			}
36647ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
36657ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
36667ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
36677ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
36687ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
36697ccf41a8SJoe Perches				my $cur = $1;
36707ccf41a8SJoe Perches				my $curval = $2;
36717ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
36727ccf41a8SJoe Perches				my $prev = $1;
36737ccf41a8SJoe Perches				my $prevval = $2;
36747ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
36757ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
36767ccf41a8SJoe Perches				if ($curindex < 0) {
36777ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
36787ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
36797ccf41a8SJoe Perches				} else {
36807ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
36817ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
36827ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
36837ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
36847ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
36857ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
36867ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
36877ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
36887ccf41a8SJoe Perches					}
36897ccf41a8SJoe Perches				}
36907ccf41a8SJoe Perches			}
36917ccf41a8SJoe Perches		}
3692628f91a2SJoe Perches
3693c68e5878SArnaud Lacombe# check for DT compatible documentation
3694c68e5878SArnaud Lacombe		if (defined $root &&
3695c68e5878SArnaud Lacombe			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3696c68e5878SArnaud Lacombe			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3697c68e5878SArnaud Lacombe
3698c68e5878SArnaud Lacombe			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3699c68e5878SArnaud Lacombe
3700c68e5878SArnaud Lacombe			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3701c68e5878SArnaud Lacombe			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3702c68e5878SArnaud Lacombe
3703c68e5878SArnaud Lacombe			foreach my $compat (@compats) {
3704c68e5878SArnaud Lacombe				my $compat2 = $compat;
3705c68e5878SArnaud Lacombe				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3706c68e5878SArnaud Lacombe				my $compat3 = $compat;
3707bff5da43SRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
37087dd05b38SFlorian Vaussard				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
37097dd05b38SFlorian Vaussard				if ( $? >> 8 ) {
37107dd05b38SFlorian Vaussard					WARN("UNDOCUMENTED_DT_STRING",
37117dd05b38SFlorian Vaussard					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3712bff5da43SRob Herring				}
3713bff5da43SRob Herring
3714cc93319bSFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3715852d095dSRob Herring				my $vendor = $1;
3716cc93319bSFlorian Vaussard				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3717bff5da43SRob Herring				if ( $? >> 8 ) {
3718bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3719185d566bSRob Herring					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3720185d566bSRob Herring				}
3721185d566bSRob Herring			}
3722185d566bSRob Herring		}
3723bff5da43SRob Herring
3724bff5da43SRob Herring# check for using SPDX license tag at beginning of files
3725bff5da43SRob Herring		if ($realline == $checklicenseline) {
3726bff5da43SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3727bff5da43SRob Herring				$checklicenseline = 2;
37284fbf32a6SFlorian Vaussard			} elsif ($rawline =~ /^\+/) {
37294fbf32a6SFlorian Vaussard				my $comment = "";
3730852d095dSRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
3731bff5da43SRob Herring					$comment = '/*';
3732bff5da43SRob Herring				} elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) {
3733cc93319bSFlorian Vaussard					$comment = '//';
3734bff5da43SRob Herring				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
3735bff5da43SRob Herring					$comment = '#';
3736bff5da43SRob Herring				} elsif ($realfile =~ /\.rst$/) {
3737bff5da43SRob Herring					$comment = '..';
37389f3a8992SRob Herring				}
37399f3a8992SRob Herring
37409f3a8992SRob Herring# check SPDX comment style for .[chsS] files
37419f3a8992SRob Herring				if ($realfile =~ /\.[chsS]$/ &&
37429f3a8992SRob Herring				    $rawline =~ /SPDX-License-Identifier:/ &&
37439f3a8992SRob Herring				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
37449f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
37459f3a8992SRob Herring					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3746d1d84b5fSMiguel Ojeda				}
37479f3a8992SRob Herring
3748c8df0ab6SLubomir Rintel				if ($comment !~ /^$/ &&
37499f3a8992SRob Herring				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
37509f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
37519f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
37529f3a8992SRob Herring				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
37539f3a8992SRob Herring					my $spdx_license = $1;
3754fdf13693SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
3755fdf13693SJoe Perches						WARN("SPDX_LICENSE_TAG",
3756fdf13693SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3757ffbce897SJoe Perches					}
3758fdf13693SJoe Perches					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3759fdf13693SJoe Perches					    $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) {
3760fdf13693SJoe Perches						my $msg_level = \&WARN;
3761fdf13693SJoe Perches						$msg_level = \&CHK if ($file);
37629f3a8992SRob Herring						if (&{$msg_level}("SPDX_LICENSE_TAG",
3763ffbce897SJoe Perches
37649f3a8992SRob Herring								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
37659f3a8992SRob Herring						    $fix) {
37663b6e8ac9SJoe Perches							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
37673b6e8ac9SJoe Perches						}
37683b6e8ac9SJoe Perches					}
37693b6e8ac9SJoe Perches					if ($realfile =~ m@^include/dt-bindings/@ &&
37703b6e8ac9SJoe Perches					    $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) {
37713b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
377250c92900SLubomir Rintel						     "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr);
3773a04bb4c2SDmitry Rokosov					}
377450c92900SLubomir Rintel				}
377550c92900SLubomir Rintel			}
377650c92900SLubomir Rintel		}
377750c92900SLubomir Rintel
377850c92900SLubomir Rintel# check for embedded filenames
377950c92900SLubomir Rintel		if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
378050c92900SLubomir Rintel			WARN("EMBEDDED_FILENAME",
378150c92900SLubomir Rintel			     "It's generally not useful to have the filename in the file\n" . $herecurr);
378250c92900SLubomir Rintel		}
3783a04bb4c2SDmitry Rokosov
3784a04bb4c2SDmitry Rokosov# check we are in a valid source file if not then ignore this hunk
3785a04bb4c2SDmitry Rokosov		next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/);
3786a04bb4c2SDmitry Rokosov
3787a04bb4c2SDmitry Rokosov# check for using SPDX-License-Identifier on the wrong line number
37889f3a8992SRob Herring		if ($realline != $checklicenseline &&
37899f3a8992SRob Herring		    $rawline =~ /\bSPDX-License-Identifier:/ &&
37909f3a8992SRob Herring		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
37919f3a8992SRob Herring			WARN("SPDX_LICENSE_TAG",
3792a0154cdbSJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
379336217357SJoe Perches		}
3794a0154cdbSJoe Perches
3795a0154cdbSJoe Perches# line length limit (with some exclusions)
3796a0154cdbSJoe Perches#
3797a0154cdbSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
37985368df20SAndy Whitcroft#	logging functions like pr_info that end in a string
3799d1d84b5fSMiguel Ojeda#	lines with a single string
38005368df20SAndy Whitcroft#	#defines that are a single string
3801a8da38a9SJoe Perches#	lines with an RFC3986 like URL
3802a8da38a9SJoe Perches#
3803a8da38a9SJoe Perches# There are 3 different line length message types:
3804a8da38a9SJoe Perches# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
3805a8da38a9SJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
3806a8da38a9SJoe Perches# LONG_LINE		all other lines longer than $max_line_length
3807a8da38a9SJoe Perches#
3808a8da38a9SJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
380947e0c88bSJoe Perches#
381047e0c88bSJoe Perches
381147e0c88bSJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
381247e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
381347e0c88bSJoe Perches
381447e0c88bSJoe Perches			# Check the allowed long line types first
38152e4bbbc5SAndreas Brauchli
381647e0c88bSJoe Perches			# logging functions that end in a string that starts
381747e0c88bSJoe Perches			# before $max_line_length
3818ab1ecabfSJean Delvare			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
381947e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
382047e0c88bSJoe Perches				$msg_type = "";
382147e0c88bSJoe Perches
382247e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
382347e0c88bSJoe Perches			# #defines with only strings
382447e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3825b4749e96SJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
382647e0c88bSJoe Perches				$msg_type = "";
382747e0c88bSJoe Perches
382847e0c88bSJoe Perches			# More special cases
382947e0c88bSJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
383047e0c88bSJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
383147e0c88bSJoe Perches				$msg_type = "";
383247e0c88bSJoe Perches
383347e0c88bSJoe Perches			# URL ($rawline is used in case the URL is in a comment)
383447e0c88bSJoe Perches			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
383547e0c88bSJoe Perches				$msg_type = "";
383647e0c88bSJoe Perches
383747e0c88bSJoe Perches			# Otherwise set the alternate message types
383847e0c88bSJoe Perches
383947e0c88bSJoe Perches			# a comment starts before $max_line_length
384047e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
384147e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3842cc147506SJoe Perches				$msg_type = "LONG_LINE_COMMENT"
3843cc147506SJoe Perches
3844cc147506SJoe Perches			# a quoted string starts before $max_line_length
3845d560a5f8SJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3846d560a5f8SJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
38472e4bbbc5SAndreas Brauchli				$msg_type = "LONG_LINE_STRING"
38482e4bbbc5SAndreas Brauchli			}
38492e4bbbc5SAndreas Brauchli
38502e4bbbc5SAndreas Brauchli			if ($msg_type ne "" &&
385147e0c88bSJoe Perches			    show_type("LONG_LINE") && show_type($msg_type)) {
385247e0c88bSJoe Perches				my $msg_level = \&WARN;
385347e0c88bSJoe Perches				$msg_level = \&CHK if ($file);
385447e0c88bSJoe Perches				&{$msg_level}($msg_type,
385547e0c88bSJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
385647e0c88bSJoe Perches			}
385747e0c88bSJoe Perches		}
385847e0c88bSJoe Perches
385947e0c88bSJoe Perches# check for adding lines without a newline.
386047e0c88bSJoe Perches		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
386147e0c88bSJoe Perches			if (WARN("MISSING_EOF_NEWLINE",
386247e0c88bSJoe Perches			         "adding a line without newline at end of file\n" . $herecurr) &&
386347e0c88bSJoe Perches			    $fix) {
386447e0c88bSJoe Perches				fix_delete_line($fixlinenr+1, "No newline at end of file");
3865d6bb3951SWolfram Sang			}
3866bdc48fa1SJoe Perches		}
3867bdc48fa1SJoe Perches
3868bdc48fa1SJoe Perches# check for .L prefix local symbols in .S files
3869bdc48fa1SJoe Perches		if ($realfile =~ /\.S$/ &&
38700a920b5bSAndy Whitcroft		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
387147e0c88bSJoe Perches			WARN("AVOID_L_PREFIX",
38720a920b5bSAndy Whitcroft			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr);
38738905a67cSAndy Whitcroft		}
38748905a67cSAndy Whitcroft
387547ca69b8STom Rix# check we are in a valid source file C or perl if not then ignore this hunk
387647ca69b8STom Rix		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
387747ca69b8STom Rix
387847ca69b8STom Rix# at the beginning of a line any tabs must come first and anything
387947ca69b8STom Rix# more than $tabsize must use tabs.
38808905a67cSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
38818905a67cSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3882de93245cSAditya Srivastava			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3883de93245cSAditya Srivastava			$rpt_cleaners = 1;
3884de93245cSAditya Srivastava			if (ERROR("CODE_INDENT",
3885de93245cSAditya Srivastava				  "code indent should use tabs where possible\n" . $herevet) &&
3886f4bf1cd4SJonathan Corbet			    $fix) {
3887de93245cSAditya Srivastava				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3888de93245cSAditya Srivastava			}
3889b9ea10d6SAndy Whitcroft		}
3890de4c924cSGeert Uytterhoeven
38910a920b5bSAndy Whitcroft# check for space before tabs.
38920a920b5bSAndy Whitcroft		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3893713a09deSAntonio Borneo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3894c2fdda0dSAndy Whitcroft			if (WARN("SPACE_BEFORE_TAB",
3895c2fdda0dSAndy Whitcroft				"please, no space before tabs\n" . $herevet) &&
3896c2fdda0dSAndy Whitcroft			    $fix) {
3897d2c0a235SAndy Whitcroft				while ($fixed[$fixlinenr] =~
38983705ce5bSJoe Perches					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
38993705ce5bSJoe Perches				while ($fixed[$fixlinenr] =~
39003705ce5bSJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
3901194f66fcSJoe Perches			}
39023705ce5bSJoe Perches		}
39030a920b5bSAndy Whitcroft
39040a920b5bSAndy Whitcroft# check for assignments on the start of a line
390508e44365SAlberto Panizzo		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
390608e44365SAlberto Panizzo			my $operator = $1;
390708e44365SAlberto Panizzo			if (CHK("ASSIGNMENT_CONTINUATIONS",
39083705ce5bSJoe Perches				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
39093705ce5bSJoe Perches			    $fix && $prevrawline =~ /^\+/) {
39103705ce5bSJoe Perches				# add assignment operator to the previous line, remove from current line
3911194f66fcSJoe Perches				$fixed[$fixlinenr - 1] .= " $operator";
3912713a09deSAntonio Borneo				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3913194f66fcSJoe Perches			}
3914c76f4cb3SJoe Perches		}
39153705ce5bSJoe Perches
391608e44365SAlberto Panizzo# check for && or || at the start of a line
391708e44365SAlberto Panizzo		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
39186a487211SJoe Perches			my $operator = $1;
39196a487211SJoe Perches			if (CHK("LOGICAL_CONTINUATIONS",
3920da7355abSAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
3921da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3922da7355abSAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
3923da7355abSAditya Srivastava				$prevline =~ /[\s$;]*$/;
3924da7355abSAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
3925da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
3926da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3927da7355abSAditya Srivastava			}
39286a487211SJoe Perches		}
39296a487211SJoe Perches
3930d1fe9c09SJoe Perches# check indentation starts on a tab stop
3931d1fe9c09SJoe Perches		if ($perl_version_ok &&
39328e08f076SAditya Srivastava		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
39338e08f076SAditya Srivastava			my $indent = length($1);
39348e08f076SAditya Srivastava			if ($indent % $tabsize) {
39358e08f076SAditya Srivastava				if (WARN("TABSTOP",
39368e08f076SAditya Srivastava					 "Statements should start on a tabstop\n" . $herecurr) &&
39378e08f076SAditya Srivastava				    $fix) {
39388e08f076SAditya Srivastava					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
39398e08f076SAditya Srivastava				}
39408e08f076SAditya Srivastava			}
39418e08f076SAditya Srivastava		}
3942d1fe9c09SJoe Perches
3943d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
3944a91e8994SJoe Perches		if ($perl_version_ok &&
39455b57980dSJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3946bd49111fSJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3947a91e8994SJoe Perches			my $oldindent = $1;
3948713a09deSAntonio Borneo			my $rest = $2;
3949a91e8994SJoe Perches
3950a91e8994SJoe Perches			my $pos = pos_last_openparen($rest);
3951a91e8994SJoe Perches			if ($pos >= 0) {
3952713a09deSAntonio Borneo				$line =~ /^(\+| )([ \t]*)/;
3953a91e8994SJoe Perches				my $newindent = $2;
3954a91e8994SJoe Perches
3955a91e8994SJoe Perches				my $goodtabindent = $oldindent .
3956a91e8994SJoe Perches					"\t" x ($pos / $tabsize) .
3957d1fe9c09SJoe Perches					" "  x ($pos % $tabsize);
39585b57980dSJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3959fd71f632SJoe Perches
3960d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3961d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
3962d1fe9c09SJoe Perches
3963d1fe9c09SJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
3964d1fe9c09SJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
3965d1fe9c09SJoe Perches					    $fix && $line =~ /^\+/) {
3966b34a26f3SJoe Perches						$fixed[$fixlinenr] =~
3967b34a26f3SJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
3968d1fe9c09SJoe Perches					}
3969d1fe9c09SJoe Perches				}
3970713a09deSAntonio Borneo			}
3971713a09deSAntonio Borneo		}
3972d1fe9c09SJoe Perches
3973d1fe9c09SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
3974d1fe9c09SJoe Perches# avoid checking a few false positives:
3975d1fe9c09SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
39763705ce5bSJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
39773705ce5bSJoe Perches#   structure definitions like "(struct foo) { 0 };"
39783705ce5bSJoe Perches#   multiline macros that define functions
39793705ce5bSJoe Perches#   known attributes or the __attribute__ keyword
3980194f66fcSJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
39813705ce5bSJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
39823705ce5bSJoe Perches			if (CHK("SPACING",
3983d1fe9c09SJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
3984d1fe9c09SJoe Perches			    $fix) {
3985d1fe9c09SJoe Perches				$fixed[$fixlinenr] =~
3986d1fe9c09SJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
39876ab3a970SJoe Perches			}
39886ab3a970SJoe Perches		}
39896ab3a970SJoe Perches
39906ab3a970SJoe Perches# Block comments use * on subsequent lines
39916ab3a970SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
39926ab3a970SJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
39936ab3a970SJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
39946ab3a970SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
39956ab3a970SJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
39963705ce5bSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
3997f27c95dbSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
39983705ce5bSJoe Perches		}
3999194f66fcSJoe Perches
4000f27c95dbSJoe Perches# Block comments use */ on trailing lines
40013705ce5bSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
4002aad4f614SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
4003aad4f614SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
400486406b1cSJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
400586406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
400686406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
4007a605e32eSJoe Perches		}
400861135e96SJoe Perches
4009a605e32eSJoe Perches# Block comment * alignment
401086406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
401186406b1cSJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
4012a605e32eSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
4013a605e32eSJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
401486406b1cSJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
401586406b1cSJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
4016c24f9f19SJoe Perches			my $oldindent;
4017c24f9f19SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
4018c24f9f19SJoe Perches			if (defined($1)) {
401986406b1cSJoe Perches				$oldindent = expand_tabs($1);
402086406b1cSJoe Perches			} else {
402105880600SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
402205880600SJoe Perches				$oldindent = expand_tabs($1);
402308eb9b80SJoe Perches			}
402408eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
4025af207524SJoe Perches			my $newindent = $1;
4026af207524SJoe Perches			$newindent = expand_tabs($newindent);
4027af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
402808eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
4029af207524SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
4030af207524SJoe Perches			}
403108eb9b80SJoe Perches		}
4032af207524SJoe Perches
4033af207524SJoe Perches# check for missing blank lines after struct/union declarations
4034af207524SJoe Perches# with exceptions for various attributes and macros
4035af207524SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
4036af207524SJoe Perches		    $line =~ /^\+/ &&
4037af207524SJoe Perches		    !($line =~ /^\+\s*$/ ||
403808eb9b80SJoe Perches		      $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param|ALLOW_ERROR_INJECTION)/ ||
403908eb9b80SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
404008eb9b80SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
4041af207524SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
404208eb9b80SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
404308eb9b80SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
404408eb9b80SJoe Perches		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
404508eb9b80SJoe Perches		      $line =~ /^\+\s*__setup/)) {
404608eb9b80SJoe Perches			if (CHK("LINE_SPACING",
40477f619191SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
40487f619191SJoe Perches			    $fix) {
40497f619191SJoe Perches				fix_insert_line($fixlinenr, "\+");
40507f619191SJoe Perches			}
40517f619191SJoe Perches		}
405271aa3419SSergey Senozhatsky
40537f619191SJoe Perches# check for multiple consecutive blank lines
40547f619191SJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
40557f619191SJoe Perches		    $line =~ /^\+\s*$/ &&
40567f619191SJoe Perches		    $last_blank_line != ($linenr - 1)) {
40577f619191SJoe Perches			if (CHK("LINE_SPACING",
40580bc989ffSMasahiro Yamada				"Please don't use multiple blank lines\n" . $hereprev) &&
40597f619191SJoe Perches			    $fix) {
4060d752fcc8SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4061d752fcc8SJoe Perches			}
4062d752fcc8SJoe Perches
4063f2d7e4d4SJoe Perches			$last_blank_line = $linenr;
4064d752fcc8SJoe Perches		}
40657f619191SJoe Perches
40667f619191SJoe Perches# check for missing blank lines after declarations
4067365dd4eaSJoe Perches# (declarations must have the same indentation and not be at the start of line)
4068365dd4eaSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
4069365dd4eaSJoe Perches			# use temporaries
4070365dd4eaSJoe Perches			my $sl = $sline;
4071d752fcc8SJoe Perches			my $pl = $prevline;
4072d752fcc8SJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
4073d752fcc8SJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4074f2d7e4d4SJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4075d752fcc8SJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
4076d752fcc8SJoe Perches			# function pointer declarations
4077365dd4eaSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
4078365dd4eaSJoe Perches			# foo bar; where foo is some local typedef or #define
4079365dd4eaSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
40803b617e3bSJoe Perches			# known declaration macros
4081b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
4082b5e8736aSJoe Perches			# for "else if" which can look like "$Ident $Ident"
4083b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
4084b5e8736aSJoe Perches			# other possible extensions of declaration lines
4085b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
4086b5e8736aSJoe Perches			# not starting a section or a macro "\" extended line
4087b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
4088b5e8736aSJoe Perches			# looks like a declaration
4089b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
40905a4e1fd3SJoe Perches			# function pointer declarations
4091b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
40923f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
4093b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
40943f7bac03SJoe Perches			# known declaration macros
4095b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
40963f7bac03SJoe Perches			# start of struct or union or enum
4097b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
40983f7bac03SJoe Perches			# start or end of block or continuation of declaration
4099b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
41003f7bac03SJoe Perches			# bitfield continuation
4101b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
41023f7bac03SJoe Perches			# other possible extensions of declaration lines
4103b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
41045a4e1fd3SJoe Perches				if (WARN("LINE_SPACING",
4105b5e8736aSJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
41063f7bac03SJoe Perches				    $fix) {
4107b5e8736aSJoe Perches					fix_insert_line($fixlinenr, "\+");
41083f7bac03SJoe Perches				}
4109b5e8736aSJoe Perches			}
41103f7bac03SJoe Perches		}
4111b5e8736aSJoe Perches
41123f7bac03SJoe Perches# check for spaces at the beginning of a line.
4113b5e8736aSJoe Perches# Exceptions:
41143f7bac03SJoe Perches#  1) within comments
4115b5e8736aSJoe Perches#  2) indented preprocessor commands
41163f7bac03SJoe Perches#  3) hanging labels
4117b5e8736aSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
4118d752fcc8SJoe Perches			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
4119d752fcc8SJoe Perches			if (WARN("LEADING_SPACE",
4120d752fcc8SJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
4121f2d7e4d4SJoe Perches			    $fix) {
4122d752fcc8SJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
41233b617e3bSJoe Perches			}
4124b5e8736aSJoe Perches		}
41253b617e3bSJoe Perches
41265f7ddae6SRaffaele Recalcati# check we are in a valid C source file if not then ignore this hunk
41276b4c5bebSAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
41286b4c5bebSAndy Whitcroft
41296b4c5bebSAndy Whitcroft# check for unusual line ending [ or (
41306b4c5bebSAndy Whitcroft		if ($line =~ /^\+.*([\[\(])\s*$/) {
41313705ce5bSJoe Perches			CHK("OPEN_ENDED_LINE",
41325f7ddae6SRaffaele Recalcati			    "Lines should not end with a '$1'\n" . $herecurr);
41333705ce5bSJoe Perches		}
41343705ce5bSJoe Perches
41353705ce5bSJoe Perches# check if this appears to be the start function declaration, save the name
4136194f66fcSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
41373705ce5bSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
41385f7ddae6SRaffaele Recalcati			$context_function = $1;
41395f7ddae6SRaffaele Recalcati		}
4140b9ea10d6SAndy Whitcroft
4141b9ea10d6SAndy Whitcroft# check if this appears to be the end of function declaration
4142b9ea10d6SAndy Whitcroft		if ($sline =~ /^\+\}\s*$/) {
41435751a24eSJoe Perches			undef $context_function;
41445751a24eSJoe Perches		}
41455751a24eSJoe Perches
41465751a24eSJoe Perches# check indentation of any line with a bare else
41475751a24eSJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
41485751a24eSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
41494dbed76fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
41504dbed76fSJoe Perches			my $tabs = length($1) + 1;
41514dbed76fSJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
41524dbed76fSJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
41534dbed76fSJoe Perches			     defined $lines[$linenr] &&
41544dbed76fSJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
41554dbed76fSJoe Perches				WARN("UNNECESSARY_ELSE",
41564dbed76fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
41574dbed76fSJoe Perches			}
41584dbed76fSJoe Perches		}
41594dbed76fSJoe Perches
4160032a4c0fSJoe Perches# check indentation of a line with a break;
4161840080a0SJoe Perches# if the previous line is a goto, return or break
4162032a4c0fSJoe Perches# and is indented the same # of tabs
4163032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4164032a4c0fSJoe Perches			my $tabs = $1;
4165840080a0SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4166840080a0SJoe Perches				if (WARN("UNNECESSARY_BREAK",
4167840080a0SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
4168840080a0SJoe Perches				    $fix) {
4169032a4c0fSJoe Perches					fix_delete_line($fixlinenr, $rawline);
4170032a4c0fSJoe Perches				}
4171032a4c0fSJoe Perches			}
4172032a4c0fSJoe Perches		}
4173032a4c0fSJoe Perches
4174c00df19aSJoe Perches# check for RCS/CVS revision markers
4175dc58bc55SJoe Perches		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4176dc58bc55SJoe Perches			WARN("CVS_KEYWORD",
4177c00df19aSJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4178c00df19aSJoe Perches		}
4179dc58bc55SJoe Perches
4180dc58bc55SJoe Perches# check for old HOTPLUG __dev<foo> section markings
4181dc58bc55SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
4182dc58bc55SJoe Perches			WARN("HOTPLUG_SECTION",
4183dc58bc55SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
4184dc58bc55SJoe Perches		}
4185c00df19aSJoe Perches
4186c00df19aSJoe Perches# Check for potential 'bare' types
4187c00df19aSJoe Perches		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
4188c2fdda0dSAndy Whitcroft		    $realline_next);
4189cf655043SAndy Whitcroft#print "LINE<$line>\n";
4190000d1cc1SJoe Perches		if ($linenr > $suppress_statement &&
4191000d1cc1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
4192c2fdda0dSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
419322f2a2efSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
419456e77d70SJoe Perches			$stat =~ s/\n./\n /g;
419556e77d70SJoe Perches			$cond =~ s/\n./\n /g;
419656e77d70SJoe Perches
419756e77d70SJoe Perches#print "linenr<$linenr> <$stat>\n";
419856e77d70SJoe Perches			# If this statement has no statement boundaries within
419956e77d70SJoe Perches			# it there is no point in retrying a statement scan
42009c0ca6f9SAndy Whitcroft			# until we hit end of it.
42012b474a1aSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
42022b474a1aSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
42033e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
4204ca819864SJoe Perches				$suppress_statement = $line_nr_next;
42051b5539b1SJoe Perches			}
4206170d3a22SAndy Whitcroft
4207f5fe35ddSAndy Whitcroft			# Find the real next line.
4208171ae1a4SAndy Whitcroft			$realline_next = $line_nr_next;
4209171ae1a4SAndy Whitcroft			if (defined $realline_next &&
4210171ae1a4SAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
42113e469cdcSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
42123e469cdcSAndy Whitcroft				$realline_next++;
42133e469cdcSAndy Whitcroft			}
42143e469cdcSAndy Whitcroft
42153e469cdcSAndy Whitcroft			my $s = $stat;
42163e469cdcSAndy Whitcroft			$s =~ s/{.*$//s;
42173e469cdcSAndy Whitcroft
42183e469cdcSAndy Whitcroft			# Ignore goto labels.
42193e469cdcSAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
4220f74bd194SAndy Whitcroft
42212b474a1aSAndy Whitcroft			# Ignore functions being called
42222b474a1aSAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
42232b474a1aSAndy Whitcroft
42242b474a1aSAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
42252b474a1aSAndy Whitcroft
42262b474a1aSAndy Whitcroft			# declarations always start with types
42272b474a1aSAndy 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) {
42282b474a1aSAndy Whitcroft				my $type = $1;
4229171ae1a4SAndy Whitcroft				$type =~ s/\s+/ /g;
4230171ae1a4SAndy Whitcroft				possible($type, "A:" . $s);
4231cf655043SAndy Whitcroft
4232c2fdda0dSAndy Whitcroft			# definitions in global scope can only start with types
4233171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4234c2fdda0dSAndy Whitcroft				possible($1, "B:" . $s);
4235c2fdda0dSAndy Whitcroft			}
4236171ae1a4SAndy Whitcroft
4237c2fdda0dSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
4238463f2864SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4239463f2864SAndy Whitcroft				possible($1, "C:" . $s);
4240c45dcabdSAndy Whitcroft			}
4241d2506586SAndy Whitcroft
4242c45dcabdSAndy Whitcroft			# Check for any sort of function declaration.
4243c45dcabdSAndy Whitcroft			# int foo(something bar, other baz);
4244c45dcabdSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
4245c45dcabdSAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
42466c72ffaaSAndy Whitcroft				my ($name_len) = length($1);
4247a6a84062SAndy Whitcroft
4248c45dcabdSAndy Whitcroft				my $ctx = $s;
4249c2fdda0dSAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
42508905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
42516c72ffaaSAndy Whitcroft
425265863862SAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4253c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
42549c0ca6f9SAndy Whitcroft
42558905a67cSAndy Whitcroft						possible($1, "D:" . $s);
42568905a67cSAndy Whitcroft					}
42578905a67cSAndy Whitcroft				}
42588905a67cSAndy Whitcroft			}
4259171ae1a4SAndy Whitcroft
42608905a67cSAndy Whitcroft		}
42618905a67cSAndy Whitcroft
4262cf655043SAndy Whitcroft#
4263773647a0SAndy Whitcroft# Checks which may be anchored in the context.
42648905a67cSAndy Whitcroft#
4265cf655043SAndy Whitcroft
42668905a67cSAndy Whitcroft# Check for switch () and associated case and default
4267c45dcabdSAndy Whitcroft# statements should be at the same indent.
42688905a67cSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
4269c45dcabdSAndy Whitcroft			my $err = '';
42708905a67cSAndy Whitcroft			my $sep = '';
42718905a67cSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
42728905a67cSAndy Whitcroft			shift(@ctx);
42738905a67cSAndy Whitcroft			for my $ctx (@ctx) {
42749c0ca6f9SAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
42759c0ca6f9SAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
427600df344fSAndy Whitcroft							$indent != $cindent) {
427700df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
427800df344fSAndy Whitcroft					$sep = '';
427900df344fSAndy Whitcroft				} else {
428000df344fSAndy Whitcroft					$sep = "[...]\n";
428100df344fSAndy Whitcroft				}
428200df344fSAndy Whitcroft			}
428300df344fSAndy Whitcroft			if ($err ne '') {
428400df344fSAndy Whitcroft				ERROR("SWITCH_CASE_INDENT_LEVEL",
428500df344fSAndy Whitcroft				      "switch and case should be at the same indent\n$hereline$err");
428600df344fSAndy Whitcroft			}
428700df344fSAndy Whitcroft		}
428800df344fSAndy Whitcroft
428900df344fSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
429000df344fSAndy Whitcroft# or if that brace on the next line is for something else
429100df344fSAndy Whitcroft		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
429200df344fSAndy Whitcroft			my $pre_ctx = "$1$2";
429300df344fSAndy Whitcroft
429400df344fSAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
429500df344fSAndy Whitcroft
429600df344fSAndy Whitcroft			if ($line =~ /^\+\t{6,}/) {
429700df344fSAndy Whitcroft				WARN("DEEP_INDENTATION",
4298000d1cc1SJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
4299000d1cc1SJoe Perches			}
4300de7d4f0eSAndy Whitcroft
4301de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4302de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4303de7d4f0eSAndy Whitcroft
4304de7d4f0eSAndy Whitcroft			my $ctx_ln = $linenr;
43050fe3dc2bSJoe Perches			my $ctx_skip = $realcnt;
4306773647a0SAndy Whitcroft
4307773647a0SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
43089c0ca6f9SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
43098eef05ddSJoe Perches					$lines[$ctx_ln - 1] =~ /^-/)) {
43108eef05ddSJoe Perches				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
43118eef05ddSJoe Perches				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
43128eef05ddSJoe Perches				$ctx_ln++;
43138eef05ddSJoe Perches			}
43148eef05ddSJoe Perches
4315de7d4f0eSAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
4316de7d4f0eSAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4317de7d4f0eSAndy Whitcroft
4318548596d5SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4319548596d5SAndy Whitcroft				ERROR("OPEN_BRACE",
4320de7d4f0eSAndy Whitcroft				      "that open brace { should be on the previous line\n" .
4321548596d5SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
4322548596d5SAndy Whitcroft			}
4323548596d5SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4324548596d5SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4325548596d5SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4326773647a0SAndy Whitcroft			{
4327773647a0SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
4328548596d5SAndy Whitcroft				if ($nindent > $indent) {
432953210168SAndy Whitcroft					WARN("TRAILING_SEMICOLON",
433053210168SAndy Whitcroft					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
4331773647a0SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
4332773647a0SAndy Whitcroft				}
4333000d1cc1SJoe Perches			}
4334000d1cc1SJoe Perches		}
433501464f30SAndy Whitcroft
433600df344fSAndy Whitcroft# Check relative indent for conditionals and blocks.
4337773647a0SAndy Whitcroft		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
4338773647a0SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4339773647a0SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
4340773647a0SAndy Whitcroft					if (!defined $stat);
43419c0ca6f9SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
43429c0ca6f9SAndy Whitcroft
4343000d1cc1SJoe Perches			substr($s, 0, length($c), '');
4344000d1cc1SJoe Perches
434501464f30SAndy Whitcroft			# remove inline comments
43469c0ca6f9SAndy Whitcroft			$s =~ s/$;/ /g;
43479c0ca6f9SAndy Whitcroft			$c =~ s/$;/ /g;
434800df344fSAndy Whitcroft
434900df344fSAndy Whitcroft			# Find out how long the conditional actually is.
43504d001e4dSAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
4351f6950a73SJoe Perches			my $cond_lines = 1 + $#newlines;
43523e469cdcSAndy Whitcroft
43533e469cdcSAndy Whitcroft			# Make sure we remove the line prefixes as we have
43543e469cdcSAndy Whitcroft			# none on the first line, and are going to readd them
43554d001e4dSAndy Whitcroft			# where necessary.
43564d001e4dSAndy Whitcroft			$s =~ s/\n./\n/gs;
43574d001e4dSAndy Whitcroft			while ($s =~ /\n\s+\\\n/) {
43584d001e4dSAndy Whitcroft				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
43599f5af480SJoe Perches			}
43609f5af480SJoe Perches
43619f5af480SJoe Perches			# We want to check the first line inside the block
43624d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
43634d001e4dSAndy Whitcroft			#  1) any blank line termination
43646f779c18SAndy Whitcroft			#  2) any opening brace { on end of the line
43656f779c18SAndy Whitcroft			#  3) any do (...) {
43664d001e4dSAndy Whitcroft			my $continuation = 0;
43679f5af480SJoe Perches			my $check = 0;
43689f5af480SJoe Perches			$s =~ s/^.*\bdo\b//;
43699f5af480SJoe Perches			$s =~ s/^\s*{//;
43709f5af480SJoe Perches			if ($s =~ s/^\s*\\//) {
43719f5af480SJoe Perches				$continuation = 1;
43729f5af480SJoe Perches			}
43739f5af480SJoe Perches			if ($s =~ s/^\s*?\n//) {
43749f5af480SJoe Perches				$check = 1;
43754d001e4dSAndy Whitcroft				$cond_lines++;
43764d001e4dSAndy Whitcroft			}
43774d001e4dSAndy Whitcroft
43784d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
43794d001e4dSAndy Whitcroft			# preprocessor statement.
43804d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
43814d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
43824d001e4dSAndy Whitcroft				$check = 0;
43834d001e4dSAndy Whitcroft			}
43844d001e4dSAndy Whitcroft
43854d001e4dSAndy Whitcroft			my $cond_ptr = -1;
43864d001e4dSAndy Whitcroft			$continuation = 0;
43879bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
43884d001e4dSAndy Whitcroft				$cond_ptr = $cond_lines;
43894d001e4dSAndy Whitcroft
43904d001e4dSAndy Whitcroft				# If we see an #else/#elif then the code
43914d001e4dSAndy Whitcroft				# is not linear.
43924d001e4dSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
43934d001e4dSAndy Whitcroft					$check = 0;
43944d001e4dSAndy Whitcroft				}
43954d001e4dSAndy Whitcroft
43964d001e4dSAndy Whitcroft				# Ignore:
43974d001e4dSAndy Whitcroft				#  1) blank lines, they should be at 0,
43984d001e4dSAndy Whitcroft				#  2) preprocessor lines, and
43999bd49efeSAndy Whitcroft				#  3) labels.
4400740504c6SAndy Whitcroft				if ($continuation ||
44019bd49efeSAndy Whitcroft				    $s =~ /^\s*?\n/ ||
44029bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
44034d001e4dSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4404f16fa28fSAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
4405f16fa28fSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
4406f16fa28fSAndy Whitcroft						$cond_lines++;
4407f16fa28fSAndy Whitcroft					}
4408f16fa28fSAndy Whitcroft				}
4409f16fa28fSAndy Whitcroft			}
44109bd49efeSAndy Whitcroft
44119bd49efeSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
44129bd49efeSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
44139bd49efeSAndy Whitcroft
4414740504c6SAndy Whitcroft			# Check if either of these lines are modified, else
4415740504c6SAndy Whitcroft			# this is not this patch's fault.
44169bd49efeSAndy Whitcroft			if (!defined($stat_real) ||
44179bd49efeSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
4418740504c6SAndy Whitcroft				$check = 0;
441930dad6ebSAndy Whitcroft			}
44209bd49efeSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
44219bd49efeSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
44224d001e4dSAndy Whitcroft			}
442330dad6ebSAndy Whitcroft
44244d001e4dSAndy 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";
44254d001e4dSAndy Whitcroft
44264d001e4dSAndy Whitcroft			if ($check && $s ne '' &&
44274d001e4dSAndy Whitcroft			    (($sindent % $tabsize) != 0 ||
44284d001e4dSAndy Whitcroft			     ($sindent < $indent) ||
44294d001e4dSAndy Whitcroft			     ($sindent == $indent &&
44304d001e4dSAndy Whitcroft			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
44314d001e4dSAndy Whitcroft			     ($sindent > $indent + $tabsize))) {
44324d001e4dSAndy Whitcroft				WARN("SUSPECT_CODE_INDENT",
44334d001e4dSAndy Whitcroft				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
44344d001e4dSAndy Whitcroft			}
44354d001e4dSAndy Whitcroft		}
44364d001e4dSAndy Whitcroft
44374d001e4dSAndy Whitcroft		# Track the 'values' across context and added lines.
44389bd49efeSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
44394d001e4dSAndy Whitcroft		my ($curr_values, $curr_vars) =
44409f5af480SJoe Perches				annotate_values($opline . "\n", $prev_values);
4441713a09deSAntonio Borneo		$curr_values = $prev_values . $curr_values;
44429f5af480SJoe Perches		if ($dbg_values) {
4443f6950a73SJoe Perches			my $outline = $opline; $outline =~ s/\t/ /g;
4444f6950a73SJoe Perches			print "$linenr > .$outline\n";
4445713a09deSAntonio Borneo			print "$linenr > $curr_values\n";
4446000d1cc1SJoe Perches			print "$linenr >  $curr_vars\n";
4447000d1cc1SJoe Perches		}
44484d001e4dSAndy Whitcroft		$prev_values = substr($curr_values, -1);
44494d001e4dSAndy Whitcroft
44504d001e4dSAndy Whitcroft#ignore lines not being added
44516c72ffaaSAndy Whitcroft		next if ($line =~ /^[^\+]/);
44526c72ffaaSAndy Whitcroft
44531f65f947SAndy Whitcroft# check for self assignments used to avoid compiler warnings
44541f65f947SAndy Whitcroft# e.g.:	int foo = foo, *bar = NULL;
44556c72ffaaSAndy Whitcroft#	struct foo bar = *(&(bar));
4456c2fdda0dSAndy Whitcroft		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
4457c2fdda0dSAndy Whitcroft			my $var = $1;
4458cf655043SAndy Whitcroft			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
4459cf655043SAndy Whitcroft				WARN("SELF_ASSIGNMENT",
44601f65f947SAndy Whitcroft				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
4461c2fdda0dSAndy Whitcroft			}
44626c72ffaaSAndy Whitcroft		}
44636c72ffaaSAndy Whitcroft
446400df344fSAndy Whitcroft# check for dereferences that span multiple lines
44653705ce5bSJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
446600df344fSAndy Whitcroft		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
446799ca38c2SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
446899ca38c2SJoe Perches			my $ref = $1;
446999ca38c2SJoe Perches			$line =~ /^.\s*($Lval)/;
447099ca38c2SJoe Perches			$ref .= $1;
447199ca38c2SJoe Perches			$ref =~ s/\s//g;
447299ca38c2SJoe Perches			WARN("MULTILINE_DEREFERENCE",
447399ca38c2SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
447499ca38c2SJoe Perches		}
447599ca38c2SJoe Perches
447699ca38c2SJoe Perches# check for declarations of signed or unsigned without int
447799ca38c2SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
447811ca40a0SJoe Perches			my $type = $1;
447911ca40a0SJoe Perches			my $var = $2;
448011ca40a0SJoe Perches			$var = "" if (!defined $var);
448111ca40a0SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
448211ca40a0SJoe Perches				my $sign = $1;
448311ca40a0SJoe Perches				my $pointer = $2;
448411ca40a0SJoe Perches
448511ca40a0SJoe Perches				$pointer = "" if (!defined $pointer);
448611ca40a0SJoe Perches
448711ca40a0SJoe Perches				if (WARN("UNSPECIFIED_INT",
448811ca40a0SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
448911ca40a0SJoe Perches				    $fix) {
4490a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4491c8447115SJoe Perches					my $comp_pointer = $pointer;
4492a1ce18e4SJoe Perches					$comp_pointer =~ s/\s//g;
4493a1ce18e4SJoe Perches					$decl .= $comp_pointer;
4494207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4495207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4496a1ce18e4SJoe Perches				}
4497a1ce18e4SJoe Perches			}
4498a1ce18e4SJoe Perches		}
4499a1ce18e4SJoe Perches
4500a1ce18e4SJoe Perches# TEST: allow direct testing of the type matcher.
4501a1ce18e4SJoe Perches		if ($dbg_type) {
4502a1ce18e4SJoe Perches			if ($line =~ /^.\s*$Declare\s*$/) {
4503a1ce18e4SJoe Perches				ERROR("TEST_TYPE",
4504a1ce18e4SJoe Perches				      "TEST: is type\n" . $herecurr);
4505207a8e84SJoe Perches			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4506207a8e84SJoe Perches				ERROR("TEST_NOT_TYPE",
4507207a8e84SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
4508207a8e84SJoe Perches			}
4509207a8e84SJoe Perches			next;
4510a1ce18e4SJoe Perches		}
4511a1ce18e4SJoe Perches# TEST: allow direct testing of the attribute matcher.
4512a1ce18e4SJoe Perches		if ($dbg_attr) {
4513a1ce18e4SJoe Perches			if ($line =~ /^.\s*$Modifier\s*$/) {
4514653d4876SAndy Whitcroft				ERROR("TEST_ATTR",
45157429c690SAndy Whitcroft				      "TEST: is attr\n" . $herecurr);
45167429c690SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4517000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4518000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
45197429c690SAndy Whitcroft			}
4520000d1cc1SJoe Perches			next;
4521000d1cc1SJoe Perches		}
45227429c690SAndy Whitcroft
4523653d4876SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
4524653d4876SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
4525a1ef277eSAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4526a1ef277eSAndy Whitcroft			if (ERROR("OPEN_BRACE",
45279360b0e5SAndy Whitcroft				  "that open brace { should be on the previous line\n" . $hereprev) &&
4528000d1cc1SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4529000d1cc1SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
45309360b0e5SAndy Whitcroft				fix_delete_line($fixlinenr, $rawline);
4531000d1cc1SJoe Perches				my $fixedline = $prevrawline;
4532000d1cc1SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4533a1ef277eSAndy Whitcroft				fix_insert_line($fixlinenr, $fixedline);
4534a1ef277eSAndy Whitcroft				$fixedline = $line;
4535a1ef277eSAndy Whitcroft				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4536653d4876SAndy Whitcroft				fix_insert_line($fixlinenr, $fixedline);
4537f0a594c1SAndy Whitcroft			}
453899423c20SAndy Whitcroft		}
453999423c20SAndy Whitcroft
4540d752fcc8SJoe Perches#
4541d752fcc8SJoe Perches# Checks which are anchored on the added line.
4542f2d7e4d4SJoe Perches#
4543f2d7e4d4SJoe Perches
4544f2d7e4d4SJoe Perches# check for malformed paths in #include statements (uses RAW line)
4545d752fcc8SJoe Perches		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4546d752fcc8SJoe Perches			my $path = $1;
4547f2d7e4d4SJoe Perches			if ($path =~ m{//}) {
4548d752fcc8SJoe Perches				ERROR("MALFORMED_INCLUDE",
45498d81ae05SCyril Bur				      "malformed #include filename\n" . $herecurr);
4550f2d7e4d4SJoe Perches			}
4551d752fcc8SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4552f0a594c1SAndy Whitcroft				ERROR("UAPI_INCLUDE",
4553f0a594c1SAndy Whitcroft				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
455400df344fSAndy Whitcroft			}
455500df344fSAndy Whitcroft		}
455600df344fSAndy Whitcroft
455700df344fSAndy Whitcroft# no C99 // comments
4558653d4876SAndy Whitcroft		if ($line =~ m{//}) {
4559c45dcabdSAndy Whitcroft			if (ERROR("C99_COMMENTS",
4560653d4876SAndy Whitcroft				  "do not use C99 // comments\n" . $herecurr) &&
4561653d4876SAndy Whitcroft			    $fix) {
4562000d1cc1SJoe Perches				my $line = $fixed[$fixlinenr];
4563495e9d84SJoe Perches				if ($line =~ /\/\/(.*)$/) {
4564495e9d84SJoe Perches					my $comment = trim($1);
4565495e9d84SJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
4566495e9d84SJoe Perches				}
4567495e9d84SJoe Perches			}
4568653d4876SAndy Whitcroft		}
4569653d4876SAndy Whitcroft		# Remove C99 comments.
4570653d4876SAndy Whitcroft		$line =~ s@//.*@@;
457100df344fSAndy Whitcroft		$opline =~ s@//.*@@;
457200df344fSAndy Whitcroft
45733705ce5bSJoe Perches# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
45743705ce5bSJoe Perches# the whole statement.
45753705ce5bSJoe Perches#print "APW <$lines[$realline_next - 1]>\n";
4576194f66fcSJoe Perches		if (defined $realline_next &&
45773705ce5bSJoe Perches		    exists $lines[$realline_next - 1] &&
45783705ce5bSJoe Perches		    !defined $suppress_export{$realline_next} &&
4579194f66fcSJoe Perches		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
45803705ce5bSJoe Perches			# Handle definitions which produce identifiers with
45813705ce5bSJoe Perches			# a prefix:
458200df344fSAndy Whitcroft			#   XXX(foo);
458300df344fSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
45840a920b5bSAndy Whitcroft			my $name = $1;
45856c72ffaaSAndy Whitcroft			$name =~ s/^\s*($Ident).*/$1/;
45860a920b5bSAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
45872b474a1aSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
45882b474a1aSAndy Whitcroft#print "FOO C name<$name>\n";
45892b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
45902b474a1aSAndy Whitcroft
45912b474a1aSAndy Whitcroft			} elsif ($stat !~ /(?:
45922b474a1aSAndy Whitcroft				\n.}\s*$|
459336794822SChristoph Hellwig				^.DEFINE_$Ident\(\Q$name\E\)|
45943cbf62dfSAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
45953cbf62dfSAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
45963cbf62dfSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
45973cbf62dfSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
4598653d4876SAndy Whitcroft			    )/x) {
459970a11659SJoe Perches#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
460087a53877SAndy Whitcroft				$suppress_export{$realline_next} = 2;
46013cbf62dfSAndy Whitcroft			} else {
46023cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
46033cbf62dfSAndy Whitcroft			}
46043cbf62dfSAndy Whitcroft		}
46053cbf62dfSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
46062b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
460748012058SAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
460848012058SAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
460948012058SAndy Whitcroft			$suppress_export{$linenr} = 2;
46102b474a1aSAndy Whitcroft		}
46112b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
461248012058SAndy Whitcroft		    $suppress_export{$linenr} == 2) {
46132b474a1aSAndy Whitcroft			WARN("EXPORT_SYMBOL",
46142b474a1aSAndy Whitcroft			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
46152b474a1aSAndy Whitcroft		}
46162b474a1aSAndy Whitcroft
46170a920b5bSAndy Whitcroft# check for global initialisers.
46180a920b5bSAndy Whitcroft		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
46192b474a1aSAndy Whitcroft		    !exclude_global_initialisers($realfile)) {
46202b474a1aSAndy Whitcroft			if (ERROR("GLOBAL_INITIALISERS",
462136794822SChristoph Hellwig				  "do not initialise globals to $1\n" . $herecurr) &&
46222b474a1aSAndy Whitcroft			    $fix) {
46232b474a1aSAndy Whitcroft				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
46242b474a1aSAndy Whitcroft			}
46252b474a1aSAndy Whitcroft		}
46262b474a1aSAndy Whitcroft# check for static initialisers.
4627000d1cc1SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4628000d1cc1SJoe Perches			if (ERROR("INITIALISED_STATIC",
46292b474a1aSAndy Whitcroft				  "do not initialise statics to $1\n" .
46300a920b5bSAndy Whitcroft				      $herecurr) &&
46315150bda4SJoe Eloff			    $fix) {
46325b8f82e1SSong Liu				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
46335b8f82e1SSong Liu			}
4634d5e616fcSJoe Perches		}
46356d32f7a3SJoe Perches
4636d5e616fcSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
46376d32f7a3SJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
4638d5e616fcSJoe Perches			my $tmp = trim($1);
4639f0a594c1SAndy Whitcroft			WARN("MISORDERED_TYPE",
46400a920b5bSAndy Whitcroft			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
46416d32f7a3SJoe Perches		}
4642d5e616fcSJoe Perches
46436d32f7a3SJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4644d5e616fcSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4645d5e616fcSJoe Perches			my $type = trim($1);
46466d32f7a3SJoe Perches			next if ($type !~ /\bint\b/);
4647d5e616fcSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
46480a920b5bSAndy Whitcroft			my $new_type = $type;
46490a920b5bSAndy Whitcroft			$new_type =~ s/\b\s*int\s*\b/ /;
46501813087dSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
46511813087dSJoe Perches			$new_type =~ s/^const\s+//;
46521813087dSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
46531813087dSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
46541813087dSJoe Perches			$new_type =~ s/\s+/ /g;
46551813087dSJoe Perches			$new_type = trim($new_type);
46561813087dSJoe Perches			if (WARN("UNNECESSARY_INT",
4657809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4658809e082eSJoe Perches			    $fix) {
4659809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4660809e082eSJoe Perches			}
4661809e082eSJoe Perches		}
4662809e082eSJoe Perches
4663809e082eSJoe Perches# check for static const char * arrays.
4664809e082eSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4665809e082eSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4666809e082eSJoe Perches			     "static const char * array should probably be static const char * const\n" .
4667809e082eSJoe Perches				$herecurr);
4668809e082eSJoe Perches		}
4669809e082eSJoe Perches
4670809e082eSJoe Perches# check for initialized const char arrays that should be static const
4671809e082eSJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4672809e082eSJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
4673809e082eSJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
4674809e082eSJoe Perches			    $fix) {
4675809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4676809e082eSJoe Perches			}
4677cb710ecaSJoe Perches		}
4678cb710ecaSJoe Perches
4679000d1cc1SJoe Perches# check for static char foo[] = "bar" declarations.
4680000d1cc1SJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4681cb710ecaSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4682cb710ecaSJoe Perches			     "static char array declaration should probably be static const char\n" .
4683cb710ecaSJoe Perches				$herecurr);
468477b8c0a8SJoe Perches		}
468577b8c0a8SJoe Perches
468677b8c0a8SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
468777b8c0a8SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
468877b8c0a8SJoe Perches			my $found = $1;
468977b8c0a8SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
469077b8c0a8SJoe Perches				WARN("CONST_CONST",
469177b8c0a8SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
469277b8c0a8SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4693cb710ecaSJoe Perches				WARN("CONST_CONST",
4694cb710ecaSJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4695000d1cc1SJoe Perches			}
4696000d1cc1SJoe Perches		}
4697cb710ecaSJoe Perches
4698cb710ecaSJoe Perches# check for const static or static <non ptr type> const declarations
4699cb710ecaSJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
4700ab7e23f3SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
4701ab7e23f3SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
4702ab7e23f3SJoe Perches			if (WARN("STATIC_CONST",
4703ab7e23f3SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
4704ab7e23f3SJoe Perches			    $fix) {
4705ab7e23f3SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
4706ab7e23f3SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
4707ab7e23f3SJoe Perches			}
4708ab7e23f3SJoe Perches		}
4709ab7e23f3SJoe Perches
4710ab7e23f3SJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
4711ab7e23f3SJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
471273169765SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
471373169765SJoe Perches			     "char * array declaration might be better as static const\n" .
471473169765SJoe Perches				$herecurr);
471573169765SJoe Perches		}
471673169765SJoe Perches
471773169765SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
471873169765SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
471973169765SJoe Perches			my $array = $1;
472073169765SJoe 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*\))@) {
472173169765SJoe Perches				my $array_div = $1;
472273169765SJoe Perches				if (WARN("ARRAY_SIZE",
472373169765SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
47249b0fa60dSJoe Perches				    $fix) {
47259b0fa60dSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
47269b0fa60dSJoe Perches				}
47279b0fa60dSJoe Perches			}
47289b0fa60dSJoe Perches		}
47299b0fa60dSJoe Perches
47309b0fa60dSJoe Perches# check for function declarations without arguments like "int foo()"
4731b598b670SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4732b598b670SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4733b598b670SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4734b598b670SJoe Perches			    $fix) {
4735b598b670SJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4736b598b670SJoe Perches			}
4737b598b670SJoe Perches		}
4738b598b670SJoe Perches
4739b598b670SJoe Perches# check for new typedefs, only function parameters and sparse annotations
4740b598b670SJoe Perches# make sense.
4741b598b670SJoe Perches		if ($line =~ /\btypedef\s/ &&
4742b598b670SJoe Perches		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4743b598b670SJoe Perches		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
4744b36190c5SJoe Perches		    $line !~ /\b$typeTypedefs\b/ &&
474516b7f3c8SJoe Perches		    $line !~ /\b__bitwise\b/) {
4746b36190c5SJoe Perches			WARN("NEW_TYPEDEFS",
4747b36190c5SJoe Perches			     "do not add new typedefs\n" . $herecurr);
4748b36190c5SJoe Perches		}
4749194f66fcSJoe Perches
4750b36190c5SJoe Perches# * goes on variable not on type
4751b36190c5SJoe Perches		# (char*[ const])
4752b36190c5SJoe Perches		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4753653d4876SAndy Whitcroft			#print "AA<$1>\n";
4754653d4876SAndy Whitcroft			my ($ident, $from, $to) = ($1, $2, $2);
4755653d4876SAndy Whitcroft
47568054576dSAndy Whitcroft			# Should start with a space.
4757c45dcabdSAndy Whitcroft			$to =~ s/^(\S)/ $1/;
47588ed22cadSAndy Whitcroft			# Should not end with a space.
475946d832f5SMichael S. Tsirkin			$to =~ s/\s+$//;
4760000d1cc1SJoe Perches			# '*'s should not have spaces between.
4761000d1cc1SJoe Perches			while ($to =~ s/\*\s+\*/\*\*/) {
47620a920b5bSAndy Whitcroft			}
47630a920b5bSAndy Whitcroft
47640a920b5bSAndy Whitcroft##			print "1: from<$from> to<$to> ident<$ident>\n";
476565863862SAndy Whitcroft			if ($from ne $to) {
4766bfcb2cc7SAndy Whitcroft				if (ERROR("POINTER_LOCATION",
4767bfcb2cc7SAndy Whitcroft					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
47683705ce5bSJoe Perches				    $fix) {
4769d8aaf121SAndy Whitcroft					my $sub_from = $ident;
477065863862SAndy Whitcroft					my $sub_to = $ident;
477165863862SAndy Whitcroft					$sub_to =~ s/\Q$from\E/$to/;
477265863862SAndy Whitcroft					$fixed[$fixlinenr] =~
477365863862SAndy Whitcroft					    s@\Q$sub_from\E@$sub_to@;
477465863862SAndy Whitcroft				}
4775f9a0b3d1SAndy Whitcroft			}
477665863862SAndy Whitcroft		}
4777d8aaf121SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
47783705ce5bSJoe Perches			#print "BB<$1>\n";
477965863862SAndy Whitcroft			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
47803705ce5bSJoe Perches
47813705ce5bSJoe Perches			# Should start with a space.
47823705ce5bSJoe Perches			$to =~ s/^(\S)/ $1/;
47833705ce5bSJoe Perches			# Should not end with a space.
47843705ce5bSJoe Perches			$to =~ s/\s+$//;
47853705ce5bSJoe Perches			# '*'s should not have spaces between.
4786194f66fcSJoe Perches			while ($to =~ s/\*\s+\*/\*\*/) {
47873705ce5bSJoe Perches			}
47883705ce5bSJoe Perches			# Modifiers should have spaces.
478965863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
4790bfcb2cc7SAndy Whitcroft
4791bfcb2cc7SAndy Whitcroft##			print "2: from<$from> to<$to> ident<$ident>\n";
4792bfcb2cc7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
47933705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
4794d8aaf121SAndy Whitcroft					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
479565863862SAndy Whitcroft				    $fix) {
479665863862SAndy Whitcroft
479765863862SAndy Whitcroft					my $sub_from = $match;
479865863862SAndy Whitcroft					my $sub_to = $match;
479965863862SAndy Whitcroft					$sub_to =~ s/\Q$from\E/$to/;
4800f9a0b3d1SAndy Whitcroft					$fixed[$fixlinenr] =~
480165863862SAndy Whitcroft					    s@\Q$sub_from\E@$sub_to@;
480265863862SAndy Whitcroft				}
480365863862SAndy Whitcroft			}
480465863862SAndy Whitcroft		}
48053705ce5bSJoe Perches
4806667026e7SAndy Whitcroft# do not use BUG() or variants
48073705ce5bSJoe Perches		if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) {
48083705ce5bSJoe Perches			my $msg_level = \&WARN;
48093705ce5bSJoe Perches			$msg_level = \&CHK if ($file);
48103705ce5bSJoe Perches			&{$msg_level}("AVOID_BUG",
48113705ce5bSJoe Perches				      "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr);
48123705ce5bSJoe Perches		}
48133705ce5bSJoe Perches
4814194f66fcSJoe Perches# avoid LINUX_VERSION_CODE
48153705ce5bSJoe Perches		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
48163705ce5bSJoe Perches			WARN("LINUX_VERSION_CODE",
481765863862SAndy Whitcroft			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
48180a920b5bSAndy Whitcroft		}
48190a920b5bSAndy Whitcroft
482069d517e6SDavid Hildenbrand# check for uses of printk_ratelimit
482169d517e6SDavid Hildenbrand		if ($line =~ /\bprintk_ratelimit\s*\(/) {
48220675a8fbSJean Delvare			WARN("PRINTK_RATELIMITED",
48230675a8fbSJean Delvare			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
48240675a8fbSJean Delvare		}
482569d517e6SDavid Hildenbrand
48269d3e3c70SJoe Perches# printk should use KERN_* levels
48270a920b5bSAndy Whitcroft		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
48289d3e3c70SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
48298905a67cSAndy Whitcroft			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
4830000d1cc1SJoe Perches		}
4831000d1cc1SJoe Perches
48328905a67cSAndy Whitcroft# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
48338905a67cSAndy Whitcroft		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
483417441227SJoe Perches			my $printk = $1;
483517441227SJoe Perches			my $modifier = $2;
4836000d1cc1SJoe Perches			my $orig = $3;
4837000d1cc1SJoe Perches			$modifier = "" if (!defined($modifier));
483817441227SJoe Perches			my $level = lc($orig);
483917441227SJoe Perches			$level = "warn" if ($level eq "warning");
4840eeef5733SJoe Perches			my $level2 = $level;
4841eeef5733SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4842000d1cc1SJoe Perches			$level .= $modifier;
4843eeef5733SJoe Perches			$level2 .= $modifier;
484400df344fSAndy Whitcroft			WARN("PREFER_PR_LEVEL",
48450a920b5bSAndy Whitcroft			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4846f5eea3b0SJoe Perches		}
4847f5eea3b0SJoe Perches
4848f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4849f5eea3b0SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4850f5eea3b0SJoe Perches			my $orig = $1;
4851f5eea3b0SJoe Perches			my $level = lc($orig);
4852243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
4853243f3803SJoe Perches			$level = "dbg" if ($level eq "debug");
48548f26b837SJoe Perches			WARN("PREFER_DEV_LEVEL",
48558f26b837SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4856f5eea3b0SJoe Perches		}
4857f5eea3b0SJoe Perches
4858243f3803SJoe Perches# trace_printk should not be used in production code.
4859f5eea3b0SJoe Perches		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
4860243f3803SJoe Perches			WARN("TRACE_PRINTK",
4861243f3803SJoe Perches			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
4862f5eea3b0SJoe Perches		}
4863dc139313SJoe Perches
4864dc139313SJoe Perches# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
4865dc139313SJoe Perches# number of false positives, but assembly files are not checked, so at
4866dc139313SJoe Perches# least the arch entry code will not trigger this warning.
4867dc139313SJoe Perches		if ($line =~ /\bENOSYS\b/) {
4868dc139313SJoe Perches			WARN("ENOSYS",
4869dc139313SJoe Perches			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4870dc139313SJoe Perches		}
4871dc139313SJoe Perches
48728020b253SNicolas Boichat# ENOTSUPP is not a standard error code and should be avoided in new patches.
48738020b253SNicolas Boichat# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
48748020b253SNicolas Boichat# Similarly to ENOSYS warning a small number of false positives is expected.
48758020b253SNicolas Boichat		if (!$file && $line =~ /\bENOTSUPP\b/) {
48768020b253SNicolas Boichat			if (WARN("ENOTSUPP",
48778020b253SNicolas Boichat				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
487891c9afafSAndy Lutomirski			    $fix) {
487991c9afafSAndy Lutomirski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
488091c9afafSAndy Lutomirski			}
488191c9afafSAndy Lutomirski		}
488291c9afafSAndy Lutomirski
488391c9afafSAndy Lutomirski# function brace can't be on same line, except for #defines of do while,
488491c9afafSAndy Lutomirski# or if closed on same line
488591c9afafSAndy Lutomirski		if ($perl_version_ok &&
48866b9ea5ffSJakub Kicinski		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
48876b9ea5ffSJakub Kicinski		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
48886b9ea5ffSJakub Kicinski		    $sline !~ /}/) {
48896b9ea5ffSJakub Kicinski			if (ERROR("OPEN_BRACE",
48906b9ea5ffSJakub Kicinski				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
48916b9ea5ffSJakub Kicinski			    $fix) {
48926b9ea5ffSJakub Kicinski				fix_delete_line($fixlinenr, $rawline);
48936b9ea5ffSJakub Kicinski				my $fixed_line = $rawline;
48946b9ea5ffSJakub Kicinski				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
48956b9ea5ffSJakub Kicinski				my $line1 = $1;
48966b9ea5ffSJakub Kicinski				my $line2 = $2;
4897653d4876SAndy Whitcroft				fix_insert_line($fixlinenr, ltrim($line1));
4898653d4876SAndy Whitcroft				fix_insert_line($fixlinenr, "\+{");
48995b57980dSJoe Perches				if ($line2 !~ /^\s*$/) {
49002d453e3bSJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
49012d453e3bSJoe Perches				}
49022d453e3bSJoe Perches			}
49038d182478SJoe Perches		}
49042d453e3bSJoe Perches
49058d182478SJoe Perches# open braces for enum, union and struct go on the same line.
49068d182478SJoe Perches		if ($line =~ /^.\s*{/ &&
49078d182478SJoe Perches		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
490803f49351SDwaipayan Ray			if (ERROR("OPEN_BRACE",
49098d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
49108d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
49118d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
49128d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
49138d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
49148d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
49158d182478SJoe Perches				$fixedline = $rawline;
49168d182478SJoe Perches				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
49170a920b5bSAndy Whitcroft				if ($fixedline !~ /^\+\s*$/) {
4918653d4876SAndy Whitcroft					fix_insert_line($fixlinenr, $fixedline);
49198905a67cSAndy Whitcroft				}
49208905a67cSAndy Whitcroft			}
49218905a67cSAndy Whitcroft		}
49228d182478SJoe Perches
49238d182478SJoe Perches# missing space after union, struct or enum definition
49248d182478SJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
49258d182478SJoe Perches			if (WARN("SPACING",
49268d182478SJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
49278d182478SJoe Perches			    $fix) {
49288d182478SJoe Perches				$fixed[$fixlinenr] =~
49298d182478SJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
49308d81ae05SCyril Bur			}
49318d182478SJoe Perches		}
49328d182478SJoe Perches
49338d182478SJoe Perches# Function pointer declarations
49348d182478SJoe Perches# check spacing between type, funcptr, and args
49358905a67cSAndy Whitcroft# canonical declaration is "type (*funcptr)(args...)"
49368905a67cSAndy Whitcroft		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
49370c73b4ebSAndy Whitcroft			my $declare = $1;
49383705ce5bSJoe Perches			my $pre_pointer_space = $2;
49393705ce5bSJoe Perches			my $post_pointer_space = $3;
49403705ce5bSJoe Perches			my $funcname = $4;
49413705ce5bSJoe Perches			my $post_funcname_space = $5;
4942194f66fcSJoe Perches			my $pre_args_space = $6;
49433705ce5bSJoe Perches
49443705ce5bSJoe Perches# the $Declare variable will capture all spaces after the type
49450c73b4ebSAndy Whitcroft# so check it for a missing trailing missing space but pointer return types
49460c73b4ebSAndy Whitcroft# don't need a space so don't warn for those.
494731070b5dSJoe Perches			my $post_declare_space = "";
494831070b5dSJoe Perches			if ($declare =~ /(\s+)$/) {
494931070b5dSJoe Perches				$post_declare_space = $1;
495091f72e9cSJoe Perches				$declare = rtrim($declare);
495131070b5dSJoe Perches			}
495231070b5dSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
495331070b5dSJoe Perches				WARN("SPACING",
495431070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
495531070b5dSJoe Perches				$post_declare_space = " ";
495631070b5dSJoe Perches			}
495731070b5dSJoe Perches
495891f72e9cSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
495991f72e9cSJoe Perches# This test is not currently implemented because these declarations are
496091f72e9cSJoe Perches# equivalent to
496191f72e9cSJoe Perches#	int  foo(int bar, ...)
496291f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
496391f72e9cSJoe Perches#
496491f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
496591f72e9cSJoe Perches#				WARN("SPACING",
496691f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
496731070b5dSJoe Perches#			}
496831070b5dSJoe Perches
496991f72e9cSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
497031070b5dSJoe Perches			if (defined $pre_pointer_space &&
497131070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
497231070b5dSJoe Perches				WARN("SPACING",
497391f72e9cSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
497491f72e9cSJoe Perches			}
497591f72e9cSJoe Perches
497691f72e9cSJoe Perches# unnecessary space "type (* funcptr)(args...)"
497791f72e9cSJoe Perches			if (defined $post_pointer_space &&
497891f72e9cSJoe Perches			    $post_pointer_space =~ /^\s/) {
497991f72e9cSJoe Perches				WARN("SPACING",
498091f72e9cSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
498191f72e9cSJoe Perches			}
498231070b5dSJoe Perches
498331070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
498431070b5dSJoe Perches			if (defined $post_funcname_space &&
498531070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
498631070b5dSJoe Perches				WARN("SPACING",
498731070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
498831070b5dSJoe Perches			}
498931070b5dSJoe Perches
499031070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
499131070b5dSJoe Perches			if (defined $pre_args_space &&
499231070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
499331070b5dSJoe Perches				WARN("SPACING",
499431070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
499531070b5dSJoe Perches			}
499631070b5dSJoe Perches
499731070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
499831070b5dSJoe Perches				$fixed[$fixlinenr] =~
499931070b5dSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
500031070b5dSJoe Perches			}
500131070b5dSJoe Perches		}
500231070b5dSJoe Perches
500331070b5dSJoe Perches# check for spacing round square brackets; allowed:
500431070b5dSJoe Perches#  1. with a type on the left -- int [] a;
500531070b5dSJoe Perches#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
500631070b5dSJoe Perches#  3. inside a curly brace -- = { [0...10] = 5 }
500731070b5dSJoe Perches		while ($line =~ /(.*?\s)\[/g) {
500831070b5dSJoe Perches			my ($where, $prefix) = ($-[1], $1);
500931070b5dSJoe Perches			if ($prefix !~ /$Type\s+$/ &&
501031070b5dSJoe Perches			    ($where != 0 || $prefix !~ /^.\s+$/) &&
501131070b5dSJoe Perches			    $prefix !~ /[{,:]\s+$/) {
5012194f66fcSJoe Perches				if (ERROR("BRACKET_SPACE",
501391f72e9cSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
501431070b5dSJoe Perches				    $fix) {
501531070b5dSJoe Perches				    $fixed[$fixlinenr] =~
501631070b5dSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
50178d31cfceSAndy Whitcroft				}
50188d31cfceSAndy Whitcroft			}
5019fe2a7dbcSAndy Whitcroft		}
5020fe2a7dbcSAndy Whitcroft
50218d31cfceSAndy Whitcroft# check for spaces between functions and their parentheses.
50228d31cfceSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
50238d31cfceSAndy Whitcroft			my $name = $1;
5024fe2a7dbcSAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
502538dca988SHeinrich Schuchardt			my $ctx = "$ctx_before$name";
50263705ce5bSJoe Perches
50273705ce5bSJoe Perches			# Ignore those directives where spaces _are_ permitted.
50283705ce5bSJoe Perches			if ($name =~ /^(?:
5029194f66fcSJoe Perches				if|for|while|switch|return|case|
50303705ce5bSJoe Perches				volatile|__volatile__|
50313705ce5bSJoe Perches				__attribute__|format|__extension__|
50328d31cfceSAndy Whitcroft				asm|__asm__|scoped_guard)$/x)
50338d31cfceSAndy Whitcroft			{
50348d31cfceSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
5035f0a594c1SAndy Whitcroft			# if there is a space between the name and the open
50366c72ffaaSAndy Whitcroft			# parenthesis it is simply not a parameter group.
5037c2fdda0dSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
5038773647a0SAndy Whitcroft
5039773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
5040c2fdda0dSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
5041c2fdda0dSAndy Whitcroft
5042773647a0SAndy Whitcroft			# If this whole things ends with a type its most
5043773647a0SAndy Whitcroft			# likely a typedef for a function.
5044773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
5045773647a0SAndy Whitcroft
504654da6a09SPeter Zijlstra			} else {
5047773647a0SAndy Whitcroft				if (WARN("SPACING",
5048c2fdda0dSAndy Whitcroft					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
5049c2fdda0dSAndy Whitcroft					     $fix) {
5050c2fdda0dSAndy Whitcroft					$fixed[$fixlinenr] =~
5051c45dcabdSAndy Whitcroft					    s/\b$name\s+\(/$name\(/;
5052773647a0SAndy Whitcroft				}
5053773647a0SAndy Whitcroft			}
5054c45dcabdSAndy Whitcroft		}
5055c2fdda0dSAndy Whitcroft
5056c2fdda0dSAndy Whitcroft# Check operator spacing.
5057c2fdda0dSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
5058773647a0SAndy Whitcroft			my $fixed_line = "";
5059c2fdda0dSAndy Whitcroft			my $line_fixed = 0;
5060c2fdda0dSAndy Whitcroft
50613705ce5bSJoe Perches			my $ops = qr{
50623705ce5bSJoe Perches				<<=|>>=|<=|>=|==|!=|
50633705ce5bSJoe Perches				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
5064194f66fcSJoe Perches				=>|->|<<|>>|<|>|=|!|~|
50653705ce5bSJoe Perches				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
50663705ce5bSJoe Perches				\?:|\?|:
5067f0a594c1SAndy Whitcroft			}x;
50686c72ffaaSAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
50699a4cad4eSEric Nelson
5070653d4876SAndy Whitcroft##			print("element count: <" . $#elements . ">\n");
50710a920b5bSAndy Whitcroft##			foreach my $el (@elements) {
50723705ce5bSJoe Perches##				print("el: <$el>\n");
50733705ce5bSJoe Perches##			}
50743705ce5bSJoe Perches
50759c0ca6f9SAndy Whitcroft			my @fix_elements = ();
50769c0ca6f9SAndy Whitcroft			my $off = 0;
50779c0ca6f9SAndy Whitcroft
50789c0ca6f9SAndy Whitcroft			foreach my $el (@elements) {
50791f65f947SAndy Whitcroft				push(@fix_elements, substr($rawline, $off, length($el)));
508084731623SJoe Perches				$off += length($el);
50819c0ca6f9SAndy Whitcroft			}
5082cf655043SAndy Whitcroft
50833705ce5bSJoe Perches			$off = 0;
50843705ce5bSJoe Perches
50853705ce5bSJoe Perches			my $blank = copy_spacing($opline);
50863705ce5bSJoe Perches			my $last_after = -1;
50873705ce5bSJoe Perches
50883705ce5bSJoe Perches			for (my $n = 0; $n < $#elements; $n += 2) {
50893705ce5bSJoe Perches
509000df344fSAndy Whitcroft				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
50916c72ffaaSAndy Whitcroft
50923705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
50933705ce5bSJoe Perches
50943705ce5bSJoe Perches				$off += length($elements[$n]);
50953705ce5bSJoe Perches
50963705ce5bSJoe Perches				# Pick up the preceding and succeeding characters.
50973705ce5bSJoe Perches				my $ca = substr($opline, 0, $off);
50983705ce5bSJoe Perches				my $cc = '';
50996c72ffaaSAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
5100b34c648bSJoe Perches					$cc = substr($opline, $off + length($elements[$n + 1]));
51016c72ffaaSAndy Whitcroft				}
51020a920b5bSAndy Whitcroft				my $cb = "$ca$;$cc";
51033705ce5bSJoe Perches
51043705ce5bSJoe Perches				my $a = '';
51053705ce5bSJoe Perches				$a = 'V' if ($elements[$n] ne '');
51063705ce5bSJoe Perches				$a = 'W' if ($elements[$n] =~ /\s$/);
51073705ce5bSJoe Perches				$a = 'C' if ($elements[$n] =~ /$;$/);
51084a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
51094a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
511025985edcSLucas De Marchi				$a = 'E' if ($ca =~ /^\s*$/);
5111773647a0SAndy Whitcroft
5112773647a0SAndy Whitcroft				my $op = $elements[$n + 1];
5113773647a0SAndy Whitcroft
5114773647a0SAndy Whitcroft				my $c = '';
5115773647a0SAndy Whitcroft				if (defined $elements[$n + 2]) {
5116773647a0SAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
5117773647a0SAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
51184a0df2efSAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
51194a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
51204a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
5121cf655043SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
51224a0df2efSAndy Whitcroft				} else {
51234a0df2efSAndy Whitcroft					$c = 'E';
5124773647a0SAndy Whitcroft				}
51254a0df2efSAndy Whitcroft
51260a920b5bSAndy Whitcroft				my $ctx = "${a}x${c}";
51274a0df2efSAndy Whitcroft
51284a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
51290a920b5bSAndy Whitcroft
51304a0df2efSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
51314a0df2efSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
5132cf655043SAndy Whitcroft
51334a0df2efSAndy Whitcroft				# Pull out the value of this operator.
51344a0df2efSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
51358b1b3378SAndy Whitcroft
51364a0df2efSAndy Whitcroft				# Get the full operator variant.
51374a0df2efSAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
51380a920b5bSAndy Whitcroft
51390a920b5bSAndy Whitcroft				# Ignore operators passed as parameters.
51404a0df2efSAndy Whitcroft				if ($op_type ne 'V' &&
51414a0df2efSAndy Whitcroft				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
51424a0df2efSAndy Whitcroft
51434a0df2efSAndy Whitcroft#				# Ignore comments
51446c72ffaaSAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
5145de7d4f0eSAndy Whitcroft
51460a920b5bSAndy Whitcroft				# ; should have either the end of line or a space or \ after it
514774048ed8SAndy Whitcroft				} elsif ($op eq ';') {
51486c72ffaaSAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
51490a920b5bSAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
51501f65f947SAndy Whitcroft						if (ERROR("SPACING",
51511f65f947SAndy Whitcroft							  "space required after that '$op' $at\n" . $hereptr)) {
51521f65f947SAndy Whitcroft							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
515313214adfSAndy Whitcroft							$line_fixed = 1;
515413214adfSAndy Whitcroft						}
5155d7fe8065SSam Bobroff					}
515613214adfSAndy Whitcroft
5157cf655043SAndy Whitcroft				# // is a comment
5158cf655043SAndy Whitcroft				} elsif ($op eq '//') {
515913214adfSAndy Whitcroft
5160d8aaf121SAndy Whitcroft				#   :   when part of a bitfield
516113214adfSAndy Whitcroft				} elsif ($opv eq ':B') {
5162cf655043SAndy Whitcroft					# skip the bitfield test for now
5163cf655043SAndy Whitcroft
51643705ce5bSJoe Perches				# No spaces for:
51653705ce5bSJoe Perches				#   ->
5166b34c648bSJoe Perches				} elsif ($op eq '->') {
51673705ce5bSJoe Perches					if ($ctx =~ /Wx.|.xW/) {
51683705ce5bSJoe Perches						if (ERROR("SPACING",
5169d8aaf121SAndy Whitcroft							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5170d8aaf121SAndy Whitcroft							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5171d8aaf121SAndy Whitcroft							if (defined $fix_elements[$n + 2]) {
5172d8aaf121SAndy Whitcroft								$fix_elements[$n + 2] =~ s/^\s+//;
51730a920b5bSAndy Whitcroft							}
5174b00e4814SJoe Perches							$line_fixed = 1;
5175b00e4814SJoe Perches						}
5176b00e4814SJoe Perches					}
5177b00e4814SJoe Perches
51781f65f947SAndy Whitcroft				# , must not have a space before and must have a space on the right.
51791f65f947SAndy Whitcroft				} elsif ($op eq ',') {
5180b00e4814SJoe Perches					my $rtrim_before = 0;
51814a0df2efSAndy Whitcroft					my $space_after = 0;
51823705ce5bSJoe Perches					if ($ctx =~ /Wx./) {
51833705ce5bSJoe Perches						if (ERROR("SPACING",
5184b34c648bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
51853705ce5bSJoe Perches							$line_fixed = 1;
51863705ce5bSJoe Perches							$rtrim_before = 1;
51873705ce5bSJoe Perches						}
5188b34c648bSJoe Perches					}
51893705ce5bSJoe Perches					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
51900a920b5bSAndy Whitcroft						if (ERROR("SPACING",
51910a920b5bSAndy Whitcroft							  "space required after that '$op' $at\n" . $hereptr)) {
51922381097bSJoe Perches							$line_fixed = 1;
51930a920b5bSAndy Whitcroft							$last_after = $n;
51942381097bSJoe Perches							$space_after = 1;
51952381097bSJoe Perches						}
51962381097bSJoe Perches					}
51972381097bSJoe Perches					if ($rtrim_before || $space_after) {
51982381097bSJoe Perches						if ($rtrim_before) {
51992381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
52002381097bSJoe Perches						} else {
52012381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
52022381097bSJoe Perches						}
5203cf655043SAndy Whitcroft						if ($space_after) {
52043705ce5bSJoe Perches							$good .= " ";
52053705ce5bSJoe Perches						}
52063705ce5bSJoe Perches					}
5207b34c648bSJoe Perches
52082381097bSJoe Perches				# '*' as part of a type definition -- reported already.
52092381097bSJoe Perches				} elsif ($opv eq '*_') {
52102381097bSJoe Perches					#warn "'*' is part of type\n";
52112381097bSJoe Perches
52122381097bSJoe Perches				# unary operators should have a space before and
52132381097bSJoe Perches				# none after.  May be left adjacent to another
52142381097bSJoe Perches				# unary operator, or a cast
52152381097bSJoe Perches				} elsif ($op eq '!' || $op eq '~' ||
52162381097bSJoe Perches					 $opv eq '*U' || $opv eq '-U' ||
52172381097bSJoe Perches					 $opv eq '&U' || $opv eq '&&U') {
52182381097bSJoe Perches					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
52193705ce5bSJoe Perches						if (ERROR("SPACING",
52200a920b5bSAndy Whitcroft							  "space required before that '$op' $at\n" . $hereptr)) {
52210a920b5bSAndy Whitcroft							if ($n != $last_after + 2) {
52229c0ca6f9SAndy Whitcroft								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
522374048ed8SAndy Whitcroft								$line_fixed = 1;
52249c0ca6f9SAndy Whitcroft							}
52259c0ca6f9SAndy Whitcroft						}
52269c0ca6f9SAndy Whitcroft					}
52279c0ca6f9SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
52289c0ca6f9SAndy Whitcroft						# A unary '*' may be const
52299c0ca6f9SAndy Whitcroft
523074048ed8SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
52310d413866SAndy Whitcroft						if (ERROR("SPACING",
5232cf655043SAndy Whitcroft							  "space prohibited after that '$op' $at\n" . $hereptr)) {
52333705ce5bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
52343705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5235b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5236b34c648bSJoe Perches							}
52373705ce5bSJoe Perches							$line_fixed = 1;
52383705ce5bSJoe Perches						}
52390a920b5bSAndy Whitcroft					}
5240b34c648bSJoe Perches
5241a3340b35SAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
5242171ae1a4SAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
5243171ae1a4SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
5244171ae1a4SAndy Whitcroft						if (ERROR("SPACING",
52453705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
52463705ce5bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
5247b34c648bSJoe Perches							$line_fixed = 1;
52483705ce5bSJoe Perches						}
52493705ce5bSJoe Perches					}
52503705ce5bSJoe Perches					if ($ctx =~ /Wx[BE]/ ||
5251b34c648bSJoe Perches					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
52523705ce5bSJoe Perches						if (ERROR("SPACING",
52530a920b5bSAndy Whitcroft							  "space prohibited before that '$op' $at\n" . $hereptr)) {
52540a920b5bSAndy Whitcroft							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
52550a920b5bSAndy Whitcroft							$line_fixed = 1;
52560a920b5bSAndy Whitcroft						}
5257773647a0SAndy Whitcroft					}
52583705ce5bSJoe Perches					if ($ctx =~ /ExW/) {
52593705ce5bSJoe Perches						if (ERROR("SPACING",
5260b34c648bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
52613705ce5bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
52623705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
52630a920b5bSAndy Whitcroft								$fix_elements[$n + 2] =~ s/^\s+//;
5264773647a0SAndy Whitcroft							}
5265773647a0SAndy Whitcroft							$line_fixed = 1;
52663705ce5bSJoe Perches						}
52673705ce5bSJoe Perches					}
5268b34c648bSJoe Perches
52693705ce5bSJoe Perches				# << and >> may either have or not have spaces both sides
52703705ce5bSJoe Perches				} elsif ($op eq '<<' or $op eq '>>' or
5271653d4876SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
5272773647a0SAndy Whitcroft					 $op eq '+' or $op eq '-' or
52733705ce5bSJoe Perches					 $op eq '*' or $op eq '/' or
52743705ce5bSJoe Perches					 $op eq '%')
5275b34c648bSJoe Perches				{
52763705ce5bSJoe Perches					if ($check) {
52773705ce5bSJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5278773647a0SAndy Whitcroft							if (CHK("SPACING",
5279b34c648bSJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
52803705ce5bSJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
52813705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
52820a920b5bSAndy Whitcroft								$line_fixed = 1;
52830a920b5bSAndy Whitcroft							}
52849c0ca6f9SAndy Whitcroft						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
52859c0ca6f9SAndy Whitcroft							if (CHK("SPACING",
52869c0ca6f9SAndy Whitcroft								"space preferred before that '$op' $at\n" . $hereptr)) {
5287c2fdda0dSAndy Whitcroft								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5288c2fdda0dSAndy Whitcroft								$line_fixed = 1;
52890a920b5bSAndy Whitcroft							}
5290d2e025f3SJoe Perches						}
5291d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
5292d2e025f3SJoe Perches						if (ERROR("SPACING",
5293d2e025f3SJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5294d2e025f3SJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5295d2e025f3SJoe Perches							if (defined $fix_elements[$n + 2]) {
5296d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5297d2e025f3SJoe Perches							}
5298d2e025f3SJoe Perches							$line_fixed = 1;
5299d2e025f3SJoe Perches						}
5300d2e025f3SJoe Perches					}
5301d2e025f3SJoe Perches
5302d2e025f3SJoe Perches				# A colon needs no spaces before when it is
5303d2e025f3SJoe Perches				# terminating a case value or a label.
5304d2e025f3SJoe Perches				} elsif ($opv eq ':C' || $opv eq ':L') {
5305d2e025f3SJoe Perches					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
53063705ce5bSJoe Perches						if (ERROR("SPACING",
53073705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5308b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5309b34c648bSJoe Perches							$line_fixed = 1;
5310b34c648bSJoe Perches						}
5311b34c648bSJoe Perches					}
53123705ce5bSJoe Perches
53133705ce5bSJoe Perches				# All the others need spaces both sides.
53140a920b5bSAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
53150a920b5bSAndy Whitcroft					my $ok = 0;
53161f65f947SAndy Whitcroft
53171f65f947SAndy Whitcroft					# Ignore email addresses <foo@bar>
53181f65f947SAndy Whitcroft					if (($op eq '<' &&
5319263afd39SChris Down					     $cc =~ /^\S+\@\S+>/) ||
53203705ce5bSJoe Perches					    ($op eq '>' &&
53213705ce5bSJoe Perches					     $ca =~ /<\S+\@\S+$/))
5322b34c648bSJoe Perches					{
53233705ce5bSJoe Perches						$ok = 1;
53243705ce5bSJoe Perches					}
53251f65f947SAndy Whitcroft
53261f65f947SAndy Whitcroft					# for asm volatile statements
53270a920b5bSAndy Whitcroft					# ignore a colon with another
5328cf655043SAndy Whitcroft					# colon immediately before or after
53291f65f947SAndy Whitcroft					if (($op eq ':') &&
53301f65f947SAndy Whitcroft					    ($ca =~ /:$/ || $cc =~ /^:/)) {
533122f2a2efSAndy Whitcroft						$ok = 1;
53321f65f947SAndy Whitcroft					}
53331f65f947SAndy Whitcroft
53341f65f947SAndy Whitcroft					# messages are ERROR, but ?: are CHK
53351f65f947SAndy Whitcroft					if ($ok == 0) {
53361f65f947SAndy Whitcroft						my $msg_level = \&ERROR;
53371f65f947SAndy Whitcroft						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
53381f65f947SAndy Whitcroft
53391f65f947SAndy Whitcroft						if (&{$msg_level}("SPACING",
5340e0df7e1fSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5341e0df7e1fSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5342e0df7e1fSJoe Perches							if (defined $fix_elements[$n + 2]) {
5343e0df7e1fSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5344e0df7e1fSJoe Perches							}
5345e0df7e1fSJoe Perches							$line_fixed = 1;
5346e0df7e1fSJoe Perches						}
5347e0df7e1fSJoe Perches					}
534884731623SJoe Perches				}
53491f65f947SAndy Whitcroft				$off += length($elements[$n + 1]);
53500675a8fbSJean Delvare
53510675a8fbSJean Delvare##				print("n: <$n> GOOD: <$good>\n");
535284731623SJoe Perches
53530675a8fbSJean Delvare				$fixed_line = $fixed_line . $good;
53543705ce5bSJoe Perches			}
5355b34c648bSJoe Perches
5356b34c648bSJoe Perches			if (($#elements % 2) == 0) {
5357b34c648bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
5358b34c648bSJoe Perches			}
53593705ce5bSJoe Perches
53603705ce5bSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
53610a920b5bSAndy Whitcroft				$fixed[$fixlinenr] = $fixed_line;
536222f2a2efSAndy Whitcroft			}
53634a0df2efSAndy Whitcroft
53643705ce5bSJoe Perches
53653705ce5bSJoe Perches		}
53663705ce5bSJoe Perches
53673705ce5bSJoe Perches# check for whitespace before a non-naked semicolon
53680a920b5bSAndy Whitcroft		if ($line =~ /^\+.*\S\s+;\s*$/) {
53693705ce5bSJoe Perches			if (WARN("SPACING",
53703705ce5bSJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
53713705ce5bSJoe Perches			    $fix) {
53723705ce5bSJoe Perches				1 while $fixed[$fixlinenr] =~
53733705ce5bSJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5374194f66fcSJoe Perches			}
5375194f66fcSJoe Perches		}
53763705ce5bSJoe Perches
53773705ce5bSJoe Perches# check for multiple assignments
53783705ce5bSJoe Perches		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
53790a920b5bSAndy Whitcroft			CHK("MULTIPLE_ASSIGNMENTS",
53800a920b5bSAndy Whitcroft			    "multiple assignments should be avoided\n" . $herecurr);
5381786b6326SJoe Perches		}
5382d2e248e7SJoe Perches
5383786b6326SJoe Perches## # check for multiple declarations, allowing for a function declaration
5384786b6326SJoe Perches## # continuation.
5385786b6326SJoe Perches## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
5386194f66fcSJoe Perches## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
5387786b6326SJoe Perches##
5388786b6326SJoe Perches## 			# Remove any bracketed sections to ensure we do not
5389786b6326SJoe Perches## 			# falsely report the parameters of functions.
5390786b6326SJoe Perches## 			my $ln = $line;
5391f0a594c1SAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
5392f0a594c1SAndy Whitcroft## 			}
5393000d1cc1SJoe Perches## 			if ($ln =~ /,/) {
5394000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5395f0a594c1SAndy Whitcroft##				     "declaring multiple variables together should be avoided\n" . $herecurr);
5396f0a594c1SAndy Whitcroft## 			}
539722f2a2efSAndy Whitcroft## 		}
539822f2a2efSAndy Whitcroft
539922f2a2efSAndy Whitcroft#need space before brace following if, while, etc
540022f2a2efSAndy Whitcroft		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
540122f2a2efSAndy Whitcroft		    $line =~ /\b(?:else|do)\{/) {
540222f2a2efSAndy Whitcroft			if (ERROR("SPACING",
5403e73d2715SDwaipayan Ray				  "space required before the open brace '{'\n" . $herecurr) &&
540422f2a2efSAndy Whitcroft			    $fix) {
540522f2a2efSAndy Whitcroft				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
540622f2a2efSAndy Whitcroft			}
540722f2a2efSAndy Whitcroft		}
5408000d1cc1SJoe Perches
5409000d1cc1SJoe Perches## # check for blank lines before declarations
541022f2a2efSAndy Whitcroft##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
541122f2a2efSAndy Whitcroft##		    $prevrawline =~ /^.\s*$/) {
5412f0a594c1SAndy Whitcroft##			WARN("SPACING",
54130a920b5bSAndy Whitcroft##			     "No blank lines before declarations\n" . $hereprev);
54146b8c69e4SGeyslan G. Bem##		}
54156ad724e2SMichal Zylowski##
54163705ce5bSJoe Perches
54173705ce5bSJoe Perches# closing brace should have a space following it when it has anything
54183705ce5bSJoe Perches# on the line
54196ad724e2SMichal Zylowski		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
54203705ce5bSJoe Perches			if (ERROR("SPACING",
5421de7d4f0eSAndy Whitcroft				  "space required after that close brace '}'\n" . $herecurr) &&
5422de7d4f0eSAndy Whitcroft			    $fix) {
5423c4a62ef9SJoe Perches				$fixed[$fixlinenr] =~
5424c4a62ef9SJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5425c4a62ef9SJoe Perches			}
5426c4a62ef9SJoe Perches		}
5427c4a62ef9SJoe Perches
5428c4a62ef9SJoe Perches# check spacing on square brackets
5429c4a62ef9SJoe Perches		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
5430c4a62ef9SJoe Perches			if (ERROR("SPACING",
5431de7d4f0eSAndy Whitcroft				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
5432de7d4f0eSAndy Whitcroft			    $fix) {
543394fb9845SJoe Perches				$fixed[$fixlinenr] =~
5434d5e616fcSJoe Perches				    s/\[\s+/\[/;
5435d5e616fcSJoe Perches			}
5436d5e616fcSJoe Perches		}
5437194f66fcSJoe Perches		if ($line =~ /\s\]/) {
5438d5e616fcSJoe Perches			if (ERROR("SPACING",
5439d5e616fcSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
54400a920b5bSAndy Whitcroft			    $fix) {
54410a920b5bSAndy Whitcroft				$fixed[$fixlinenr] =~
544222f2a2efSAndy Whitcroft				    s/\s+\]/\]/;
544322f2a2efSAndy Whitcroft			}
54443705ce5bSJoe Perches		}
54453705ce5bSJoe Perches
54463705ce5bSJoe Perches# check spacing on parentheses
5447194f66fcSJoe Perches		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
54483705ce5bSJoe Perches		    $line !~ /for\s*\(\s+;/) {
54493705ce5bSJoe Perches			if (ERROR("SPACING",
545022f2a2efSAndy Whitcroft				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
545122f2a2efSAndy Whitcroft			    $fix) {
54523705ce5bSJoe Perches				$fixed[$fixlinenr] =~
54533705ce5bSJoe Perches				    s/\(\s+/\(/;
54543705ce5bSJoe Perches			}
5455194f66fcSJoe Perches		}
54563705ce5bSJoe Perches		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
54573705ce5bSJoe Perches		    $line !~ /for\s*\(.*;\s+\)/ &&
545822f2a2efSAndy Whitcroft		    $line !~ /:\s+\)/) {
545922f2a2efSAndy Whitcroft			if (ERROR("SPACING",
5460c45dcabdSAndy Whitcroft				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
54619c0ca6f9SAndy Whitcroft			    $fix) {
54629c0ca6f9SAndy Whitcroft				$fixed[$fixlinenr] =~
54633705ce5bSJoe Perches				    s/\s+\)/\)/;
54643705ce5bSJoe Perches			}
54653705ce5bSJoe Perches		}
5466194f66fcSJoe Perches
54673705ce5bSJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
54683705ce5bSJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
546922f2a2efSAndy Whitcroft
547013214adfSAndy Whitcroft		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5471c45dcabdSAndy Whitcroft			my $var = $1;
5472c45dcabdSAndy Whitcroft			if (CHK("UNNECESSARY_PARENTHESES",
54733705ce5bSJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
54743705ce5bSJoe Perches			    $fix) {
54753705ce5bSJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5476194f66fcSJoe Perches			}
54773705ce5bSJoe Perches		}
54783705ce5bSJoe Perches
547922f2a2efSAndy Whitcroft# check for unnecessary parentheses around function pointer uses
548022f2a2efSAndy Whitcroft# ie: (foo->bar)(); should be foo->bar();
5481e2826fd0SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5482e2826fd0SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5483e2826fd0SJoe Perches			my $var = $2;
5484e2826fd0SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5485ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5486ea4acbb1SJoe Perches			    $fix) {
5487ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5488ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5489ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5490ea4acbb1SJoe Perches			}
5491ea4acbb1SJoe Perches		}
5492ea4acbb1SJoe Perches
5493ea4acbb1SJoe Perches# check for unnecessary parentheses around comparisons
5494ea4acbb1SJoe Perches# except in drivers/staging
5495ea4acbb1SJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@) &&
5496ea4acbb1SJoe Perches		    $perl_version_ok && defined($stat) &&
5497ea4acbb1SJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
5498ea4acbb1SJoe Perches			my $if_stat = $1;
5499ea4acbb1SJoe Perches			my $test = substr($2, 1, -1);
5500ea4acbb1SJoe Perches			my $herectx;
5501ea4acbb1SJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
5502ea4acbb1SJoe Perches				my $match = $1;
5503ea4acbb1SJoe Perches				# avoid parentheses around potential macro args
5504ea4acbb1SJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
5505e2826fd0SJoe Perches				if (!defined($herectx)) {
5506e2826fd0SJoe Perches					$herectx = $here . "\n";
5507d22feb5bSDan Carpenter					my $cnt = statement_rawlines($if_stat);
5508d22feb5bSDan Carpenter					for (my $n = 0; $n < $cnt; $n++) {
5509d22feb5bSDan Carpenter						my $rl = raw_line($linenr, $n);
55105b57980dSJoe Perches						$herectx .=  $rl . "\n";
551163b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
551263b7c73eSJoe Perches					}
551363b7c73eSJoe Perches				}
551463b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
551563b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
551663b7c73eSJoe Perches			}
551763b7c73eSJoe Perches		}
551863b7c73eSJoe Perches
551963b7c73eSJoe Perches# check that goto labels aren't indented (allow a single space indentation)
552063b7c73eSJoe Perches# and ignore bitfield definitions like foo:1
552163b7c73eSJoe Perches# Strictly, labels can have whitespace after the identifier and before the :
552263b7c73eSJoe Perches# but this is not allowed here as many ?: uses would appear to be labels
552363b7c73eSJoe Perches		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
552463b7c73eSJoe Perches		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
552563b7c73eSJoe Perches		    $sline !~ /^.\s+default:/) {
552663b7c73eSJoe Perches			if (WARN("INDENTED_LABEL",
552763b7c73eSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
552863b7c73eSJoe Perches			    $fix) {
552963b7c73eSJoe Perches				$fixed[$fixlinenr] =~
553063b7c73eSJoe Perches				    s/^(.)\s+/$1/;
553163b7c73eSJoe Perches			}
553263b7c73eSJoe Perches		}
553369078651SJoe Perches
553469078651SJoe Perches# check if a statement with a comma should be two statements like:
553569078651SJoe Perches#	foo = bar(),	/* comma should be semicolon */
553669078651SJoe Perches#	bar = baz();
553769078651SJoe Perches		if (defined($stat) &&
553869078651SJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
553969078651SJoe Perches			my $cnt = statement_rawlines($stat);
55403705ce5bSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
55413705ce5bSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
55423705ce5bSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
5543194f66fcSJoe Perches		}
55443705ce5bSJoe Perches
55453705ce5bSJoe Perches# return is not a function
55460a920b5bSAndy Whitcroft		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
55470a920b5bSAndy Whitcroft			my $spacing = $1;
554840873abaSJoe Perches			if ($perl_version_ok &&
554940873abaSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
555040873abaSJoe Perches				my $value = $1;
555140873abaSJoe Perches				$value = deparenthesize($value);
555240873abaSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
555340873abaSJoe Perches					ERROR("RETURN_PARENTHESES",
555440873abaSJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
555540873abaSJoe Perches				}
555640873abaSJoe Perches			} elsif ($spacing !~ /\s+/) {
555740873abaSJoe Perches				ERROR("SPACING",
555840873abaSJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
55595b9553abSJoe Perches			}
5560507e5141SJoe Perches		}
5561c45dcabdSAndy Whitcroft
55625b57980dSJoe Perches# unnecessary return in a void function
55635b9553abSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
55645b9553abSJoe Perches# and the line before that not a goto label target like "out:"
55655b9553abSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
55665b9553abSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5567000d1cc1SJoe Perches		    $linenr >= 3 &&
5568000d1cc1SJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
55695b9553abSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
5570c45dcabdSAndy Whitcroft			WARN("RETURN_VOID",
5571000d1cc1SJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
5572000d1cc1SJoe Perches		}
5573c45dcabdSAndy Whitcroft
5574c45dcabdSAndy Whitcroft# if statements using unnecessary parentheses - ie: if ((foo == bar))
5575507e5141SJoe Perches		if ($perl_version_ok &&
5576b43ae21bSJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5577b43ae21bSJoe Perches			my $openparens = $1;
5578b43ae21bSJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5579b43ae21bSJoe Perches			my $msg = "";
5580b43ae21bSJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5581b43ae21bSJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5582b43ae21bSJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5583b43ae21bSJoe Perches				WARN("UNNECESSARY_PARENTHESES",
55849819cf25SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5585b43ae21bSJoe Perches			}
55869819cf25SJoe Perches		}
55879819cf25SJoe Perches
5588189248d8SJoe Perches# comparisons with a constant or upper case identifier on the left
55895b57980dSJoe Perches#	avoid cases like "foo + BAR < baz"
5590189248d8SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5591189248d8SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
5592189248d8SJoe Perches		if ($perl_version_ok &&
5593189248d8SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5594189248d8SJoe Perches			my $lead = $1;
5595189248d8SJoe Perches			my $const = $2;
5596189248d8SJoe Perches			my $comp = $3;
5597189248d8SJoe Perches			my $to = $4;
5598189248d8SJoe Perches			my $newcomp = $comp;
5599189248d8SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5600189248d8SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5601189248d8SJoe Perches			    WARN("CONSTANT_COMPARISON",
5602c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5603c5595fa2SJoe Perches			    $fix) {
5604c5595fa2SJoe Perches				if ($comp eq "<") {
5605c5595fa2SJoe Perches					$newcomp = ">";
56065b57980dSJoe Perches				} elsif ($comp eq "<=") {
5607c5595fa2SJoe Perches					$newcomp = ">=";
5608c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5609c5595fa2SJoe Perches					$newcomp = "<";
5610c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5611c5595fa2SJoe Perches					$newcomp = "<=";
5612c5595fa2SJoe Perches				}
5613f39e1769SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5614c5595fa2SJoe Perches			}
5615c5595fa2SJoe Perches		}
5616c5595fa2SJoe Perches
5617c5595fa2SJoe Perches# Return of what appears to be an errno should normally be negative
5618c5595fa2SJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
5619c5595fa2SJoe Perches			my $name = $1;
5620c5595fa2SJoe Perches			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5621c5595fa2SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5622c5595fa2SJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
5623c5595fa2SJoe Perches			}
5624c5595fa2SJoe Perches		}
5625c5595fa2SJoe Perches
5626c5595fa2SJoe Perches# Need a space before open parenthesis after if, while etc
5627c5595fa2SJoe Perches		if ($line =~ /\b(if|while|for|switch)\(/) {
5628c5595fa2SJoe Perches			if (ERROR("SPACING",
5629c5595fa2SJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
5630c5595fa2SJoe Perches			    $fix) {
5631f34e4a4fSJoe Perches				$fixed[$fixlinenr] =~
5632f34e4a4fSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
563353a3c448SAndy Whitcroft			}
563446b85bf9SGuenter Roeck		}
5635000d1cc1SJoe Perches
5636f34e4a4fSJoe Perches# Check for illegal assignment in if conditional -- and check for trailing
563753a3c448SAndy Whitcroft# statements after the conditional.
563853a3c448SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
5639c45dcabdSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
56400a920b5bSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
56414a0df2efSAndy Whitcroft					if (!defined $stat);
56423705ce5bSJoe Perches			my ($stat_next) = ctx_statement_block($line_nr_next,
56433705ce5bSJoe Perches						$remain_next, $off_next);
56443705ce5bSJoe Perches			$stat_next =~ s/\n./\n /g;
5645194f66fcSJoe Perches			##print "stat<$stat> stat_next<$stat_next>\n";
56463705ce5bSJoe Perches
56473705ce5bSJoe Perches			if ($stat_next =~ /^\s*while\b/) {
56480a920b5bSAndy Whitcroft				# If the statement carries leading newlines,
56490a920b5bSAndy Whitcroft				# then count those as offsets.
5650f5fe35ddSAndy Whitcroft				my ($whitespace) =
5651f5fe35ddSAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5652170d3a22SAndy Whitcroft				my $offset =
56533e469cdcSAndy Whitcroft					statement_rawlines($whitespace) - 1;
56543e469cdcSAndy Whitcroft
56553e469cdcSAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5656170d3a22SAndy Whitcroft								$offset} = 1;
5657170d3a22SAndy Whitcroft			}
5658170d3a22SAndy Whitcroft		}
5659170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5660170d3a22SAndy Whitcroft		    defined($stat) && defined($cond) &&
5661170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5662170d3a22SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
5663170d3a22SAndy Whitcroft			my $fixed_assign_in_if = 0;
5664170d3a22SAndy Whitcroft
5665170d3a22SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
5666170d3a22SAndy Whitcroft				if (ERROR("ASSIGN_IN_IF",
5667170d3a22SAndy Whitcroft					  "do not use assignment in if condition\n" . $herecurr) &&
5668170d3a22SAndy Whitcroft				    $fix && $perl_version_ok) {
5669170d3a22SAndy Whitcroft					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
5670170d3a22SAndy Whitcroft						my $space = $1;
5671170d3a22SAndy Whitcroft						my $not = $2;
5672170d3a22SAndy Whitcroft						my $statement = $3;
5673170d3a22SAndy Whitcroft						my $assigned = $4;
5674c11230f4SJoe Perches						my $test = $8;
5675170d3a22SAndy Whitcroft						my $against = $9;
5676171ae1a4SAndy Whitcroft						my $brace = $15;
5677481efd7bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
56788905a67cSAndy Whitcroft						fix_insert_line($fixlinenr, "$space$statement;");
5679b53c8e10SAndy Whitcroft						my $newline = "${space}if (";
568065b64b3bSJoe Perches						$newline .= '!' if defined($not);
568165b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
568265b64b3bSJoe Perches						$newline .= "$assigned";
568365b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
568465b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
568565b64b3bSJoe Perches						$newline .= ')';
568665b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
568765b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
568865b64b3bSJoe Perches						$fixed_assign_in_if = 1;
568965b64b3bSJoe Perches					}
569065b64b3bSJoe Perches				}
569165b64b3bSJoe Perches			}
569265b64b3bSJoe Perches
569365b64b3bSJoe Perches			# Find out what is on the end of the line after the
569465b64b3bSJoe Perches			# conditional.
569565b64b3bSJoe Perches			substr($s, 0, length($c), '');
569665b64b3bSJoe Perches			$s =~ s/\n.*//g;
569765b64b3bSJoe Perches			$s =~ s/$;//g;	# Remove any comments
569865b64b3bSJoe Perches			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
569965b64b3bSJoe Perches			    $c !~ /}\s*while\s*/)
570065b64b3bSJoe Perches			{
570165b64b3bSJoe Perches				# Find out how long the conditional actually is.
5702481efd7bSJoe Perches				my @newlines = ($c =~ /\n/gs);
570365b64b3bSJoe Perches				my $cond_lines = 1 + $#newlines;
570465b64b3bSJoe Perches				my $stat_real = '';
57058905a67cSAndy Whitcroft
57068905a67cSAndy Whitcroft				$stat_real = raw_line($linenr, $cond_lines)
57078905a67cSAndy Whitcroft							. "\n" if ($cond_lines);
57088905a67cSAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5709773647a0SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
57108905a67cSAndy Whitcroft				}
571113214adfSAndy Whitcroft
571253210168SAndy Whitcroft				if (ERROR("TRAILING_STATEMENTS",
571353210168SAndy Whitcroft					  "trailing statements should be on next line\n" . $herecurr . $stat_real) &&
5714773647a0SAndy Whitcroft				    !$fixed_assign_in_if &&
5715bb44ad39SAndy Whitcroft				    $cond_lines == 0 &&
5716bb44ad39SAndy Whitcroft				    $fix && $perl_version_ok &&
5717bb44ad39SAndy Whitcroft				    $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) {
571842bdf74cSHidetoshi Seto					my $indent = $1;
5719bb44ad39SAndy Whitcroft					my $test = $2;
572042bdf74cSHidetoshi Seto					my $rest = rtrim($4);
572142bdf74cSHidetoshi Seto					if ($rest =~ /;$/) {
5722bb44ad39SAndy Whitcroft						$fixed[$fixlinenr] = "\+$indent$test";
5723bb44ad39SAndy Whitcroft						fix_insert_line($fixlinenr + 1, "$indent\t$rest");
5724bb44ad39SAndy Whitcroft					}
5725bb44ad39SAndy Whitcroft				}
5726481efd7bSJoe Perches			}
5727481efd7bSJoe Perches		}
5728481efd7bSJoe Perches
5729481efd7bSJoe Perches# Check for bitwise tests written as boolean
5730481efd7bSJoe Perches		if ($line =~ /
5731481efd7bSJoe Perches			(?:
5732481efd7bSJoe Perches				(?:\[|\(|\&\&|\|\|)
5733481efd7bSJoe Perches				\s*0[xX][0-9]+\s*
5734481efd7bSJoe Perches				(?:\&\&|\|\|)
5735481efd7bSJoe Perches			|
5736481efd7bSJoe Perches				(?:\&\&|\|\|)
5737481efd7bSJoe Perches				\s*0[xX][0-9]+\s*
5738481efd7bSJoe Perches				(?:\&\&|\|\||\)|\])
5739481efd7bSJoe Perches			)/x)
57408905a67cSAndy Whitcroft		{
57418905a67cSAndy Whitcroft			WARN("HEXADECIMAL_BOOLEAN_TEST",
57428905a67cSAndy Whitcroft			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
574313214adfSAndy Whitcroft		}
574413214adfSAndy Whitcroft
574513214adfSAndy Whitcroft# if and else should not have general statements after it
574613214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
574713214adfSAndy Whitcroft			my $s = $1;
574813214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
574913214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
575013214adfSAndy Whitcroft				ERROR("TRAILING_STATEMENTS",
575113214adfSAndy Whitcroft				      "trailing statements should be on next line\n" . $herecurr);
575213214adfSAndy Whitcroft			}
575313214adfSAndy Whitcroft		}
575413214adfSAndy Whitcroft# if should not continue a brace
5755000d1cc1SJoe Perches		if ($line =~ /}\s*if\b/) {
5756000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
575713214adfSAndy Whitcroft			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
575813214adfSAndy Whitcroft				$herecurr);
57598905a67cSAndy Whitcroft		}
576013214adfSAndy Whitcroft# case and default should not have general statements after them
576113214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
576213214adfSAndy Whitcroft		    $line !~ /\G(?:
576313214adfSAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5764000d1cc1SJoe Perches			\s*return\s+
5765000d1cc1SJoe Perches		    )/xg)
57660a920b5bSAndy Whitcroft		{
576713214adfSAndy Whitcroft			ERROR("TRAILING_STATEMENTS",
576839667782SAndy Whitcroft			      "trailing statements should be on next line\n" . $herecurr);
576939667782SAndy Whitcroft		}
5770000d1cc1SJoe Perches
5771048b123fSRasmus Villemoes		# Check for }<nl>else {, these must be at the same
577239667782SAndy Whitcroft		# indent level to be relevant to each other.
577339667782SAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
5774a1080bf8SAndy Whitcroft		    $previndent == $indent) {
5775a1080bf8SAndy Whitcroft			if (ERROR("ELSE_AFTER_BRACE",
5776a1080bf8SAndy Whitcroft				  "else should follow close brace '}'\n" . $hereprev) &&
57773fef12d6SAndy Whitcroft			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5778a1080bf8SAndy Whitcroft				fix_delete_line($fixlinenr - 1, $prevrawline);
5779a1080bf8SAndy Whitcroft				fix_delete_line($fixlinenr, $rawline);
5780a1080bf8SAndy Whitcroft				my $fixedline = $prevrawline;
5781000d1cc1SJoe Perches				$fixedline =~ s/}\s*$//;
5782000d1cc1SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
5783a1080bf8SAndy Whitcroft					fix_insert_line($fixlinenr, $fixedline);
57840a920b5bSAndy Whitcroft				}
57850a920b5bSAndy Whitcroft				$fixedline = $rawline;
57860a920b5bSAndy Whitcroft				$fixedline =~ s/^(.\s*)else/$1} else/;
57878b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
57880a920b5bSAndy Whitcroft			}
57898b8856f4SJoe Perches		}
57908b8856f4SJoe Perches
57918b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
57928b8856f4SJoe Perches		    $previndent == $indent) {
57938b8856f4SJoe Perches			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
57948b8856f4SJoe Perches
57958b8856f4SJoe Perches			# Find out what is on the end of the line after the
57968b8856f4SJoe Perches			# conditional.
57978b8856f4SJoe Perches			substr($s, 0, length($c), '');
57988b8856f4SJoe Perches			$s =~ s/\n.*//g;
57998b8856f4SJoe Perches
58008b8856f4SJoe Perches			if ($s =~ /^\s*;/) {
58018b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
58028b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
58030a920b5bSAndy Whitcroft				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
58040a920b5bSAndy Whitcroft					fix_delete_line($fixlinenr - 1, $prevrawline);
58058b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
5806c2fdda0dSAndy Whitcroft					my $fixedline = $prevrawline;
5807c2fdda0dSAndy Whitcroft					my $trailing = $rawline;
5808c2fdda0dSAndy Whitcroft					$trailing =~ s/^\+//;
5809c2fdda0dSAndy Whitcroft					$trailing = trim($trailing);
5810c2fdda0dSAndy Whitcroft					$fixedline =~ s/}\s*$/} $trailing/;
5811773647a0SAndy Whitcroft					fix_insert_line($fixlinenr, $fixedline);
5812c2fdda0dSAndy Whitcroft				}
5813c2fdda0dSAndy Whitcroft			}
5814c2fdda0dSAndy Whitcroft		}
58158b8856f4SJoe Perches
58168b8856f4SJoe Perches#Specific variable tests
58178b8856f4SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
58188b8856f4SJoe Perches			my $var = $1;
58198b8856f4SJoe Perches
58208b8856f4SJoe Perches#CamelCase
58218b8856f4SJoe Perches			if ($var !~ /^$Constant$/ &&
58228b8856f4SJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
58238b8856f4SJoe Perches#Ignore C keywords
58248b8856f4SJoe Perches			    $var !~ /^_Generic$/ &&
58258b8856f4SJoe Perches#Ignore some autogenerated defines and enum values
58268b8856f4SJoe Perches			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
5827c2fdda0dSAndy Whitcroft#Ignore Page<foo> variants
5828c2fdda0dSAndy Whitcroft			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5829c2fdda0dSAndy Whitcroft#Ignore ETHTOOL_LINK_MODE_<foo> variants
583095e2c602SJoe Perches			    $var !~ /^ETHTOOL_LINK_MODE_/ &&
5831323c1260SJoe Perches#Ignore SI style variants like nS, mV and dB
5832323c1260SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
583395e2c602SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
583495e2c602SJoe Perches#Ignore some three character SI units explicitly, like MiB and KHz
5835807bd26cSJoe Perches			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
5836be79794bSJoe Perches				while ($var =~ m{\b($Ident)}g) {
583720d00cfaSPrzemek Kitszel					my $word = $1;
583820d00cfaSPrzemek Kitszel					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
58394104a206SŁukasz Stelmach					if ($check) {
58404104a206SŁukasz Stelmach						seed_camelcase_includes();
584122735ce8SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5842807bd26cSJoe Perches							seed_camelcase_file($realfile);
5843d99a4158SGerhard Engleder							$camelcase_file_seeded = 1;
5844d99a4158SGerhard Engleder						}
5845d439e6a5SJoe Perches					}
5846d439e6a5SJoe Perches					if (!defined $camelcase{$word}) {
5847d439e6a5SJoe Perches						$camelcase{$word} = 1;
5848f5123576SJulius Werner						CHK("CAMELCASE",
5849f5123576SJulius Werner						    "Avoid CamelCase: <$word>\n" . $herecurr);
5850f858e23aSAntonio Borneo					}
58517e781f67SJoe Perches				}
58527e781f67SJoe Perches			}
5853d8b07710SJoe Perches		}
5854d8b07710SJoe Perches
5855d8b07710SJoe Perches#no spaces allowed after \ in define
5856d8b07710SJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5857d8b07710SJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5858d8b07710SJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5859d8b07710SJoe Perches			    $fix) {
58607e781f67SJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
58617e781f67SJoe Perches			}
5862be79794bSJoe Perches		}
58637e781f67SJoe Perches
58647e781f67SJoe Perches# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
5865323c1260SJoe Perches# itself <asm/foo.h> (uses RAW line)
5866323c1260SJoe Perches		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
58673445686aSJoe Perches			my $file = "$1.h";
58680a920b5bSAndy Whitcroft			my $checkfile = "include/linux/$file";
58690a920b5bSAndy Whitcroft			if (-f "$root/$checkfile" &&
5870d5e616fcSJoe Perches			    $realfile ne $checkfile &&
5871d5e616fcSJoe Perches			    $1 !~ /$allowed_asm_includes/)
5872d5e616fcSJoe Perches			{
5873d5e616fcSJoe Perches				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5874194f66fcSJoe Perches				if ($asminclude > 0) {
5875d5e616fcSJoe Perches					if ($realfile =~ m{^arch/}) {
58760a920b5bSAndy Whitcroft						CHK("ARCH_INCLUDE_LINUX",
58770a920b5bSAndy Whitcroft						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
58780e212e0aSFabian Frederick					} else {
58790e212e0aSFabian Frederick						WARN("INCLUDE_LINUX",
5880c45dcabdSAndy Whitcroft						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5881e09dec48SAndy Whitcroft					}
5882e09dec48SAndy Whitcroft				}
5883e09dec48SAndy Whitcroft			}
5884e09dec48SAndy Whitcroft		}
58857840a94cSWolfram Sang
5886c45dcabdSAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
58870e212e0aSFabian Frederick# first statement and ensure its the whole macro if its not enclosed
58880e212e0aSFabian Frederick# in a known good container
5889e09dec48SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5890000d1cc1SJoe Perches		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5891000d1cc1SJoe Perches			my $ln = $linenr;
5892e09dec48SAndy Whitcroft			my $cnt = $realcnt;
5893000d1cc1SJoe Perches			my ($off, $dstat, $dcond, $rest);
5894000d1cc1SJoe Perches			my $ctx = '';
5895e09dec48SAndy Whitcroft			my $has_flow_statement = 0;
58960a920b5bSAndy Whitcroft			my $has_arg_concat = 0;
58970a920b5bSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
58980e212e0aSFabian Frederick				ctx_statement_block($linenr, $realcnt, 0);
58990a920b5bSAndy Whitcroft			$ctx = $dstat;
5900653d4876SAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5901653d4876SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5902cf655043SAndy Whitcroft
5903b8f96a31SAndy Whitcroft			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
5904b8f96a31SAndy Whitcroft			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
5905d8aaf121SAndy Whitcroft
5906d8aaf121SAndy Whitcroft			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5907c45dcabdSAndy Whitcroft			my $define_args = $1;
5908c45dcabdSAndy Whitcroft			my $define_stmt = $dstat;
590908a2843eSJoe Perches			my @def_args = ();
591008a2843eSJoe Perches
5911c45dcabdSAndy Whitcroft			if (defined $define_args && $define_args ne "") {
5912f74bd194SAndy Whitcroft				$define_args = substr($define_args, 1, length($define_args) - 2);
5913f74bd194SAndy Whitcroft				$define_args =~ s/\s*//g;
5914c45dcabdSAndy Whitcroft				$define_args =~ s/\\\+?//g;
5915a3bb97a7SAndy Whitcroft				@def_args = split(",", $define_args);
5916c45dcabdSAndy Whitcroft			}
591708a2843eSJoe Perches
591862e15a6dSJoe Perches			$dstat =~ s/$;//g;
591908a2843eSJoe Perches			$dstat =~ s/\\\n.//g;
5920f59b64bfSJoe Perches			$dstat =~ s/^\s*//s;
5921f59b64bfSJoe Perches			$dstat =~ s/\s*$//s;
5922f59b64bfSJoe Perches
5923f59b64bfSJoe Perches			# Flatten any parentheses and braces
5924f59b64bfSJoe Perches			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
5925f59b64bfSJoe Perches			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
5926f59b64bfSJoe Perches			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5927f59b64bfSJoe Perches			{
59288c8c45cfSJoe Perches			}
5929f59b64bfSJoe Perches
5930f59b64bfSJoe Perches			# Flatten any obvious string concatenation.
5931f59b64bfSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5932292f1a9bSAndy Whitcroft			       $dstat =~ s/$Ident\s*($String)/$1/)
5933c45dcabdSAndy Whitcroft			{
5934c45dcabdSAndy Whitcroft			}
5935c45dcabdSAndy Whitcroft
5936c45dcabdSAndy Whitcroft			# Make asm volatile uses seem like a generic function
5937c45dcabdSAndy Whitcroft			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
59382e44e803SDwaipayan Ray
59392e44e803SDwaipayan Ray			my $exceptions = qr{
59402e44e803SDwaipayan Ray				$Declare|
5941bf30d6edSAndy Whitcroft				module_param_named|
5942c45dcabdSAndy Whitcroft				MODULE_PARM_DESC|
5943c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5944342d3d2fSAntonio Borneo				DEFINE_PER_CPU|
594533acb54aSJoe Perches				__typeof__\(|
594633acb54aSJoe Perches				union|
5947e45bab8eSAndy Whitcroft				struct|
5948e45bab8eSAndy Whitcroft				\.$Ident\s*=\s*|
5949e45bab8eSAndy Whitcroft				^\"|\"$|
595042e15293SJoe Perches				^\[
595142e15293SJoe Perches			}x;
595242e15293SJoe Perches			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5953c45dcabdSAndy Whitcroft
5954c45dcabdSAndy Whitcroft			$ctx =~ s/\n*$//;
5955c45dcabdSAndy Whitcroft			my $stmt_cnt = statement_rawlines($ctx);
5956a0a0a7a9SKees Cook			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5957c45dcabdSAndy Whitcroft
5958c45dcabdSAndy Whitcroft			if ($dstat ne '' &&
5959383099fdSAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
596022fd2d3eSStefani Seibold			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
596122fd2d3eSStefani Seibold			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5962ea71a0a0SAndy Whitcroft			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
59636b10df42SVladimir Zapolskiy			    $dstat !~ /$exceptions/ &&
59646b10df42SVladimir Zapolskiy			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5965c45dcabdSAndy Whitcroft			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
59665eaa20b9SAndy Whitcroft			    $dstat !~ /^case\b/ &&					# case ...
5967f59b64bfSJoe Perches			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
5968f59b64bfSJoe Perches			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5969f59b64bfSJoe Perches			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5970e3d95a2aSTobin C. Harding			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5971f59b64bfSJoe Perches			    $dstat !~ /^do\s*{/ &&					# do {...
5972f74bd194SAndy Whitcroft			    $dstat !~ /^\(\{/ &&						# ({...
5973f74bd194SAndy Whitcroft			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5974f74bd194SAndy Whitcroft			{
59753cc4b1c3SJoe Perches				if ($dstat =~ /^\s*if\b/) {
5976356fd398SJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5977f74bd194SAndy Whitcroft					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5978f74bd194SAndy Whitcroft				} elsif ($dstat =~ /;/) {
5979e942e2c3SJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5980dc3f4deeSStanislaw Gruszka					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
598172f115f9SAndy Whitcroft				} else {
59822e44e803SDwaipayan Ray					ERROR("COMPLEX_MACRO",
5983f74bd194SAndy Whitcroft					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5984f74bd194SAndy Whitcroft				}
5985f74bd194SAndy Whitcroft
59864e5d56bdSEddie Kovsky			}
5987f95a7e6aSJoe Perches
5988c45dcabdSAndy Whitcroft			# Make $define_stmt single line, comment-free, etc
5989e795556aSJoe Perches			my @stmt_array = split('\n', $define_stmt);
5990e795556aSJoe Perches			my $first = 1;
5991e795556aSJoe Perches			$define_stmt = "";
5992e795556aSJoe Perches			foreach my $l (@stmt_array) {
5993f74bd194SAndy Whitcroft				$l =~ s/\\$//;
5994f74bd194SAndy Whitcroft				if ($first) {
5995f74bd194SAndy Whitcroft					$define_stmt = $l;
5996000d1cc1SJoe Perches					$first = 0;
5997388982b5SAndrew Morton				} elsif ($l =~ /^[\+ ]/) {
5998d8aaf121SAndy Whitcroft					$define_stmt .= substr($l, 1);
5999f59b64bfSJoe Perches				}
6000f59b64bfSJoe Perches			}
60015207649bSJoe Perches			$define_stmt =~ s/$;//g;
60025207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
60035207649bSJoe Perches			$define_stmt = trim($define_stmt);
60045207649bSJoe Perches
60055207649bSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
60065207649bSJoe Perches			foreach my $arg (@def_args) {
60075207649bSJoe Perches			        next if ($arg =~ /\.\.\./);
60085207649bSJoe Perches			        next if ($arg =~ /^type$/i);
60095207649bSJoe Perches				my $tmp_stmt = $define_stmt;
60105207649bSJoe Perches				$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;
60115207649bSJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
60125207649bSJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
60135207649bSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
60145207649bSJoe Perches				if ($use_cnt > 1) {
60155207649bSJoe Perches					CHK("MACRO_ARG_REUSE",
60165207649bSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
60175207649bSJoe Perches				    }
60185207649bSJoe Perches# check if any macro arguments may have other precedence issues
6019f59b64bfSJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
6020f59b64bfSJoe Perches				    ((defined($1) && $1 ne ',') ||
6021f59b64bfSJoe Perches				     (defined($2) && $2 ne ','))) {
60229192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
60237fe528a2SJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
60247b844345SVincent Mailhol				}
60257fe528a2SJoe Perches
60267fe528a2SJoe Perches# check if this is an unused argument
6027d41362edSJoe Perches				if ($define_stmt !~ /\b$arg\b/) {
6028f59b64bfSJoe Perches					WARN("MACRO_ARG_UNUSED",
6029f59b64bfSJoe Perches					     "Argument '$arg' is not used in function-like macro\n" . "$herectx");
6030f59b64bfSJoe Perches				}
6031f59b64bfSJoe Perches			}
60329192d41aSJoe Perches
60337fe528a2SJoe Perches# check for macros with flow control, but without ## concatenation
60349192d41aSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
60359192d41aSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
60369192d41aSJoe Perches				my $cnt = statement_rawlines($ctx);
60379192d41aSJoe Perches				my $herectx = get_stat_here($linenr, $cnt, $here);
60389192d41aSJoe Perches
6039b1be5844SXining Xu				WARN("MACRO_WITH_FLOW_CONTROL",
6040b1be5844SXining Xu				     "Macros with flow control statements should be avoided\n" . "$herectx");
6041b1be5844SXining Xu			}
6042b1be5844SXining Xu
6043b1be5844SXining Xu# check for line continuations outside of #defines, preprocessor #, and asm
6044b1be5844SXining Xu
60450a920b5bSAndy Whitcroft		} elsif ($realfile =~ m@/vmlinux.lds.h$@) {
60465023d347SJoe Perches		    $line =~ s/(\w+)/$maybe_linker_symbol{$1}++/ge;
604708a2843eSJoe Perches		    #print "REAL: $realfile\nln: $line\nkeys:", sort keys %maybe_linker_symbol;
604808a2843eSJoe Perches		} else {
604908a2843eSJoe Perches			if ($prevline !~ /^..*\\$/ &&
605008a2843eSJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
6051e3d95a2aSTobin C. Harding			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
605208a2843eSJoe Perches			    $line =~ /^\+.*\\$/) {
605308a2843eSJoe Perches				WARN("LINE_CONTINUATIONS",
605408a2843eSJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
605508a2843eSJoe Perches			}
605608a2843eSJoe Perches		}
6057481eb486SJoe Perches
60585023d347SJoe Perches# do {} while (0) macro tests:
60595b2c7334SJim Cromie# single-statement macros do not need to be enclosed in do while (0) loop,
60605b2c7334SJim Cromie# macro should not end with a semicolon
60615b2c7334SJim Cromie		if ($perl_version_ok &&
60625023d347SJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
60635023d347SJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
6064481eb486SJoe Perches			my $ln = $linenr;
6065481eb486SJoe Perches			my $cnt = $realcnt;
60665023d347SJoe Perches			my ($off, $dstat, $dcond, $rest);
60675023d347SJoe Perches			my $ctx = '';
60685023d347SJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
60695023d347SJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
6070653d4876SAndy Whitcroft			$ctx = $dstat;
60710a920b5bSAndy Whitcroft
6072b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
6073b13edf7fSJoe Perches			$dstat =~ s/$;/ /g;
6074b13edf7fSJoe Perches
60755b57980dSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
6076b13edf7fSJoe Perches				my $stmts = $2;
6077b13edf7fSJoe Perches				my $semis = $3;
6078b13edf7fSJoe Perches
6079b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
6080b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
6081b13edf7fSJoe Perches				my $herectx = get_stat_here($linenr, $cnt, $here);
6082b13edf7fSJoe Perches
6083b13edf7fSJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
6084b13edf7fSJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
6085b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
6086b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
60871b36b201SJoe Perches				}
6088b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
6089b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
6090b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
6091b13edf7fSJoe Perches				}
6092b13edf7fSJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
6093b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
6094b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
6095e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6096b13edf7fSJoe Perches
6097ac8e97f8SJoe Perches				WARN("TRAILING_SEMICOLON",
6098ac8e97f8SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
6099b13edf7fSJoe Perches			}
6100b13edf7fSJoe Perches		}
6101b13edf7fSJoe Perches
6102b13edf7fSJoe Perches# check for redundant bracing round if etc
6103b13edf7fSJoe Perches		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
6104b13edf7fSJoe Perches			my ($level, $endln, @chunks) =
6105b13edf7fSJoe Perches				ctx_statement_full($linenr, $realcnt, 1);
6106f5ef95b1SJoe Perches			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
6107f5ef95b1SJoe Perches			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
6108f5ef95b1SJoe Perches			if ($#chunks > 0 && $level == 0) {
6109e3d95a2aSTobin C. Harding				my @allowed = ();
6110f5ef95b1SJoe Perches				my $allow = 0;
6111f5ef95b1SJoe Perches				my $seen = 0;
6112f5ef95b1SJoe Perches				my $herectx = $here . "\n";
6113b13edf7fSJoe Perches				my $ln = $linenr - 1;
6114b13edf7fSJoe Perches				for my $chunk (@chunks) {
6115b13edf7fSJoe Perches					my ($cond, $block) = @{$chunk};
6116f0a594c1SAndy Whitcroft
611713214adfSAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
611813214adfSAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
6119cf655043SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
612013214adfSAndy Whitcroft
6121cf655043SAndy Whitcroft					$allowed[$allow] = 0;
6122cf655043SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
6123aad4f614SJoe Perches
6124aad4f614SJoe Perches					# We have looked at and allowed this specific line.
612513214adfSAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
6126773647a0SAndy Whitcroft
6127cf655043SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
612813214adfSAndy Whitcroft					$ln += statement_rawlines($block) - 1;
612913214adfSAndy Whitcroft
613013214adfSAndy Whitcroft					substr($block, 0, length($cond), '');
6131773647a0SAndy Whitcroft
6132773647a0SAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
6133773647a0SAndy Whitcroft
6134773647a0SAndy Whitcroft					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
6135aad4f614SJoe Perches					if (statement_lines($cond) > 1) {
6136773647a0SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
6137773647a0SAndy Whitcroft						$allowed[$allow] = 1;
6138773647a0SAndy Whitcroft					}
6139773647a0SAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
6140773647a0SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
6141773647a0SAndy Whitcroft						$allowed[$allow] = 1;
6142cf655043SAndy Whitcroft					}
6143cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
6144773647a0SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
614513214adfSAndy Whitcroft						$allowed[$allow] = 1;
614613214adfSAndy Whitcroft					}
614713214adfSAndy Whitcroft					$allow++;
6148aad4f614SJoe Perches				}
6149cf655043SAndy Whitcroft				if ($seen) {
6150cf655043SAndy Whitcroft					my $sum_allowed = 0;
6151aad4f614SJoe Perches					foreach (@allowed) {
615213214adfSAndy Whitcroft						$sum_allowed += $_;
615313214adfSAndy Whitcroft					}
6154cf655043SAndy Whitcroft					if ($sum_allowed == 0) {
6155aad4f614SJoe Perches						WARN("BRACES",
615613214adfSAndy Whitcroft						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
6157cf655043SAndy Whitcroft					} elsif ($sum_allowed != $allow &&
6158cf655043SAndy Whitcroft						 $seen != $allow) {
6159aad4f614SJoe Perches						CHK("BRACES",
616013214adfSAndy Whitcroft						    "braces {} should be used on all arms of this statement\n" . $herectx);
6161aad4f614SJoe Perches					}
616213214adfSAndy Whitcroft				}
6163aad4f614SJoe Perches			}
6164aad4f614SJoe Perches		}
6165aad4f614SJoe Perches		if (!defined $suppress_ifbraces{$linenr - 1} &&
6166aad4f614SJoe Perches					$line =~ /\b(if|while|for|else)\b/) {
6167aad4f614SJoe Perches			my $allowed = 0;
6168aad4f614SJoe Perches
6169000d1cc1SJoe Perches			# Check the pre-context.
6170000d1cc1SJoe Perches			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6171aad4f614SJoe Perches				#print "APW: ALLOWED: pre<$1>\n";
6172aad4f614SJoe Perches				$allowed = 1;
6173aad4f614SJoe Perches			}
6174aad4f614SJoe Perches
6175aad4f614SJoe Perches			my ($level, $endln, @chunks) =
617613214adfSAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
617713214adfSAndy Whitcroft
617813214adfSAndy Whitcroft			# Check the condition.
6179773647a0SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
618013214adfSAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
6181cf655043SAndy Whitcroft			if (defined $cond) {
6182f0a594c1SAndy Whitcroft				substr($block, 0, length($cond), '');
6183cf655043SAndy Whitcroft			}
6184cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
6185cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
6186cf655043SAndy Whitcroft				$allowed = 1;
6187f0a594c1SAndy Whitcroft			}
6188773647a0SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
6189773647a0SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
6190773647a0SAndy Whitcroft				$allowed = 1;
6191773647a0SAndy Whitcroft			}
6192cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
6193cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
6194773647a0SAndy Whitcroft				$allowed = 1;
6195cf655043SAndy Whitcroft			}
6196773647a0SAndy Whitcroft			# Check the post-context.
6197cf655043SAndy Whitcroft			if (defined $chunks[1]) {
6198cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
6199cf655043SAndy Whitcroft				if (defined $cond) {
6200cf655043SAndy Whitcroft					substr($block, 0, length($cond), '');
6201cf655043SAndy Whitcroft				}
6202cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
6203cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6204cf655043SAndy Whitcroft					$allowed = 1;
6205cf655043SAndy Whitcroft				}
6206cf655043SAndy Whitcroft			}
6207cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6208cf655043SAndy Whitcroft				my $cnt = statement_rawlines($block);
6209cf655043SAndy Whitcroft				my $herectx = get_stat_here($linenr, $cnt, $here);
6210cf655043SAndy Whitcroft
6211cf655043SAndy Whitcroft				WARN("BRACES",
6212cf655043SAndy Whitcroft				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6213cf655043SAndy Whitcroft			}
6214773647a0SAndy Whitcroft		}
6215cf655043SAndy Whitcroft
6216cf655043SAndy Whitcroft# check for single line unbalanced braces
6217cf655043SAndy Whitcroft		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
6218cf655043SAndy Whitcroft		    $sline =~ /^.\s*else\s*\{\s*$/) {
6219cf655043SAndy Whitcroft			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6220cf655043SAndy Whitcroft		}
6221cf655043SAndy Whitcroft
6222f055663cSAndy Whitcroft# check for unnecessary blank lines around braces
6223e3d95a2aSTobin C. Harding		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6224cf655043SAndy Whitcroft			if (CHK("BRACES",
6225000d1cc1SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6226000d1cc1SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
6227f0a594c1SAndy Whitcroft				fix_delete_line($fixlinenr - 1, $prevrawline);
6228f0a594c1SAndy Whitcroft			}
6229f0a594c1SAndy Whitcroft		}
6230e4c5babdSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
623195330473SSven Eckelmann			if (CHK("BRACES",
623295330473SSven Eckelmann				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6233e4c5babdSJoe Perches			    $fix) {
6234e4c5babdSJoe Perches				fix_delete_line($fixlinenr, $rawline);
6235e4c5babdSJoe Perches			}
62360979ae66SJoe Perches		}
623777b9a53aSJoe Perches
6238f8e58219SJoe Perches# no volatiles please
6239f8e58219SJoe Perches		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
6240f8e58219SJoe Perches		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6241f8e58219SJoe Perches			WARN("VOLATILE",
6242f8e58219SJoe Perches			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
62430979ae66SJoe Perches		}
624477b9a53aSJoe Perches
6245f8e58219SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
6246f8e58219SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
6247f8e58219SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
6248f8e58219SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
6249f8e58219SJoe Perches		if ($line =~ /^\+\s*$String/ &&
62500979ae66SJoe Perches		    $prevline =~ /"\s*$/ &&
62510979ae66SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
62524a0df2efSAndy Whitcroft			if (WARN("SPLIT_STRING",
62536c72ffaaSAndy Whitcroft				 "quoted string split across lines\n" . $hereprev) &&
62546c72ffaaSAndy Whitcroft				     $fix &&
6255000d1cc1SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
62568c27ceffSMauro Carvalho Chehab				     $last_coalesced_string_linenr != $linenr - 1) {
62574a0df2efSAndy Whitcroft				my $extracted_string = get_quoted_string($line, $rawline);
62584a0df2efSAndy Whitcroft				my $comma_close = "";
62595e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
62605e4f6ba5SJoe Perches					$comma_close = $1;
62615e4f6ba5SJoe Perches				}
62625e4f6ba5SJoe Perches
626333acb54aSJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
62645e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
62655e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
62665e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
62675e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
62685e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
62695e4f6ba5SJoe Perches				$fixedline = $rawline;
62705e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
62715e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
62725e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
62735e4f6ba5SJoe Perches				}
62745e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
62755e4f6ba5SJoe Perches			}
62765e4f6ba5SJoe Perches		}
62775e4f6ba5SJoe Perches
62785e4f6ba5SJoe Perches# check for missing a space in a string concatenation
62795e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
62805e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
62815e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
62825e4f6ba5SJoe Perches		}
62835e4f6ba5SJoe Perches
62845e4f6ba5SJoe Perches# check for an embedded function name in a string when the function is known
62855e4f6ba5SJoe Perches# This does not work very well for -f --file checking as it depends on patch
62865e4f6ba5SJoe Perches# context providing the function name or a single line form for in-file
62875e4f6ba5SJoe Perches# function declarations
62885e4f6ba5SJoe Perches		if ($line =~ /^\+.*$String/ &&
62895e4f6ba5SJoe Perches		    defined($context_function) &&
62905e4f6ba5SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
62915e4f6ba5SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
62925e4f6ba5SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
62935e4f6ba5SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
62945e4f6ba5SJoe Perches		}
62955e4f6ba5SJoe Perches
62965e4f6ba5SJoe Perches# check for unnecessary function tracing like uses
62975e4f6ba5SJoe Perches# This does not use $logFunctions because there are many instances like
629877cb8546SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6299e4b7d309SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6300e4b7d309SJoe Perches			if (WARN("TRACING_LOGGING",
6301e4b7d309SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
630277cb8546SJoe Perches			    $fix) {
630377cb8546SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6304e4b7d309SJoe Perches			}
6305e4b7d309SJoe Perches		}
630677cb8546SJoe Perches
6307e4b7d309SJoe Perches# check for spaces before a quoted newline
630877cb8546SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
630977cb8546SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
6310adb2da82SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
6311adb2da82SJoe Perches			    $fix) {
6312adb2da82SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
6313adb2da82SJoe Perches			}
6314adb2da82SJoe Perches
6315adb2da82SJoe Perches		}
6316adb2da82SJoe Perches
6317adb2da82SJoe Perches# concatenated string without spaces between elements
6318adb2da82SJoe Perches		if ($line =~ /$String[A-Z_]/ ||
6319adb2da82SJoe Perches		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
6320adb2da82SJoe Perches			if (CHK("CONCATENATED_STRING",
63215e4f6ba5SJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
63225e4f6ba5SJoe Perches			    $fix) {
63235e4f6ba5SJoe Perches				while ($line =~ /($String)/g) {
63245e4f6ba5SJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
63255e4f6ba5SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
63265e4f6ba5SJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
63275e4f6ba5SJoe Perches				}
63285e4f6ba5SJoe Perches			}
63295e4f6ba5SJoe Perches		}
63305e4f6ba5SJoe Perches
6331f17dba4fSJoe Perches# uncoalesced string fragments
6332d2af5aa6SJoe Perches		if ($line =~ /$String\s*[Lu]?"/) {
6333d2af5aa6SJoe Perches			if (WARN("STRING_FRAGMENTS",
633479682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
633579682c0cSJoe Perches			    $fix) {
633679682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
633779682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
633879682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
633979682c0cSJoe Perches				}
634079682c0cSJoe Perches			}
634179682c0cSJoe Perches		}
634279682c0cSJoe Perches
6343f17dba4fSJoe Perches# check for non-standard and hex prefixed decimal printf formats
6344f17dba4fSJoe Perches		my $show_L = 1;	#don't show the same defect twice
634590ad30e5SJoe Perches		my $show_Z = 1;
6346d2af5aa6SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
634779682c0cSJoe Perches			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
634879682c0cSJoe Perches			$string =~ s/%%/__/g;
634979682c0cSJoe Perches			# check for %L
635079682c0cSJoe Perches			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
635179682c0cSJoe Perches				WARN("PRINTF_L",
635279682c0cSJoe Perches				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
635379682c0cSJoe Perches				$show_L = 0;
635479682c0cSJoe Perches			}
635590ad30e5SJoe Perches			# check for %Z
635690ad30e5SJoe Perches			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6357522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6358522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6359522b837cSAlexey Dobriyan				$show_Z = 0;
63605e4f6ba5SJoe Perches			}
6361522b837cSAlexey Dobriyan			# check for 0x<decimal>
63625e4f6ba5SJoe Perches			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6363522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
6364522b837cSAlexey Dobriyan				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
63655e4f6ba5SJoe Perches			}
6366522b837cSAlexey Dobriyan		}
6367522b837cSAlexey Dobriyan
63685e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
6369522b837cSAlexey Dobriyan		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
6370522b837cSAlexey Dobriyan			WARN("LINE_CONTINUATIONS",
6371522b837cSAlexey Dobriyan			     "Avoid line continuations in quoted strings\n" . $herecurr);
6372522b837cSAlexey Dobriyan		}
6373522b837cSAlexey Dobriyan
6374522b837cSAlexey Dobriyan# warn about #if 0
6375522b837cSAlexey Dobriyan		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
6376522b837cSAlexey Dobriyan			WARN("IF_0",
6377522b837cSAlexey Dobriyan			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
63786e300757SJoe Perches		}
63796e300757SJoe Perches
63805e4f6ba5SJoe Perches# warn about #if 1
63815e4f6ba5SJoe Perches		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
63825e4f6ba5SJoe Perches			WARN("IF_1",
63833f7f335dSJoe Perches			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
63845e4f6ba5SJoe Perches		}
63855e4f6ba5SJoe Perches
63865e4f6ba5SJoe Perches# check for needless "if (<foo>) fn(<foo>)" uses
63875e4f6ba5SJoe Perches		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
638800df344fSAndy Whitcroft			my $tested = quotemeta($1);
6389c45dcabdSAndy Whitcroft			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
639060f89010SPrakruthi Deepak Heragu			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
639160f89010SPrakruthi Deepak Heragu				my $func = $1;
639260f89010SPrakruthi Deepak Heragu				if (WARN('NEEDLESS_IF',
639360f89010SPrakruthi Deepak Heragu					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
639460f89010SPrakruthi Deepak Heragu				    $fix) {
639560f89010SPrakruthi Deepak Heragu					my $do_fix = 1;
639660f89010SPrakruthi Deepak Heragu					my $leading_tabs = "";
639760f89010SPrakruthi Deepak Heragu					my $new_leading_tabs = "";
63984a0df2efSAndy Whitcroft					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
63994a0df2efSAndy Whitcroft						$leading_tabs = $1;
640003df4b51SAndy Whitcroft					} else {
640103df4b51SAndy Whitcroft						$do_fix = 0;
6402100425deSJoe Perches					}
6403100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6404100425deSJoe Perches						$new_leading_tabs = $1;
6405100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6406100425deSJoe Perches							$do_fix = 0;
6407100425deSJoe Perches						}
6408100425deSJoe Perches					} else {
6409100425deSJoe Perches						$do_fix = 0;
6410100425deSJoe Perches					}
6411100425deSJoe Perches					if ($do_fix) {
6412100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6413100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6414100425deSJoe Perches					}
6415100425deSJoe Perches				}
6416100425deSJoe Perches			}
6417100425deSJoe Perches		}
6418100425deSJoe Perches
6419100425deSJoe Perches# check for unnecessary "Out of Memory" messages
6420100425deSJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6421100425deSJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6422100425deSJoe Perches		    (defined $1 || defined $3) &&
6423100425deSJoe Perches		    $linenr > 3) {
6424100425deSJoe Perches			my $testval = $2;
6425100425deSJoe Perches			my $testline = $lines[$linenr - 3];
6426100425deSJoe Perches
6427100425deSJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6428100425deSJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6429100425deSJoe Perches
64304c432a8fSGreg Kroah-Hartman			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
64314c432a8fSGreg Kroah-Hartman			    $s !~ /\b__GFP_NOWARN\b/ ) {
6432f0a594c1SAndy Whitcroft				WARN("OOM_MESSAGE",
6433ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6434ebfdc409SJoe Perches			}
6435ebfdc409SJoe Perches		}
6436ebfdc409SJoe Perches
6437ebfdc409SJoe Perches# check for logging functions with KERN_<LEVEL>
6438ebfdc409SJoe Perches		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6439ebfdc409SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6440ebfdc409SJoe Perches			my $level = $1;
6441ebfdc409SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6442ebfdc409SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6443ebfdc409SJoe Perches			    $fix) {
6444e29a70f1SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6445e29a70f1SJoe Perches			}
6446ebfdc409SJoe Perches		}
6447ebfdc409SJoe Perches
6448ebfdc409SJoe Perches# check for logging continuations
6449ebfdc409SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
6450ebfdc409SJoe Perches			WARN("LOGGING_CONTINUATION",
6451f78d98f6SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
6452dcaf1123SPaolo Bonzini		}
6453f78d98f6SJoe Perches
6454f78d98f6SJoe Perches# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
6455f78d98f6SJoe Perches		if (defined $stat &&
6456f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(/ &&
6457f78d98f6SJoe Perches		    index($stat, '"') >= 0) {
6458f78d98f6SJoe Perches			my $lc = $stat =~ tr@\n@@;
6459f78d98f6SJoe Perches			$lc = $lc + $linenr;
6460f78d98f6SJoe Perches			my $stat_real = get_stat_real($linenr, $lc);
6461f78d98f6SJoe Perches			pos($stat_real) = index($stat_real, '"');
646245c55e92SJoe Perches			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
646345c55e92SJoe Perches				my $pspec = $1;
646445c55e92SJoe Perches				my $h = $2;
646545c55e92SJoe Perches				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
646645c55e92SJoe Perches				if (WARN("UNNECESSARY_MODIFIER",
646745c55e92SJoe Perches					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
646870eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
646970eb2275SDwaipayan Ray					my $nspec = $pspec;
647070eb2275SDwaipayan Ray					$nspec =~ s/h//g;
647170eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
647270eb2275SDwaipayan Ray				}
647370eb2275SDwaipayan Ray			}
647470eb2275SDwaipayan Ray		}
647570eb2275SDwaipayan Ray
647670eb2275SDwaipayan Ray# check for mask then right shift without a parentheses
647770eb2275SDwaipayan Ray		if ($perl_version_ok &&
647870eb2275SDwaipayan Ray		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
647970eb2275SDwaipayan Ray		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
648070eb2275SDwaipayan Ray			WARN("MASK_THEN_SHIFT",
648170eb2275SDwaipayan Ray			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
648270eb2275SDwaipayan Ray		}
648370eb2275SDwaipayan Ray
648470eb2275SDwaipayan Ray# check for pointer comparisons to NULL
648570eb2275SDwaipayan Ray		if ($perl_version_ok) {
648670eb2275SDwaipayan Ray			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
648770eb2275SDwaipayan Ray				my $val = $1;
648870eb2275SDwaipayan Ray				my $equal = "!";
648970eb2275SDwaipayan Ray				$equal = "" if ($4 eq "!=");
6490abb08a53SJoe Perches				if (CHK("COMPARISON_TO_NULL",
64915b57980dSJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6492abb08a53SJoe Perches					    $fix) {
6493abb08a53SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6494abb08a53SJoe Perches				}
6495abb08a53SJoe Perches			}
6496abb08a53SJoe Perches		}
6497abb08a53SJoe Perches
6498b75ac618SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
64995b57980dSJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
6500b75ac618SJoe Perches			my $attr = $1;
6501b75ac618SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
6502b75ac618SJoe Perches				my $ptr = $1;
6503b75ac618SJoe Perches				my $var = $2;
6504b75ac618SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
6505b75ac618SJoe Perches				      ERROR("MISPLACED_INIT",
6506b75ac618SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
6507b75ac618SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
6508b75ac618SJoe Perches				      WARN("MISPLACED_INIT",
6509b75ac618SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
6510b75ac618SJoe Perches				    $fix) {
6511b75ac618SJoe 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;
65128716de38SJoe Perches				}
65138716de38SJoe Perches			}
65148716de38SJoe Perches		}
65158716de38SJoe Perches
65168716de38SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
65178716de38SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
65188716de38SJoe Perches			my $attr = $1;
65198716de38SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
65208716de38SJoe Perches			my $attr_prefix = $1;
65218716de38SJoe Perches			my $attr_type = $2;
65228716de38SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
65238716de38SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
65248716de38SJoe Perches			    $fix) {
6525194f66fcSJoe Perches				$fixed[$fixlinenr] =~
65268716de38SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
65278716de38SJoe Perches			}
65288716de38SJoe Perches		}
65298716de38SJoe Perches
6530e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6531e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6532e970b884SJoe Perches			my $attr = $1;
6533e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6534e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6535e970b884SJoe Perches			    $fix) {
6536e970b884SJoe Perches				my $lead = $fixed[$fixlinenr] =~
6537e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6538e970b884SJoe Perches				$lead = rtrim($1);
6539194f66fcSJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6540e970b884SJoe Perches				$lead = "${lead}const ";
6541e970b884SJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6542e970b884SJoe Perches			}
6543e970b884SJoe Perches		}
6544e970b884SJoe Perches
6545e970b884SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6546e970b884SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6547e970b884SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6548e970b884SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6549e970b884SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6550194f66fcSJoe Perches			    $fix) {
6551e970b884SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6552e970b884SJoe Perches			}
6553e970b884SJoe Perches		}
6554e970b884SJoe Perches
6555194f66fcSJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6556e970b884SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6557e970b884SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6558e970b884SJoe Perches			my $constant_func = $1;
6559c17893c7SJoe Perches			my $func = $constant_func;
6560c17893c7SJoe Perches			$func =~ s/^__constant_//;
6561c17893c7SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6562c17893c7SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6563c17893c7SJoe Perches			    $fix) {
6564c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6565c17893c7SJoe Perches			}
6566c17893c7SJoe Perches		}
6567c17893c7SJoe Perches
6568c17893c7SJoe Perches# prefer usleep_range over udelay
6569fbdb8138SJoe Perches		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
6570fbdb8138SJoe Perches			my $delay = $1;
6571fbdb8138SJoe Perches			# ignore udelay's < 10, however
6572fbdb8138SJoe Perches			if (! ($delay < 10) ) {
6573fbdb8138SJoe Perches				CHK("USLEEP_RANGE",
6574fbdb8138SJoe Perches				    "usleep_range is preferred over udelay; see function description of usleep_range() and udelay().\n" . $herecurr);
6575fbdb8138SJoe Perches			}
6576fbdb8138SJoe Perches			if ($delay > 2000) {
6577fbdb8138SJoe Perches				WARN("LONG_UDELAY",
6578194f66fcSJoe Perches				     "long udelay - prefer mdelay; see function description of mdelay().\n" . $herecurr);
6579fbdb8138SJoe Perches			}
6580fbdb8138SJoe Perches		}
6581fbdb8138SJoe Perches
65821a15a250SPatrick Pannuto# warn about unexpectedly long msleep's
658337581c28SBruce Allan		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
658443c1d77cSJoe Perches			if ($1 < 20) {
65851a15a250SPatrick Pannuto				WARN("MSLEEP",
658643c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see function description of msleep().\n" . $herecurr);
6587000d1cc1SJoe Perches			}
65886534086aSAnna-Maria Behnsen		}
658943c1d77cSJoe Perches
659043c1d77cSJoe Perches# check for comparisons of jiffies
659143c1d77cSJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
65926534086aSAnna-Maria Behnsen			WARN("JIFFIES_COMPARISON",
65931a15a250SPatrick Pannuto			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
65941a15a250SPatrick Pannuto		}
65951a15a250SPatrick Pannuto
659609ef8725SPatrick Pannuto# check for comparisons of get_jiffies_64()
659709ef8725SPatrick Pannuto		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
659809ef8725SPatrick Pannuto			WARN("JIFFIES_COMPARISON",
6599000d1cc1SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
66006534086aSAnna-Maria Behnsen		}
660109ef8725SPatrick Pannuto
660209ef8725SPatrick Pannuto# warn about #ifdefs in C files
660309ef8725SPatrick Pannuto#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
660436ec1939SJoe Perches#			print "#ifdef in C files should be avoided\n";
660536ec1939SJoe Perches#			print "$herecurr";
660636ec1939SJoe Perches#			$clean = 0;
660736ec1939SJoe Perches#		}
660836ec1939SJoe Perches
660936ec1939SJoe Perches# warn about spacing in #ifdefs
66109d7a34a5SJoe Perches		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
66119d7a34a5SJoe Perches			if (ERROR("SPACING",
66129d7a34a5SJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
66139d7a34a5SJoe Perches			    $fix) {
66149d7a34a5SJoe Perches				$fixed[$fixlinenr] =~
66159d7a34a5SJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
661600df344fSAndy Whitcroft			}
6617c45dcabdSAndy Whitcroft
661800df344fSAndy Whitcroft		}
661900df344fSAndy Whitcroft
662000df344fSAndy Whitcroft# check for spinlock_t definitions without a comment.
662100df344fSAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
662200df344fSAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
662322f2a2efSAndy Whitcroft			my $which = $1;
6624c45dcabdSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
66253705ce5bSJoe Perches				CHK("UNCOMMENTED_DEFINITION",
66263705ce5bSJoe Perches				    "$1 definition without comment\n" . $herecurr);
66273705ce5bSJoe Perches			}
6628194f66fcSJoe Perches		}
66293705ce5bSJoe Perches# check for memory barriers without a comment.
66303705ce5bSJoe Perches
66313705ce5bSJoe Perches		my $barriers = qr{
663222f2a2efSAndy Whitcroft			mb|
663322f2a2efSAndy Whitcroft			rmb|
66344a0df2efSAndy Whitcroft			wmb
6635171ae1a4SAndy Whitcroft		}x;
6636171ae1a4SAndy Whitcroft		my $barrier_stems = qr{
66374a0df2efSAndy Whitcroft			mb__before_atomic|
66384a0df2efSAndy Whitcroft			mb__after_atomic|
6639000d1cc1SJoe Perches			store_release|
6640000d1cc1SJoe Perches			load_acquire|
66414a0df2efSAndy Whitcroft			store_mb|
66424a0df2efSAndy Whitcroft			(?:$barriers)
66434a0df2efSAndy Whitcroft		}x;
6644402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6645402c2553SMichael S. Tsirkin			(?:$barriers)|
6646402c2553SMichael S. Tsirkin			smp_(?:$barrier_stems)|
6647402c2553SMichael S. Tsirkin			virt_(?:$barrier_stems)
6648ad83ec6cSWill Deacon		}x;
6649402c2553SMichael S. Tsirkin
6650402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
6651402c2553SMichael S. Tsirkin			if (!ctx_has_comment($first_line, $linenr)) {
6652402c2553SMichael S. Tsirkin				WARN("MEMORY_BARRIER",
6653402c2553SMichael S. Tsirkin				     "memory barrier without comment\n" . $herecurr);
6654402c2553SMichael S. Tsirkin			}
6655402c2553SMichael S. Tsirkin		}
6656402c2553SMichael S. Tsirkin
6657402c2553SMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6658402c2553SMichael S. Tsirkin
6659402c2553SMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
666043e361f2SMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
666143e361f2SMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6662402c2553SMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6663402c2553SMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6664402c2553SMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
66654a0df2efSAndy Whitcroft		}
6666c1fd7bb9SJoe Perches
6667000d1cc1SJoe Perches# check for waitqueue_active without a comment.
66684a0df2efSAndy Whitcroft		if ($line =~ /\bwaitqueue_active\s*\(/) {
66694a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
66703ad81779SPaul E. McKenney				WARN("WAITQUEUE_ACTIVE",
6671f4073b0fSMichael S. Tsirkin				     "waitqueue_active without comment\n" . $herecurr);
6672f4073b0fSMichael S. Tsirkin			}
6673f4073b0fSMichael S. Tsirkin		}
6674f4073b0fSMichael S. Tsirkin
6675f4073b0fSMichael S. Tsirkin# check for data_race without a comment.
6676f4073b0fSMichael S. Tsirkin		if ($line =~ /\bdata_race\s*\(/) {
6677f4073b0fSMichael S. Tsirkin			if (!ctx_has_comment($first_line, $linenr)) {
6678f4073b0fSMichael S. Tsirkin				WARN("DATA_RACE",
6679f4073b0fSMichael S. Tsirkin				     "data_race without comment\n" . $herecurr);
6680f4073b0fSMichael S. Tsirkin			}
6681cb426e99SJoe Perches		}
6682cb426e99SJoe Perches
6683cb426e99SJoe Perches# check of hardware specific defines
6684cb426e99SJoe Perches		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6685cb426e99SJoe Perches			CHK("ARCH_DEFINES",
6686cb426e99SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
6687cb426e99SJoe Perches		}
66883ad81779SPaul E. McKenney
66895099a722SMarco Elver# check that the storage class is not after a type
66905099a722SMarco Elver		if ($line =~ /\b($Type)\s+($Storage)\b/) {
66915099a722SMarco Elver			WARN("STORAGE_CLASS",
66925099a722SMarco Elver			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
66935099a722SMarco Elver		}
66945099a722SMarco Elver# Check that the storage class is at the beginning of a declaration
66955099a722SMarco Elver		if ($line =~ /\b$Storage\b/ &&
66965099a722SMarco Elver		    $line !~ /^.\s*$Storage/ &&
66974a0df2efSAndy Whitcroft		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6698c45dcabdSAndy Whitcroft		    $1 !~ /[\,\)]\s*$/) {
6699000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6700000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
67010a920b5bSAndy Whitcroft		}
6702653d4876SAndy Whitcroft
6703596ed45bSJoe Perches# check the location of the inline attribute, that it is between
6704596ed45bSJoe Perches# storage class and type.
6705000d1cc1SJoe Perches		if ($line =~ /\b$Type\s+$Inline\b/ ||
6706596ed45bSJoe Perches		    $line =~ /\b$Inline\s+$Storage\b/) {
6707596ed45bSJoe Perches			ERROR("INLINE_LOCATION",
6708596ed45bSJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6709596ed45bSJoe Perches		}
6710596ed45bSJoe Perches
6711596ed45bSJoe Perches# Check for __inline__ and __inline, prefer inline
6712596ed45bSJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6713596ed45bSJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6714596ed45bSJoe Perches			if (WARN("INLINE",
6715d4977c78STobias Klauser				 "plain inline is preferred over $1\n" . $herecurr) &&
6716d4977c78STobias Klauser			    $fix) {
6717de7d4f0eSAndy Whitcroft				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6718de7d4f0eSAndy Whitcroft
67199c0ca6f9SAndy Whitcroft			}
67209c0ca6f9SAndy Whitcroft		}
6721000d1cc1SJoe Perches
6722000d1cc1SJoe Perches# Check for compiler attributes
6723de7d4f0eSAndy Whitcroft		if ($realfile !~ m@\binclude/uapi/@ &&
6724de7d4f0eSAndy Whitcroft		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
67258905a67cSAndy Whitcroft			my $attr = $1;
67262b7ab453SJoe Perches			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
67272b7ab453SJoe Perches
6728d5e616fcSJoe Perches			my %attr_list = (
6729d5e616fcSJoe Perches				"alias"				=> "__alias",
6730d5e616fcSJoe Perches				"aligned"			=> "__aligned",
6731194f66fcSJoe Perches				"always_inline"			=> "__always_inline",
6732d5e616fcSJoe Perches				"assume_aligned"		=> "__assume_aligned",
6733d5e616fcSJoe Perches				"cold"				=> "__cold",
67348905a67cSAndy Whitcroft				"const"				=> "__attribute_const__",
67358905a67cSAndy Whitcroft				"copy"				=> "__copy",
67367ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
67372b7ab453SJoe Perches				"externally_visible"		=> "__visible",
67387ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
67397ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
67407ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
67417ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
67427ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
67430830aab0SJoe Perches				"noclone"			=> "__noclone",
67447ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
67457ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
67467ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
67477ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
67487ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
67497ebe1d17SDwaipayan Ray				"section"			=> "__section",
67507ebe1d17SDwaipayan Ray				"used"				=> "__used",
67517ebe1d17SDwaipayan Ray				"weak"				=> "__weak"
67527ebe1d17SDwaipayan Ray			);
67537ebe1d17SDwaipayan Ray
67547ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
67557ebe1d17SDwaipayan Ray				my $orig_attr = $1;
67567ebe1d17SDwaipayan Ray				my $params = '';
67577ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
67587ebe1d17SDwaipayan Ray				my $curr_attr = $orig_attr;
67597ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
67607ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
67617ebe1d17SDwaipayan Ray					my $new = $attr_list{$curr_attr};
67627ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
6763339f29d9SJoe Perches						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
67640830aab0SJoe Perches						$new = "__$1\($2";
67650830aab0SJoe Perches					} else {
67667ebe1d17SDwaipayan Ray						$new = "$new$params";
67677ebe1d17SDwaipayan Ray					}
67687ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6769339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
67707ebe1d17SDwaipayan Ray					    $fix) {
67717ebe1d17SDwaipayan Ray						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6772339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
67737ebe1d17SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
67747ebe1d17SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6775339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
67767ebe1d17SDwaipayan Ray					}
67777ebe1d17SDwaipayan Ray				}
6778339f29d9SJoe Perches			}
67797ebe1d17SDwaipayan Ray
6780339f29d9SJoe Perches			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
67817ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
67827ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6783339f29d9SJoe Perches				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
67847ebe1d17SDwaipayan Ray			}
6785339f29d9SJoe Perches		}
6786339f29d9SJoe Perches
6787339f29d9SJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
6788339f29d9SJoe Perches		if ($perl_version_ok &&
6789339f29d9SJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
67907ebe1d17SDwaipayan Ray		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
679139b7e287SJoe Perches		     $line =~ /\b__weak\b/)) {
6792462811d9SJoe Perches			ERROR("WEAK_DECLARATION",
6793462811d9SJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
67947ebe1d17SDwaipayan Ray		}
67957ebe1d17SDwaipayan Ray
67967ebe1d17SDwaipayan Ray# check for c99 types like uint8_t used outside of uapi/ and tools/
67977ebe1d17SDwaipayan Ray		if ($realfile !~ m@\binclude/uapi/@ &&
6798d5e616fcSJoe Perches		    $realfile !~ m@\btools/@ &&
67996061d949SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
68006061d949SJoe Perches			my $type = $1;
6801619a908aSJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
68025b57980dSJoe Perches				$type = $1;
6803619a908aSJoe Perches				my $kernel_type = 'u';
6804619a908aSJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6805619a908aSJoe Perches				$type =~ /(\d+)/;
6806619a908aSJoe Perches				$kernel_type .= $1;
6807619a908aSJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6808619a908aSJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6809619a908aSJoe Perches				    $fix) {
6810fd39f904STomas Winkler					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6811e6176fa4SJoe Perches				}
6812fd39f904STomas Winkler			}
6813e6176fa4SJoe Perches		}
6814e6176fa4SJoe Perches
6815e6176fa4SJoe Perches# check for cast of C90 native int or longer types constants
6816e6176fa4SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6817e6176fa4SJoe Perches			my $cast = $1;
6818e6176fa4SJoe Perches			my $const = $2;
6819e6176fa4SJoe Perches			my $suffix = "";
6820e6176fa4SJoe Perches			my $newconst = $const;
6821e6176fa4SJoe Perches			$newconst =~ s/${Int_type}$//;
6822e6176fa4SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6823e6176fa4SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6824e6176fa4SJoe Perches			    $suffix .= 'LL';
6825e6176fa4SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6826e6176fa4SJoe Perches			    $suffix .= 'L';
6827e6176fa4SJoe Perches			}
6828e6176fa4SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
6829938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
6830938224b5SJoe Perches			    $fix) {
6831938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6832938224b5SJoe Perches			}
6833938224b5SJoe Perches		}
6834938224b5SJoe Perches
6835938224b5SJoe Perches# check for sizeof(&)
6836938224b5SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6837938224b5SJoe Perches			WARN("SIZEOF_ADDRESS",
6838938224b5SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
6839938224b5SJoe Perches		}
6840938224b5SJoe Perches
6841938224b5SJoe Perches# check for sizeof without parenthesis
68420972b8bfSJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
68430972b8bfSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
68440972b8bfSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6845938224b5SJoe Perches			    $fix) {
6846938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6847938224b5SJoe Perches			}
6848938224b5SJoe Perches		}
68498f53a9b8SJoe Perches
68508f53a9b8SJoe Perches# check for struct spinlock declarations
6851000d1cc1SJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
6852000d1cc1SJoe Perches			WARN("USE_SPINLOCK_T",
68538f53a9b8SJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
68548f53a9b8SJoe Perches		}
685566c80b60SJoe Perches
685666c80b60SJoe Perches# check for seq_printf uses that could be seq_puts
6857d5e616fcSJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6858d5e616fcSJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6859d5e616fcSJoe Perches			$fmt =~ s/%%//g;
6860194f66fcSJoe Perches			if ($fmt !~ /%/) {
6861d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
686266c80b60SJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
686366c80b60SJoe Perches				    $fix) {
686488982feaSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
686588982feaSJoe Perches				}
686688982feaSJoe Perches			}
686788982feaSJoe Perches		}
686888982feaSJoe Perches
686988982feaSJoe Perches# check for vsprintf extension %p<foo> misuses
6870a6962d72SJoe Perches		if ($perl_version_ok &&
687106668727SJoe Perches		    defined $stat &&
6872a6962d72SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
6873caac1d5fSHeba Aamer		    $1 !~ /^_*volatile_*$/) {
6874caac1d5fSHeba Aamer			my $stat_real;
6875d5e616fcSJoe Perches
6876d5e616fcSJoe Perches			my $lc = $stat =~ tr@\n@@;
6877d5e616fcSJoe Perches			$lc = $lc + $linenr;
6878194f66fcSJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6879d5e616fcSJoe Perches				my $specifier;
6880a6962d72SJoe Perches				my $extension;
6881a6962d72SJoe Perches				my $qualifier;
6882a6962d72SJoe Perches				my $bad_specifier = "";
68830b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
68845b57980dSJoe Perches				$fmt =~ s/%%//g;
68850b523769SJoe Perches
68860b523769SJoe Perches				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
68870b523769SJoe Perches					$specifier = $1;
6888e3c6bc95STobin C. Harding					$extension = $2;
6889e3c6bc95STobin C. Harding					$qualifier = $3;
68900b523769SJoe Perches					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
68910b523769SJoe Perches					    ($extension eq "f" &&
68920b523769SJoe Perches					     defined $qualifier && $qualifier !~ /^w/) ||
6893ffe07513SJoe Perches					    ($extension eq "4" &&
6894ffe07513SJoe Perches					     defined $qualifier && $qualifier !~ /^cc/)) {
68953bd32d6aSSakari Ailus						$bad_specifier = $specifier;
6896ffe07513SJoe Perches						last;
68970b523769SJoe Perches					}
68980b523769SJoe Perches					if ($extension eq "x" && !defined($stat_real)) {
6899e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
69003bd32d6aSSakari Ailus							$stat_real = get_stat_real($linenr, $lc);
6901e3c6bc95STobin C. Harding						}
6902e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
69033bd32d6aSSakari Ailus						     "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");
6904af612e43SSakari Ailus					}
69053bd32d6aSSakari Ailus				}
6906af612e43SSakari Ailus				if ($bad_specifier ne "") {
6907af612e43SSakari Ailus					my $stat_real = get_stat_real($linenr, $lc);
6908af612e43SSakari Ailus					my $msg_level = \&WARN;
6909e3c6bc95STobin C. Harding					my $ext_type = "Invalid";
69100b523769SJoe Perches					my $use = "";
69110b523769SJoe Perches					if ($bad_specifier =~ /p[Ff]/) {
6912e3c6bc95STobin C. Harding						$use = " - use %pS instead";
6913e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6914e3c6bc95STobin C. Harding					} elsif ($bad_specifier =~ /pA/) {
69150b523769SJoe Perches						$use =  " - '%pA' is only intended to be used from Rust code";
6916e3c6bc95STobin C. Harding						$msg_level = \&ERROR;
6917e3c6bc95STobin C. Harding					}
6918e3c6bc95STobin C. Harding
6919e3c6bc95STobin C. Harding					&{$msg_level}("VSPRINTF_POINTER_EXTENSION",
6920e3c6bc95STobin C. Harding						      "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
69212a9f9d85STobin C. Harding				}
6922de48fa1aSMiguel Ojeda			}
69231df7338aSSergey Senozhatsky		}
69241df7338aSSergey Senozhatsky
6925e3c6bc95STobin C. Harding# Check for misused memsets
69261df7338aSSergey Senozhatsky		if ($perl_version_ok &&
6927e3c6bc95STobin C. Harding		    defined $stat &&
6928de48fa1aSMiguel Ojeda		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6929de48fa1aSMiguel Ojeda
6930de48fa1aSMiguel Ojeda			my $ms_addr = $2;
69311df7338aSSergey Senozhatsky			my $ms_val = $7;
69322a9f9d85STobin C. Harding			my $ms_size = $12;
6933de48fa1aSMiguel Ojeda
6934e3c6bc95STobin C. Harding			if ($ms_size =~ /^(0x|)0$/i) {
6935e3c6bc95STobin C. Harding				ERROR("MEMSET",
69360b523769SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
69370b523769SJoe Perches			} elsif ($ms_size =~ /^(0x|)1$/i) {
69380b523769SJoe Perches				WARN("MEMSET",
6939554e165cSAndy Whitcroft				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
69405b57980dSJoe Perches			}
6941d1fe9c09SJoe Perches		}
69429e20a853SMateusz Kulikowski
6943554e165cSAndy Whitcroft# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
6944d7c76ba7SJoe Perches#		if ($perl_version_ok &&
6945d1fe9c09SJoe Perches#		    defined $stat &&
6946d1fe9c09SJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6947d7c76ba7SJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6948554e165cSAndy Whitcroft#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6949554e165cSAndy Whitcroft#			    $fix) {
6950d7c76ba7SJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6951554e165cSAndy Whitcroft#			}
6952554e165cSAndy Whitcroft#		}
6953d7c76ba7SJoe Perches
6954d7c76ba7SJoe Perches# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
6955d7c76ba7SJoe Perches#		if ($perl_version_ok &&
6956d7c76ba7SJoe Perches#		    defined $stat &&
695798a9bba5SJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
69585b57980dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6959f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6960f333195dSJoe Perches#		}
6961f333195dSJoe Perches
6962f333195dSJoe Perches# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
6963f333195dSJoe Perches# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
6964f333195dSJoe Perches#		if ($perl_version_ok &&
6965f333195dSJoe Perches#		    defined $stat &&
6966f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
696798a9bba5SJoe Perches#
6968b6117d17SMateusz Kulikowski#			my $ms_val = $7;
69695b57980dSJoe Perches#
6970f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6971f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6972f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6973f333195dSJoe Perches#				    $fix) {
6974f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6975b6117d17SMateusz Kulikowski#				}
69768617cd09SMateusz Kulikowski#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
69778617cd09SMateusz Kulikowski#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
69785b57980dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6979f333195dSJoe Perches#				    $fix) {
6980f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6981f333195dSJoe Perches#				}
6982f333195dSJoe Perches#			}
6983f333195dSJoe Perches#		}
6984f333195dSJoe Perches
6985f333195dSJoe Perches# strcpy uses that should likely be strscpy
6986f333195dSJoe Perches		if ($line =~ /\bstrcpy\s*\(/) {
6987f333195dSJoe Perches			WARN("STRCPY",
6988f333195dSJoe Perches			     "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr);
6989f333195dSJoe Perches		}
6990f333195dSJoe Perches
6991f333195dSJoe Perches# strlcpy uses that should likely be strscpy
6992f333195dSJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
6993f333195dSJoe Perches			WARN("STRLCPY",
6994f333195dSJoe Perches			     "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr);
6995f333195dSJoe Perches		}
6996f333195dSJoe Perches
6997f333195dSJoe Perches# strncpy uses that should likely be strscpy or strscpy_pad
69988617cd09SMateusz Kulikowski		if ($line =~ /\bstrncpy\s*\(/) {
6999d0f90841SKees Cook			WARN("STRNCPY",
7000d0f90841SKees Cook			     "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr);
7001d0f90841SKees Cook		}
7002d0f90841SKees Cook
7003d0f90841SKees Cook# ethtool_sprintf uses that should likely be ethtool_puts
7004d0f90841SKees Cook		if ($line =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
70055dbdb2d8SJoe Perches			if (WARN("PREFER_ETHTOOL_PUTS",
70065dbdb2d8SJoe Perches				 "Prefer ethtool_puts over ethtool_sprintf with only two arguments\n" . $herecurr) &&
70075dbdb2d8SJoe Perches			    $fix) {
7008d0f90841SKees Cook				$fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*($FuncArg)/ethtool_puts($1, $7)/;
7009d0f90841SKees Cook			}
7010d0f90841SKees Cook		}
7011d0f90841SKees Cook
7012d0f90841SKees Cook		# use $rawline because $line loses %s via sanitization and thus we can't match against it.
7013d0f90841SKees Cook		if ($rawline =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*\"\%s\"\s*,\s*$FuncArg\s*\)/) {
7014d0f90841SKees Cook			if (WARN("PREFER_ETHTOOL_PUTS",
70155dbdb2d8SJoe Perches				 "Prefer ethtool_puts over ethtool_sprintf with standalone \"%s\" specifier\n" . $herecurr) &&
70165dbdb2d8SJoe Perches			    $fix) {
70179b5f621cS[email protected]				$fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*"\%s"\s*,\s*($FuncArg)/ethtool_puts($1, $7)/;
70189b5f621cS[email protected]			}
70199b5f621cS[email protected]		}
70209b5f621cS[email protected]
70219b5f621cS[email protected]
70229b5f621cS[email protected]# typecasts on min/max could be min_t/max_t
70239b5f621cS[email protected]		if ($perl_version_ok &&
70249b5f621cS[email protected]		    defined $stat &&
70259b5f621cS[email protected]		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
70269b5f621cS[email protected]			if (defined $2 || defined $7) {
70279b5f621cS[email protected]				my $call = $1;
70289b5f621cS[email protected]				my $cast1 = deparenthesize($2);
70299b5f621cS[email protected]				my $arg1 = $3;
70309b5f621cS[email protected]				my $cast2 = deparenthesize($7);
70319b5f621cS[email protected]				my $arg2 = $8;
70329b5f621cS[email protected]				my $cast;
70339b5f621cS[email protected]
70349b5f621cS[email protected]				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
70359b5f621cS[email protected]					$cast = "$cast1 or $cast2";
7036d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
70375b57980dSJoe Perches					$cast = $cast1;
7038d1fe9c09SJoe Perches				} else {
7039d7c76ba7SJoe Perches					$cast = $cast2;
7040d1fe9c09SJoe Perches				}
7041d7c76ba7SJoe Perches				WARN("MINMAX",
7042d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
7043d7c76ba7SJoe Perches			}
7044d1fe9c09SJoe Perches		}
7045d1fe9c09SJoe Perches
7046d7c76ba7SJoe Perches# check usleep_range arguments
7047d7c76ba7SJoe Perches		if ($perl_version_ok &&
7048d1fe9c09SJoe Perches		    defined $stat &&
7049d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
7050d7c76ba7SJoe Perches			my $min = $1;
7051d7c76ba7SJoe Perches			my $max = $7;
7052d7c76ba7SJoe Perches			if ($min eq $max) {
7053d7c76ba7SJoe Perches				WARN("USLEEP_RANGE",
7054d7c76ba7SJoe Perches				     "usleep_range should not use min == max args;  see function description of usleep_range().\n" . "$here\n$stat\n");
7055d7c76ba7SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
7056d7c76ba7SJoe Perches				 $min > $max) {
7057554e165cSAndy Whitcroft				WARN("USLEEP_RANGE",
7058554e165cSAndy Whitcroft				     "usleep_range args reversed, use min then max;  see function description of usleep_range().\n" . "$here\n$stat\n");
7059554e165cSAndy Whitcroft			}
70604a273195SJoe Perches		}
70615b57980dSJoe Perches
70624a273195SJoe Perches# check for naked sscanf
70634a273195SJoe Perches		if ($perl_version_ok &&
70644a273195SJoe Perches		    defined $stat &&
70654a273195SJoe Perches		    $line =~ /\bsscanf\b/ &&
70664a273195SJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
70674a273195SJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
70686534086aSAnna-Maria Behnsen		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
70694a273195SJoe Perches			my $lc = $stat =~ tr@\n@@;
70704a273195SJoe Perches			$lc = $lc + $linenr;
70714a273195SJoe Perches			my $stat_real = get_stat_real($linenr, $lc);
70726534086aSAnna-Maria Behnsen			WARN("NAKED_SSCANF",
70734a273195SJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
70744a273195SJoe Perches		}
70754a273195SJoe Perches
7076823b794cSJoe Perches# check for simple sscanf that should be kstrto<foo>
70775b57980dSJoe Perches		if ($perl_version_ok &&
7078823b794cSJoe Perches		    defined $stat &&
70796c8bd707SJoe Perches		    $line =~ /\bsscanf\b/) {
7080823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
7081823b794cSJoe Perches			$lc = $lc + $linenr;
7082823b794cSJoe Perches			my $stat_real = get_stat_real($linenr, $lc);
7083823b794cSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
7084823b794cSJoe Perches				my $format = $6;
70852a9f9d85STobin C. Harding				my $count = $format =~ tr@%@%@;
7086823b794cSJoe Perches				if ($count == 1 &&
7087823b794cSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
7088823b794cSJoe Perches					WARN("SSCANF_TO_KSTRTO",
7089823b794cSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
7090afc819abSJoe Perches				}
70915b57980dSJoe Perches			}
7092afc819abSJoe Perches		}
7093afc819abSJoe Perches
7094afc819abSJoe Perches# check for new externs in .h files.
7095afc819abSJoe Perches		if ($realfile =~ /\.h$/ &&
70962a9f9d85STobin C. Harding		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
7097afc819abSJoe Perches			if (CHK("AVOID_EXTERNS",
7098afc819abSJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
7099afc819abSJoe Perches			    $fix) {
7100afc819abSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
7101afc819abSJoe Perches			}
7102afc819abSJoe Perches		}
7103afc819abSJoe Perches
7104afc819abSJoe Perches# check for new externs in .c files.
7105afc819abSJoe Perches		if ($realfile =~ /\.c$/ && defined $stat &&
7106afc819abSJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
7107afc819abSJoe Perches		{
710870dc8a48SJoe Perches			my $function_name = $1;
710970dc8a48SJoe Perches			my $paren_space = $2;
711070dc8a48SJoe Perches
7111d1d85780SJoe Perches			my $s = $stat;
711270dc8a48SJoe Perches			if (defined $cond) {
711370dc8a48SJoe Perches				substr($s, 0, length($cond), '');
7114194f66fcSJoe Perches			}
711570dc8a48SJoe Perches			if ($s =~ /^\s*;/)
711670dc8a48SJoe Perches			{
711770dc8a48SJoe Perches				WARN("AVOID_EXTERNS",
7118de7d4f0eSAndy Whitcroft				     "externs should be avoided in .c files\n" .  $herecurr);
7119171ae1a4SAndy Whitcroft			}
7120c45dcabdSAndy Whitcroft
7121171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
7122c45dcabdSAndy Whitcroft				WARN("FUNCTION_ARGUMENTS",
7123c45dcabdSAndy Whitcroft				     "arguments for function declarations should follow identifier\n" . $herecurr);
7124171ae1a4SAndy Whitcroft			}
7125171ae1a4SAndy Whitcroft
7126171ae1a4SAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
7127171ae1a4SAndy Whitcroft		    $stat =~ /^\+extern struct\s+(\w+)\s+(\w+)\[\];/)
7128171ae1a4SAndy Whitcroft		{
7129d8b44b58SKees Cook			my ($st_type, $st_name) = ($1, $2);
7130c45dcabdSAndy Whitcroft
7131000d1cc1SJoe Perches			for my $s (keys %maybe_linker_symbol) {
7132000d1cc1SJoe Perches			    #print "Linker symbol? $st_name : $s\n";
7133de7d4f0eSAndy Whitcroft			    goto LIKELY_LINKER_SYMBOL
7134de7d4f0eSAndy Whitcroft				if $st_name =~ /$s/;
7135171ae1a4SAndy Whitcroft			}
7136000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
7137000d1cc1SJoe Perches			     "found a file-scoped extern type:$st_type name:$st_name in .c file\n"
7138171ae1a4SAndy Whitcroft			     . "is this a linker symbol ?\n" . $herecurr);
71399c9ba34eSAndy Whitcroft		  LIKELY_LINKER_SYMBOL:
71409c9ba34eSAndy Whitcroft
71415b2c7334SJim Cromie		} elsif ($realfile =~ /\.c$/ && defined $stat &&
71425b2c7334SJim Cromie		    $stat =~ /^.\s*extern\s+/)
71435b2c7334SJim Cromie		{
71445b2c7334SJim Cromie			WARN("AVOID_EXTERNS",
71455b2c7334SJim Cromie			     "externs should be avoided in .c files\n" .  $herecurr);
71465b2c7334SJim Cromie		}
71475b2c7334SJim Cromie
71485b2c7334SJim Cromie# check for function declarations that have arguments without identifier names
71495b2c7334SJim Cromie		if (defined $stat &&
71505b2c7334SJim Cromie		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
71515b2c7334SJim Cromie		    $1 ne "void") {
71525b2c7334SJim Cromie			my $args = trim($1);
71535b2c7334SJim Cromie			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
71545b2c7334SJim Cromie				my $arg = trim($1);
71555b2c7334SJim Cromie				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
71569c9ba34eSAndy Whitcroft					WARN("FUNCTION_ARGUMENTS",
71579c9ba34eSAndy Whitcroft					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
7158000d1cc1SJoe Perches				}
7159000d1cc1SJoe Perches			}
7160171ae1a4SAndy Whitcroft		}
7161171ae1a4SAndy Whitcroft
7162a0ad7596SJoe Perches# check for function definitions
7163a0ad7596SJoe Perches		if ($perl_version_ok &&
7164d8b44b58SKees Cook		    defined $stat &&
7165d8b44b58SKees Cook		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
7166d8b44b58SKees Cook			$context_function = $1;
7167ca0d8929SJoe Perches
7168ca0d8929SJoe Perches# check for multiline function definition with misplaced open brace
7169d8b44b58SKees Cook			my $ok = 0;
7170ca0d8929SJoe Perches			my $cnt = statement_rawlines($stat);
7171ca0d8929SJoe Perches			my $herectx = $here . "\n";
7172ca0d8929SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
7173ca0d8929SJoe Perches				my $rl = raw_line($linenr, $n);
7174ca0d8929SJoe Perches				$herectx .=  $rl . "\n";
7175ca0d8929SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
7176a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
71775b57980dSJoe Perches				last if $rl =~ /^[ \+].*\{/;
7178a0ad7596SJoe Perches			}
7179a0ad7596SJoe Perches			if (!$ok) {
7180a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
7181a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
7182a0ad7596SJoe Perches			}
7183a0ad7596SJoe Perches		}
7184a0ad7596SJoe Perches
7185a0ad7596SJoe Perches# checks for new __setup's
7186a0ad7596SJoe Perches		if ($rawline =~ /\b__setup\("([^"]*)"/) {
7187a0ad7596SJoe Perches			my $name = $1;
7188a0ad7596SJoe Perches
7189a0ad7596SJoe Perches			if (!grep(/$name/, @setup_docs)) {
7190a0ad7596SJoe Perches				CHK("UNDOCUMENTED_SETUP",
7191a0ad7596SJoe Perches				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
7192a0ad7596SJoe Perches			}
7193a0ad7596SJoe Perches		}
7194a0ad7596SJoe Perches
7195a0ad7596SJoe Perches# check for pointless casting of alloc functions
7196a0ad7596SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
7197a0ad7596SJoe Perches			WARN("UNNECESSARY_CASTS",
7198a0ad7596SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
7199de7d4f0eSAndy Whitcroft		}
7200de7d4f0eSAndy Whitcroft
7201de7d4f0eSAndy Whitcroft# alloc style
7202de7d4f0eSAndy Whitcroft# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
7203de7d4f0eSAndy Whitcroft		if ($perl_version_ok &&
7204000d1cc1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
72052581ac7cSTim Froidcoeur			CHK("ALLOC_SIZEOF_STRUCT",
7206de7d4f0eSAndy Whitcroft			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
7207653d4876SAndy Whitcroft		}
72089c0ca6f9SAndy Whitcroft
7209e29a70f1SJoe Perches# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc
7210e29a70f1SJoe Perches		if ($perl_version_ok &&
7211000d1cc1SJoe Perches		    defined $stat &&
7212000d1cc1SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
72139c0ca6f9SAndy Whitcroft			my $oldfunc = $3;
721413214adfSAndy Whitcroft			my $a1 = $4;
7215a640d25cSJoe Perches			my $a2 = $10;
7216a640d25cSJoe Perches			my $newfunc = "kmalloc_array";
72175b57980dSJoe Perches			$newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");
7218e29a70f1SJoe Perches			$newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");
7219a640d25cSJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
7220a640d25cSJoe Perches			my $r1 = $a1;
7221a640d25cSJoe Perches			my $r2 = $a2;
7222a640d25cSJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
722373f1d07eSGustavo A. R. Silva				$r1 = $a2;
72245b57980dSJoe Perches				$r2 = $a1;
72251b4a2ed4SJoe Perches			}
722673f1d07eSGustavo A. R. Silva			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
722760a55369SJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
722860a55369SJoe Perches				my $cnt = statement_rawlines($stat);
722960a55369SJoe Perches				my $herectx = get_stat_here($linenr, $cnt, $here);
723060a55369SJoe Perches
723173f1d07eSGustavo A. R. Silva				if (WARN("ALLOC_WITH_MULTIPLY",
723273f1d07eSGustavo A. R. Silva					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
723360a55369SJoe Perches				    $cnt == 1 &&
723460a55369SJoe Perches				    $fix) {
723560a55369SJoe Perches					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
723660a55369SJoe Perches				}
723760a55369SJoe Perches			}
723860a55369SJoe Perches		}
723960a55369SJoe Perches
7240e367455aSJoe Perches# check for krealloc arg reuse
7241e367455aSJoe Perches		if ($perl_version_ok &&
72421b4a2ed4SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
7243e3d95a2aSTobin C. Harding		    $1 eq $3) {
7244e3d95a2aSTobin C. Harding			WARN("KREALLOC_ARG_REUSE",
7245e367455aSJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
72461b4a2ed4SJoe Perches		}
72471b4a2ed4SJoe Perches
7248e367455aSJoe Perches# check for alloc argument mismatch
724973f1d07eSGustavo A. R. Silva		if ($line =~ /\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/) {
725060a55369SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
725160a55369SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
725260a55369SJoe Perches		}
725360a55369SJoe Perches
7254972fdea2SJoe Perches# check for multiple semicolons
72555b57980dSJoe Perches		if ($line =~ /;\s*;\s*$/) {
72564cab63ceSJoe Perches			if (WARN("ONE_SEMICOLON",
72574cab63ceSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7258972fdea2SJoe Perches			    $fix) {
7259972fdea2SJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7260972fdea2SJoe Perches			}
7261972fdea2SJoe Perches		}
72625ce59ae0SJoe Perches
72633965292aSLiao Chang# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
72645ce59ae0SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
72655ce59ae0SJoe Perches		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
72665ce59ae0SJoe Perches			my $ull = "";
72675ce59ae0SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
7268caf2a54fSJoe Perches			if (CHK("BIT_MACRO",
7269caf2a54fSJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
7270d5e616fcSJoe Perches			    $fix) {
7271d5e616fcSJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
7272d5e616fcSJoe Perches			}
7273194f66fcSJoe Perches		}
7274d5e616fcSJoe Perches
7275d1e2ad07SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
7276d1e2ad07SJoe Perches		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
7277cec3aaa5STomas Winkler			WARN("IS_ENABLED_CONFIG",
7278cec3aaa5STomas Winkler			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
7279cec3aaa5STomas Winkler		}
72800ab90191SJoe Perches
72810ab90191SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
72820ab90191SJoe Perches		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
72830ab90191SJoe Perches			my $config = $1;
72840ab90191SJoe Perches			if (WARN("PREFER_IS_ENABLED",
72850ab90191SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
72860ab90191SJoe Perches			    $fix) {
72870ab90191SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
72880ab90191SJoe Perches			}
728950161266SJoe Perches		}
72903e89ad85SJerome Forissier
729150161266SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
72923e89ad85SJerome Forissier		my @fallthroughs = (
729350161266SJoe Perches			'fallthrough',
729450161266SJoe Perches			'@fallthrough@',
72952d632745SJoe Perches			'lint -fallthrough[ \t]*',
72963e89ad85SJerome Forissier			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
72972d632745SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
72982d632745SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
72993e89ad85SJerome Forissier			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
73002d632745SJoe Perches		    );
73012d632745SJoe Perches		if ($raw_comment ne '') {
73022d632745SJoe Perches			foreach my $ft (@fallthroughs) {
73032d632745SJoe Perches				if ($raw_comment =~ /$ft/) {
73042d632745SJoe Perches					my $msg_level = \&WARN;
7305f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
7306f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
7307f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7308f36d3eb8SJoe Perches					last;
7309f36d3eb8SJoe Perches				}
7310f36d3eb8SJoe Perches			}
7311f36d3eb8SJoe Perches		}
7312f36d3eb8SJoe Perches
7313f36d3eb8SJoe Perches# check for switch/default statements without a break;
7314f36d3eb8SJoe Perches		if ($perl_version_ok &&
7315f36d3eb8SJoe Perches		    defined $stat &&
7316f36d3eb8SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7317f36d3eb8SJoe Perches			my $cnt = statement_rawlines($stat);
7318f36d3eb8SJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
7319f36d3eb8SJoe Perches
7320f36d3eb8SJoe Perches			WARN("DEFAULT_NO_BREAK",
7321f36d3eb8SJoe Perches			     "switch default: should use break\n" . $herectx);
7322f36d3eb8SJoe Perches		}
7323f36d3eb8SJoe Perches
7324f36d3eb8SJoe Perches# check for gcc specific __FUNCTION__
7325f36d3eb8SJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
7326f36d3eb8SJoe Perches			if (WARN("USE_FUNC",
7327d1e2ad07SJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
73285b57980dSJoe Perches			    $fix) {
7329d1e2ad07SJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7330d1e2ad07SJoe Perches			}
7331d1e2ad07SJoe Perches		}
7332e3d95a2aSTobin C. Harding
7333e3d95a2aSTobin C. Harding# check for uses of __DATE__, __TIME__, __TIMESTAMP__
7334d1e2ad07SJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
7335d1e2ad07SJoe Perches			ERROR("DATE_TIME",
7336caf2a54fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
7337caf2a54fSJoe Perches		}
733813214adfSAndy Whitcroft
7339d5e616fcSJoe Perches# check for use of yield()
7340d5e616fcSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
7341d5e616fcSJoe Perches			WARN("YIELD",
7342d5e616fcSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
7343194f66fcSJoe Perches		}
7344d5e616fcSJoe Perches
734513214adfSAndy Whitcroft# check for comparisons against true and false
7346773647a0SAndy Whitcroft		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
734762ec818fSJoe Perches			my $lead = $1;
734862ec818fSJoe Perches			my $arg = $2;
734962ec818fSJoe Perches			my $test = $3;
735062ec818fSJoe Perches			my $otype = $4;
735162ec818fSJoe Perches			my $trail = $5;
735262ec818fSJoe Perches			my $op = "!";
73532c92488aSJoe Perches
73542c92488aSJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
73552c92488aSJoe Perches
73562c92488aSJoe Perches			my $type = lc($otype);
73572c92488aSJoe Perches			if ($type =~ /^(?:true|false)$/) {
73582c92488aSJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7359179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7360179f8f40SJoe Perches					$op = "";
7361179f8f40SJoe Perches				}
7362179f8f40SJoe Perches
7363179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7364179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7365179f8f40SJoe Perches
7366179f8f40SJoe Perches## maybe suggesting a correct construct would better
7367179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7368179f8f40SJoe Perches
7369179f8f40SJoe Perches			}
7370179f8f40SJoe Perches		}
7371179f8f40SJoe Perches
7372179f8f40SJoe Perches# check for semaphores initialized locked
7373179f8f40SJoe Perches		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7374179f8f40SJoe Perches			WARN("CONSIDER_COMPLETION",
7375179f8f40SJoe Perches			     "consider using a completion\n" . $herecurr);
7376179f8f40SJoe Perches		}
7377179f8f40SJoe Perches
7378179f8f40SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
7379179f8f40SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7380179f8f40SJoe Perches			WARN("CONSIDER_KSTRTO",
7381179f8f40SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7382179f8f40SJoe Perches		}
7383179f8f40SJoe Perches
7384179f8f40SJoe Perches# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7385179f8f40SJoe Perches		if ($line =~ /^.\s*__initcall\s*\(/) {
73864882720bSThomas Gleixner			WARN("USE_DEVICE_INITCALL",
73874882720bSThomas Gleixner			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7388000d1cc1SJoe Perches		}
7389000d1cc1SJoe Perches
7390773647a0SAndy Whitcroft# check for spin_is_locked(), suggest lockdep instead
73916712d858SJoe Perches		if ($line =~ /\bspin_is_locked\(/) {
739267d0a075SJoe Perches			WARN("USE_LOCKDEP",
739367d0a075SJoe Perches			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
7394000d1cc1SJoe Perches		}
739567d0a075SJoe Perches
7396773647a0SAndy Whitcroft# check for deprecated apis
73976712d858SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
7398ae3ccc46SFabian Frederick			my $deprecated_api = $1;
7399f3db6639SMichael Ellerman			my $new_api = $deprecated_apis{$deprecated_api};
7400000d1cc1SJoe Perches			WARN("DEPRECATED_API",
7401ae3ccc46SFabian Frederick			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
7402f3db6639SMichael Ellerman		}
74036712d858SJoe Perches
74043d709ab5SPaul E. McKenney# check for various structs that are normally const (ops, kgdb, device_tree)
74053d709ab5SPaul E. McKenney# and avoid what seem like struct definitions 'struct foo {'
74063d709ab5SPaul E. McKenney		if (defined($const_structs) &&
74073d709ab5SPaul E. McKenney		    $line !~ /\bconst\b/ &&
74083d709ab5SPaul E. McKenney		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
74093d709ab5SPaul E. McKenney			WARN("CONST_STRUCT",
74109189c7e7SJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
74119189c7e7SJoe Perches		}
74129189c7e7SJoe Perches
74139189c7e7SJoe Perches# use of NR_CPUS is usually wrong
74149189c7e7SJoe Perches# ignore definitions of NR_CPUS and usage to define arrays as likely right
74159189c7e7SJoe Perches# ignore designated initializers using NR_CPUS
74169189c7e7SJoe Perches		if ($line =~ /\bNR_CPUS\b/ &&
74179189c7e7SJoe Perches		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
74180f3c5aabSJoe Perches		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7419d9190e4eSJoe Perches		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7420ced69da1SQuentin Monnet		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
7421ced69da1SQuentin Monnet		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
7422d9190e4eSJoe Perches		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7423000d1cc1SJoe Perches		{
7424d9190e4eSJoe Perches			WARN("NR_CPUS",
74252b6db5cbSAndy Whitcroft			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7426773647a0SAndy Whitcroft		}
7427773647a0SAndy Whitcroft
7428773647a0SAndy Whitcroft# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
742935cdcbfcSPeng Wang		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
7430773647a0SAndy Whitcroft			ERROR("DEFINE_ARCH_HAS",
7431c45dcabdSAndy Whitcroft			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
7432c45dcabdSAndy Whitcroft		}
7433171ae1a4SAndy Whitcroft
7434171ae1a4SAndy Whitcroft# likely/unlikely comparisons similar to "(likely(foo) > 0)"
743535cdcbfcSPeng Wang		if ($perl_version_ok &&
743635cdcbfcSPeng Wang		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7437773647a0SAndy Whitcroft			WARN("LIKELY_MISUSE",
7438000d1cc1SJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7439000d1cc1SJoe Perches		}
7440773647a0SAndy Whitcroft
74419c9ba34eSAndy Whitcroft# return sysfs_emit(foo, fmt, ...) fmt without newline
744252ea8506SJoe Perches		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
744352ea8506SJoe Perches		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
744452ea8506SJoe Perches			my $offset = $+[6] - 1;
744552ea8506SJoe Perches			if (WARN("SYSFS_EMIT",
744652ea8506SJoe Perches				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
744752ea8506SJoe Perches			    $fix) {
7448acd9362cSJoe Perches				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
74495b57980dSJoe Perches			}
7450acd9362cSJoe Perches		}
7451acd9362cSJoe Perches
7452acd9362cSJoe Perches# check for array definition/declarations that should use flexible arrays instead
7453acd9362cSJoe Perches		if ($sline =~ /^[\+ ]\s*\}(?:\s*__packed)?\s*;\s*$/ &&
7454acd9362cSJoe Perches		    $prevline =~ /^\+\s*(?:\}(?:\s*__packed\s*)?|$Type)\s*$Ident\s*\[\s*(0|1)\s*\]\s*;\s*$/) {
7455fbe74541SJoe Perches			if (ERROR("FLEXIBLE_ARRAY",
7456fbe74541SJoe Perches				  "Use C99 flexible arrays - see https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays\n" . $hereprev) &&
7457fbe74541SJoe Perches			    $1 == '0' && $fix) {
7458fbe74541SJoe Perches				$fixed[$fixlinenr - 1] =~ s/\[\s*0\s*\]/[]/;
7459fbe74541SJoe Perches			}
7460fbe74541SJoe Perches		}
7461fbe74541SJoe Perches
7462fbe74541SJoe Perches# nested likely/unlikely calls
7463fbe74541SJoe Perches		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7464fbe74541SJoe Perches			WARN("LIKELY_MISUSE",
7465fbe74541SJoe Perches			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
74668515e4a7SKees Cook		}
74678515e4a7SKees Cook
74688515e4a7SKees Cook# whine mightly about in_atomic
74698515e4a7SKees Cook		if ($line =~ /\bin_atomic\s*\(/) {
74708515e4a7SKees Cook			if ($realfile =~ m@^drivers/@) {
74718515e4a7SKees Cook				ERROR("IN_ATOMIC",
74728515e4a7SKees Cook				      "do not use in_atomic in drivers\n" . $herecurr);
74738515e4a7SKees Cook			} elsif ($realfile !~ m@^kernel/@) {
74748515e4a7SKees Cook				WARN("IN_ATOMIC",
74758515e4a7SKees Cook				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7476de3f186fSDenis Efremov			}
7477de3f186fSDenis Efremov		}
7478de3f186fSDenis Efremov
7479de3f186fSDenis Efremov# Complain about RCU Tasks Trace used outside of BPF (and of course, RCU).
7480de3f186fSDenis Efremov		our $rcu_trace_funcs = qr{(?x:
7481de3f186fSDenis Efremov			rcu_read_lock_trace |
7482691d77b6SAndy Whitcroft			rcu_read_lock_trace_held |
7483691d77b6SAndy Whitcroft			rcu_read_unlock_trace |
7484691d77b6SAndy Whitcroft			call_rcu_tasks_trace |
7485000d1cc1SJoe Perches			synchronize_rcu_tasks_trace |
7486000d1cc1SJoe Perches			rcu_barrier_tasks_trace |
7487f4a87736SAndy Whitcroft			rcu_request_urgent_qs_task
7488000d1cc1SJoe Perches		)};
7489000d1cc1SJoe Perches		our $rcu_trace_paths = qr{(?x:
7490691d77b6SAndy Whitcroft			kernel/bpf/ |
7491691d77b6SAndy Whitcroft			include/linux/bpf |
74921704f47bSPeter Zijlstra			net/bpf/ |
749384dd7f19SPaul E. McKenney			kernel/rcu/ |
749484dd7f19SPaul E. McKenney			include/linux/rcu
749584dd7f19SPaul E. McKenney		)};
749684dd7f19SPaul E. McKenney		if ($line =~ /\b($rcu_trace_funcs)\s*\(/) {
749784dd7f19SPaul E. McKenney			if ($realfile !~ m{^$rcu_trace_paths}) {
749884dd7f19SPaul E. McKenney				WARN("RCU_TASKS_TRACE",
749984dd7f19SPaul E. McKenney				     "use of RCU tasks trace is incorrect outside BPF or core RCU code\n" . $herecurr);
750084dd7f19SPaul E. McKenney			}
750184dd7f19SPaul E. McKenney		}
750284dd7f19SPaul E. McKenney
750384dd7f19SPaul E. McKenney# check for lockdep_set_novalidate_class
750484dd7f19SPaul E. McKenney		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
750584dd7f19SPaul E. McKenney		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
750684dd7f19SPaul E. McKenney			if ($realfile !~ m@^kernel/lockdep@ &&
750784dd7f19SPaul E. McKenney			    $realfile !~ m@^include/linux/lockdep@ &&
750884dd7f19SPaul E. McKenney			    $realfile !~ m@^drivers/base/core@) {
750984dd7f19SPaul E. McKenney				ERROR("LOCKDEP",
751084dd7f19SPaul E. McKenney				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
751184dd7f19SPaul E. McKenney			}
751284dd7f19SPaul E. McKenney		}
751384dd7f19SPaul E. McKenney
751484dd7f19SPaul E. McKenney		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
751584dd7f19SPaul E. McKenney		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
751684dd7f19SPaul E. McKenney			WARN("EXPORTED_WORLD_WRITABLE",
75171704f47bSPeter Zijlstra			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
75181704f47bSPeter Zijlstra		}
75191704f47bSPeter Zijlstra
75201704f47bSPeter Zijlstra# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
75211704f47bSPeter Zijlstra# and whether or not function naming is typical and if
75221704f47bSPeter Zijlstra# DEVICE_ATTR permissions uses are unusual too
7523000d1cc1SJoe Perches		if ($perl_version_ok &&
7524000d1cc1SJoe Perches		    defined $stat &&
75251704f47bSPeter Zijlstra		    $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*\)/) {
75261704f47bSPeter Zijlstra			my $var = $1;
752788f8831cSDave Jones			my $perms = $2;
7528b392c64fSJoe Perches			my $show = $3;
7529b392c64fSJoe Perches			my $store = $4;
7530000d1cc1SJoe Perches			my $octal_perms = perms_to_octal($perms);
7531000d1cc1SJoe Perches			if ($show =~ /^${var}_show$/ &&
753288f8831cSDave Jones			    $store =~ /^${var}_store$/ &&
75332435880fSJoe Perches			    $octal_perms eq "0644") {
753400180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
753500180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
753600180468SJoe Perches				    $fix) {
75375b57980dSJoe 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})/;
753800180468SJoe Perches				}
753900180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
754000180468SJoe Perches				 $store =~ /^NULL$/ &&
754100180468SJoe Perches				 $octal_perms eq "0444") {
754200180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
754300180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
754400180468SJoe Perches				    $fix) {
754500180468SJoe 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})/;
754600180468SJoe Perches				}
754700180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
754800180468SJoe Perches				 $store =~ /^${var}_store$/ &&
754900180468SJoe Perches				 $octal_perms eq "0200") {
755000180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
755100180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
755200180468SJoe Perches				    $fix) {
755300180468SJoe 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})/;
755400180468SJoe Perches				}
755500180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
755600180468SJoe Perches				 $octal_perms eq "0444" ||
755700180468SJoe Perches				 $octal_perms eq "0200") {
755800180468SJoe Perches				my $newshow = "$show";
755900180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
756000180468SJoe Perches				my $newstore = $store;
756100180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
756200180468SJoe Perches				my $rename = "";
756300180468SJoe Perches				if ($show ne $newshow) {
756400180468SJoe Perches					$rename .= " '$show' to '$newshow'";
756500180468SJoe Perches				}
756600180468SJoe Perches				if ($store ne $newstore) {
756700180468SJoe Perches					$rename .= " '$store' to '$newstore'";
756800180468SJoe Perches				}
756900180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
757000180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
757100180468SJoe Perches			} else {
757200180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
757300180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
757400180468SJoe Perches			}
757500180468SJoe Perches		}
757600180468SJoe Perches
757700180468SJoe Perches# Mode permission misuses where it seems decimal should be octal
757800180468SJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
757900180468SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
758000180468SJoe Perches#   specific definition of not visible in sysfs.
758100180468SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
758200180468SJoe Perches#   use the default permissions
758300180468SJoe Perches		if ($perl_version_ok &&
758400180468SJoe Perches		    defined $stat &&
758500180468SJoe Perches		    $line =~ /$mode_perms_search/) {
758600180468SJoe Perches			foreach my $entry (@mode_permission_funcs) {
758700180468SJoe Perches				my $func = $entry->[0];
758800180468SJoe Perches				my $arg_pos = $entry->[1];
758900180468SJoe Perches
759000180468SJoe Perches				my $lc = $stat =~ tr@\n@@;
7591515a235eSJoe Perches				$lc = $lc + $linenr;
7592515a235eSJoe Perches				my $stat_real = get_stat_real($linenr, $lc);
759373121534SJoe Perches
759473121534SJoe Perches				my $skip_args = "";
759573121534SJoe Perches				if ($arg_pos > 1) {
759673121534SJoe Perches					$arg_pos--;
75975b57980dSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
7598459cf0aeSJoe Perches				}
7599515a235eSJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
76002435880fSJoe Perches				if ($stat =~ /$test/) {
76012435880fSJoe Perches					my $val = $1;
76022435880fSJoe Perches					$val = $6 if ($skip_args ne "");
76032435880fSJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
7604459cf0aeSJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
7605459cf0aeSJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
76062a9f9d85STobin C. Harding						ERROR("NON_OCTAL_PERMISSIONS",
7607459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
76082435880fSJoe Perches					}
76092435880fSJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
76102435880fSJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
76112435880fSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
76122435880fSJoe Perches					}
7613f90774e1SJoe Perches				}
7614459cf0aeSJoe Perches			}
76152435880fSJoe Perches		}
76162435880fSJoe Perches
761773121534SJoe Perches# check for uses of S_<PERMS> that could be octal for readability
761873121534SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
761973121534SJoe Perches			my $oval = $1;
76202435880fSJoe Perches			my $octal = perms_to_octal($oval);
7621459cf0aeSJoe Perches			if (WARN("SYMBOLIC_PERMS",
7622f90774e1SJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7623f90774e1SJoe Perches			    $fix) {
7624c0a5c898SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
7625459cf0aeSJoe Perches			}
76262435880fSJoe Perches		}
7627459cf0aeSJoe Perches
7628459cf0aeSJoe Perches# validate content of MODULE_LICENSE against list from include/linux/module.h
7629459cf0aeSJoe Perches		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
7630459cf0aeSJoe Perches			my $extracted_string = get_quoted_string($line, $rawline);
7631459cf0aeSJoe Perches			my $valid_licenses = qr{
7632bc22d9a7SJoe Perches						GPL|
763300180468SJoe Perches						GPL\ v2|
763400180468SJoe Perches						GPL\ and\ additional\ rights|
7635f90774e1SJoe Perches						Dual\ BSD/GPL|
7636459cf0aeSJoe Perches						Dual\ MIT/GPL|
7637f90774e1SJoe Perches						Dual\ MPL/GPL|
763800180468SJoe Perches						Proprietary
76392435880fSJoe Perches					}x;
764013214adfSAndy Whitcroft			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
76415a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
76425a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
76435a6d20ceSBjorn Andersson			}
76445a6d20ceSBjorn Andersson			if (!$file && $extracted_string eq '"GPL v2"') {
76455a6d20ceSBjorn Andersson				if (WARN("MODULE_LICENSE",
76465a6d20ceSBjorn Andersson				     "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&
76475a6d20ceSBjorn Andersson				    $fix) {
76485a6d20ceSBjorn Andersson					$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;
76495a6d20ceSBjorn Andersson				}
76505a6d20ceSBjorn Andersson			}
76515a6d20ceSBjorn Andersson		}
76525a6d20ceSBjorn Andersson
76535a6d20ceSBjorn Andersson# check for sysctl duplicate constants
76545a6d20ceSBjorn Andersson		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
76555a6d20ceSBjorn Andersson			WARN("DUPLICATED_SYSCTL_CONST",
76565a6d20ceSBjorn Andersson				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
76575a6d20ceSBjorn Andersson		}
76586e8f42dcSJoe Perches	}
76596e8f42dcSJoe Perches
76606e8f42dcSJoe Perches	# If we have no input at all, then there is nothing to report on
76616e8f42dcSJoe Perches	# so just keep quiet.
76626e8f42dcSJoe Perches	if ($#rawlines == -1) {
76636e8f42dcSJoe Perches		exit(0);
76646e8f42dcSJoe Perches	}
76655a6d20ceSBjorn Andersson
76666a8d76cbSMatteo Croce	# In mailback mode only produce a report in the negative, for
76676a8d76cbSMatteo Croce	# things that appear to be patches.
76686a8d76cbSMatteo Croce	if ($mailback && ($clean == 1 || !$is_patch)) {
76696a8d76cbSMatteo Croce		exit(0);
76706a8d76cbSMatteo Croce	}
76716a8d76cbSMatteo Croce
7672515a235eSJoe Perches	# This is not a patch, and we are in 'no-patch' mode so
767313214adfSAndy Whitcroft	# just keep quiet.
767413214adfSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
767513214adfSAndy Whitcroft		exit(0);
767613214adfSAndy Whitcroft	}
767713214adfSAndy Whitcroft
76780a920b5bSAndy Whitcroft	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
76790a920b5bSAndy Whitcroft		ERROR("NOT_UNIFIED_DIFF",
76808905a67cSAndy Whitcroft		      "Does not appear to be a unified-diff format patch\n");
76818905a67cSAndy Whitcroft	}
76828905a67cSAndy Whitcroft	if ($is_patch && $has_commit_log && $chk_fixes_tag) {
76838905a67cSAndy Whitcroft		if ($needs_fixes_tag ne "" && !$is_revert && !$fixes_tag) {
76848905a67cSAndy Whitcroft			WARN("MISSING_FIXES_TAG",
76858905a67cSAndy Whitcroft				 "The commit message has '$needs_fixes_tag', perhaps it also needs a 'Fixes:' tag?\n");
7686e73d2715SDwaipayan Ray		}
76878905a67cSAndy Whitcroft	}
76888905a67cSAndy Whitcroft	if ($is_patch && $has_commit_log && $chk_signoff) {
76898905a67cSAndy Whitcroft		if ($signoff == 0) {
76908905a67cSAndy Whitcroft			ERROR("MISSING_SIGN_OFF",
76918905a67cSAndy Whitcroft			      "Missing Signed-off-by: line(s)\n");
7692a08ffbefSStafford Horne		} elsif ($authorsignoff != 1) {
7693000d1cc1SJoe Perches			# authorsignoff values:
7694000d1cc1SJoe Perches			# 0 -> missing sign off
76950a920b5bSAndy Whitcroft			# 1 -> sign off identical
7696d5d6281aSDan Carpenter			# 2 -> names and addresses match, comments mismatch
7697d5d6281aSDan Carpenter			# 3 -> addresses match, names different
7698d5d6281aSDan Carpenter			# 4 -> names match, addresses different
7699d5d6281aSDan Carpenter			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
7700d5d6281aSDan Carpenter
7701d5d6281aSDan Carpenter			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
7702cd261496SGeert Uytterhoeven
7703cd261496SGeert Uytterhoeven			if ($authorsignoff == 0) {
7704000d1cc1SJoe Perches				ERROR("NO_AUTHOR_SIGN_OFF",
7705000d1cc1SJoe Perches				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
770648ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
770748ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
770848ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
770948ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
771048ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
771148ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
771248ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
771348ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
771448ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
771548ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
771648ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
771748ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
771848ca2d8aSDwaipayan Ray			}
7719cd261496SGeert Uytterhoeven		}
772048ca2d8aSDwaipayan Ray	}
772148ca2d8aSDwaipayan Ray
772248ca2d8aSDwaipayan Ray	print report_dump();
772348ca2d8aSDwaipayan Ray	if ($summary && !($clean == 1 && $quiet == 1)) {
772448ca2d8aSDwaipayan Ray		print "$filename " if ($summary_file);
772548ca2d8aSDwaipayan Ray		print "total: $cnt_error errors, $cnt_warn warnings, " .
772648ca2d8aSDwaipayan Ray			(($check)? "$cnt_chk checks, " : "") .
772748ca2d8aSDwaipayan Ray			"$cnt_lines lines checked\n";
772848ca2d8aSDwaipayan Ray	}
772948ca2d8aSDwaipayan Ray
773048ca2d8aSDwaipayan Ray	if ($quiet == 0) {
773148ca2d8aSDwaipayan Ray		# If there were any defects found and not already fixing them
773248ca2d8aSDwaipayan Ray		if (!$clean and !$fix) {
7733cd261496SGeert Uytterhoeven			print << "EOM"
77340a920b5bSAndy Whitcroft
77350a920b5bSAndy WhitcroftNOTE: For some of the reported defects, checkpatch may be able to
7736f0a594c1SAndy Whitcroft      mechanically convert to the typical style using --fix or --fix-inplace.
773713214adfSAndy WhitcroftEOM
773813214adfSAndy Whitcroft		}
77396c72ffaaSAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
77406c72ffaaSAndy Whitcroft		# then suggest that.
77416c72ffaaSAndy Whitcroft		if ($rpt_cleaners) {
77426c72ffaaSAndy Whitcroft			$rpt_cleaners = 0;
77438905a67cSAndy Whitcroft			print << "EOM"
7744d2c0a235SAndy Whitcroft
7745ef212196SJoe PerchesNOTE: Whitespace errors detected.
7746ef212196SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7747ef212196SJoe PerchesEOM
7748ef212196SJoe Perches		}
7749ef212196SJoe Perches	}
7750ef212196SJoe Perches
7751ef212196SJoe Perches	if ($clean == 0 && $fix &&
7752ef212196SJoe Perches	    ("@rawlines" ne "@fixed" ||
7753d2c0a235SAndy Whitcroft	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
7754d2c0a235SAndy Whitcroft		my $newfile = $filename;
7755d2c0a235SAndy Whitcroft		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
7756b0781216SMike Frysinger		my $linecount = 0;
7757d8469f16SJoe Perches		my $f;
7758d8469f16SJoe Perches
7759d8469f16SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7760d8469f16SJoe Perches
7761d8469f16SJoe Perches		open($f, '>', $newfile)
7762d2c0a235SAndy Whitcroft		    or die "$P: Can't open $newfile for write\n";
7763d2c0a235SAndy Whitcroft		foreach my $fixed_line (@fixed) {
7764d2c0a235SAndy Whitcroft			$linecount++;
7765d752fcc8SJoe Perches			if ($file) {
7766d752fcc8SJoe Perches				if ($linecount > 3) {
7767d752fcc8SJoe Perches					$fixed_line =~ s/^\+//;
77689624b8d6SJoe Perches					print $f $fixed_line . "\n";
77699624b8d6SJoe Perches				}
77703705ce5bSJoe Perches			} else {
77713705ce5bSJoe Perches				print $f $fixed_line . "\n";
77723705ce5bSJoe Perches			}
7773d752fcc8SJoe Perches		}
7774d752fcc8SJoe Perches		close($f);
77753705ce5bSJoe Perches
77763705ce5bSJoe Perches		if (!$quiet) {
77773705ce5bSJoe Perches			print << "EOM";
77783705ce5bSJoe Perches
77793705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
77803705ce5bSJoe Perches
77813705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
77823705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
77833705ce5bSJoe Perches
77843705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
77853705ce5bSJoe PerchesNo warranties, expressed or implied...
77863705ce5bSJoe PerchesEOM
77873705ce5bSJoe Perches		}
77883705ce5bSJoe Perches	}
77893705ce5bSJoe Perches
77903705ce5bSJoe Perches	if ($quiet == 0) {
77913705ce5bSJoe Perches		print "\n";
7792d8469f16SJoe Perches		if ($clean == 1) {
77933705ce5bSJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
77943705ce5bSJoe Perches		} else {
77953705ce5bSJoe Perches			print "$vname has style problems, please review.\n";
77963705ce5bSJoe Perches		}
77973705ce5bSJoe Perches	}
77983705ce5bSJoe Perches	return $clean;
77993705ce5bSJoe Perches}
78003705ce5bSJoe Perches