162306a36Sopenharmony_ci#!/usr/bin/env perl
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# (c) 2001, Dave Jones. (the file handling bit)
562306a36Sopenharmony_ci# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
662306a36Sopenharmony_ci# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
762306a36Sopenharmony_ci# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
862306a36Sopenharmony_ci# (c) 2010-2018 Joe Perches <joe@perches.com>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciuse strict;
1162306a36Sopenharmony_ciuse warnings;
1262306a36Sopenharmony_ciuse POSIX;
1362306a36Sopenharmony_ciuse File::Basename;
1462306a36Sopenharmony_ciuse Cwd 'abs_path';
1562306a36Sopenharmony_ciuse Term::ANSIColor qw(:constants);
1662306a36Sopenharmony_ciuse Encode qw(decode encode);
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cimy $P = $0;
1962306a36Sopenharmony_cimy $D = dirname(abs_path($P));
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cimy $V = '0.32';
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciuse Getopt::Long qw(:config no_auto_abbrev);
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cimy $quiet = 0;
2662306a36Sopenharmony_cimy $verbose = 0;
2762306a36Sopenharmony_cimy %verbose_messages = ();
2862306a36Sopenharmony_cimy %verbose_emitted = ();
2962306a36Sopenharmony_cimy $tree = 1;
3062306a36Sopenharmony_cimy $chk_signoff = 1;
3162306a36Sopenharmony_cimy $chk_patch = 1;
3262306a36Sopenharmony_cimy $tst_only;
3362306a36Sopenharmony_cimy $emacs = 0;
3462306a36Sopenharmony_cimy $terse = 0;
3562306a36Sopenharmony_cimy $showfile = 0;
3662306a36Sopenharmony_cimy $file = 0;
3762306a36Sopenharmony_cimy $git = 0;
3862306a36Sopenharmony_cimy %git_commits = ();
3962306a36Sopenharmony_cimy $check = 0;
4062306a36Sopenharmony_cimy $check_orig = 0;
4162306a36Sopenharmony_cimy $summary = 1;
4262306a36Sopenharmony_cimy $mailback = 0;
4362306a36Sopenharmony_cimy $summary_file = 0;
4462306a36Sopenharmony_cimy $show_types = 0;
4562306a36Sopenharmony_cimy $list_types = 0;
4662306a36Sopenharmony_cimy $fix = 0;
4762306a36Sopenharmony_cimy $fix_inplace = 0;
4862306a36Sopenharmony_cimy $root;
4962306a36Sopenharmony_cimy $gitroot = $ENV{'GIT_DIR'};
5062306a36Sopenharmony_ci$gitroot = ".git" if !defined($gitroot);
5162306a36Sopenharmony_cimy %debug;
5262306a36Sopenharmony_cimy %camelcase = ();
5362306a36Sopenharmony_cimy %use_type = ();
5462306a36Sopenharmony_cimy @use = ();
5562306a36Sopenharmony_cimy %ignore_type = ();
5662306a36Sopenharmony_cimy @ignore = ();
5762306a36Sopenharmony_cimy $help = 0;
5862306a36Sopenharmony_cimy $configuration_file = ".checkpatch.conf";
5962306a36Sopenharmony_cimy $max_line_length = 100;
6062306a36Sopenharmony_cimy $ignore_perl_version = 0;
6162306a36Sopenharmony_cimy $minimum_perl_version = 5.10.0;
6262306a36Sopenharmony_cimy $min_conf_desc_length = 4;
6362306a36Sopenharmony_cimy $spelling_file = "$D/spelling.txt";
6462306a36Sopenharmony_cimy $codespell = 0;
6562306a36Sopenharmony_cimy $codespellfile = "/usr/share/codespell/dictionary.txt";
6662306a36Sopenharmony_cimy $user_codespellfile = "";
6762306a36Sopenharmony_cimy $conststructsfile = "$D/const_structs.checkpatch";
6862306a36Sopenharmony_cimy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
6962306a36Sopenharmony_cimy $typedefsfile;
7062306a36Sopenharmony_cimy $color = "auto";
7162306a36Sopenharmony_cimy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
7262306a36Sopenharmony_ci# git output parsing needs US English output, so first set backtick child process LANGUAGE
7362306a36Sopenharmony_cimy $git_command ='export LANGUAGE=en_US.UTF-8; git';
7462306a36Sopenharmony_cimy $tabsize = 8;
7562306a36Sopenharmony_cimy ${CONFIG_} = "CONFIG_";
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cimy %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cisub help {
8062306a36Sopenharmony_ci	my ($exitcode) = @_;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	print << "EOM";
8362306a36Sopenharmony_ciUsage: $P [OPTION]... [FILE]...
8462306a36Sopenharmony_ciVersion: $V
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ciOptions:
8762306a36Sopenharmony_ci  -q, --quiet                quiet
8862306a36Sopenharmony_ci  -v, --verbose              verbose mode
8962306a36Sopenharmony_ci  --no-tree                  run without a kernel tree
9062306a36Sopenharmony_ci  --no-signoff               do not check for 'Signed-off-by' line
9162306a36Sopenharmony_ci  --patch                    treat FILE as patchfile (default)
9262306a36Sopenharmony_ci  --emacs                    emacs compile window format
9362306a36Sopenharmony_ci  --terse                    one line per report
9462306a36Sopenharmony_ci  --showfile                 emit diffed file position, not input file position
9562306a36Sopenharmony_ci  -g, --git                  treat FILE as a single commit or git revision range
9662306a36Sopenharmony_ci                             single git commit with:
9762306a36Sopenharmony_ci                               <rev>
9862306a36Sopenharmony_ci                               <rev>^
9962306a36Sopenharmony_ci                               <rev>~n
10062306a36Sopenharmony_ci                             multiple git commits with:
10162306a36Sopenharmony_ci                               <rev1>..<rev2>
10262306a36Sopenharmony_ci                               <rev1>...<rev2>
10362306a36Sopenharmony_ci                               <rev>-<count>
10462306a36Sopenharmony_ci                             git merges are ignored
10562306a36Sopenharmony_ci  -f, --file                 treat FILE as regular source file
10662306a36Sopenharmony_ci  --subjective, --strict     enable more subjective tests
10762306a36Sopenharmony_ci  --list-types               list the possible message types
10862306a36Sopenharmony_ci  --types TYPE(,TYPE2...)    show only these comma separated message types
10962306a36Sopenharmony_ci  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
11062306a36Sopenharmony_ci  --show-types               show the specific message type in the output
11162306a36Sopenharmony_ci  --max-line-length=n        set the maximum line length, (default $max_line_length)
11262306a36Sopenharmony_ci                             if exceeded, warn on patches
11362306a36Sopenharmony_ci                             requires --strict for use with --file
11462306a36Sopenharmony_ci  --min-conf-desc-length=n   set the min description length, if shorter, warn
11562306a36Sopenharmony_ci  --tab-size=n               set the number of spaces for tab (default $tabsize)
11662306a36Sopenharmony_ci  --root=PATH                PATH to the kernel tree root
11762306a36Sopenharmony_ci  --no-summary               suppress the per-file summary
11862306a36Sopenharmony_ci  --mailback                 only produce a report in case of warnings/errors
11962306a36Sopenharmony_ci  --summary-file             include the filename in summary
12062306a36Sopenharmony_ci  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
12162306a36Sopenharmony_ci                             'values', 'possible', 'type', and 'attr' (default
12262306a36Sopenharmony_ci                             is all off)
12362306a36Sopenharmony_ci  --test-only=WORD           report only warnings/errors containing WORD
12462306a36Sopenharmony_ci                             literally
12562306a36Sopenharmony_ci  --fix                      EXPERIMENTAL - may create horrible results
12662306a36Sopenharmony_ci                             If correctable single-line errors exist, create
12762306a36Sopenharmony_ci                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
12862306a36Sopenharmony_ci                             with potential errors corrected to the preferred
12962306a36Sopenharmony_ci                             checkpatch style
13062306a36Sopenharmony_ci  --fix-inplace              EXPERIMENTAL - may create horrible results
13162306a36Sopenharmony_ci                             Is the same as --fix, but overwrites the input
13262306a36Sopenharmony_ci                             file.  It's your fault if there's no backup or git
13362306a36Sopenharmony_ci  --ignore-perl-version      override checking of perl version.  expect
13462306a36Sopenharmony_ci                             runtime errors.
13562306a36Sopenharmony_ci  --codespell                Use the codespell dictionary for spelling/typos
13662306a36Sopenharmony_ci                             (default:$codespellfile)
13762306a36Sopenharmony_ci  --codespellfile            Use this codespell dictionary
13862306a36Sopenharmony_ci  --typedefsfile             Read additional types from this file
13962306a36Sopenharmony_ci  --color[=WHEN]             Use colors 'always', 'never', or only when output
14062306a36Sopenharmony_ci                             is a terminal ('auto'). Default is 'auto'.
14162306a36Sopenharmony_ci  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
14262306a36Sopenharmony_ci                             ${CONFIG_})
14362306a36Sopenharmony_ci  -h, --help, --version      display this help and exit
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ciWhen FILE is - read standard input.
14662306a36Sopenharmony_ciEOM
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	exit($exitcode);
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cisub uniq {
15262306a36Sopenharmony_ci	my %seen;
15362306a36Sopenharmony_ci	return grep { !$seen{$_}++ } @_;
15462306a36Sopenharmony_ci}
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cisub list_types {
15762306a36Sopenharmony_ci	my ($exitcode) = @_;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	my $count = 0;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	local $/ = undef;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	open(my $script, '<', abs_path($P)) or
16462306a36Sopenharmony_ci	    die "$P: Can't read '$P' $!\n";
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	my $text = <$script>;
16762306a36Sopenharmony_ci	close($script);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	my %types = ();
17062306a36Sopenharmony_ci	# Also catch when type or level is passed through a variable
17162306a36Sopenharmony_ci	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
17262306a36Sopenharmony_ci		if (defined($1)) {
17362306a36Sopenharmony_ci			if (exists($types{$2})) {
17462306a36Sopenharmony_ci				$types{$2} .= ",$1" if ($types{$2} ne $1);
17562306a36Sopenharmony_ci			} else {
17662306a36Sopenharmony_ci				$types{$2} = $1;
17762306a36Sopenharmony_ci			}
17862306a36Sopenharmony_ci		} else {
17962306a36Sopenharmony_ci			$types{$2} = "UNDETERMINED";
18062306a36Sopenharmony_ci		}
18162306a36Sopenharmony_ci	}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	print("#\tMessage type\n\n");
18462306a36Sopenharmony_ci	if ($color) {
18562306a36Sopenharmony_ci		print(" ( Color coding: ");
18662306a36Sopenharmony_ci		print(RED . "ERROR" . RESET);
18762306a36Sopenharmony_ci		print(" | ");
18862306a36Sopenharmony_ci		print(YELLOW . "WARNING" . RESET);
18962306a36Sopenharmony_ci		print(" | ");
19062306a36Sopenharmony_ci		print(GREEN . "CHECK" . RESET);
19162306a36Sopenharmony_ci		print(" | ");
19262306a36Sopenharmony_ci		print("Multiple levels / Undetermined");
19362306a36Sopenharmony_ci		print(" )\n\n");
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	foreach my $type (sort keys %types) {
19762306a36Sopenharmony_ci		my $orig_type = $type;
19862306a36Sopenharmony_ci		if ($color) {
19962306a36Sopenharmony_ci			my $level = $types{$type};
20062306a36Sopenharmony_ci			if ($level eq "ERROR") {
20162306a36Sopenharmony_ci				$type = RED . $type . RESET;
20262306a36Sopenharmony_ci			} elsif ($level eq "WARN") {
20362306a36Sopenharmony_ci				$type = YELLOW . $type . RESET;
20462306a36Sopenharmony_ci			} elsif ($level eq "CHK") {
20562306a36Sopenharmony_ci				$type = GREEN . $type . RESET;
20662306a36Sopenharmony_ci			}
20762306a36Sopenharmony_ci		}
20862306a36Sopenharmony_ci		print(++$count . "\t" . $type . "\n");
20962306a36Sopenharmony_ci		if ($verbose && exists($verbose_messages{$orig_type})) {
21062306a36Sopenharmony_ci			my $message = $verbose_messages{$orig_type};
21162306a36Sopenharmony_ci			$message =~ s/\n/\n\t/g;
21262306a36Sopenharmony_ci			print("\t" . $message . "\n\n");
21362306a36Sopenharmony_ci		}
21462306a36Sopenharmony_ci	}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	exit($exitcode);
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cimy $conf = which_conf($configuration_file);
22062306a36Sopenharmony_ciif (-f $conf) {
22162306a36Sopenharmony_ci	my @conf_args;
22262306a36Sopenharmony_ci	open(my $conffile, '<', "$conf")
22362306a36Sopenharmony_ci	    or warn "$P: Can't find a readable $configuration_file file $!\n";
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	while (<$conffile>) {
22662306a36Sopenharmony_ci		my $line = $_;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci		$line =~ s/\s*\n?$//g;
22962306a36Sopenharmony_ci		$line =~ s/^\s*//g;
23062306a36Sopenharmony_ci		$line =~ s/\s+/ /g;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci		next if ($line =~ m/^\s*#/);
23362306a36Sopenharmony_ci		next if ($line =~ m/^\s*$/);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci		my @words = split(" ", $line);
23662306a36Sopenharmony_ci		foreach my $word (@words) {
23762306a36Sopenharmony_ci			last if ($word =~ m/^#/);
23862306a36Sopenharmony_ci			push (@conf_args, $word);
23962306a36Sopenharmony_ci		}
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci	close($conffile);
24262306a36Sopenharmony_ci	unshift(@ARGV, @conf_args) if @conf_args;
24362306a36Sopenharmony_ci}
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cisub load_docs {
24662306a36Sopenharmony_ci	open(my $docs, '<', "$docsfile")
24762306a36Sopenharmony_ci	    or warn "$P: Can't read the documentation file $docsfile $!\n";
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	my $type = '';
25062306a36Sopenharmony_ci	my $desc = '';
25162306a36Sopenharmony_ci	my $in_desc = 0;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	while (<$docs>) {
25462306a36Sopenharmony_ci		chomp;
25562306a36Sopenharmony_ci		my $line = $_;
25662306a36Sopenharmony_ci		$line =~ s/\s+$//;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
25962306a36Sopenharmony_ci			if ($desc ne '') {
26062306a36Sopenharmony_ci				$verbose_messages{$type} = trim($desc);
26162306a36Sopenharmony_ci			}
26262306a36Sopenharmony_ci			$type = $1;
26362306a36Sopenharmony_ci			$desc = '';
26462306a36Sopenharmony_ci			$in_desc = 1;
26562306a36Sopenharmony_ci		} elsif ($in_desc) {
26662306a36Sopenharmony_ci			if ($line =~ /^(?:\s{4,}|$)/) {
26762306a36Sopenharmony_ci				$line =~ s/^\s{4}//;
26862306a36Sopenharmony_ci				$desc .= $line;
26962306a36Sopenharmony_ci				$desc .= "\n";
27062306a36Sopenharmony_ci			} else {
27162306a36Sopenharmony_ci				$verbose_messages{$type} = trim($desc);
27262306a36Sopenharmony_ci				$type = '';
27362306a36Sopenharmony_ci				$desc = '';
27462306a36Sopenharmony_ci				$in_desc = 0;
27562306a36Sopenharmony_ci			}
27662306a36Sopenharmony_ci		}
27762306a36Sopenharmony_ci	}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	if ($desc ne '') {
28062306a36Sopenharmony_ci		$verbose_messages{$type} = trim($desc);
28162306a36Sopenharmony_ci	}
28262306a36Sopenharmony_ci	close($docs);
28362306a36Sopenharmony_ci}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci# Perl's Getopt::Long allows options to take optional arguments after a space.
28662306a36Sopenharmony_ci# Prevent --color by itself from consuming other arguments
28762306a36Sopenharmony_ciforeach (@ARGV) {
28862306a36Sopenharmony_ci	if ($_ eq "--color" || $_ eq "-color") {
28962306a36Sopenharmony_ci		$_ = "--color=$color";
29062306a36Sopenharmony_ci	}
29162306a36Sopenharmony_ci}
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ciGetOptions(
29462306a36Sopenharmony_ci	'q|quiet+'	=> \$quiet,
29562306a36Sopenharmony_ci	'v|verbose!'	=> \$verbose,
29662306a36Sopenharmony_ci	'tree!'		=> \$tree,
29762306a36Sopenharmony_ci	'signoff!'	=> \$chk_signoff,
29862306a36Sopenharmony_ci	'patch!'	=> \$chk_patch,
29962306a36Sopenharmony_ci	'emacs!'	=> \$emacs,
30062306a36Sopenharmony_ci	'terse!'	=> \$terse,
30162306a36Sopenharmony_ci	'showfile!'	=> \$showfile,
30262306a36Sopenharmony_ci	'f|file!'	=> \$file,
30362306a36Sopenharmony_ci	'g|git!'	=> \$git,
30462306a36Sopenharmony_ci	'subjective!'	=> \$check,
30562306a36Sopenharmony_ci	'strict!'	=> \$check,
30662306a36Sopenharmony_ci	'ignore=s'	=> \@ignore,
30762306a36Sopenharmony_ci	'types=s'	=> \@use,
30862306a36Sopenharmony_ci	'show-types!'	=> \$show_types,
30962306a36Sopenharmony_ci	'list-types!'	=> \$list_types,
31062306a36Sopenharmony_ci	'max-line-length=i' => \$max_line_length,
31162306a36Sopenharmony_ci	'min-conf-desc-length=i' => \$min_conf_desc_length,
31262306a36Sopenharmony_ci	'tab-size=i'	=> \$tabsize,
31362306a36Sopenharmony_ci	'root=s'	=> \$root,
31462306a36Sopenharmony_ci	'summary!'	=> \$summary,
31562306a36Sopenharmony_ci	'mailback!'	=> \$mailback,
31662306a36Sopenharmony_ci	'summary-file!'	=> \$summary_file,
31762306a36Sopenharmony_ci	'fix!'		=> \$fix,
31862306a36Sopenharmony_ci	'fix-inplace!'	=> \$fix_inplace,
31962306a36Sopenharmony_ci	'ignore-perl-version!' => \$ignore_perl_version,
32062306a36Sopenharmony_ci	'debug=s'	=> \%debug,
32162306a36Sopenharmony_ci	'test-only=s'	=> \$tst_only,
32262306a36Sopenharmony_ci	'codespell!'	=> \$codespell,
32362306a36Sopenharmony_ci	'codespellfile=s'	=> \$user_codespellfile,
32462306a36Sopenharmony_ci	'typedefsfile=s'	=> \$typedefsfile,
32562306a36Sopenharmony_ci	'color=s'	=> \$color,
32662306a36Sopenharmony_ci	'no-color'	=> \$color,	#keep old behaviors of -nocolor
32762306a36Sopenharmony_ci	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
32862306a36Sopenharmony_ci	'kconfig-prefix=s'	=> \${CONFIG_},
32962306a36Sopenharmony_ci	'h|help'	=> \$help,
33062306a36Sopenharmony_ci	'version'	=> \$help
33162306a36Sopenharmony_ci) or $help = 2;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ciif ($user_codespellfile) {
33462306a36Sopenharmony_ci	# Use the user provided codespell file unconditionally
33562306a36Sopenharmony_ci	$codespellfile = $user_codespellfile;
33662306a36Sopenharmony_ci} elsif (!(-f $codespellfile)) {
33762306a36Sopenharmony_ci	# If /usr/share/codespell/dictionary.txt is not present, try to find it
33862306a36Sopenharmony_ci	# under codespell's install directory: <codespell_root>/data/dictionary.txt
33962306a36Sopenharmony_ci	if (($codespell || $help) && which("python3") ne "") {
34062306a36Sopenharmony_ci		my $python_codespell_dict = << "EOF";
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ciimport os.path as op
34362306a36Sopenharmony_ciimport codespell_lib
34462306a36Sopenharmony_cicodespell_dir = op.dirname(codespell_lib.__file__)
34562306a36Sopenharmony_cicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
34662306a36Sopenharmony_ciprint(codespell_file, end='')
34762306a36Sopenharmony_ciEOF
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci		my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`;
35062306a36Sopenharmony_ci		$codespellfile = $codespell_dict if (-f $codespell_dict);
35162306a36Sopenharmony_ci	}
35262306a36Sopenharmony_ci}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0
35562306a36Sopenharmony_ci# $help is 2 if invalid option is passed - exitcode: 1
35662306a36Sopenharmony_cihelp($help - 1) if ($help);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_cidie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
35962306a36Sopenharmony_cidie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ciif ($color =~ /^[01]$/) {
36262306a36Sopenharmony_ci	$color = !$color;
36362306a36Sopenharmony_ci} elsif ($color =~ /^always$/i) {
36462306a36Sopenharmony_ci	$color = 1;
36562306a36Sopenharmony_ci} elsif ($color =~ /^never$/i) {
36662306a36Sopenharmony_ci	$color = 0;
36762306a36Sopenharmony_ci} elsif ($color =~ /^auto$/i) {
36862306a36Sopenharmony_ci	$color = (-t STDOUT);
36962306a36Sopenharmony_ci} else {
37062306a36Sopenharmony_ci	die "$P: Invalid color mode: $color\n";
37162306a36Sopenharmony_ci}
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ciload_docs() if ($verbose);
37462306a36Sopenharmony_cilist_types(0) if ($list_types);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci$fix = 1 if ($fix_inplace);
37762306a36Sopenharmony_ci$check_orig = $check;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cimy $exit = 0;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cimy $perl_version_ok = 1;
38262306a36Sopenharmony_ciif ($^V && $^V lt $minimum_perl_version) {
38362306a36Sopenharmony_ci	$perl_version_ok = 0;
38462306a36Sopenharmony_ci	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
38562306a36Sopenharmony_ci	exit(1) if (!$ignore_perl_version);
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci#if no filenames are given, push '-' to read patch from stdin
38962306a36Sopenharmony_ciif ($#ARGV < 0) {
39062306a36Sopenharmony_ci	push(@ARGV, '-');
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci# skip TAB size 1 to avoid additional checks on $tabsize - 1
39462306a36Sopenharmony_cidie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_cisub hash_save_array_words {
39762306a36Sopenharmony_ci	my ($hashRef, $arrayRef) = @_;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	my @array = split(/,/, join(',', @$arrayRef));
40062306a36Sopenharmony_ci	foreach my $word (@array) {
40162306a36Sopenharmony_ci		$word =~ s/\s*\n?$//g;
40262306a36Sopenharmony_ci		$word =~ s/^\s*//g;
40362306a36Sopenharmony_ci		$word =~ s/\s+/ /g;
40462306a36Sopenharmony_ci		$word =~ tr/[a-z]/[A-Z]/;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci		next if ($word =~ m/^\s*#/);
40762306a36Sopenharmony_ci		next if ($word =~ m/^\s*$/);
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci		$hashRef->{$word}++;
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cisub hash_show_words {
41462306a36Sopenharmony_ci	my ($hashRef, $prefix) = @_;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	if (keys %$hashRef) {
41762306a36Sopenharmony_ci		print "\nNOTE: $prefix message types:";
41862306a36Sopenharmony_ci		foreach my $word (sort keys %$hashRef) {
41962306a36Sopenharmony_ci			print " $word";
42062306a36Sopenharmony_ci		}
42162306a36Sopenharmony_ci		print "\n";
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cihash_save_array_words(\%ignore_type, \@ignore);
42662306a36Sopenharmony_cihash_save_array_words(\%use_type, \@use);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cimy $dbg_values = 0;
42962306a36Sopenharmony_cimy $dbg_possible = 0;
43062306a36Sopenharmony_cimy $dbg_type = 0;
43162306a36Sopenharmony_cimy $dbg_attr = 0;
43262306a36Sopenharmony_cifor my $key (keys %debug) {
43362306a36Sopenharmony_ci	## no critic
43462306a36Sopenharmony_ci	eval "\${dbg_$key} = '$debug{$key}';";
43562306a36Sopenharmony_ci	die "$@" if ($@);
43662306a36Sopenharmony_ci}
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_cimy $rpt_cleaners = 0;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ciif ($terse) {
44162306a36Sopenharmony_ci	$emacs = 1;
44262306a36Sopenharmony_ci	$quiet++;
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ciif ($tree) {
44662306a36Sopenharmony_ci	if (defined $root) {
44762306a36Sopenharmony_ci		if (!top_of_kernel_tree($root)) {
44862306a36Sopenharmony_ci			die "$P: $root: --root does not point at a valid tree\n";
44962306a36Sopenharmony_ci		}
45062306a36Sopenharmony_ci	} else {
45162306a36Sopenharmony_ci		if (top_of_kernel_tree('.')) {
45262306a36Sopenharmony_ci			$root = '.';
45362306a36Sopenharmony_ci		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
45462306a36Sopenharmony_ci						top_of_kernel_tree($1)) {
45562306a36Sopenharmony_ci			$root = $1;
45662306a36Sopenharmony_ci		}
45762306a36Sopenharmony_ci	}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	if (!defined $root) {
46062306a36Sopenharmony_ci		print "Must be run from the top-level dir. of a kernel tree\n";
46162306a36Sopenharmony_ci		exit(2);
46262306a36Sopenharmony_ci	}
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_cimy $emitted_corrupt = 0;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ciour $Ident	= qr{
46862306a36Sopenharmony_ci			[A-Za-z_][A-Za-z\d_]*
46962306a36Sopenharmony_ci			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
47062306a36Sopenharmony_ci		}x;
47162306a36Sopenharmony_ciour $Storage	= qr{extern|static|asmlinkage};
47262306a36Sopenharmony_ciour $Sparse	= qr{
47362306a36Sopenharmony_ci			__user|
47462306a36Sopenharmony_ci			__kernel|
47562306a36Sopenharmony_ci			__force|
47662306a36Sopenharmony_ci			__iomem|
47762306a36Sopenharmony_ci			__must_check|
47862306a36Sopenharmony_ci			__kprobes|
47962306a36Sopenharmony_ci			__ref|
48062306a36Sopenharmony_ci			__refconst|
48162306a36Sopenharmony_ci			__refdata|
48262306a36Sopenharmony_ci			__rcu|
48362306a36Sopenharmony_ci			__private
48462306a36Sopenharmony_ci		}x;
48562306a36Sopenharmony_ciour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
48662306a36Sopenharmony_ciour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
48762306a36Sopenharmony_ciour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
48862306a36Sopenharmony_ciour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
48962306a36Sopenharmony_ciour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci# Notes to $Attribute:
49262306a36Sopenharmony_ci# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
49362306a36Sopenharmony_ciour $Attribute	= qr{
49462306a36Sopenharmony_ci			const|
49562306a36Sopenharmony_ci			volatile|
49662306a36Sopenharmony_ci			__percpu|
49762306a36Sopenharmony_ci			__nocast|
49862306a36Sopenharmony_ci			__safe|
49962306a36Sopenharmony_ci			__bitwise|
50062306a36Sopenharmony_ci			__packed__|
50162306a36Sopenharmony_ci			__packed2__|
50262306a36Sopenharmony_ci			__naked|
50362306a36Sopenharmony_ci			__maybe_unused|
50462306a36Sopenharmony_ci			__always_unused|
50562306a36Sopenharmony_ci			__noreturn|
50662306a36Sopenharmony_ci			__used|
50762306a36Sopenharmony_ci			__cold|
50862306a36Sopenharmony_ci			__pure|
50962306a36Sopenharmony_ci			__noclone|
51062306a36Sopenharmony_ci			__deprecated|
51162306a36Sopenharmony_ci			__read_mostly|
51262306a36Sopenharmony_ci			__ro_after_init|
51362306a36Sopenharmony_ci			__kprobes|
51462306a36Sopenharmony_ci			$InitAttribute|
51562306a36Sopenharmony_ci			____cacheline_aligned|
51662306a36Sopenharmony_ci			____cacheline_aligned_in_smp|
51762306a36Sopenharmony_ci			____cacheline_internodealigned_in_smp|
51862306a36Sopenharmony_ci			__weak|
51962306a36Sopenharmony_ci			__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
52062306a36Sopenharmony_ci		  }x;
52162306a36Sopenharmony_ciour $Modifier;
52262306a36Sopenharmony_ciour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
52362306a36Sopenharmony_ciour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
52462306a36Sopenharmony_ciour $Lval	= qr{$Ident(?:$Member)*};
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ciour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
52762306a36Sopenharmony_ciour $Binary	= qr{(?i)0b[01]+$Int_type?};
52862306a36Sopenharmony_ciour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
52962306a36Sopenharmony_ciour $Int	= qr{[0-9]+$Int_type?};
53062306a36Sopenharmony_ciour $Octal	= qr{0[0-7]+$Int_type?};
53162306a36Sopenharmony_ciour $String	= qr{(?:\b[Lu])?"[X\t]*"};
53262306a36Sopenharmony_ciour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
53362306a36Sopenharmony_ciour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
53462306a36Sopenharmony_ciour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
53562306a36Sopenharmony_ciour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
53662306a36Sopenharmony_ciour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
53762306a36Sopenharmony_ciour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
53862306a36Sopenharmony_ciour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
53962306a36Sopenharmony_ciour $Arithmetic = qr{\+|-|\*|\/|%};
54062306a36Sopenharmony_ciour $Operators	= qr{
54162306a36Sopenharmony_ci			<=|>=|==|!=|
54262306a36Sopenharmony_ci			=>|->|<<|>>|<|>|!|~|
54362306a36Sopenharmony_ci			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
54462306a36Sopenharmony_ci		  }x;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ciour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ciour $BasicType;
54962306a36Sopenharmony_ciour $NonptrType;
55062306a36Sopenharmony_ciour $NonptrTypeMisordered;
55162306a36Sopenharmony_ciour $NonptrTypeWithAttr;
55262306a36Sopenharmony_ciour $Type;
55362306a36Sopenharmony_ciour $TypeMisordered;
55462306a36Sopenharmony_ciour $Declare;
55562306a36Sopenharmony_ciour $DeclareMisordered;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ciour $NON_ASCII_UTF8	= qr{
55862306a36Sopenharmony_ci	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
55962306a36Sopenharmony_ci	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
56062306a36Sopenharmony_ci	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
56162306a36Sopenharmony_ci	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
56262306a36Sopenharmony_ci	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
56362306a36Sopenharmony_ci	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
56462306a36Sopenharmony_ci	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
56562306a36Sopenharmony_ci}x;
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ciour $UTF8	= qr{
56862306a36Sopenharmony_ci	[\x09\x0A\x0D\x20-\x7E]              # ASCII
56962306a36Sopenharmony_ci	| $NON_ASCII_UTF8
57062306a36Sopenharmony_ci}x;
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ciour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
57362306a36Sopenharmony_ciour $typeOtherOSTypedefs = qr{(?x:
57462306a36Sopenharmony_ci	u_(?:char|short|int|long) |          # bsd
57562306a36Sopenharmony_ci	u(?:nchar|short|int|long)            # sysv
57662306a36Sopenharmony_ci)};
57762306a36Sopenharmony_ciour $typeKernelTypedefs = qr{(?x:
57862306a36Sopenharmony_ci	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
57962306a36Sopenharmony_ci	atomic_t
58062306a36Sopenharmony_ci)};
58162306a36Sopenharmony_ciour $typeStdioTypedefs = qr{(?x:
58262306a36Sopenharmony_ci	FILE
58362306a36Sopenharmony_ci)};
58462306a36Sopenharmony_ciour $typeTypedefs = qr{(?x:
58562306a36Sopenharmony_ci	$typeC99Typedefs\b|
58662306a36Sopenharmony_ci	$typeOtherOSTypedefs\b|
58762306a36Sopenharmony_ci	$typeKernelTypedefs\b|
58862306a36Sopenharmony_ci	$typeStdioTypedefs\b
58962306a36Sopenharmony_ci)};
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ciour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ciour $logFunctions = qr{(?x:
59462306a36Sopenharmony_ci	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
59562306a36Sopenharmony_ci	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
59662306a36Sopenharmony_ci	TP_printk|
59762306a36Sopenharmony_ci	WARN(?:_RATELIMIT|_ONCE|)|
59862306a36Sopenharmony_ci	panic|
59962306a36Sopenharmony_ci	MODULE_[A-Z_]+|
60062306a36Sopenharmony_ci	seq_vprintf|seq_printf|seq_puts
60162306a36Sopenharmony_ci)};
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ciour $allocFunctions = qr{(?x:
60462306a36Sopenharmony_ci	(?:(?:devm_)?
60562306a36Sopenharmony_ci		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
60662306a36Sopenharmony_ci		kstrdup(?:_const)? |
60762306a36Sopenharmony_ci		kmemdup(?:_nul)?) |
60862306a36Sopenharmony_ci	(?:\w+)?alloc_skb(?:_ip_align)? |
60962306a36Sopenharmony_ci				# dev_alloc_skb/netdev_alloc_skb, et al
61062306a36Sopenharmony_ci	dma_alloc_coherent
61162306a36Sopenharmony_ci)};
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ciour $signature_tags = qr{(?xi:
61462306a36Sopenharmony_ci	Signed-off-by:|
61562306a36Sopenharmony_ci	Co-developed-by:|
61662306a36Sopenharmony_ci	Acked-by:|
61762306a36Sopenharmony_ci	Tested-by:|
61862306a36Sopenharmony_ci	Reviewed-by:|
61962306a36Sopenharmony_ci	Reported-by:|
62062306a36Sopenharmony_ci	Suggested-by:|
62162306a36Sopenharmony_ci	To:|
62262306a36Sopenharmony_ci	Cc:
62362306a36Sopenharmony_ci)};
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ciour @link_tags = qw(Link Closes);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci#Create a search and print patterns for all these strings to be used directly below
62862306a36Sopenharmony_ciour $link_tags_search = "";
62962306a36Sopenharmony_ciour $link_tags_print = "";
63062306a36Sopenharmony_ciforeach my $entry (@link_tags) {
63162306a36Sopenharmony_ci	if ($link_tags_search ne "") {
63262306a36Sopenharmony_ci		$link_tags_search .= '|';
63362306a36Sopenharmony_ci		$link_tags_print .= ' or ';
63462306a36Sopenharmony_ci	}
63562306a36Sopenharmony_ci	$entry .= ':';
63662306a36Sopenharmony_ci	$link_tags_search .= $entry;
63762306a36Sopenharmony_ci	$link_tags_print .= "'$entry'";
63862306a36Sopenharmony_ci}
63962306a36Sopenharmony_ci$link_tags_search = "(?:${link_tags_search})";
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ciour $tracing_logging_tags = qr{(?xi:
64262306a36Sopenharmony_ci	[=-]*> |
64362306a36Sopenharmony_ci	<[=-]* |
64462306a36Sopenharmony_ci	\[ |
64562306a36Sopenharmony_ci	\] |
64662306a36Sopenharmony_ci	start |
64762306a36Sopenharmony_ci	called |
64862306a36Sopenharmony_ci	entered |
64962306a36Sopenharmony_ci	entry |
65062306a36Sopenharmony_ci	enter |
65162306a36Sopenharmony_ci	in |
65262306a36Sopenharmony_ci	inside |
65362306a36Sopenharmony_ci	here |
65462306a36Sopenharmony_ci	begin |
65562306a36Sopenharmony_ci	exit |
65662306a36Sopenharmony_ci	end |
65762306a36Sopenharmony_ci	done |
65862306a36Sopenharmony_ci	leave |
65962306a36Sopenharmony_ci	completed |
66062306a36Sopenharmony_ci	out |
66162306a36Sopenharmony_ci	return |
66262306a36Sopenharmony_ci	[\.\!:\s]*
66362306a36Sopenharmony_ci)};
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_cisub edit_distance_min {
66662306a36Sopenharmony_ci	my (@arr) = @_;
66762306a36Sopenharmony_ci	my $len = scalar @arr;
66862306a36Sopenharmony_ci	if ((scalar @arr) < 1) {
66962306a36Sopenharmony_ci		# if underflow, return
67062306a36Sopenharmony_ci		return;
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci	my $min = $arr[0];
67362306a36Sopenharmony_ci	for my $i (0 .. ($len-1)) {
67462306a36Sopenharmony_ci		if ($arr[$i] < $min) {
67562306a36Sopenharmony_ci			$min = $arr[$i];
67662306a36Sopenharmony_ci		}
67762306a36Sopenharmony_ci	}
67862306a36Sopenharmony_ci	return $min;
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cisub get_edit_distance {
68262306a36Sopenharmony_ci	my ($str1, $str2) = @_;
68362306a36Sopenharmony_ci	$str1 = lc($str1);
68462306a36Sopenharmony_ci	$str2 = lc($str2);
68562306a36Sopenharmony_ci	$str1 =~ s/-//g;
68662306a36Sopenharmony_ci	$str2 =~ s/-//g;
68762306a36Sopenharmony_ci	my $len1 = length($str1);
68862306a36Sopenharmony_ci	my $len2 = length($str2);
68962306a36Sopenharmony_ci	# two dimensional array storing minimum edit distance
69062306a36Sopenharmony_ci	my @distance;
69162306a36Sopenharmony_ci	for my $i (0 .. $len1) {
69262306a36Sopenharmony_ci		for my $j (0 .. $len2) {
69362306a36Sopenharmony_ci			if ($i == 0) {
69462306a36Sopenharmony_ci				$distance[$i][$j] = $j;
69562306a36Sopenharmony_ci			} elsif ($j == 0) {
69662306a36Sopenharmony_ci				$distance[$i][$j] = $i;
69762306a36Sopenharmony_ci			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
69862306a36Sopenharmony_ci				$distance[$i][$j] = $distance[$i - 1][$j - 1];
69962306a36Sopenharmony_ci			} else {
70062306a36Sopenharmony_ci				my $dist1 = $distance[$i][$j - 1]; #insert distance
70162306a36Sopenharmony_ci				my $dist2 = $distance[$i - 1][$j]; # remove
70262306a36Sopenharmony_ci				my $dist3 = $distance[$i - 1][$j - 1]; #replace
70362306a36Sopenharmony_ci				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
70462306a36Sopenharmony_ci			}
70562306a36Sopenharmony_ci		}
70662306a36Sopenharmony_ci	}
70762306a36Sopenharmony_ci	return $distance[$len1][$len2];
70862306a36Sopenharmony_ci}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_cisub find_standard_signature {
71162306a36Sopenharmony_ci	my ($sign_off) = @_;
71262306a36Sopenharmony_ci	my @standard_signature_tags = (
71362306a36Sopenharmony_ci		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
71462306a36Sopenharmony_ci		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
71562306a36Sopenharmony_ci	);
71662306a36Sopenharmony_ci	foreach my $signature (@standard_signature_tags) {
71762306a36Sopenharmony_ci		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
71862306a36Sopenharmony_ci	}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	return "";
72162306a36Sopenharmony_ci}
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ciour $obsolete_archives = qr{(?xi:
72462306a36Sopenharmony_ci	\Qfreedesktop.org/archives/dri-devel\E |
72562306a36Sopenharmony_ci	\Qlists.infradead.org\E |
72662306a36Sopenharmony_ci	\Qlkml.org\E |
72762306a36Sopenharmony_ci	\Qmail-archive.com\E |
72862306a36Sopenharmony_ci	\Qmailman.alsa-project.org/pipermail\E |
72962306a36Sopenharmony_ci	\Qmarc.info\E |
73062306a36Sopenharmony_ci	\Qozlabs.org/pipermail\E |
73162306a36Sopenharmony_ci	\Qspinics.net\E
73262306a36Sopenharmony_ci)};
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ciour @typeListMisordered = (
73562306a36Sopenharmony_ci	qr{char\s+(?:un)?signed},
73662306a36Sopenharmony_ci	qr{int\s+(?:(?:un)?signed\s+)?short\s},
73762306a36Sopenharmony_ci	qr{int\s+short(?:\s+(?:un)?signed)},
73862306a36Sopenharmony_ci	qr{short\s+int(?:\s+(?:un)?signed)},
73962306a36Sopenharmony_ci	qr{(?:un)?signed\s+int\s+short},
74062306a36Sopenharmony_ci	qr{short\s+(?:un)?signed},
74162306a36Sopenharmony_ci	qr{long\s+int\s+(?:un)?signed},
74262306a36Sopenharmony_ci	qr{int\s+long\s+(?:un)?signed},
74362306a36Sopenharmony_ci	qr{long\s+(?:un)?signed\s+int},
74462306a36Sopenharmony_ci	qr{int\s+(?:un)?signed\s+long},
74562306a36Sopenharmony_ci	qr{int\s+(?:un)?signed},
74662306a36Sopenharmony_ci	qr{int\s+long\s+long\s+(?:un)?signed},
74762306a36Sopenharmony_ci	qr{long\s+long\s+int\s+(?:un)?signed},
74862306a36Sopenharmony_ci	qr{long\s+long\s+(?:un)?signed\s+int},
74962306a36Sopenharmony_ci	qr{long\s+long\s+(?:un)?signed},
75062306a36Sopenharmony_ci	qr{long\s+(?:un)?signed},
75162306a36Sopenharmony_ci);
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ciour @typeList = (
75462306a36Sopenharmony_ci	qr{void},
75562306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?char},
75662306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?short\s+int},
75762306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?short},
75862306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?int},
75962306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+int},
76062306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
76162306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+long},
76262306a36Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long},
76362306a36Sopenharmony_ci	qr{(?:un)?signed},
76462306a36Sopenharmony_ci	qr{float},
76562306a36Sopenharmony_ci	qr{double},
76662306a36Sopenharmony_ci	qr{bool},
76762306a36Sopenharmony_ci	qr{struct\s+$Ident},
76862306a36Sopenharmony_ci	qr{union\s+$Ident},
76962306a36Sopenharmony_ci	qr{enum\s+$Ident},
77062306a36Sopenharmony_ci	qr{${Ident}_t},
77162306a36Sopenharmony_ci	qr{${Ident}_handler},
77262306a36Sopenharmony_ci	qr{${Ident}_handler_fn},
77362306a36Sopenharmony_ci	@typeListMisordered,
77462306a36Sopenharmony_ci);
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ciour $C90_int_types = qr{(?x:
77762306a36Sopenharmony_ci	long\s+long\s+int\s+(?:un)?signed|
77862306a36Sopenharmony_ci	long\s+long\s+(?:un)?signed\s+int|
77962306a36Sopenharmony_ci	long\s+long\s+(?:un)?signed|
78062306a36Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+long\s+int|
78162306a36Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+long|
78262306a36Sopenharmony_ci	int\s+long\s+long\s+(?:un)?signed|
78362306a36Sopenharmony_ci	int\s+(?:(?:un)?signed\s+)?long\s+long|
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	long\s+int\s+(?:un)?signed|
78662306a36Sopenharmony_ci	long\s+(?:un)?signed\s+int|
78762306a36Sopenharmony_ci	long\s+(?:un)?signed|
78862306a36Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+int|
78962306a36Sopenharmony_ci	(?:(?:un)?signed\s+)?long|
79062306a36Sopenharmony_ci	int\s+long\s+(?:un)?signed|
79162306a36Sopenharmony_ci	int\s+(?:(?:un)?signed\s+)?long|
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci	int\s+(?:un)?signed|
79462306a36Sopenharmony_ci	(?:(?:un)?signed\s+)?int
79562306a36Sopenharmony_ci)};
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ciour @typeListFile = ();
79862306a36Sopenharmony_ciour @typeListWithAttr = (
79962306a36Sopenharmony_ci	@typeList,
80062306a36Sopenharmony_ci	qr{struct\s+$InitAttribute\s+$Ident},
80162306a36Sopenharmony_ci	qr{union\s+$InitAttribute\s+$Ident},
80262306a36Sopenharmony_ci);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ciour @modifierList = (
80562306a36Sopenharmony_ci	qr{fastcall},
80662306a36Sopenharmony_ci);
80762306a36Sopenharmony_ciour @modifierListFile = ();
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ciour @mode_permission_funcs = (
81062306a36Sopenharmony_ci	["module_param", 3],
81162306a36Sopenharmony_ci	["module_param_(?:array|named|string)", 4],
81262306a36Sopenharmony_ci	["module_param_array_named", 5],
81362306a36Sopenharmony_ci	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
81462306a36Sopenharmony_ci	["proc_create(?:_data|)", 2],
81562306a36Sopenharmony_ci	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
81662306a36Sopenharmony_ci	["IIO_DEV_ATTR_[A-Z_]+", 1],
81762306a36Sopenharmony_ci	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
81862306a36Sopenharmony_ci	["SENSOR_TEMPLATE(?:_2|)", 3],
81962306a36Sopenharmony_ci	["__ATTR", 2],
82062306a36Sopenharmony_ci);
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_cimy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci#Create a search pattern for all these functions to speed up a loop below
82562306a36Sopenharmony_ciour $mode_perms_search = "";
82662306a36Sopenharmony_ciforeach my $entry (@mode_permission_funcs) {
82762306a36Sopenharmony_ci	$mode_perms_search .= '|' if ($mode_perms_search ne "");
82862306a36Sopenharmony_ci	$mode_perms_search .= $entry->[0];
82962306a36Sopenharmony_ci}
83062306a36Sopenharmony_ci$mode_perms_search = "(?:${mode_perms_search})";
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ciour %deprecated_apis = (
83362306a36Sopenharmony_ci	"synchronize_rcu_bh"			=> "synchronize_rcu",
83462306a36Sopenharmony_ci	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
83562306a36Sopenharmony_ci	"call_rcu_bh"				=> "call_rcu",
83662306a36Sopenharmony_ci	"rcu_barrier_bh"			=> "rcu_barrier",
83762306a36Sopenharmony_ci	"synchronize_sched"			=> "synchronize_rcu",
83862306a36Sopenharmony_ci	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
83962306a36Sopenharmony_ci	"call_rcu_sched"			=> "call_rcu",
84062306a36Sopenharmony_ci	"rcu_barrier_sched"			=> "rcu_barrier",
84162306a36Sopenharmony_ci	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
84262306a36Sopenharmony_ci	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
84362306a36Sopenharmony_ci	"kmap"					=> "kmap_local_page",
84462306a36Sopenharmony_ci	"kunmap"				=> "kunmap_local",
84562306a36Sopenharmony_ci	"kmap_atomic"				=> "kmap_local_page",
84662306a36Sopenharmony_ci	"kunmap_atomic"				=> "kunmap_local",
84762306a36Sopenharmony_ci);
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci#Create a search pattern for all these strings to speed up a loop below
85062306a36Sopenharmony_ciour $deprecated_apis_search = "";
85162306a36Sopenharmony_ciforeach my $entry (keys %deprecated_apis) {
85262306a36Sopenharmony_ci	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
85362306a36Sopenharmony_ci	$deprecated_apis_search .= $entry;
85462306a36Sopenharmony_ci}
85562306a36Sopenharmony_ci$deprecated_apis_search = "(?:${deprecated_apis_search})";
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ciour $mode_perms_world_writable = qr{
85862306a36Sopenharmony_ci	S_IWUGO		|
85962306a36Sopenharmony_ci	S_IWOTH		|
86062306a36Sopenharmony_ci	S_IRWXUGO	|
86162306a36Sopenharmony_ci	S_IALLUGO	|
86262306a36Sopenharmony_ci	0[0-7][0-7][2367]
86362306a36Sopenharmony_ci}x;
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ciour %mode_permission_string_types = (
86662306a36Sopenharmony_ci	"S_IRWXU" => 0700,
86762306a36Sopenharmony_ci	"S_IRUSR" => 0400,
86862306a36Sopenharmony_ci	"S_IWUSR" => 0200,
86962306a36Sopenharmony_ci	"S_IXUSR" => 0100,
87062306a36Sopenharmony_ci	"S_IRWXG" => 0070,
87162306a36Sopenharmony_ci	"S_IRGRP" => 0040,
87262306a36Sopenharmony_ci	"S_IWGRP" => 0020,
87362306a36Sopenharmony_ci	"S_IXGRP" => 0010,
87462306a36Sopenharmony_ci	"S_IRWXO" => 0007,
87562306a36Sopenharmony_ci	"S_IROTH" => 0004,
87662306a36Sopenharmony_ci	"S_IWOTH" => 0002,
87762306a36Sopenharmony_ci	"S_IXOTH" => 0001,
87862306a36Sopenharmony_ci	"S_IRWXUGO" => 0777,
87962306a36Sopenharmony_ci	"S_IRUGO" => 0444,
88062306a36Sopenharmony_ci	"S_IWUGO" => 0222,
88162306a36Sopenharmony_ci	"S_IXUGO" => 0111,
88262306a36Sopenharmony_ci);
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci#Create a search pattern for all these strings to speed up a loop below
88562306a36Sopenharmony_ciour $mode_perms_string_search = "";
88662306a36Sopenharmony_ciforeach my $entry (keys %mode_permission_string_types) {
88762306a36Sopenharmony_ci	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
88862306a36Sopenharmony_ci	$mode_perms_string_search .= $entry;
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ciour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
89162306a36Sopenharmony_ciour $multi_mode_perms_string_search = qr{
89262306a36Sopenharmony_ci	${single_mode_perms_string_search}
89362306a36Sopenharmony_ci	(?:\s*\|\s*${single_mode_perms_string_search})*
89462306a36Sopenharmony_ci}x;
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_cisub perms_to_octal {
89762306a36Sopenharmony_ci	my ($string) = @_;
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	my $val = "";
90262306a36Sopenharmony_ci	my $oval = "";
90362306a36Sopenharmony_ci	my $to = 0;
90462306a36Sopenharmony_ci	my $curpos = 0;
90562306a36Sopenharmony_ci	my $lastpos = 0;
90662306a36Sopenharmony_ci	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
90762306a36Sopenharmony_ci		$curpos = pos($string);
90862306a36Sopenharmony_ci		my $match = $2;
90962306a36Sopenharmony_ci		my $omatch = $1;
91062306a36Sopenharmony_ci		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
91162306a36Sopenharmony_ci		$lastpos = $curpos;
91262306a36Sopenharmony_ci		$to |= $mode_permission_string_types{$match};
91362306a36Sopenharmony_ci		$val .= '\s*\|\s*' if ($val ne "");
91462306a36Sopenharmony_ci		$val .= $match;
91562306a36Sopenharmony_ci		$oval .= $omatch;
91662306a36Sopenharmony_ci	}
91762306a36Sopenharmony_ci	$oval =~ s/^\s*\|\s*//;
91862306a36Sopenharmony_ci	$oval =~ s/\s*\|\s*$//;
91962306a36Sopenharmony_ci	return sprintf("%04o", $to);
92062306a36Sopenharmony_ci}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ciour $allowed_asm_includes = qr{(?x:
92362306a36Sopenharmony_ci	irq|
92462306a36Sopenharmony_ci	memory|
92562306a36Sopenharmony_ci	time|
92662306a36Sopenharmony_ci	reboot
92762306a36Sopenharmony_ci)};
92862306a36Sopenharmony_ci# memory.h: ARM has a custom one
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci# Load common spelling mistakes and build regular expression list.
93162306a36Sopenharmony_cimy $misspellings;
93262306a36Sopenharmony_cimy %spelling_fix;
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ciif (open(my $spelling, '<', $spelling_file)) {
93562306a36Sopenharmony_ci	while (<$spelling>) {
93662306a36Sopenharmony_ci		my $line = $_;
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci		$line =~ s/\s*\n?$//g;
93962306a36Sopenharmony_ci		$line =~ s/^\s*//g;
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci		next if ($line =~ m/^\s*#/);
94262306a36Sopenharmony_ci		next if ($line =~ m/^\s*$/);
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci		my ($suspect, $fix) = split(/\|\|/, $line);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci		$spelling_fix{$suspect} = $fix;
94762306a36Sopenharmony_ci	}
94862306a36Sopenharmony_ci	close($spelling);
94962306a36Sopenharmony_ci} else {
95062306a36Sopenharmony_ci	warn "No typos will be found - file '$spelling_file': $!\n";
95162306a36Sopenharmony_ci}
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ciif ($codespell) {
95462306a36Sopenharmony_ci	if (open(my $spelling, '<', $codespellfile)) {
95562306a36Sopenharmony_ci		while (<$spelling>) {
95662306a36Sopenharmony_ci			my $line = $_;
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci			$line =~ s/\s*\n?$//g;
95962306a36Sopenharmony_ci			$line =~ s/^\s*//g;
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci			next if ($line =~ m/^\s*#/);
96262306a36Sopenharmony_ci			next if ($line =~ m/^\s*$/);
96362306a36Sopenharmony_ci			next if ($line =~ m/, disabled/i);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci			$line =~ s/,.*$//;
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci			my ($suspect, $fix) = split(/->/, $line);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci			$spelling_fix{$suspect} = $fix;
97062306a36Sopenharmony_ci		}
97162306a36Sopenharmony_ci		close($spelling);
97262306a36Sopenharmony_ci	} else {
97362306a36Sopenharmony_ci		warn "No codespell typos will be found - file '$codespellfile': $!\n";
97462306a36Sopenharmony_ci	}
97562306a36Sopenharmony_ci}
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_cisub read_words {
98062306a36Sopenharmony_ci	my ($wordsRef, $file) = @_;
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	if (open(my $words, '<', $file)) {
98362306a36Sopenharmony_ci		while (<$words>) {
98462306a36Sopenharmony_ci			my $line = $_;
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ci			$line =~ s/\s*\n?$//g;
98762306a36Sopenharmony_ci			$line =~ s/^\s*//g;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci			next if ($line =~ m/^\s*#/);
99062306a36Sopenharmony_ci			next if ($line =~ m/^\s*$/);
99162306a36Sopenharmony_ci			if ($line =~ /\s/) {
99262306a36Sopenharmony_ci				print("$file: '$line' invalid - ignored\n");
99362306a36Sopenharmony_ci				next;
99462306a36Sopenharmony_ci			}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci			$$wordsRef .= '|' if (defined $$wordsRef);
99762306a36Sopenharmony_ci			$$wordsRef .= $line;
99862306a36Sopenharmony_ci		}
99962306a36Sopenharmony_ci		close($file);
100062306a36Sopenharmony_ci		return 1;
100162306a36Sopenharmony_ci	}
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	return 0;
100462306a36Sopenharmony_ci}
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_cimy $const_structs;
100762306a36Sopenharmony_ciif (show_type("CONST_STRUCT")) {
100862306a36Sopenharmony_ci	read_words(\$const_structs, $conststructsfile)
100962306a36Sopenharmony_ci	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
101062306a36Sopenharmony_ci}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ciif (defined($typedefsfile)) {
101362306a36Sopenharmony_ci	my $typeOtherTypedefs;
101462306a36Sopenharmony_ci	read_words(\$typeOtherTypedefs, $typedefsfile)
101562306a36Sopenharmony_ci	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
101662306a36Sopenharmony_ci	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
101762306a36Sopenharmony_ci}
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_cisub build_types {
102062306a36Sopenharmony_ci	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
102162306a36Sopenharmony_ci	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
102262306a36Sopenharmony_ci	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
102362306a36Sopenharmony_ci	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
102462306a36Sopenharmony_ci	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
102562306a36Sopenharmony_ci	$BasicType	= qr{
102662306a36Sopenharmony_ci				(?:$typeTypedefs\b)|
102762306a36Sopenharmony_ci				(?:${all}\b)
102862306a36Sopenharmony_ci		}x;
102962306a36Sopenharmony_ci	$NonptrType	= qr{
103062306a36Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
103162306a36Sopenharmony_ci			(?:
103262306a36Sopenharmony_ci				(?:typeof|__typeof__)\s*\([^\)]*\)|
103362306a36Sopenharmony_ci				(?:$typeTypedefs\b)|
103462306a36Sopenharmony_ci				(?:${all}\b)
103562306a36Sopenharmony_ci			)
103662306a36Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
103762306a36Sopenharmony_ci		  }x;
103862306a36Sopenharmony_ci	$NonptrTypeMisordered	= qr{
103962306a36Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
104062306a36Sopenharmony_ci			(?:
104162306a36Sopenharmony_ci				(?:${Misordered}\b)
104262306a36Sopenharmony_ci			)
104362306a36Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
104462306a36Sopenharmony_ci		  }x;
104562306a36Sopenharmony_ci	$NonptrTypeWithAttr	= qr{
104662306a36Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
104762306a36Sopenharmony_ci			(?:
104862306a36Sopenharmony_ci				(?:typeof|__typeof__)\s*\([^\)]*\)|
104962306a36Sopenharmony_ci				(?:$typeTypedefs\b)|
105062306a36Sopenharmony_ci				(?:${allWithAttr}\b)
105162306a36Sopenharmony_ci			)
105262306a36Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
105362306a36Sopenharmony_ci		  }x;
105462306a36Sopenharmony_ci	$Type	= qr{
105562306a36Sopenharmony_ci			$NonptrType
105662306a36Sopenharmony_ci			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
105762306a36Sopenharmony_ci			(?:\s+$Inline|\s+$Modifier)*
105862306a36Sopenharmony_ci		  }x;
105962306a36Sopenharmony_ci	$TypeMisordered	= qr{
106062306a36Sopenharmony_ci			$NonptrTypeMisordered
106162306a36Sopenharmony_ci			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
106262306a36Sopenharmony_ci			(?:\s+$Inline|\s+$Modifier)*
106362306a36Sopenharmony_ci		  }x;
106462306a36Sopenharmony_ci	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
106562306a36Sopenharmony_ci	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
106662306a36Sopenharmony_ci}
106762306a36Sopenharmony_cibuild_types();
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ciour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci# Using $balanced_parens, $LvalOrFunc, or $FuncArg
107262306a36Sopenharmony_ci# requires at least perl version v5.10.0
107362306a36Sopenharmony_ci# Any use must be runtime checked with $^V
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ciour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
107662306a36Sopenharmony_ciour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
107762306a36Sopenharmony_ciour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ciour $declaration_macros = qr{(?x:
108062306a36Sopenharmony_ci	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
108162306a36Sopenharmony_ci	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
108262306a36Sopenharmony_ci	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(|
108362306a36Sopenharmony_ci	(?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\(
108462306a36Sopenharmony_ci)};
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ciour %allow_repeated_words = (
108762306a36Sopenharmony_ci	add => '',
108862306a36Sopenharmony_ci	added => '',
108962306a36Sopenharmony_ci	bad => '',
109062306a36Sopenharmony_ci	be => '',
109162306a36Sopenharmony_ci);
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_cisub deparenthesize {
109462306a36Sopenharmony_ci	my ($string) = @_;
109562306a36Sopenharmony_ci	return "" if (!defined($string));
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci	while ($string =~ /^\s*\(.*\)\s*$/) {
109862306a36Sopenharmony_ci		$string =~ s@^\s*\(\s*@@;
109962306a36Sopenharmony_ci		$string =~ s@\s*\)\s*$@@;
110062306a36Sopenharmony_ci	}
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci	$string =~ s@\s+@ @g;
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci	return $string;
110562306a36Sopenharmony_ci}
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_cisub seed_camelcase_file {
110862306a36Sopenharmony_ci	my ($file) = @_;
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	return if (!(-f $file));
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci	local $/;
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	open(my $include_file, '<', "$file")
111562306a36Sopenharmony_ci	    or warn "$P: Can't read '$file' $!\n";
111662306a36Sopenharmony_ci	my $text = <$include_file>;
111762306a36Sopenharmony_ci	close($include_file);
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	my @lines = split('\n', $text);
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	foreach my $line (@lines) {
112262306a36Sopenharmony_ci		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
112362306a36Sopenharmony_ci		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
112462306a36Sopenharmony_ci			$camelcase{$1} = 1;
112562306a36Sopenharmony_ci		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
112662306a36Sopenharmony_ci			$camelcase{$1} = 1;
112762306a36Sopenharmony_ci		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
112862306a36Sopenharmony_ci			$camelcase{$1} = 1;
112962306a36Sopenharmony_ci		}
113062306a36Sopenharmony_ci	}
113162306a36Sopenharmony_ci}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ciour %maintained_status = ();
113462306a36Sopenharmony_ci
113562306a36Sopenharmony_cisub is_maintained_obsolete {
113662306a36Sopenharmony_ci	my ($filename) = @_;
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci	if (!exists($maintained_status{$filename})) {
114162306a36Sopenharmony_ci		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
114262306a36Sopenharmony_ci	}
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci	return $maintained_status{$filename} =~ /obsolete/i;
114562306a36Sopenharmony_ci}
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_cisub is_SPDX_License_valid {
114862306a36Sopenharmony_ci	my ($license) = @_;
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	my $root_path = abs_path($root);
115362306a36Sopenharmony_ci	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
115462306a36Sopenharmony_ci	return 0 if ($status ne "");
115562306a36Sopenharmony_ci	return 1;
115662306a36Sopenharmony_ci}
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_cimy $camelcase_seeded = 0;
115962306a36Sopenharmony_cisub seed_camelcase_includes {
116062306a36Sopenharmony_ci	return if ($camelcase_seeded);
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	my $files;
116362306a36Sopenharmony_ci	my $camelcase_cache = "";
116462306a36Sopenharmony_ci	my @include_files = ();
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci	$camelcase_seeded = 1;
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	if (-e "$gitroot") {
116962306a36Sopenharmony_ci		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
117062306a36Sopenharmony_ci		chomp $git_last_include_commit;
117162306a36Sopenharmony_ci		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
117262306a36Sopenharmony_ci	} else {
117362306a36Sopenharmony_ci		my $last_mod_date = 0;
117462306a36Sopenharmony_ci		$files = `find $root/include -name "*.h"`;
117562306a36Sopenharmony_ci		@include_files = split('\n', $files);
117662306a36Sopenharmony_ci		foreach my $file (@include_files) {
117762306a36Sopenharmony_ci			my $date = POSIX::strftime("%Y%m%d%H%M",
117862306a36Sopenharmony_ci						   localtime((stat $file)[9]));
117962306a36Sopenharmony_ci			$last_mod_date = $date if ($last_mod_date < $date);
118062306a36Sopenharmony_ci		}
118162306a36Sopenharmony_ci		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
118262306a36Sopenharmony_ci	}
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	if ($camelcase_cache ne "" && -f $camelcase_cache) {
118562306a36Sopenharmony_ci		open(my $camelcase_file, '<', "$camelcase_cache")
118662306a36Sopenharmony_ci		    or warn "$P: Can't read '$camelcase_cache' $!\n";
118762306a36Sopenharmony_ci		while (<$camelcase_file>) {
118862306a36Sopenharmony_ci			chomp;
118962306a36Sopenharmony_ci			$camelcase{$_} = 1;
119062306a36Sopenharmony_ci		}
119162306a36Sopenharmony_ci		close($camelcase_file);
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci		return;
119462306a36Sopenharmony_ci	}
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci	if (-e "$gitroot") {
119762306a36Sopenharmony_ci		$files = `${git_command} ls-files "include/*.h"`;
119862306a36Sopenharmony_ci		@include_files = split('\n', $files);
119962306a36Sopenharmony_ci	}
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	foreach my $file (@include_files) {
120262306a36Sopenharmony_ci		seed_camelcase_file($file);
120362306a36Sopenharmony_ci	}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	if ($camelcase_cache ne "") {
120662306a36Sopenharmony_ci		unlink glob ".checkpatch-camelcase.*";
120762306a36Sopenharmony_ci		open(my $camelcase_file, '>', "$camelcase_cache")
120862306a36Sopenharmony_ci		    or warn "$P: Can't write '$camelcase_cache' $!\n";
120962306a36Sopenharmony_ci		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
121062306a36Sopenharmony_ci			print $camelcase_file ("$_\n");
121162306a36Sopenharmony_ci		}
121262306a36Sopenharmony_ci		close($camelcase_file);
121362306a36Sopenharmony_ci	}
121462306a36Sopenharmony_ci}
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_cisub git_is_single_file {
121762306a36Sopenharmony_ci	my ($filename) = @_;
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
122262306a36Sopenharmony_ci	my $count = $output =~ tr/\n//;
122362306a36Sopenharmony_ci	return $count eq 1 && $output =~ m{^${filename}$};
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_cisub git_commit_info {
122762306a36Sopenharmony_ci	my ($commit, $id, $desc) = @_;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
123262306a36Sopenharmony_ci	$output =~ s/^\s*//gm;
123362306a36Sopenharmony_ci	my @lines = split("\n", $output);
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci	return ($id, $desc) if ($#lines < 0);
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
123862306a36Sopenharmony_ci# Maybe one day convert this block of bash into something that returns
123962306a36Sopenharmony_ci# all matching commit ids, but it's very slow...
124062306a36Sopenharmony_ci#
124162306a36Sopenharmony_ci#		echo "checking commits $1..."
124262306a36Sopenharmony_ci#		git rev-list --remotes | grep -i "^$1" |
124362306a36Sopenharmony_ci#		while read line ; do
124462306a36Sopenharmony_ci#		    git log --format='%H %s' -1 $line |
124562306a36Sopenharmony_ci#		    echo "commit $(cut -c 1-12,41-)"
124662306a36Sopenharmony_ci#		done
124762306a36Sopenharmony_ci	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
124862306a36Sopenharmony_ci		 $lines[0] =~ /^fatal: bad object $commit/) {
124962306a36Sopenharmony_ci		$id = undef;
125062306a36Sopenharmony_ci	} else {
125162306a36Sopenharmony_ci		$id = substr($lines[0], 0, 12);
125262306a36Sopenharmony_ci		$desc = substr($lines[0], 41);
125362306a36Sopenharmony_ci	}
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	return ($id, $desc);
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci$chk_signoff = 0 if ($file);
125962306a36Sopenharmony_ci
126062306a36Sopenharmony_cimy @rawlines = ();
126162306a36Sopenharmony_cimy @lines = ();
126262306a36Sopenharmony_cimy @fixed = ();
126362306a36Sopenharmony_cimy @fixed_inserted = ();
126462306a36Sopenharmony_cimy @fixed_deleted = ();
126562306a36Sopenharmony_cimy $fixlinenr = -1;
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci# If input is git commits, extract all commits from the commit expressions.
126862306a36Sopenharmony_ci# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
126962306a36Sopenharmony_cidie "$P: No git repository found\n" if ($git && !-e "$gitroot");
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ciif ($git) {
127262306a36Sopenharmony_ci	my @commits = ();
127362306a36Sopenharmony_ci	foreach my $commit_expr (@ARGV) {
127462306a36Sopenharmony_ci		my $git_range;
127562306a36Sopenharmony_ci		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
127662306a36Sopenharmony_ci			$git_range = "-$2 $1";
127762306a36Sopenharmony_ci		} elsif ($commit_expr =~ m/\.\./) {
127862306a36Sopenharmony_ci			$git_range = "$commit_expr";
127962306a36Sopenharmony_ci		} else {
128062306a36Sopenharmony_ci			$git_range = "-1 $commit_expr";
128162306a36Sopenharmony_ci		}
128262306a36Sopenharmony_ci		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
128362306a36Sopenharmony_ci		foreach my $line (split(/\n/, $lines)) {
128462306a36Sopenharmony_ci			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
128562306a36Sopenharmony_ci			next if (!defined($1) || !defined($2));
128662306a36Sopenharmony_ci			my $sha1 = $1;
128762306a36Sopenharmony_ci			my $subject = $2;
128862306a36Sopenharmony_ci			unshift(@commits, $sha1);
128962306a36Sopenharmony_ci			$git_commits{$sha1} = $subject;
129062306a36Sopenharmony_ci		}
129162306a36Sopenharmony_ci	}
129262306a36Sopenharmony_ci	die "$P: no git commits after extraction!\n" if (@commits == 0);
129362306a36Sopenharmony_ci	@ARGV = @commits;
129462306a36Sopenharmony_ci}
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_cimy $vname;
129762306a36Sopenharmony_ci$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
129862306a36Sopenharmony_cifor my $filename (@ARGV) {
129962306a36Sopenharmony_ci	my $FILE;
130062306a36Sopenharmony_ci	my $is_git_file = git_is_single_file($filename);
130162306a36Sopenharmony_ci	my $oldfile = $file;
130262306a36Sopenharmony_ci	$file = 1 if ($is_git_file);
130362306a36Sopenharmony_ci	if ($git) {
130462306a36Sopenharmony_ci		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
130562306a36Sopenharmony_ci			die "$P: $filename: git format-patch failed - $!\n";
130662306a36Sopenharmony_ci	} elsif ($file) {
130762306a36Sopenharmony_ci		open($FILE, '-|', "diff -u /dev/null $filename") ||
130862306a36Sopenharmony_ci			die "$P: $filename: diff failed - $!\n";
130962306a36Sopenharmony_ci	} elsif ($filename eq '-') {
131062306a36Sopenharmony_ci		open($FILE, '<&STDIN');
131162306a36Sopenharmony_ci	} else {
131262306a36Sopenharmony_ci		open($FILE, '<', "$filename") ||
131362306a36Sopenharmony_ci			die "$P: $filename: open failed - $!\n";
131462306a36Sopenharmony_ci	}
131562306a36Sopenharmony_ci	if ($filename eq '-') {
131662306a36Sopenharmony_ci		$vname = 'Your patch';
131762306a36Sopenharmony_ci	} elsif ($git) {
131862306a36Sopenharmony_ci		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
131962306a36Sopenharmony_ci	} else {
132062306a36Sopenharmony_ci		$vname = $filename;
132162306a36Sopenharmony_ci	}
132262306a36Sopenharmony_ci	while (<$FILE>) {
132362306a36Sopenharmony_ci		chomp;
132462306a36Sopenharmony_ci		push(@rawlines, $_);
132562306a36Sopenharmony_ci		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
132662306a36Sopenharmony_ci	}
132762306a36Sopenharmony_ci	close($FILE);
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci	if ($#ARGV > 0 && $quiet == 0) {
133062306a36Sopenharmony_ci		print '-' x length($vname) . "\n";
133162306a36Sopenharmony_ci		print "$vname\n";
133262306a36Sopenharmony_ci		print '-' x length($vname) . "\n";
133362306a36Sopenharmony_ci	}
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ci	if (!process($filename)) {
133662306a36Sopenharmony_ci		$exit = 1;
133762306a36Sopenharmony_ci	}
133862306a36Sopenharmony_ci	@rawlines = ();
133962306a36Sopenharmony_ci	@lines = ();
134062306a36Sopenharmony_ci	@fixed = ();
134162306a36Sopenharmony_ci	@fixed_inserted = ();
134262306a36Sopenharmony_ci	@fixed_deleted = ();
134362306a36Sopenharmony_ci	$fixlinenr = -1;
134462306a36Sopenharmony_ci	@modifierListFile = ();
134562306a36Sopenharmony_ci	@typeListFile = ();
134662306a36Sopenharmony_ci	build_types();
134762306a36Sopenharmony_ci	$file = $oldfile if ($is_git_file);
134862306a36Sopenharmony_ci}
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ciif (!$quiet) {
135162306a36Sopenharmony_ci	hash_show_words(\%use_type, "Used");
135262306a36Sopenharmony_ci	hash_show_words(\%ignore_type, "Ignored");
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	if (!$perl_version_ok) {
135562306a36Sopenharmony_ci		print << "EOM"
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ciNOTE: perl $^V is not modern enough to detect all possible issues.
135862306a36Sopenharmony_ci      An upgrade to at least perl $minimum_perl_version is suggested.
135962306a36Sopenharmony_ciEOM
136062306a36Sopenharmony_ci	}
136162306a36Sopenharmony_ci	if ($exit) {
136262306a36Sopenharmony_ci		print << "EOM"
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ciNOTE: If any of the errors are false positives, please report
136562306a36Sopenharmony_ci      them to the maintainer, see CHECKPATCH in MAINTAINERS.
136662306a36Sopenharmony_ciEOM
136762306a36Sopenharmony_ci	}
136862306a36Sopenharmony_ci}
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ciexit($exit);
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_cisub top_of_kernel_tree {
137362306a36Sopenharmony_ci	my ($root) = @_;
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	my @tree_check = (
137662306a36Sopenharmony_ci		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
137762306a36Sopenharmony_ci		"README", "Documentation", "arch", "include", "drivers",
137862306a36Sopenharmony_ci		"fs", "init", "ipc", "kernel", "lib", "scripts",
137962306a36Sopenharmony_ci	);
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	foreach my $check (@tree_check) {
138262306a36Sopenharmony_ci		if (! -e $root . '/' . $check) {
138362306a36Sopenharmony_ci			return 0;
138462306a36Sopenharmony_ci		}
138562306a36Sopenharmony_ci	}
138662306a36Sopenharmony_ci	return 1;
138762306a36Sopenharmony_ci}
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_cisub parse_email {
139062306a36Sopenharmony_ci	my ($formatted_email) = @_;
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	my $name = "";
139362306a36Sopenharmony_ci	my $quoted = "";
139462306a36Sopenharmony_ci	my $name_comment = "";
139562306a36Sopenharmony_ci	my $address = "";
139662306a36Sopenharmony_ci	my $comment = "";
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
139962306a36Sopenharmony_ci		$name = $1;
140062306a36Sopenharmony_ci		$address = $2;
140162306a36Sopenharmony_ci		$comment = $3 if defined $3;
140262306a36Sopenharmony_ci	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
140362306a36Sopenharmony_ci		$address = $1;
140462306a36Sopenharmony_ci		$comment = $2 if defined $2;
140562306a36Sopenharmony_ci	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
140662306a36Sopenharmony_ci		$address = $1;
140762306a36Sopenharmony_ci		$comment = $2 if defined $2;
140862306a36Sopenharmony_ci		$formatted_email =~ s/\Q$address\E.*$//;
140962306a36Sopenharmony_ci		$name = $formatted_email;
141062306a36Sopenharmony_ci		$name = trim($name);
141162306a36Sopenharmony_ci		$name =~ s/^\"|\"$//g;
141262306a36Sopenharmony_ci		# If there's a name left after stripping spaces and
141362306a36Sopenharmony_ci		# leading quotes, and the address doesn't have both
141462306a36Sopenharmony_ci		# leading and trailing angle brackets, the address
141562306a36Sopenharmony_ci		# is invalid. ie:
141662306a36Sopenharmony_ci		#   "joe smith joe@smith.com" bad
141762306a36Sopenharmony_ci		#   "joe smith <joe@smith.com" bad
141862306a36Sopenharmony_ci		if ($name ne "" && $address !~ /^<[^>]+>$/) {
141962306a36Sopenharmony_ci			$name = "";
142062306a36Sopenharmony_ci			$address = "";
142162306a36Sopenharmony_ci			$comment = "";
142262306a36Sopenharmony_ci		}
142362306a36Sopenharmony_ci	}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci	# Extract comments from names excluding quoted parts
142662306a36Sopenharmony_ci	# "John D. (Doe)" - Do not extract
142762306a36Sopenharmony_ci	if ($name =~ s/\"(.+)\"//) {
142862306a36Sopenharmony_ci		$quoted = $1;
142962306a36Sopenharmony_ci	}
143062306a36Sopenharmony_ci	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
143162306a36Sopenharmony_ci		$name_comment .= trim($1);
143262306a36Sopenharmony_ci	}
143362306a36Sopenharmony_ci	$name =~ s/^[ \"]+|[ \"]+$//g;
143462306a36Sopenharmony_ci	$name = trim("$quoted $name");
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	$address = trim($address);
143762306a36Sopenharmony_ci	$address =~ s/^\<|\>$//g;
143862306a36Sopenharmony_ci	$comment = trim($comment);
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
144162306a36Sopenharmony_ci		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
144262306a36Sopenharmony_ci		$name = "\"$name\"";
144362306a36Sopenharmony_ci	}
144462306a36Sopenharmony_ci
144562306a36Sopenharmony_ci	return ($name, $name_comment, $address, $comment);
144662306a36Sopenharmony_ci}
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_cisub format_email {
144962306a36Sopenharmony_ci	my ($name, $name_comment, $address, $comment) = @_;
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci	my $formatted_email;
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_ci	$name =~ s/^[ \"]+|[ \"]+$//g;
145462306a36Sopenharmony_ci	$address = trim($address);
145562306a36Sopenharmony_ci	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
145862306a36Sopenharmony_ci		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
145962306a36Sopenharmony_ci		$name = "\"$name\"";
146062306a36Sopenharmony_ci	}
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	$name_comment = trim($name_comment);
146362306a36Sopenharmony_ci	$name_comment = " $name_comment" if ($name_comment ne "");
146462306a36Sopenharmony_ci	$comment = trim($comment);
146562306a36Sopenharmony_ci	$comment = " $comment" if ($comment ne "");
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ci	if ("$name" eq "") {
146862306a36Sopenharmony_ci		$formatted_email = "$address";
146962306a36Sopenharmony_ci	} else {
147062306a36Sopenharmony_ci		$formatted_email = "$name$name_comment <$address>";
147162306a36Sopenharmony_ci	}
147262306a36Sopenharmony_ci	$formatted_email .= "$comment";
147362306a36Sopenharmony_ci	return $formatted_email;
147462306a36Sopenharmony_ci}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_cisub reformat_email {
147762306a36Sopenharmony_ci	my ($email) = @_;
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
148062306a36Sopenharmony_ci	return format_email($email_name, $name_comment, $email_address, $comment);
148162306a36Sopenharmony_ci}
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_cisub same_email_addresses {
148462306a36Sopenharmony_ci	my ($email1, $email2) = @_;
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
148762306a36Sopenharmony_ci	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci	return $email1_name eq $email2_name &&
149062306a36Sopenharmony_ci	       $email1_address eq $email2_address &&
149162306a36Sopenharmony_ci	       $name1_comment eq $name2_comment &&
149262306a36Sopenharmony_ci	       $comment1 eq $comment2;
149362306a36Sopenharmony_ci}
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_cisub which {
149662306a36Sopenharmony_ci	my ($bin) = @_;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	foreach my $path (split(/:/, $ENV{PATH})) {
149962306a36Sopenharmony_ci		if (-e "$path/$bin") {
150062306a36Sopenharmony_ci			return "$path/$bin";
150162306a36Sopenharmony_ci		}
150262306a36Sopenharmony_ci	}
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci	return "";
150562306a36Sopenharmony_ci}
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_cisub which_conf {
150862306a36Sopenharmony_ci	my ($conf) = @_;
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
151162306a36Sopenharmony_ci		if (-e "$path/$conf") {
151262306a36Sopenharmony_ci			return "$path/$conf";
151362306a36Sopenharmony_ci		}
151462306a36Sopenharmony_ci	}
151562306a36Sopenharmony_ci
151662306a36Sopenharmony_ci	return "";
151762306a36Sopenharmony_ci}
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_cisub expand_tabs {
152062306a36Sopenharmony_ci	my ($str) = @_;
152162306a36Sopenharmony_ci
152262306a36Sopenharmony_ci	my $res = '';
152362306a36Sopenharmony_ci	my $n = 0;
152462306a36Sopenharmony_ci	for my $c (split(//, $str)) {
152562306a36Sopenharmony_ci		if ($c eq "\t") {
152662306a36Sopenharmony_ci			$res .= ' ';
152762306a36Sopenharmony_ci			$n++;
152862306a36Sopenharmony_ci			for (; ($n % $tabsize) != 0; $n++) {
152962306a36Sopenharmony_ci				$res .= ' ';
153062306a36Sopenharmony_ci			}
153162306a36Sopenharmony_ci			next;
153262306a36Sopenharmony_ci		}
153362306a36Sopenharmony_ci		$res .= $c;
153462306a36Sopenharmony_ci		$n++;
153562306a36Sopenharmony_ci	}
153662306a36Sopenharmony_ci
153762306a36Sopenharmony_ci	return $res;
153862306a36Sopenharmony_ci}
153962306a36Sopenharmony_cisub copy_spacing {
154062306a36Sopenharmony_ci	(my $res = shift) =~ tr/\t/ /c;
154162306a36Sopenharmony_ci	return $res;
154262306a36Sopenharmony_ci}
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_cisub line_stats {
154562306a36Sopenharmony_ci	my ($line) = @_;
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ci	# Drop the diff line leader and expand tabs
154862306a36Sopenharmony_ci	$line =~ s/^.//;
154962306a36Sopenharmony_ci	$line = expand_tabs($line);
155062306a36Sopenharmony_ci
155162306a36Sopenharmony_ci	# Pick the indent from the front of the line.
155262306a36Sopenharmony_ci	my ($white) = ($line =~ /^(\s*)/);
155362306a36Sopenharmony_ci
155462306a36Sopenharmony_ci	return (length($line), length($white));
155562306a36Sopenharmony_ci}
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_cimy $sanitise_quote = '';
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_cisub sanitise_line_reset {
156062306a36Sopenharmony_ci	my ($in_comment) = @_;
156162306a36Sopenharmony_ci
156262306a36Sopenharmony_ci	if ($in_comment) {
156362306a36Sopenharmony_ci		$sanitise_quote = '*/';
156462306a36Sopenharmony_ci	} else {
156562306a36Sopenharmony_ci		$sanitise_quote = '';
156662306a36Sopenharmony_ci	}
156762306a36Sopenharmony_ci}
156862306a36Sopenharmony_cisub sanitise_line {
156962306a36Sopenharmony_ci	my ($line) = @_;
157062306a36Sopenharmony_ci
157162306a36Sopenharmony_ci	my $res = '';
157262306a36Sopenharmony_ci	my $l = '';
157362306a36Sopenharmony_ci
157462306a36Sopenharmony_ci	my $qlen = 0;
157562306a36Sopenharmony_ci	my $off = 0;
157662306a36Sopenharmony_ci	my $c;
157762306a36Sopenharmony_ci
157862306a36Sopenharmony_ci	# Always copy over the diff marker.
157962306a36Sopenharmony_ci	$res = substr($line, 0, 1);
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci	for ($off = 1; $off < length($line); $off++) {
158262306a36Sopenharmony_ci		$c = substr($line, $off, 1);
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci		# Comments we are whacking completely including the begin
158562306a36Sopenharmony_ci		# and end, all to $;.
158662306a36Sopenharmony_ci		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
158762306a36Sopenharmony_ci			$sanitise_quote = '*/';
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci			substr($res, $off, 2, "$;$;");
159062306a36Sopenharmony_ci			$off++;
159162306a36Sopenharmony_ci			next;
159262306a36Sopenharmony_ci		}
159362306a36Sopenharmony_ci		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
159462306a36Sopenharmony_ci			$sanitise_quote = '';
159562306a36Sopenharmony_ci			substr($res, $off, 2, "$;$;");
159662306a36Sopenharmony_ci			$off++;
159762306a36Sopenharmony_ci			next;
159862306a36Sopenharmony_ci		}
159962306a36Sopenharmony_ci		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
160062306a36Sopenharmony_ci			$sanitise_quote = '//';
160162306a36Sopenharmony_ci
160262306a36Sopenharmony_ci			substr($res, $off, 2, $sanitise_quote);
160362306a36Sopenharmony_ci			$off++;
160462306a36Sopenharmony_ci			next;
160562306a36Sopenharmony_ci		}
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci		# A \ in a string means ignore the next character.
160862306a36Sopenharmony_ci		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
160962306a36Sopenharmony_ci		    $c eq "\\") {
161062306a36Sopenharmony_ci			substr($res, $off, 2, 'XX');
161162306a36Sopenharmony_ci			$off++;
161262306a36Sopenharmony_ci			next;
161362306a36Sopenharmony_ci		}
161462306a36Sopenharmony_ci		# Regular quotes.
161562306a36Sopenharmony_ci		if ($c eq "'" || $c eq '"') {
161662306a36Sopenharmony_ci			if ($sanitise_quote eq '') {
161762306a36Sopenharmony_ci				$sanitise_quote = $c;
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci				substr($res, $off, 1, $c);
162062306a36Sopenharmony_ci				next;
162162306a36Sopenharmony_ci			} elsif ($sanitise_quote eq $c) {
162262306a36Sopenharmony_ci				$sanitise_quote = '';
162362306a36Sopenharmony_ci			}
162462306a36Sopenharmony_ci		}
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci		#print "c<$c> SQ<$sanitise_quote>\n";
162762306a36Sopenharmony_ci		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
162862306a36Sopenharmony_ci			substr($res, $off, 1, $;);
162962306a36Sopenharmony_ci		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
163062306a36Sopenharmony_ci			substr($res, $off, 1, $;);
163162306a36Sopenharmony_ci		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
163262306a36Sopenharmony_ci			substr($res, $off, 1, 'X');
163362306a36Sopenharmony_ci		} else {
163462306a36Sopenharmony_ci			substr($res, $off, 1, $c);
163562306a36Sopenharmony_ci		}
163662306a36Sopenharmony_ci	}
163762306a36Sopenharmony_ci
163862306a36Sopenharmony_ci	if ($sanitise_quote eq '//') {
163962306a36Sopenharmony_ci		$sanitise_quote = '';
164062306a36Sopenharmony_ci	}
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ci	# The pathname on a #include may be surrounded by '<' and '>'.
164362306a36Sopenharmony_ci	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
164462306a36Sopenharmony_ci		my $clean = 'X' x length($1);
164562306a36Sopenharmony_ci		$res =~ s@\<.*\>@<$clean>@;
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_ci	# The whole of a #error is a string.
164862306a36Sopenharmony_ci	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
164962306a36Sopenharmony_ci		my $clean = 'X' x length($1);
165062306a36Sopenharmony_ci		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
165162306a36Sopenharmony_ci	}
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
165462306a36Sopenharmony_ci		my $match = $1;
165562306a36Sopenharmony_ci		$res =~ s/\Q$match\E/"$;" x length($match)/e;
165662306a36Sopenharmony_ci	}
165762306a36Sopenharmony_ci
165862306a36Sopenharmony_ci	return $res;
165962306a36Sopenharmony_ci}
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_cisub get_quoted_string {
166262306a36Sopenharmony_ci	my ($line, $rawline) = @_;
166362306a36Sopenharmony_ci
166462306a36Sopenharmony_ci	return "" if (!defined($line) || !defined($rawline));
166562306a36Sopenharmony_ci	return "" if ($line !~ m/($String)/g);
166662306a36Sopenharmony_ci	return substr($rawline, $-[0], $+[0] - $-[0]);
166762306a36Sopenharmony_ci}
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_cisub ctx_statement_block {
167062306a36Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
167162306a36Sopenharmony_ci	my $line = $linenr - 1;
167262306a36Sopenharmony_ci	my $blk = '';
167362306a36Sopenharmony_ci	my $soff = $off;
167462306a36Sopenharmony_ci	my $coff = $off - 1;
167562306a36Sopenharmony_ci	my $coff_set = 0;
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_ci	my $loff = 0;
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci	my $type = '';
168062306a36Sopenharmony_ci	my $level = 0;
168162306a36Sopenharmony_ci	my @stack = ();
168262306a36Sopenharmony_ci	my $p;
168362306a36Sopenharmony_ci	my $c;
168462306a36Sopenharmony_ci	my $len = 0;
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci	my $remainder;
168762306a36Sopenharmony_ci	while (1) {
168862306a36Sopenharmony_ci		@stack = (['', 0]) if ($#stack == -1);
168962306a36Sopenharmony_ci
169062306a36Sopenharmony_ci		#warn "CSB: blk<$blk> remain<$remain>\n";
169162306a36Sopenharmony_ci		# If we are about to drop off the end, pull in more
169262306a36Sopenharmony_ci		# context.
169362306a36Sopenharmony_ci		if ($off >= $len) {
169462306a36Sopenharmony_ci			for (; $remain > 0; $line++) {
169562306a36Sopenharmony_ci				last if (!defined $lines[$line]);
169662306a36Sopenharmony_ci				next if ($lines[$line] =~ /^-/);
169762306a36Sopenharmony_ci				$remain--;
169862306a36Sopenharmony_ci				$loff = $len;
169962306a36Sopenharmony_ci				$blk .= $lines[$line] . "\n";
170062306a36Sopenharmony_ci				$len = length($blk);
170162306a36Sopenharmony_ci				$line++;
170262306a36Sopenharmony_ci				last;
170362306a36Sopenharmony_ci			}
170462306a36Sopenharmony_ci			# Bail if there is no further context.
170562306a36Sopenharmony_ci			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
170662306a36Sopenharmony_ci			if ($off >= $len) {
170762306a36Sopenharmony_ci				last;
170862306a36Sopenharmony_ci			}
170962306a36Sopenharmony_ci			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
171062306a36Sopenharmony_ci				$level++;
171162306a36Sopenharmony_ci				$type = '#';
171262306a36Sopenharmony_ci			}
171362306a36Sopenharmony_ci		}
171462306a36Sopenharmony_ci		$p = $c;
171562306a36Sopenharmony_ci		$c = substr($blk, $off, 1);
171662306a36Sopenharmony_ci		$remainder = substr($blk, $off);
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_ci		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
171962306a36Sopenharmony_ci
172062306a36Sopenharmony_ci		# Handle nested #if/#else.
172162306a36Sopenharmony_ci		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
172262306a36Sopenharmony_ci			push(@stack, [ $type, $level ]);
172362306a36Sopenharmony_ci		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
172462306a36Sopenharmony_ci			($type, $level) = @{$stack[$#stack - 1]};
172562306a36Sopenharmony_ci		} elsif ($remainder =~ /^#\s*endif\b/) {
172662306a36Sopenharmony_ci			($type, $level) = @{pop(@stack)};
172762306a36Sopenharmony_ci		}
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci		# Statement ends at the ';' or a close '}' at the
173062306a36Sopenharmony_ci		# outermost level.
173162306a36Sopenharmony_ci		if ($level == 0 && $c eq ';') {
173262306a36Sopenharmony_ci			last;
173362306a36Sopenharmony_ci		}
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_ci		# An else is really a conditional as long as its not else if
173662306a36Sopenharmony_ci		if ($level == 0 && $coff_set == 0 &&
173762306a36Sopenharmony_ci				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
173862306a36Sopenharmony_ci				$remainder =~ /^(else)(?:\s|{)/ &&
173962306a36Sopenharmony_ci				$remainder !~ /^else\s+if\b/) {
174062306a36Sopenharmony_ci			$coff = $off + length($1) - 1;
174162306a36Sopenharmony_ci			$coff_set = 1;
174262306a36Sopenharmony_ci			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
174362306a36Sopenharmony_ci			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
174462306a36Sopenharmony_ci		}
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci		if (($type eq '' || $type eq '(') && $c eq '(') {
174762306a36Sopenharmony_ci			$level++;
174862306a36Sopenharmony_ci			$type = '(';
174962306a36Sopenharmony_ci		}
175062306a36Sopenharmony_ci		if ($type eq '(' && $c eq ')') {
175162306a36Sopenharmony_ci			$level--;
175262306a36Sopenharmony_ci			$type = ($level != 0)? '(' : '';
175362306a36Sopenharmony_ci
175462306a36Sopenharmony_ci			if ($level == 0 && $coff < $soff) {
175562306a36Sopenharmony_ci				$coff = $off;
175662306a36Sopenharmony_ci				$coff_set = 1;
175762306a36Sopenharmony_ci				#warn "CSB: mark coff<$coff>\n";
175862306a36Sopenharmony_ci			}
175962306a36Sopenharmony_ci		}
176062306a36Sopenharmony_ci		if (($type eq '' || $type eq '{') && $c eq '{') {
176162306a36Sopenharmony_ci			$level++;
176262306a36Sopenharmony_ci			$type = '{';
176362306a36Sopenharmony_ci		}
176462306a36Sopenharmony_ci		if ($type eq '{' && $c eq '}') {
176562306a36Sopenharmony_ci			$level--;
176662306a36Sopenharmony_ci			$type = ($level != 0)? '{' : '';
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_ci			if ($level == 0) {
176962306a36Sopenharmony_ci				if (substr($blk, $off + 1, 1) eq ';') {
177062306a36Sopenharmony_ci					$off++;
177162306a36Sopenharmony_ci				}
177262306a36Sopenharmony_ci				last;
177362306a36Sopenharmony_ci			}
177462306a36Sopenharmony_ci		}
177562306a36Sopenharmony_ci		# Preprocessor commands end at the newline unless escaped.
177662306a36Sopenharmony_ci		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
177762306a36Sopenharmony_ci			$level--;
177862306a36Sopenharmony_ci			$type = '';
177962306a36Sopenharmony_ci			$off++;
178062306a36Sopenharmony_ci			last;
178162306a36Sopenharmony_ci		}
178262306a36Sopenharmony_ci		$off++;
178362306a36Sopenharmony_ci	}
178462306a36Sopenharmony_ci	# We are truly at the end, so shuffle to the next line.
178562306a36Sopenharmony_ci	if ($off == $len) {
178662306a36Sopenharmony_ci		$loff = $len + 1;
178762306a36Sopenharmony_ci		$line++;
178862306a36Sopenharmony_ci		$remain--;
178962306a36Sopenharmony_ci	}
179062306a36Sopenharmony_ci
179162306a36Sopenharmony_ci	my $statement = substr($blk, $soff, $off - $soff + 1);
179262306a36Sopenharmony_ci	my $condition = substr($blk, $soff, $coff - $soff + 1);
179362306a36Sopenharmony_ci
179462306a36Sopenharmony_ci	#warn "STATEMENT<$statement>\n";
179562306a36Sopenharmony_ci	#warn "CONDITION<$condition>\n";
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci	#print "coff<$coff> soff<$off> loff<$loff>\n";
179862306a36Sopenharmony_ci
179962306a36Sopenharmony_ci	return ($statement, $condition,
180062306a36Sopenharmony_ci			$line, $remain + 1, $off - $loff + 1, $level);
180162306a36Sopenharmony_ci}
180262306a36Sopenharmony_ci
180362306a36Sopenharmony_cisub statement_lines {
180462306a36Sopenharmony_ci	my ($stmt) = @_;
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci	# Strip the diff line prefixes and rip blank lines at start and end.
180762306a36Sopenharmony_ci	$stmt =~ s/(^|\n)./$1/g;
180862306a36Sopenharmony_ci	$stmt =~ s/^\s*//;
180962306a36Sopenharmony_ci	$stmt =~ s/\s*$//;
181062306a36Sopenharmony_ci
181162306a36Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	return $#stmt_lines + 2;
181462306a36Sopenharmony_ci}
181562306a36Sopenharmony_ci
181662306a36Sopenharmony_cisub statement_rawlines {
181762306a36Sopenharmony_ci	my ($stmt) = @_;
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
182062306a36Sopenharmony_ci
182162306a36Sopenharmony_ci	return $#stmt_lines + 2;
182262306a36Sopenharmony_ci}
182362306a36Sopenharmony_ci
182462306a36Sopenharmony_cisub statement_block_size {
182562306a36Sopenharmony_ci	my ($stmt) = @_;
182662306a36Sopenharmony_ci
182762306a36Sopenharmony_ci	$stmt =~ s/(^|\n)./$1/g;
182862306a36Sopenharmony_ci	$stmt =~ s/^\s*{//;
182962306a36Sopenharmony_ci	$stmt =~ s/}\s*$//;
183062306a36Sopenharmony_ci	$stmt =~ s/^\s*//;
183162306a36Sopenharmony_ci	$stmt =~ s/\s*$//;
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
183462306a36Sopenharmony_ci	my @stmt_statements = ($stmt =~ /;/g);
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	my $stmt_lines = $#stmt_lines + 2;
183762306a36Sopenharmony_ci	my $stmt_statements = $#stmt_statements + 1;
183862306a36Sopenharmony_ci
183962306a36Sopenharmony_ci	if ($stmt_lines > $stmt_statements) {
184062306a36Sopenharmony_ci		return $stmt_lines;
184162306a36Sopenharmony_ci	} else {
184262306a36Sopenharmony_ci		return $stmt_statements;
184362306a36Sopenharmony_ci	}
184462306a36Sopenharmony_ci}
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_cisub ctx_statement_full {
184762306a36Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
184862306a36Sopenharmony_ci	my ($statement, $condition, $level);
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	my (@chunks);
185162306a36Sopenharmony_ci
185262306a36Sopenharmony_ci	# Grab the first conditional/block pair.
185362306a36Sopenharmony_ci	($statement, $condition, $linenr, $remain, $off, $level) =
185462306a36Sopenharmony_ci				ctx_statement_block($linenr, $remain, $off);
185562306a36Sopenharmony_ci	#print "F: c<$condition> s<$statement> remain<$remain>\n";
185662306a36Sopenharmony_ci	push(@chunks, [ $condition, $statement ]);
185762306a36Sopenharmony_ci	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
185862306a36Sopenharmony_ci		return ($level, $linenr, @chunks);
185962306a36Sopenharmony_ci	}
186062306a36Sopenharmony_ci
186162306a36Sopenharmony_ci	# Pull in the following conditional/block pairs and see if they
186262306a36Sopenharmony_ci	# could continue the statement.
186362306a36Sopenharmony_ci	for (;;) {
186462306a36Sopenharmony_ci		($statement, $condition, $linenr, $remain, $off, $level) =
186562306a36Sopenharmony_ci				ctx_statement_block($linenr, $remain, $off);
186662306a36Sopenharmony_ci		#print "C: c<$condition> s<$statement> remain<$remain>\n";
186762306a36Sopenharmony_ci		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
186862306a36Sopenharmony_ci		#print "C: push\n";
186962306a36Sopenharmony_ci		push(@chunks, [ $condition, $statement ]);
187062306a36Sopenharmony_ci	}
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_ci	return ($level, $linenr, @chunks);
187362306a36Sopenharmony_ci}
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_cisub ctx_block_get {
187662306a36Sopenharmony_ci	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
187762306a36Sopenharmony_ci	my $line;
187862306a36Sopenharmony_ci	my $start = $linenr - 1;
187962306a36Sopenharmony_ci	my $blk = '';
188062306a36Sopenharmony_ci	my @o;
188162306a36Sopenharmony_ci	my @c;
188262306a36Sopenharmony_ci	my @res = ();
188362306a36Sopenharmony_ci
188462306a36Sopenharmony_ci	my $level = 0;
188562306a36Sopenharmony_ci	my @stack = ($level);
188662306a36Sopenharmony_ci	for ($line = $start; $remain > 0; $line++) {
188762306a36Sopenharmony_ci		next if ($rawlines[$line] =~ /^-/);
188862306a36Sopenharmony_ci		$remain--;
188962306a36Sopenharmony_ci
189062306a36Sopenharmony_ci		$blk .= $rawlines[$line];
189162306a36Sopenharmony_ci
189262306a36Sopenharmony_ci		# Handle nested #if/#else.
189362306a36Sopenharmony_ci		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
189462306a36Sopenharmony_ci			push(@stack, $level);
189562306a36Sopenharmony_ci		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
189662306a36Sopenharmony_ci			$level = $stack[$#stack - 1];
189762306a36Sopenharmony_ci		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
189862306a36Sopenharmony_ci			$level = pop(@stack);
189962306a36Sopenharmony_ci		}
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_ci		foreach my $c (split(//, $lines[$line])) {
190262306a36Sopenharmony_ci			##print "C<$c>L<$level><$open$close>O<$off>\n";
190362306a36Sopenharmony_ci			if ($off > 0) {
190462306a36Sopenharmony_ci				$off--;
190562306a36Sopenharmony_ci				next;
190662306a36Sopenharmony_ci			}
190762306a36Sopenharmony_ci
190862306a36Sopenharmony_ci			if ($c eq $close && $level > 0) {
190962306a36Sopenharmony_ci				$level--;
191062306a36Sopenharmony_ci				last if ($level == 0);
191162306a36Sopenharmony_ci			} elsif ($c eq $open) {
191262306a36Sopenharmony_ci				$level++;
191362306a36Sopenharmony_ci			}
191462306a36Sopenharmony_ci		}
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci		if (!$outer || $level <= 1) {
191762306a36Sopenharmony_ci			push(@res, $rawlines[$line]);
191862306a36Sopenharmony_ci		}
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_ci		last if ($level == 0);
192162306a36Sopenharmony_ci	}
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci	return ($level, @res);
192462306a36Sopenharmony_ci}
192562306a36Sopenharmony_cisub ctx_block_outer {
192662306a36Sopenharmony_ci	my ($linenr, $remain) = @_;
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
192962306a36Sopenharmony_ci	return @r;
193062306a36Sopenharmony_ci}
193162306a36Sopenharmony_cisub ctx_block {
193262306a36Sopenharmony_ci	my ($linenr, $remain) = @_;
193362306a36Sopenharmony_ci
193462306a36Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
193562306a36Sopenharmony_ci	return @r;
193662306a36Sopenharmony_ci}
193762306a36Sopenharmony_cisub ctx_statement {
193862306a36Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
193962306a36Sopenharmony_ci
194062306a36Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
194162306a36Sopenharmony_ci	return @r;
194262306a36Sopenharmony_ci}
194362306a36Sopenharmony_cisub ctx_block_level {
194462306a36Sopenharmony_ci	my ($linenr, $remain) = @_;
194562306a36Sopenharmony_ci
194662306a36Sopenharmony_ci	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
194762306a36Sopenharmony_ci}
194862306a36Sopenharmony_cisub ctx_statement_level {
194962306a36Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_ci	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
195262306a36Sopenharmony_ci}
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_cisub ctx_locate_comment {
195562306a36Sopenharmony_ci	my ($first_line, $end_line) = @_;
195662306a36Sopenharmony_ci
195762306a36Sopenharmony_ci	# If c99 comment on the current line, or the line before or after
195862306a36Sopenharmony_ci	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
195962306a36Sopenharmony_ci	return $current_comment if (defined $current_comment);
196062306a36Sopenharmony_ci	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
196162306a36Sopenharmony_ci	return $current_comment if (defined $current_comment);
196262306a36Sopenharmony_ci	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
196362306a36Sopenharmony_ci	return $current_comment if (defined $current_comment);
196462306a36Sopenharmony_ci
196562306a36Sopenharmony_ci	# Catch a comment on the end of the line itself.
196662306a36Sopenharmony_ci	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
196762306a36Sopenharmony_ci	return $current_comment if (defined $current_comment);
196862306a36Sopenharmony_ci
196962306a36Sopenharmony_ci	# Look through the context and try and figure out if there is a
197062306a36Sopenharmony_ci	# comment.
197162306a36Sopenharmony_ci	my $in_comment = 0;
197262306a36Sopenharmony_ci	$current_comment = '';
197362306a36Sopenharmony_ci	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
197462306a36Sopenharmony_ci		my $line = $rawlines[$linenr - 1];
197562306a36Sopenharmony_ci		#warn "           $line\n";
197662306a36Sopenharmony_ci		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
197762306a36Sopenharmony_ci			$in_comment = 1;
197862306a36Sopenharmony_ci		}
197962306a36Sopenharmony_ci		if ($line =~ m@/\*@) {
198062306a36Sopenharmony_ci			$in_comment = 1;
198162306a36Sopenharmony_ci		}
198262306a36Sopenharmony_ci		if (!$in_comment && $current_comment ne '') {
198362306a36Sopenharmony_ci			$current_comment = '';
198462306a36Sopenharmony_ci		}
198562306a36Sopenharmony_ci		$current_comment .= $line . "\n" if ($in_comment);
198662306a36Sopenharmony_ci		if ($line =~ m@\*/@) {
198762306a36Sopenharmony_ci			$in_comment = 0;
198862306a36Sopenharmony_ci		}
198962306a36Sopenharmony_ci	}
199062306a36Sopenharmony_ci
199162306a36Sopenharmony_ci	chomp($current_comment);
199262306a36Sopenharmony_ci	return($current_comment);
199362306a36Sopenharmony_ci}
199462306a36Sopenharmony_cisub ctx_has_comment {
199562306a36Sopenharmony_ci	my ($first_line, $end_line) = @_;
199662306a36Sopenharmony_ci	my $cmt = ctx_locate_comment($first_line, $end_line);
199762306a36Sopenharmony_ci
199862306a36Sopenharmony_ci	##print "LINE: $rawlines[$end_line - 1 ]\n";
199962306a36Sopenharmony_ci	##print "CMMT: $cmt\n";
200062306a36Sopenharmony_ci
200162306a36Sopenharmony_ci	return ($cmt ne '');
200262306a36Sopenharmony_ci}
200362306a36Sopenharmony_ci
200462306a36Sopenharmony_cisub raw_line {
200562306a36Sopenharmony_ci	my ($linenr, $cnt) = @_;
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_ci	my $offset = $linenr - 1;
200862306a36Sopenharmony_ci	$cnt++;
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_ci	my $line;
201162306a36Sopenharmony_ci	while ($cnt) {
201262306a36Sopenharmony_ci		$line = $rawlines[$offset++];
201362306a36Sopenharmony_ci		next if (defined($line) && $line =~ /^-/);
201462306a36Sopenharmony_ci		$cnt--;
201562306a36Sopenharmony_ci	}
201662306a36Sopenharmony_ci
201762306a36Sopenharmony_ci	return $line;
201862306a36Sopenharmony_ci}
201962306a36Sopenharmony_ci
202062306a36Sopenharmony_cisub get_stat_real {
202162306a36Sopenharmony_ci	my ($linenr, $lc) = @_;
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	my $stat_real = raw_line($linenr, 0);
202462306a36Sopenharmony_ci	for (my $count = $linenr + 1; $count <= $lc; $count++) {
202562306a36Sopenharmony_ci		$stat_real = $stat_real . "\n" . raw_line($count, 0);
202662306a36Sopenharmony_ci	}
202762306a36Sopenharmony_ci
202862306a36Sopenharmony_ci	return $stat_real;
202962306a36Sopenharmony_ci}
203062306a36Sopenharmony_ci
203162306a36Sopenharmony_cisub get_stat_here {
203262306a36Sopenharmony_ci	my ($linenr, $cnt, $here) = @_;
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	my $herectx = $here . "\n";
203562306a36Sopenharmony_ci	for (my $n = 0; $n < $cnt; $n++) {
203662306a36Sopenharmony_ci		$herectx .= raw_line($linenr, $n) . "\n";
203762306a36Sopenharmony_ci	}
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	return $herectx;
204062306a36Sopenharmony_ci}
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_cisub cat_vet {
204362306a36Sopenharmony_ci	my ($vet) = @_;
204462306a36Sopenharmony_ci	my ($res, $coded);
204562306a36Sopenharmony_ci
204662306a36Sopenharmony_ci	$res = '';
204762306a36Sopenharmony_ci	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
204862306a36Sopenharmony_ci		$res .= $1;
204962306a36Sopenharmony_ci		if ($2 ne '') {
205062306a36Sopenharmony_ci			$coded = sprintf("^%c", unpack('C', $2) + 64);
205162306a36Sopenharmony_ci			$res .= $coded;
205262306a36Sopenharmony_ci		}
205362306a36Sopenharmony_ci	}
205462306a36Sopenharmony_ci	$res =~ s/$/\$/;
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci	return $res;
205762306a36Sopenharmony_ci}
205862306a36Sopenharmony_ci
205962306a36Sopenharmony_cimy $av_preprocessor = 0;
206062306a36Sopenharmony_cimy $av_pending;
206162306a36Sopenharmony_cimy @av_paren_type;
206262306a36Sopenharmony_cimy $av_pend_colon;
206362306a36Sopenharmony_ci
206462306a36Sopenharmony_cisub annotate_reset {
206562306a36Sopenharmony_ci	$av_preprocessor = 0;
206662306a36Sopenharmony_ci	$av_pending = '_';
206762306a36Sopenharmony_ci	@av_paren_type = ('E');
206862306a36Sopenharmony_ci	$av_pend_colon = 'O';
206962306a36Sopenharmony_ci}
207062306a36Sopenharmony_ci
207162306a36Sopenharmony_cisub annotate_values {
207262306a36Sopenharmony_ci	my ($stream, $type) = @_;
207362306a36Sopenharmony_ci
207462306a36Sopenharmony_ci	my $res;
207562306a36Sopenharmony_ci	my $var = '_' x length($stream);
207662306a36Sopenharmony_ci	my $cur = $stream;
207762306a36Sopenharmony_ci
207862306a36Sopenharmony_ci	print "$stream\n" if ($dbg_values > 1);
207962306a36Sopenharmony_ci
208062306a36Sopenharmony_ci	while (length($cur)) {
208162306a36Sopenharmony_ci		@av_paren_type = ('E') if ($#av_paren_type < 0);
208262306a36Sopenharmony_ci		print " <" . join('', @av_paren_type) .
208362306a36Sopenharmony_ci				"> <$type> <$av_pending>" if ($dbg_values > 1);
208462306a36Sopenharmony_ci		if ($cur =~ /^(\s+)/o) {
208562306a36Sopenharmony_ci			print "WS($1)\n" if ($dbg_values > 1);
208662306a36Sopenharmony_ci			if ($1 =~ /\n/ && $av_preprocessor) {
208762306a36Sopenharmony_ci				$type = pop(@av_paren_type);
208862306a36Sopenharmony_ci				$av_preprocessor = 0;
208962306a36Sopenharmony_ci			}
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_ci		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
209262306a36Sopenharmony_ci			print "CAST($1)\n" if ($dbg_values > 1);
209362306a36Sopenharmony_ci			push(@av_paren_type, $type);
209462306a36Sopenharmony_ci			$type = 'c';
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_ci		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
209762306a36Sopenharmony_ci			print "DECLARE($1)\n" if ($dbg_values > 1);
209862306a36Sopenharmony_ci			$type = 'T';
209962306a36Sopenharmony_ci
210062306a36Sopenharmony_ci		} elsif ($cur =~ /^($Modifier)\s*/) {
210162306a36Sopenharmony_ci			print "MODIFIER($1)\n" if ($dbg_values > 1);
210262306a36Sopenharmony_ci			$type = 'T';
210362306a36Sopenharmony_ci
210462306a36Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
210562306a36Sopenharmony_ci			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
210662306a36Sopenharmony_ci			$av_preprocessor = 1;
210762306a36Sopenharmony_ci			push(@av_paren_type, $type);
210862306a36Sopenharmony_ci			if ($2 ne '') {
210962306a36Sopenharmony_ci				$av_pending = 'N';
211062306a36Sopenharmony_ci			}
211162306a36Sopenharmony_ci			$type = 'E';
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
211462306a36Sopenharmony_ci			print "UNDEF($1)\n" if ($dbg_values > 1);
211562306a36Sopenharmony_ci			$av_preprocessor = 1;
211662306a36Sopenharmony_ci			push(@av_paren_type, $type);
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
211962306a36Sopenharmony_ci			print "PRE_START($1)\n" if ($dbg_values > 1);
212062306a36Sopenharmony_ci			$av_preprocessor = 1;
212162306a36Sopenharmony_ci
212262306a36Sopenharmony_ci			push(@av_paren_type, $type);
212362306a36Sopenharmony_ci			push(@av_paren_type, $type);
212462306a36Sopenharmony_ci			$type = 'E';
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
212762306a36Sopenharmony_ci			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
212862306a36Sopenharmony_ci			$av_preprocessor = 1;
212962306a36Sopenharmony_ci
213062306a36Sopenharmony_ci			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_ci			$type = 'E';
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
213562306a36Sopenharmony_ci			print "PRE_END($1)\n" if ($dbg_values > 1);
213662306a36Sopenharmony_ci
213762306a36Sopenharmony_ci			$av_preprocessor = 1;
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_ci			# Assume all arms of the conditional end as this
214062306a36Sopenharmony_ci			# one does, and continue as if the #endif was not here.
214162306a36Sopenharmony_ci			pop(@av_paren_type);
214262306a36Sopenharmony_ci			push(@av_paren_type, $type);
214362306a36Sopenharmony_ci			$type = 'E';
214462306a36Sopenharmony_ci
214562306a36Sopenharmony_ci		} elsif ($cur =~ /^(\\\n)/o) {
214662306a36Sopenharmony_ci			print "PRECONT($1)\n" if ($dbg_values > 1);
214762306a36Sopenharmony_ci
214862306a36Sopenharmony_ci		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
214962306a36Sopenharmony_ci			print "ATTR($1)\n" if ($dbg_values > 1);
215062306a36Sopenharmony_ci			$av_pending = $type;
215162306a36Sopenharmony_ci			$type = 'N';
215262306a36Sopenharmony_ci
215362306a36Sopenharmony_ci		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
215462306a36Sopenharmony_ci			print "SIZEOF($1)\n" if ($dbg_values > 1);
215562306a36Sopenharmony_ci			if (defined $2) {
215662306a36Sopenharmony_ci				$av_pending = 'V';
215762306a36Sopenharmony_ci			}
215862306a36Sopenharmony_ci			$type = 'N';
215962306a36Sopenharmony_ci
216062306a36Sopenharmony_ci		} elsif ($cur =~ /^(if|while|for)\b/o) {
216162306a36Sopenharmony_ci			print "COND($1)\n" if ($dbg_values > 1);
216262306a36Sopenharmony_ci			$av_pending = 'E';
216362306a36Sopenharmony_ci			$type = 'N';
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci		} elsif ($cur =~/^(case)/o) {
216662306a36Sopenharmony_ci			print "CASE($1)\n" if ($dbg_values > 1);
216762306a36Sopenharmony_ci			$av_pend_colon = 'C';
216862306a36Sopenharmony_ci			$type = 'N';
216962306a36Sopenharmony_ci
217062306a36Sopenharmony_ci		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
217162306a36Sopenharmony_ci			print "KEYWORD($1)\n" if ($dbg_values > 1);
217262306a36Sopenharmony_ci			$type = 'N';
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci		} elsif ($cur =~ /^(\()/o) {
217562306a36Sopenharmony_ci			print "PAREN('$1')\n" if ($dbg_values > 1);
217662306a36Sopenharmony_ci			push(@av_paren_type, $av_pending);
217762306a36Sopenharmony_ci			$av_pending = '_';
217862306a36Sopenharmony_ci			$type = 'N';
217962306a36Sopenharmony_ci
218062306a36Sopenharmony_ci		} elsif ($cur =~ /^(\))/o) {
218162306a36Sopenharmony_ci			my $new_type = pop(@av_paren_type);
218262306a36Sopenharmony_ci			if ($new_type ne '_') {
218362306a36Sopenharmony_ci				$type = $new_type;
218462306a36Sopenharmony_ci				print "PAREN('$1') -> $type\n"
218562306a36Sopenharmony_ci							if ($dbg_values > 1);
218662306a36Sopenharmony_ci			} else {
218762306a36Sopenharmony_ci				print "PAREN('$1')\n" if ($dbg_values > 1);
218862306a36Sopenharmony_ci			}
218962306a36Sopenharmony_ci
219062306a36Sopenharmony_ci		} elsif ($cur =~ /^($Ident)\s*\(/o) {
219162306a36Sopenharmony_ci			print "FUNC($1)\n" if ($dbg_values > 1);
219262306a36Sopenharmony_ci			$type = 'V';
219362306a36Sopenharmony_ci			$av_pending = 'V';
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_ci		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
219662306a36Sopenharmony_ci			if (defined $2 && $type eq 'C' || $type eq 'T') {
219762306a36Sopenharmony_ci				$av_pend_colon = 'B';
219862306a36Sopenharmony_ci			} elsif ($type eq 'E') {
219962306a36Sopenharmony_ci				$av_pend_colon = 'L';
220062306a36Sopenharmony_ci			}
220162306a36Sopenharmony_ci			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
220262306a36Sopenharmony_ci			$type = 'V';
220362306a36Sopenharmony_ci
220462306a36Sopenharmony_ci		} elsif ($cur =~ /^($Ident|$Constant)/o) {
220562306a36Sopenharmony_ci			print "IDENT($1)\n" if ($dbg_values > 1);
220662306a36Sopenharmony_ci			$type = 'V';
220762306a36Sopenharmony_ci
220862306a36Sopenharmony_ci		} elsif ($cur =~ /^($Assignment)/o) {
220962306a36Sopenharmony_ci			print "ASSIGN($1)\n" if ($dbg_values > 1);
221062306a36Sopenharmony_ci			$type = 'N';
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_ci		} elsif ($cur =~/^(;|{|})/) {
221362306a36Sopenharmony_ci			print "END($1)\n" if ($dbg_values > 1);
221462306a36Sopenharmony_ci			$type = 'E';
221562306a36Sopenharmony_ci			$av_pend_colon = 'O';
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_ci		} elsif ($cur =~/^(,)/) {
221862306a36Sopenharmony_ci			print "COMMA($1)\n" if ($dbg_values > 1);
221962306a36Sopenharmony_ci			$type = 'C';
222062306a36Sopenharmony_ci
222162306a36Sopenharmony_ci		} elsif ($cur =~ /^(\?)/o) {
222262306a36Sopenharmony_ci			print "QUESTION($1)\n" if ($dbg_values > 1);
222362306a36Sopenharmony_ci			$type = 'N';
222462306a36Sopenharmony_ci
222562306a36Sopenharmony_ci		} elsif ($cur =~ /^(:)/o) {
222662306a36Sopenharmony_ci			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
222762306a36Sopenharmony_ci
222862306a36Sopenharmony_ci			substr($var, length($res), 1, $av_pend_colon);
222962306a36Sopenharmony_ci			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
223062306a36Sopenharmony_ci				$type = 'E';
223162306a36Sopenharmony_ci			} else {
223262306a36Sopenharmony_ci				$type = 'N';
223362306a36Sopenharmony_ci			}
223462306a36Sopenharmony_ci			$av_pend_colon = 'O';
223562306a36Sopenharmony_ci
223662306a36Sopenharmony_ci		} elsif ($cur =~ /^(\[)/o) {
223762306a36Sopenharmony_ci			print "CLOSE($1)\n" if ($dbg_values > 1);
223862306a36Sopenharmony_ci			$type = 'N';
223962306a36Sopenharmony_ci
224062306a36Sopenharmony_ci		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
224162306a36Sopenharmony_ci			my $variant;
224262306a36Sopenharmony_ci
224362306a36Sopenharmony_ci			print "OPV($1)\n" if ($dbg_values > 1);
224462306a36Sopenharmony_ci			if ($type eq 'V') {
224562306a36Sopenharmony_ci				$variant = 'B';
224662306a36Sopenharmony_ci			} else {
224762306a36Sopenharmony_ci				$variant = 'U';
224862306a36Sopenharmony_ci			}
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci			substr($var, length($res), 1, $variant);
225162306a36Sopenharmony_ci			$type = 'N';
225262306a36Sopenharmony_ci
225362306a36Sopenharmony_ci		} elsif ($cur =~ /^($Operators)/o) {
225462306a36Sopenharmony_ci			print "OP($1)\n" if ($dbg_values > 1);
225562306a36Sopenharmony_ci			if ($1 ne '++' && $1 ne '--') {
225662306a36Sopenharmony_ci				$type = 'N';
225762306a36Sopenharmony_ci			}
225862306a36Sopenharmony_ci
225962306a36Sopenharmony_ci		} elsif ($cur =~ /(^.)/o) {
226062306a36Sopenharmony_ci			print "C($1)\n" if ($dbg_values > 1);
226162306a36Sopenharmony_ci		}
226262306a36Sopenharmony_ci		if (defined $1) {
226362306a36Sopenharmony_ci			$cur = substr($cur, length($1));
226462306a36Sopenharmony_ci			$res .= $type x length($1);
226562306a36Sopenharmony_ci		}
226662306a36Sopenharmony_ci	}
226762306a36Sopenharmony_ci
226862306a36Sopenharmony_ci	return ($res, $var);
226962306a36Sopenharmony_ci}
227062306a36Sopenharmony_ci
227162306a36Sopenharmony_cisub possible {
227262306a36Sopenharmony_ci	my ($possible, $line) = @_;
227362306a36Sopenharmony_ci	my $notPermitted = qr{(?:
227462306a36Sopenharmony_ci		^(?:
227562306a36Sopenharmony_ci			$Modifier|
227662306a36Sopenharmony_ci			$Storage|
227762306a36Sopenharmony_ci			$Type|
227862306a36Sopenharmony_ci			DEFINE_\S+
227962306a36Sopenharmony_ci		)$|
228062306a36Sopenharmony_ci		^(?:
228162306a36Sopenharmony_ci			goto|
228262306a36Sopenharmony_ci			return|
228362306a36Sopenharmony_ci			case|
228462306a36Sopenharmony_ci			else|
228562306a36Sopenharmony_ci			asm|__asm__|
228662306a36Sopenharmony_ci			do|
228762306a36Sopenharmony_ci			\#|
228862306a36Sopenharmony_ci			\#\#|
228962306a36Sopenharmony_ci		)(?:\s|$)|
229062306a36Sopenharmony_ci		^(?:typedef|struct|enum)\b
229162306a36Sopenharmony_ci	    )}x;
229262306a36Sopenharmony_ci	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
229362306a36Sopenharmony_ci	if ($possible !~ $notPermitted) {
229462306a36Sopenharmony_ci		# Check for modifiers.
229562306a36Sopenharmony_ci		$possible =~ s/\s*$Storage\s*//g;
229662306a36Sopenharmony_ci		$possible =~ s/\s*$Sparse\s*//g;
229762306a36Sopenharmony_ci		if ($possible =~ /^\s*$/) {
229862306a36Sopenharmony_ci
229962306a36Sopenharmony_ci		} elsif ($possible =~ /\s/) {
230062306a36Sopenharmony_ci			$possible =~ s/\s*$Type\s*//g;
230162306a36Sopenharmony_ci			for my $modifier (split(' ', $possible)) {
230262306a36Sopenharmony_ci				if ($modifier !~ $notPermitted) {
230362306a36Sopenharmony_ci					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
230462306a36Sopenharmony_ci					push(@modifierListFile, $modifier);
230562306a36Sopenharmony_ci				}
230662306a36Sopenharmony_ci			}
230762306a36Sopenharmony_ci
230862306a36Sopenharmony_ci		} else {
230962306a36Sopenharmony_ci			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
231062306a36Sopenharmony_ci			push(@typeListFile, $possible);
231162306a36Sopenharmony_ci		}
231262306a36Sopenharmony_ci		build_types();
231362306a36Sopenharmony_ci	} else {
231462306a36Sopenharmony_ci		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
231562306a36Sopenharmony_ci	}
231662306a36Sopenharmony_ci}
231762306a36Sopenharmony_ci
231862306a36Sopenharmony_cimy $prefix = '';
231962306a36Sopenharmony_ci
232062306a36Sopenharmony_cisub show_type {
232162306a36Sopenharmony_ci	my ($type) = @_;
232262306a36Sopenharmony_ci
232362306a36Sopenharmony_ci	$type =~ tr/[a-z]/[A-Z]/;
232462306a36Sopenharmony_ci
232562306a36Sopenharmony_ci	return defined $use_type{$type} if (scalar keys %use_type > 0);
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci	return !defined $ignore_type{$type};
232862306a36Sopenharmony_ci}
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_cisub report {
233162306a36Sopenharmony_ci	my ($level, $type, $msg) = @_;
233262306a36Sopenharmony_ci
233362306a36Sopenharmony_ci	if (!show_type($type) ||
233462306a36Sopenharmony_ci	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
233562306a36Sopenharmony_ci		return 0;
233662306a36Sopenharmony_ci	}
233762306a36Sopenharmony_ci	my $output = '';
233862306a36Sopenharmony_ci	if ($color) {
233962306a36Sopenharmony_ci		if ($level eq 'ERROR') {
234062306a36Sopenharmony_ci			$output .= RED;
234162306a36Sopenharmony_ci		} elsif ($level eq 'WARNING') {
234262306a36Sopenharmony_ci			$output .= YELLOW;
234362306a36Sopenharmony_ci		} else {
234462306a36Sopenharmony_ci			$output .= GREEN;
234562306a36Sopenharmony_ci		}
234662306a36Sopenharmony_ci	}
234762306a36Sopenharmony_ci	$output .= $prefix . $level . ':';
234862306a36Sopenharmony_ci	if ($show_types) {
234962306a36Sopenharmony_ci		$output .= BLUE if ($color);
235062306a36Sopenharmony_ci		$output .= "$type:";
235162306a36Sopenharmony_ci	}
235262306a36Sopenharmony_ci	$output .= RESET if ($color);
235362306a36Sopenharmony_ci	$output .= ' ' . $msg . "\n";
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci	if ($showfile) {
235662306a36Sopenharmony_ci		my @lines = split("\n", $output, -1);
235762306a36Sopenharmony_ci		splice(@lines, 1, 1);
235862306a36Sopenharmony_ci		$output = join("\n", @lines);
235962306a36Sopenharmony_ci	}
236062306a36Sopenharmony_ci
236162306a36Sopenharmony_ci	if ($terse) {
236262306a36Sopenharmony_ci		$output = (split('\n', $output))[0] . "\n";
236362306a36Sopenharmony_ci	}
236462306a36Sopenharmony_ci
236562306a36Sopenharmony_ci	if ($verbose && exists($verbose_messages{$type}) &&
236662306a36Sopenharmony_ci	    !exists($verbose_emitted{$type})) {
236762306a36Sopenharmony_ci		$output .= $verbose_messages{$type} . "\n\n";
236862306a36Sopenharmony_ci		$verbose_emitted{$type} = 1;
236962306a36Sopenharmony_ci	}
237062306a36Sopenharmony_ci
237162306a36Sopenharmony_ci	push(our @report, $output);
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ci	return 1;
237462306a36Sopenharmony_ci}
237562306a36Sopenharmony_ci
237662306a36Sopenharmony_cisub report_dump {
237762306a36Sopenharmony_ci	our @report;
237862306a36Sopenharmony_ci}
237962306a36Sopenharmony_ci
238062306a36Sopenharmony_cisub fixup_current_range {
238162306a36Sopenharmony_ci	my ($lineRef, $offset, $length) = @_;
238262306a36Sopenharmony_ci
238362306a36Sopenharmony_ci	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
238462306a36Sopenharmony_ci		my $o = $1;
238562306a36Sopenharmony_ci		my $l = $2;
238662306a36Sopenharmony_ci		my $no = $o + $offset;
238762306a36Sopenharmony_ci		my $nl = $l + $length;
238862306a36Sopenharmony_ci		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
238962306a36Sopenharmony_ci	}
239062306a36Sopenharmony_ci}
239162306a36Sopenharmony_ci
239262306a36Sopenharmony_cisub fix_inserted_deleted_lines {
239362306a36Sopenharmony_ci	my ($linesRef, $insertedRef, $deletedRef) = @_;
239462306a36Sopenharmony_ci
239562306a36Sopenharmony_ci	my $range_last_linenr = 0;
239662306a36Sopenharmony_ci	my $delta_offset = 0;
239762306a36Sopenharmony_ci
239862306a36Sopenharmony_ci	my $old_linenr = 0;
239962306a36Sopenharmony_ci	my $new_linenr = 0;
240062306a36Sopenharmony_ci
240162306a36Sopenharmony_ci	my $next_insert = 0;
240262306a36Sopenharmony_ci	my $next_delete = 0;
240362306a36Sopenharmony_ci
240462306a36Sopenharmony_ci	my @lines = ();
240562306a36Sopenharmony_ci
240662306a36Sopenharmony_ci	my $inserted = @{$insertedRef}[$next_insert++];
240762306a36Sopenharmony_ci	my $deleted = @{$deletedRef}[$next_delete++];
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_ci	foreach my $old_line (@{$linesRef}) {
241062306a36Sopenharmony_ci		my $save_line = 1;
241162306a36Sopenharmony_ci		my $line = $old_line;	#don't modify the array
241262306a36Sopenharmony_ci		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
241362306a36Sopenharmony_ci			$delta_offset = 0;
241462306a36Sopenharmony_ci		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
241562306a36Sopenharmony_ci			$range_last_linenr = $new_linenr;
241662306a36Sopenharmony_ci			fixup_current_range(\$line, $delta_offset, 0);
241762306a36Sopenharmony_ci		}
241862306a36Sopenharmony_ci
241962306a36Sopenharmony_ci		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
242062306a36Sopenharmony_ci			$deleted = @{$deletedRef}[$next_delete++];
242162306a36Sopenharmony_ci			$save_line = 0;
242262306a36Sopenharmony_ci			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
242362306a36Sopenharmony_ci		}
242462306a36Sopenharmony_ci
242562306a36Sopenharmony_ci		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
242662306a36Sopenharmony_ci			push(@lines, ${$inserted}{'LINE'});
242762306a36Sopenharmony_ci			$inserted = @{$insertedRef}[$next_insert++];
242862306a36Sopenharmony_ci			$new_linenr++;
242962306a36Sopenharmony_ci			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
243062306a36Sopenharmony_ci		}
243162306a36Sopenharmony_ci
243262306a36Sopenharmony_ci		if ($save_line) {
243362306a36Sopenharmony_ci			push(@lines, $line);
243462306a36Sopenharmony_ci			$new_linenr++;
243562306a36Sopenharmony_ci		}
243662306a36Sopenharmony_ci
243762306a36Sopenharmony_ci		$old_linenr++;
243862306a36Sopenharmony_ci	}
243962306a36Sopenharmony_ci
244062306a36Sopenharmony_ci	return @lines;
244162306a36Sopenharmony_ci}
244262306a36Sopenharmony_ci
244362306a36Sopenharmony_cisub fix_insert_line {
244462306a36Sopenharmony_ci	my ($linenr, $line) = @_;
244562306a36Sopenharmony_ci
244662306a36Sopenharmony_ci	my $inserted = {
244762306a36Sopenharmony_ci		LINENR => $linenr,
244862306a36Sopenharmony_ci		LINE => $line,
244962306a36Sopenharmony_ci	};
245062306a36Sopenharmony_ci	push(@fixed_inserted, $inserted);
245162306a36Sopenharmony_ci}
245262306a36Sopenharmony_ci
245362306a36Sopenharmony_cisub fix_delete_line {
245462306a36Sopenharmony_ci	my ($linenr, $line) = @_;
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci	my $deleted = {
245762306a36Sopenharmony_ci		LINENR => $linenr,
245862306a36Sopenharmony_ci		LINE => $line,
245962306a36Sopenharmony_ci	};
246062306a36Sopenharmony_ci
246162306a36Sopenharmony_ci	push(@fixed_deleted, $deleted);
246262306a36Sopenharmony_ci}
246362306a36Sopenharmony_ci
246462306a36Sopenharmony_cisub ERROR {
246562306a36Sopenharmony_ci	my ($type, $msg) = @_;
246662306a36Sopenharmony_ci
246762306a36Sopenharmony_ci	if (report("ERROR", $type, $msg)) {
246862306a36Sopenharmony_ci		our $clean = 0;
246962306a36Sopenharmony_ci		our $cnt_error++;
247062306a36Sopenharmony_ci		return 1;
247162306a36Sopenharmony_ci	}
247262306a36Sopenharmony_ci	return 0;
247362306a36Sopenharmony_ci}
247462306a36Sopenharmony_cisub WARN {
247562306a36Sopenharmony_ci	my ($type, $msg) = @_;
247662306a36Sopenharmony_ci
247762306a36Sopenharmony_ci	if (report("WARNING", $type, $msg)) {
247862306a36Sopenharmony_ci		our $clean = 0;
247962306a36Sopenharmony_ci		our $cnt_warn++;
248062306a36Sopenharmony_ci		return 1;
248162306a36Sopenharmony_ci	}
248262306a36Sopenharmony_ci	return 0;
248362306a36Sopenharmony_ci}
248462306a36Sopenharmony_cisub CHK {
248562306a36Sopenharmony_ci	my ($type, $msg) = @_;
248662306a36Sopenharmony_ci
248762306a36Sopenharmony_ci	if ($check && report("CHECK", $type, $msg)) {
248862306a36Sopenharmony_ci		our $clean = 0;
248962306a36Sopenharmony_ci		our $cnt_chk++;
249062306a36Sopenharmony_ci		return 1;
249162306a36Sopenharmony_ci	}
249262306a36Sopenharmony_ci	return 0;
249362306a36Sopenharmony_ci}
249462306a36Sopenharmony_ci
249562306a36Sopenharmony_cisub check_absolute_file {
249662306a36Sopenharmony_ci	my ($absolute, $herecurr) = @_;
249762306a36Sopenharmony_ci	my $file = $absolute;
249862306a36Sopenharmony_ci
249962306a36Sopenharmony_ci	##print "absolute<$absolute>\n";
250062306a36Sopenharmony_ci
250162306a36Sopenharmony_ci	# See if any suffix of this path is a path within the tree.
250262306a36Sopenharmony_ci	while ($file =~ s@^[^/]*/@@) {
250362306a36Sopenharmony_ci		if (-f "$root/$file") {
250462306a36Sopenharmony_ci			##print "file<$file>\n";
250562306a36Sopenharmony_ci			last;
250662306a36Sopenharmony_ci		}
250762306a36Sopenharmony_ci	}
250862306a36Sopenharmony_ci	if (! -f _)  {
250962306a36Sopenharmony_ci		return 0;
251062306a36Sopenharmony_ci	}
251162306a36Sopenharmony_ci
251262306a36Sopenharmony_ci	# It is, so see if the prefix is acceptable.
251362306a36Sopenharmony_ci	my $prefix = $absolute;
251462306a36Sopenharmony_ci	substr($prefix, -length($file)) = '';
251562306a36Sopenharmony_ci
251662306a36Sopenharmony_ci	##print "prefix<$prefix>\n";
251762306a36Sopenharmony_ci	if ($prefix ne ".../") {
251862306a36Sopenharmony_ci		WARN("USE_RELATIVE_PATH",
251962306a36Sopenharmony_ci		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
252062306a36Sopenharmony_ci	}
252162306a36Sopenharmony_ci}
252262306a36Sopenharmony_ci
252362306a36Sopenharmony_cisub trim {
252462306a36Sopenharmony_ci	my ($string) = @_;
252562306a36Sopenharmony_ci
252662306a36Sopenharmony_ci	$string =~ s/^\s+|\s+$//g;
252762306a36Sopenharmony_ci
252862306a36Sopenharmony_ci	return $string;
252962306a36Sopenharmony_ci}
253062306a36Sopenharmony_ci
253162306a36Sopenharmony_cisub ltrim {
253262306a36Sopenharmony_ci	my ($string) = @_;
253362306a36Sopenharmony_ci
253462306a36Sopenharmony_ci	$string =~ s/^\s+//;
253562306a36Sopenharmony_ci
253662306a36Sopenharmony_ci	return $string;
253762306a36Sopenharmony_ci}
253862306a36Sopenharmony_ci
253962306a36Sopenharmony_cisub rtrim {
254062306a36Sopenharmony_ci	my ($string) = @_;
254162306a36Sopenharmony_ci
254262306a36Sopenharmony_ci	$string =~ s/\s+$//;
254362306a36Sopenharmony_ci
254462306a36Sopenharmony_ci	return $string;
254562306a36Sopenharmony_ci}
254662306a36Sopenharmony_ci
254762306a36Sopenharmony_cisub string_find_replace {
254862306a36Sopenharmony_ci	my ($string, $find, $replace) = @_;
254962306a36Sopenharmony_ci
255062306a36Sopenharmony_ci	$string =~ s/$find/$replace/g;
255162306a36Sopenharmony_ci
255262306a36Sopenharmony_ci	return $string;
255362306a36Sopenharmony_ci}
255462306a36Sopenharmony_ci
255562306a36Sopenharmony_cisub tabify {
255662306a36Sopenharmony_ci	my ($leading) = @_;
255762306a36Sopenharmony_ci
255862306a36Sopenharmony_ci	my $source_indent = $tabsize;
255962306a36Sopenharmony_ci	my $max_spaces_before_tab = $source_indent - 1;
256062306a36Sopenharmony_ci	my $spaces_to_tab = " " x $source_indent;
256162306a36Sopenharmony_ci
256262306a36Sopenharmony_ci	#convert leading spaces to tabs
256362306a36Sopenharmony_ci	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
256462306a36Sopenharmony_ci	#Remove spaces before a tab
256562306a36Sopenharmony_ci	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
256662306a36Sopenharmony_ci
256762306a36Sopenharmony_ci	return "$leading";
256862306a36Sopenharmony_ci}
256962306a36Sopenharmony_ci
257062306a36Sopenharmony_cisub pos_last_openparen {
257162306a36Sopenharmony_ci	my ($line) = @_;
257262306a36Sopenharmony_ci
257362306a36Sopenharmony_ci	my $pos = 0;
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci	my $opens = $line =~ tr/\(/\(/;
257662306a36Sopenharmony_ci	my $closes = $line =~ tr/\)/\)/;
257762306a36Sopenharmony_ci
257862306a36Sopenharmony_ci	my $last_openparen = 0;
257962306a36Sopenharmony_ci
258062306a36Sopenharmony_ci	if (($opens == 0) || ($closes >= $opens)) {
258162306a36Sopenharmony_ci		return -1;
258262306a36Sopenharmony_ci	}
258362306a36Sopenharmony_ci
258462306a36Sopenharmony_ci	my $len = length($line);
258562306a36Sopenharmony_ci
258662306a36Sopenharmony_ci	for ($pos = 0; $pos < $len; $pos++) {
258762306a36Sopenharmony_ci		my $string = substr($line, $pos);
258862306a36Sopenharmony_ci		if ($string =~ /^($FuncArg|$balanced_parens)/) {
258962306a36Sopenharmony_ci			$pos += length($1) - 1;
259062306a36Sopenharmony_ci		} elsif (substr($line, $pos, 1) eq '(') {
259162306a36Sopenharmony_ci			$last_openparen = $pos;
259262306a36Sopenharmony_ci		} elsif (index($string, '(') == -1) {
259362306a36Sopenharmony_ci			last;
259462306a36Sopenharmony_ci		}
259562306a36Sopenharmony_ci	}
259662306a36Sopenharmony_ci
259762306a36Sopenharmony_ci	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
259862306a36Sopenharmony_ci}
259962306a36Sopenharmony_ci
260062306a36Sopenharmony_cisub get_raw_comment {
260162306a36Sopenharmony_ci	my ($line, $rawline) = @_;
260262306a36Sopenharmony_ci	my $comment = '';
260362306a36Sopenharmony_ci
260462306a36Sopenharmony_ci	for my $i (0 .. (length($line) - 1)) {
260562306a36Sopenharmony_ci		if (substr($line, $i, 1) eq "$;") {
260662306a36Sopenharmony_ci			$comment .= substr($rawline, $i, 1);
260762306a36Sopenharmony_ci		}
260862306a36Sopenharmony_ci	}
260962306a36Sopenharmony_ci
261062306a36Sopenharmony_ci	return $comment;
261162306a36Sopenharmony_ci}
261262306a36Sopenharmony_ci
261362306a36Sopenharmony_cisub exclude_global_initialisers {
261462306a36Sopenharmony_ci	my ($realfile) = @_;
261562306a36Sopenharmony_ci
261662306a36Sopenharmony_ci	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
261762306a36Sopenharmony_ci	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
261862306a36Sopenharmony_ci		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
261962306a36Sopenharmony_ci		$realfile =~ m@/bpf/.*\.bpf\.c$@;
262062306a36Sopenharmony_ci}
262162306a36Sopenharmony_ci
262262306a36Sopenharmony_cisub process {
262362306a36Sopenharmony_ci	my $filename = shift;
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	my $linenr=0;
262662306a36Sopenharmony_ci	my $prevline="";
262762306a36Sopenharmony_ci	my $prevrawline="";
262862306a36Sopenharmony_ci	my $stashline="";
262962306a36Sopenharmony_ci	my $stashrawline="";
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci	my $length;
263262306a36Sopenharmony_ci	my $indent;
263362306a36Sopenharmony_ci	my $previndent=0;
263462306a36Sopenharmony_ci	my $stashindent=0;
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	our $clean = 1;
263762306a36Sopenharmony_ci	my $signoff = 0;
263862306a36Sopenharmony_ci	my $author = '';
263962306a36Sopenharmony_ci	my $authorsignoff = 0;
264062306a36Sopenharmony_ci	my $author_sob = '';
264162306a36Sopenharmony_ci	my $is_patch = 0;
264262306a36Sopenharmony_ci	my $is_binding_patch = -1;
264362306a36Sopenharmony_ci	my $in_header_lines = $file ? 0 : 1;
264462306a36Sopenharmony_ci	my $in_commit_log = 0;		#Scanning lines before patch
264562306a36Sopenharmony_ci	my $has_patch_separator = 0;	#Found a --- line
264662306a36Sopenharmony_ci	my $has_commit_log = 0;		#Encountered lines before patch
264762306a36Sopenharmony_ci	my $commit_log_lines = 0;	#Number of commit log lines
264862306a36Sopenharmony_ci	my $commit_log_possible_stack_dump = 0;
264962306a36Sopenharmony_ci	my $commit_log_long_line = 0;
265062306a36Sopenharmony_ci	my $commit_log_has_diff = 0;
265162306a36Sopenharmony_ci	my $reported_maintainer_file = 0;
265262306a36Sopenharmony_ci	my $non_utf8_charset = 0;
265362306a36Sopenharmony_ci
265462306a36Sopenharmony_ci	my $last_git_commit_id_linenr = -1;
265562306a36Sopenharmony_ci
265662306a36Sopenharmony_ci	my $last_blank_line = 0;
265762306a36Sopenharmony_ci	my $last_coalesced_string_linenr = -1;
265862306a36Sopenharmony_ci
265962306a36Sopenharmony_ci	our @report = ();
266062306a36Sopenharmony_ci	our $cnt_lines = 0;
266162306a36Sopenharmony_ci	our $cnt_error = 0;
266262306a36Sopenharmony_ci	our $cnt_warn = 0;
266362306a36Sopenharmony_ci	our $cnt_chk = 0;
266462306a36Sopenharmony_ci
266562306a36Sopenharmony_ci	# Trace the real file/line as we go.
266662306a36Sopenharmony_ci	my $realfile = '';
266762306a36Sopenharmony_ci	my $realline = 0;
266862306a36Sopenharmony_ci	my $realcnt = 0;
266962306a36Sopenharmony_ci	my $here = '';
267062306a36Sopenharmony_ci	my $context_function;		#undef'd unless there's a known function
267162306a36Sopenharmony_ci	my $in_comment = 0;
267262306a36Sopenharmony_ci	my $comment_edge = 0;
267362306a36Sopenharmony_ci	my $first_line = 0;
267462306a36Sopenharmony_ci	my $p1_prefix = '';
267562306a36Sopenharmony_ci
267662306a36Sopenharmony_ci	my $prev_values = 'E';
267762306a36Sopenharmony_ci
267862306a36Sopenharmony_ci	# suppression flags
267962306a36Sopenharmony_ci	my %suppress_ifbraces;
268062306a36Sopenharmony_ci	my %suppress_whiletrailers;
268162306a36Sopenharmony_ci	my %suppress_export;
268262306a36Sopenharmony_ci	my $suppress_statement = 0;
268362306a36Sopenharmony_ci
268462306a36Sopenharmony_ci	my %signatures = ();
268562306a36Sopenharmony_ci
268662306a36Sopenharmony_ci	# Pre-scan the patch sanitizing the lines.
268762306a36Sopenharmony_ci	# Pre-scan the patch looking for any __setup documentation.
268862306a36Sopenharmony_ci	#
268962306a36Sopenharmony_ci	my @setup_docs = ();
269062306a36Sopenharmony_ci	my $setup_docs = 0;
269162306a36Sopenharmony_ci
269262306a36Sopenharmony_ci	my $camelcase_file_seeded = 0;
269362306a36Sopenharmony_ci
269462306a36Sopenharmony_ci	my $checklicenseline = 1;
269562306a36Sopenharmony_ci
269662306a36Sopenharmony_ci	sanitise_line_reset();
269762306a36Sopenharmony_ci	my $line;
269862306a36Sopenharmony_ci	foreach my $rawline (@rawlines) {
269962306a36Sopenharmony_ci		$linenr++;
270062306a36Sopenharmony_ci		$line = $rawline;
270162306a36Sopenharmony_ci
270262306a36Sopenharmony_ci		push(@fixed, $rawline) if ($fix);
270362306a36Sopenharmony_ci
270462306a36Sopenharmony_ci		if ($rawline=~/^\+\+\+\s+(\S+)/) {
270562306a36Sopenharmony_ci			$setup_docs = 0;
270662306a36Sopenharmony_ci			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
270762306a36Sopenharmony_ci				$setup_docs = 1;
270862306a36Sopenharmony_ci			}
270962306a36Sopenharmony_ci			#next;
271062306a36Sopenharmony_ci		}
271162306a36Sopenharmony_ci		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
271262306a36Sopenharmony_ci			$realline=$1-1;
271362306a36Sopenharmony_ci			if (defined $2) {
271462306a36Sopenharmony_ci				$realcnt=$3+1;
271562306a36Sopenharmony_ci			} else {
271662306a36Sopenharmony_ci				$realcnt=1+1;
271762306a36Sopenharmony_ci			}
271862306a36Sopenharmony_ci			$in_comment = 0;
271962306a36Sopenharmony_ci
272062306a36Sopenharmony_ci			# Guestimate if this is a continuing comment.  Run
272162306a36Sopenharmony_ci			# the context looking for a comment "edge".  If this
272262306a36Sopenharmony_ci			# edge is a close comment then we must be in a comment
272362306a36Sopenharmony_ci			# at context start.
272462306a36Sopenharmony_ci			my $edge;
272562306a36Sopenharmony_ci			my $cnt = $realcnt;
272662306a36Sopenharmony_ci			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
272762306a36Sopenharmony_ci				next if (defined $rawlines[$ln - 1] &&
272862306a36Sopenharmony_ci					 $rawlines[$ln - 1] =~ /^-/);
272962306a36Sopenharmony_ci				$cnt--;
273062306a36Sopenharmony_ci				#print "RAW<$rawlines[$ln - 1]>\n";
273162306a36Sopenharmony_ci				last if (!defined $rawlines[$ln - 1]);
273262306a36Sopenharmony_ci				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
273362306a36Sopenharmony_ci				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
273462306a36Sopenharmony_ci					($edge) = $1;
273562306a36Sopenharmony_ci					last;
273662306a36Sopenharmony_ci				}
273762306a36Sopenharmony_ci			}
273862306a36Sopenharmony_ci			if (defined $edge && $edge eq '*/') {
273962306a36Sopenharmony_ci				$in_comment = 1;
274062306a36Sopenharmony_ci			}
274162306a36Sopenharmony_ci
274262306a36Sopenharmony_ci			# Guestimate if this is a continuing comment.  If this
274362306a36Sopenharmony_ci			# is the start of a diff block and this line starts
274462306a36Sopenharmony_ci			# ' *' then it is very likely a comment.
274562306a36Sopenharmony_ci			if (!defined $edge &&
274662306a36Sopenharmony_ci			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
274762306a36Sopenharmony_ci			{
274862306a36Sopenharmony_ci				$in_comment = 1;
274962306a36Sopenharmony_ci			}
275062306a36Sopenharmony_ci
275162306a36Sopenharmony_ci			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
275262306a36Sopenharmony_ci			sanitise_line_reset($in_comment);
275362306a36Sopenharmony_ci
275462306a36Sopenharmony_ci		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
275562306a36Sopenharmony_ci			# Standardise the strings and chars within the input to
275662306a36Sopenharmony_ci			# simplify matching -- only bother with positive lines.
275762306a36Sopenharmony_ci			$line = sanitise_line($rawline);
275862306a36Sopenharmony_ci		}
275962306a36Sopenharmony_ci		push(@lines, $line);
276062306a36Sopenharmony_ci
276162306a36Sopenharmony_ci		if ($realcnt > 1) {
276262306a36Sopenharmony_ci			$realcnt-- if ($line =~ /^(?:\+| |$)/);
276362306a36Sopenharmony_ci		} else {
276462306a36Sopenharmony_ci			$realcnt = 0;
276562306a36Sopenharmony_ci		}
276662306a36Sopenharmony_ci
276762306a36Sopenharmony_ci		#print "==>$rawline\n";
276862306a36Sopenharmony_ci		#print "-->$line\n";
276962306a36Sopenharmony_ci
277062306a36Sopenharmony_ci		if ($setup_docs && $line =~ /^\+/) {
277162306a36Sopenharmony_ci			push(@setup_docs, $line);
277262306a36Sopenharmony_ci		}
277362306a36Sopenharmony_ci	}
277462306a36Sopenharmony_ci
277562306a36Sopenharmony_ci	$prefix = '';
277662306a36Sopenharmony_ci
277762306a36Sopenharmony_ci	$realcnt = 0;
277862306a36Sopenharmony_ci	$linenr = 0;
277962306a36Sopenharmony_ci	$fixlinenr = -1;
278062306a36Sopenharmony_ci	foreach my $line (@lines) {
278162306a36Sopenharmony_ci		$linenr++;
278262306a36Sopenharmony_ci		$fixlinenr++;
278362306a36Sopenharmony_ci		my $sline = $line;	#copy of $line
278462306a36Sopenharmony_ci		$sline =~ s/$;/ /g;	#with comments as spaces
278562306a36Sopenharmony_ci
278662306a36Sopenharmony_ci		my $rawline = $rawlines[$linenr - 1];
278762306a36Sopenharmony_ci		my $raw_comment = get_raw_comment($line, $rawline);
278862306a36Sopenharmony_ci
278962306a36Sopenharmony_ci# check if it's a mode change, rename or start of a patch
279062306a36Sopenharmony_ci		if (!$in_commit_log &&
279162306a36Sopenharmony_ci		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
279262306a36Sopenharmony_ci		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
279362306a36Sopenharmony_ci		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
279462306a36Sopenharmony_ci			$is_patch = 1;
279562306a36Sopenharmony_ci		}
279662306a36Sopenharmony_ci
279762306a36Sopenharmony_ci#extract the line range in the file after the patch is applied
279862306a36Sopenharmony_ci		if (!$in_commit_log &&
279962306a36Sopenharmony_ci		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
280062306a36Sopenharmony_ci			my $context = $4;
280162306a36Sopenharmony_ci			$is_patch = 1;
280262306a36Sopenharmony_ci			$first_line = $linenr + 1;
280362306a36Sopenharmony_ci			$realline=$1-1;
280462306a36Sopenharmony_ci			if (defined $2) {
280562306a36Sopenharmony_ci				$realcnt=$3+1;
280662306a36Sopenharmony_ci			} else {
280762306a36Sopenharmony_ci				$realcnt=1+1;
280862306a36Sopenharmony_ci			}
280962306a36Sopenharmony_ci			annotate_reset();
281062306a36Sopenharmony_ci			$prev_values = 'E';
281162306a36Sopenharmony_ci
281262306a36Sopenharmony_ci			%suppress_ifbraces = ();
281362306a36Sopenharmony_ci			%suppress_whiletrailers = ();
281462306a36Sopenharmony_ci			%suppress_export = ();
281562306a36Sopenharmony_ci			$suppress_statement = 0;
281662306a36Sopenharmony_ci			if ($context =~ /\b(\w+)\s*\(/) {
281762306a36Sopenharmony_ci				$context_function = $1;
281862306a36Sopenharmony_ci			} else {
281962306a36Sopenharmony_ci				undef $context_function;
282062306a36Sopenharmony_ci			}
282162306a36Sopenharmony_ci			next;
282262306a36Sopenharmony_ci
282362306a36Sopenharmony_ci# track the line number as we move through the hunk, note that
282462306a36Sopenharmony_ci# new versions of GNU diff omit the leading space on completely
282562306a36Sopenharmony_ci# blank context lines so we need to count that too.
282662306a36Sopenharmony_ci		} elsif ($line =~ /^( |\+|$)/) {
282762306a36Sopenharmony_ci			$realline++;
282862306a36Sopenharmony_ci			$realcnt-- if ($realcnt != 0);
282962306a36Sopenharmony_ci
283062306a36Sopenharmony_ci			# Measure the line length and indent.
283162306a36Sopenharmony_ci			($length, $indent) = line_stats($rawline);
283262306a36Sopenharmony_ci
283362306a36Sopenharmony_ci			# Track the previous line.
283462306a36Sopenharmony_ci			($prevline, $stashline) = ($stashline, $line);
283562306a36Sopenharmony_ci			($previndent, $stashindent) = ($stashindent, $indent);
283662306a36Sopenharmony_ci			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
283762306a36Sopenharmony_ci
283862306a36Sopenharmony_ci			#warn "line<$line>\n";
283962306a36Sopenharmony_ci
284062306a36Sopenharmony_ci		} elsif ($realcnt == 1) {
284162306a36Sopenharmony_ci			$realcnt--;
284262306a36Sopenharmony_ci		}
284362306a36Sopenharmony_ci
284462306a36Sopenharmony_ci		my $hunk_line = ($realcnt != 0);
284562306a36Sopenharmony_ci
284662306a36Sopenharmony_ci		$here = "#$linenr: " if (!$file);
284762306a36Sopenharmony_ci		$here = "#$realline: " if ($file);
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci		my $found_file = 0;
285062306a36Sopenharmony_ci		# extract the filename as it passes
285162306a36Sopenharmony_ci		if ($line =~ /^diff --git.*?(\S+)$/) {
285262306a36Sopenharmony_ci			$realfile = $1;
285362306a36Sopenharmony_ci			$realfile =~ s@^([^/]*)/@@ if (!$file);
285462306a36Sopenharmony_ci			$in_commit_log = 0;
285562306a36Sopenharmony_ci			$found_file = 1;
285662306a36Sopenharmony_ci		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
285762306a36Sopenharmony_ci			$realfile = $1;
285862306a36Sopenharmony_ci			$realfile =~ s@^([^/]*)/@@ if (!$file);
285962306a36Sopenharmony_ci			$in_commit_log = 0;
286062306a36Sopenharmony_ci
286162306a36Sopenharmony_ci			$p1_prefix = $1;
286262306a36Sopenharmony_ci			if (!$file && $tree && $p1_prefix ne '' &&
286362306a36Sopenharmony_ci			    -e "$root/$p1_prefix") {
286462306a36Sopenharmony_ci				WARN("PATCH_PREFIX",
286562306a36Sopenharmony_ci				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
286662306a36Sopenharmony_ci			}
286762306a36Sopenharmony_ci
286862306a36Sopenharmony_ci			if ($realfile =~ m@^include/asm/@) {
286962306a36Sopenharmony_ci				ERROR("MODIFIED_INCLUDE_ASM",
287062306a36Sopenharmony_ci				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
287162306a36Sopenharmony_ci			}
287262306a36Sopenharmony_ci			$found_file = 1;
287362306a36Sopenharmony_ci		}
287462306a36Sopenharmony_ci
287562306a36Sopenharmony_ci#make up the handle for any error we report on this line
287662306a36Sopenharmony_ci		if ($showfile) {
287762306a36Sopenharmony_ci			$prefix = "$realfile:$realline: "
287862306a36Sopenharmony_ci		} elsif ($emacs) {
287962306a36Sopenharmony_ci			if ($file) {
288062306a36Sopenharmony_ci				$prefix = "$filename:$realline: ";
288162306a36Sopenharmony_ci			} else {
288262306a36Sopenharmony_ci				$prefix = "$filename:$linenr: ";
288362306a36Sopenharmony_ci			}
288462306a36Sopenharmony_ci		}
288562306a36Sopenharmony_ci
288662306a36Sopenharmony_ci		if ($found_file) {
288762306a36Sopenharmony_ci			if (is_maintained_obsolete($realfile)) {
288862306a36Sopenharmony_ci				WARN("OBSOLETE",
288962306a36Sopenharmony_ci				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
289062306a36Sopenharmony_ci			}
289162306a36Sopenharmony_ci			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
289262306a36Sopenharmony_ci				$check = 1;
289362306a36Sopenharmony_ci			} else {
289462306a36Sopenharmony_ci				$check = $check_orig;
289562306a36Sopenharmony_ci			}
289662306a36Sopenharmony_ci			$checklicenseline = 1;
289762306a36Sopenharmony_ci
289862306a36Sopenharmony_ci			if ($realfile !~ /^MAINTAINERS/) {
289962306a36Sopenharmony_ci				my $last_binding_patch = $is_binding_patch;
290062306a36Sopenharmony_ci
290162306a36Sopenharmony_ci				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
290262306a36Sopenharmony_ci
290362306a36Sopenharmony_ci				if (($last_binding_patch != -1) &&
290462306a36Sopenharmony_ci				    ($last_binding_patch ^ $is_binding_patch)) {
290562306a36Sopenharmony_ci					WARN("DT_SPLIT_BINDING_PATCH",
290662306a36Sopenharmony_ci					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
290762306a36Sopenharmony_ci				}
290862306a36Sopenharmony_ci			}
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ci			next;
291162306a36Sopenharmony_ci		}
291262306a36Sopenharmony_ci
291362306a36Sopenharmony_ci		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
291462306a36Sopenharmony_ci
291562306a36Sopenharmony_ci		my $hereline = "$here\n$rawline\n";
291662306a36Sopenharmony_ci		my $herecurr = "$here\n$rawline\n";
291762306a36Sopenharmony_ci		my $hereprev = "$here\n$prevrawline\n$rawline\n";
291862306a36Sopenharmony_ci
291962306a36Sopenharmony_ci		$cnt_lines++ if ($realcnt != 0);
292062306a36Sopenharmony_ci
292162306a36Sopenharmony_ci# Verify the existence of a commit log if appropriate
292262306a36Sopenharmony_ci# 2 is used because a $signature is counted in $commit_log_lines
292362306a36Sopenharmony_ci		if ($in_commit_log) {
292462306a36Sopenharmony_ci			if ($line !~ /^\s*$/) {
292562306a36Sopenharmony_ci				$commit_log_lines++;	#could be a $signature
292662306a36Sopenharmony_ci			}
292762306a36Sopenharmony_ci		} elsif ($has_commit_log && $commit_log_lines < 2) {
292862306a36Sopenharmony_ci			WARN("COMMIT_MESSAGE",
292962306a36Sopenharmony_ci			     "Missing commit description - Add an appropriate one\n");
293062306a36Sopenharmony_ci			$commit_log_lines = 2;	#warn only once
293162306a36Sopenharmony_ci		}
293262306a36Sopenharmony_ci
293362306a36Sopenharmony_ci# Check if the commit log has what seems like a diff which can confuse patch
293462306a36Sopenharmony_ci		if ($in_commit_log && !$commit_log_has_diff &&
293562306a36Sopenharmony_ci		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
293662306a36Sopenharmony_ci		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
293762306a36Sopenharmony_ci		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
293862306a36Sopenharmony_ci		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
293962306a36Sopenharmony_ci			ERROR("DIFF_IN_COMMIT_MSG",
294062306a36Sopenharmony_ci			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
294162306a36Sopenharmony_ci			$commit_log_has_diff = 1;
294262306a36Sopenharmony_ci		}
294362306a36Sopenharmony_ci
294462306a36Sopenharmony_ci# Check for incorrect file permissions
294562306a36Sopenharmony_ci		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
294662306a36Sopenharmony_ci			my $permhere = $here . "FILE: $realfile\n";
294762306a36Sopenharmony_ci			if ($realfile !~ m@scripts/@ &&
294862306a36Sopenharmony_ci			    $realfile !~ /\.(py|pl|awk|sh)$/) {
294962306a36Sopenharmony_ci				ERROR("EXECUTE_PERMISSIONS",
295062306a36Sopenharmony_ci				      "do not set execute permissions for source files\n" . $permhere);
295162306a36Sopenharmony_ci			}
295262306a36Sopenharmony_ci		}
295362306a36Sopenharmony_ci
295462306a36Sopenharmony_ci# Check the patch for a From:
295562306a36Sopenharmony_ci		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
295662306a36Sopenharmony_ci			$author = $1;
295762306a36Sopenharmony_ci			my $curline = $linenr;
295862306a36Sopenharmony_ci			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
295962306a36Sopenharmony_ci				$author .= $1;
296062306a36Sopenharmony_ci			}
296162306a36Sopenharmony_ci			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
296262306a36Sopenharmony_ci			$author =~ s/"//g;
296362306a36Sopenharmony_ci			$author = reformat_email($author);
296462306a36Sopenharmony_ci		}
296562306a36Sopenharmony_ci
296662306a36Sopenharmony_ci# Check the patch for a signoff:
296762306a36Sopenharmony_ci		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
296862306a36Sopenharmony_ci			$signoff++;
296962306a36Sopenharmony_ci			$in_commit_log = 0;
297062306a36Sopenharmony_ci			if ($author ne ''  && $authorsignoff != 1) {
297162306a36Sopenharmony_ci				if (same_email_addresses($1, $author)) {
297262306a36Sopenharmony_ci					$authorsignoff = 1;
297362306a36Sopenharmony_ci				} else {
297462306a36Sopenharmony_ci					my $ctx = $1;
297562306a36Sopenharmony_ci					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
297662306a36Sopenharmony_ci					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
297762306a36Sopenharmony_ci
297862306a36Sopenharmony_ci					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
297962306a36Sopenharmony_ci						$author_sob = $ctx;
298062306a36Sopenharmony_ci						$authorsignoff = 2;
298162306a36Sopenharmony_ci					} elsif (lc $email_address eq lc $author_address) {
298262306a36Sopenharmony_ci						$author_sob = $ctx;
298362306a36Sopenharmony_ci						$authorsignoff = 3;
298462306a36Sopenharmony_ci					} elsif ($email_name eq $author_name) {
298562306a36Sopenharmony_ci						$author_sob = $ctx;
298662306a36Sopenharmony_ci						$authorsignoff = 4;
298762306a36Sopenharmony_ci
298862306a36Sopenharmony_ci						my $address1 = $email_address;
298962306a36Sopenharmony_ci						my $address2 = $author_address;
299062306a36Sopenharmony_ci
299162306a36Sopenharmony_ci						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
299262306a36Sopenharmony_ci							$address1 = "$1$2";
299362306a36Sopenharmony_ci						}
299462306a36Sopenharmony_ci						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
299562306a36Sopenharmony_ci							$address2 = "$1$2";
299662306a36Sopenharmony_ci						}
299762306a36Sopenharmony_ci						if ($address1 eq $address2) {
299862306a36Sopenharmony_ci							$authorsignoff = 5;
299962306a36Sopenharmony_ci						}
300062306a36Sopenharmony_ci					}
300162306a36Sopenharmony_ci				}
300262306a36Sopenharmony_ci			}
300362306a36Sopenharmony_ci		}
300462306a36Sopenharmony_ci
300562306a36Sopenharmony_ci# Check for patch separator
300662306a36Sopenharmony_ci		if ($line =~ /^---$/) {
300762306a36Sopenharmony_ci			$has_patch_separator = 1;
300862306a36Sopenharmony_ci			$in_commit_log = 0;
300962306a36Sopenharmony_ci		}
301062306a36Sopenharmony_ci
301162306a36Sopenharmony_ci# Check if MAINTAINERS is being updated.  If so, there's probably no need to
301262306a36Sopenharmony_ci# emit the "does MAINTAINERS need updating?" message on file add/move/delete
301362306a36Sopenharmony_ci		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
301462306a36Sopenharmony_ci			$reported_maintainer_file = 1;
301562306a36Sopenharmony_ci		}
301662306a36Sopenharmony_ci
301762306a36Sopenharmony_ci# Check signature styles
301862306a36Sopenharmony_ci		if (!$in_header_lines &&
301962306a36Sopenharmony_ci		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
302062306a36Sopenharmony_ci			my $space_before = $1;
302162306a36Sopenharmony_ci			my $sign_off = $2;
302262306a36Sopenharmony_ci			my $space_after = $3;
302362306a36Sopenharmony_ci			my $email = $4;
302462306a36Sopenharmony_ci			my $ucfirst_sign_off = ucfirst(lc($sign_off));
302562306a36Sopenharmony_ci
302662306a36Sopenharmony_ci			if ($sign_off !~ /$signature_tags/) {
302762306a36Sopenharmony_ci				my $suggested_signature = find_standard_signature($sign_off);
302862306a36Sopenharmony_ci				if ($suggested_signature eq "") {
302962306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
303062306a36Sopenharmony_ci					     "Non-standard signature: $sign_off\n" . $herecurr);
303162306a36Sopenharmony_ci				} else {
303262306a36Sopenharmony_ci					if (WARN("BAD_SIGN_OFF",
303362306a36Sopenharmony_ci						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
303462306a36Sopenharmony_ci					    $fix) {
303562306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
303662306a36Sopenharmony_ci					}
303762306a36Sopenharmony_ci				}
303862306a36Sopenharmony_ci			}
303962306a36Sopenharmony_ci			if (defined $space_before && $space_before ne "") {
304062306a36Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
304162306a36Sopenharmony_ci					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
304262306a36Sopenharmony_ci				    $fix) {
304362306a36Sopenharmony_ci					$fixed[$fixlinenr] =
304462306a36Sopenharmony_ci					    "$ucfirst_sign_off $email";
304562306a36Sopenharmony_ci				}
304662306a36Sopenharmony_ci			}
304762306a36Sopenharmony_ci			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
304862306a36Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
304962306a36Sopenharmony_ci					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
305062306a36Sopenharmony_ci				    $fix) {
305162306a36Sopenharmony_ci					$fixed[$fixlinenr] =
305262306a36Sopenharmony_ci					    "$ucfirst_sign_off $email";
305362306a36Sopenharmony_ci				}
305462306a36Sopenharmony_ci
305562306a36Sopenharmony_ci			}
305662306a36Sopenharmony_ci			if (!defined $space_after || $space_after ne " ") {
305762306a36Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
305862306a36Sopenharmony_ci					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
305962306a36Sopenharmony_ci				    $fix) {
306062306a36Sopenharmony_ci					$fixed[$fixlinenr] =
306162306a36Sopenharmony_ci					    "$ucfirst_sign_off $email";
306262306a36Sopenharmony_ci				}
306362306a36Sopenharmony_ci			}
306462306a36Sopenharmony_ci
306562306a36Sopenharmony_ci			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
306662306a36Sopenharmony_ci			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
306762306a36Sopenharmony_ci			if ($suggested_email eq "") {
306862306a36Sopenharmony_ci				ERROR("BAD_SIGN_OFF",
306962306a36Sopenharmony_ci				      "Unrecognized email address: '$email'\n" . $herecurr);
307062306a36Sopenharmony_ci			} else {
307162306a36Sopenharmony_ci				my $dequoted = $suggested_email;
307262306a36Sopenharmony_ci				$dequoted =~ s/^"//;
307362306a36Sopenharmony_ci				$dequoted =~ s/" </ </;
307462306a36Sopenharmony_ci				# Don't force email to have quotes
307562306a36Sopenharmony_ci				# Allow just an angle bracketed address
307662306a36Sopenharmony_ci				if (!same_email_addresses($email, $suggested_email)) {
307762306a36Sopenharmony_ci					if (WARN("BAD_SIGN_OFF",
307862306a36Sopenharmony_ci						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
307962306a36Sopenharmony_ci					    $fix) {
308062306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
308162306a36Sopenharmony_ci					}
308262306a36Sopenharmony_ci				}
308362306a36Sopenharmony_ci
308462306a36Sopenharmony_ci				# Address part shouldn't have comments
308562306a36Sopenharmony_ci				my $stripped_address = $email_address;
308662306a36Sopenharmony_ci				$stripped_address =~ s/\([^\(\)]*\)//g;
308762306a36Sopenharmony_ci				if ($email_address ne $stripped_address) {
308862306a36Sopenharmony_ci					if (WARN("BAD_SIGN_OFF",
308962306a36Sopenharmony_ci						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
309062306a36Sopenharmony_ci					    $fix) {
309162306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
309262306a36Sopenharmony_ci					}
309362306a36Sopenharmony_ci				}
309462306a36Sopenharmony_ci
309562306a36Sopenharmony_ci				# Only one name comment should be allowed
309662306a36Sopenharmony_ci				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
309762306a36Sopenharmony_ci				if ($comment_count > 1) {
309862306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
309962306a36Sopenharmony_ci					     "Use a single name comment in email: '$email'\n" . $herecurr);
310062306a36Sopenharmony_ci				}
310162306a36Sopenharmony_ci
310262306a36Sopenharmony_ci
310362306a36Sopenharmony_ci				# stable@vger.kernel.org or stable@kernel.org shouldn't
310462306a36Sopenharmony_ci				# have an email name. In addition comments should strictly
310562306a36Sopenharmony_ci				# begin with a #
310662306a36Sopenharmony_ci				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
310762306a36Sopenharmony_ci					if (($comment ne "" && $comment !~ /^#.+/) ||
310862306a36Sopenharmony_ci					    ($email_name ne "")) {
310962306a36Sopenharmony_ci						my $cur_name = $email_name;
311062306a36Sopenharmony_ci						my $new_comment = $comment;
311162306a36Sopenharmony_ci						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
311262306a36Sopenharmony_ci
311362306a36Sopenharmony_ci						# Remove brackets enclosing comment text
311462306a36Sopenharmony_ci						# and # from start of comments to get comment text
311562306a36Sopenharmony_ci						$new_comment =~ s/^\((.*)\)$/$1/;
311662306a36Sopenharmony_ci						$new_comment =~ s/^\[(.*)\]$/$1/;
311762306a36Sopenharmony_ci						$new_comment =~ s/^[\s\#]+|\s+$//g;
311862306a36Sopenharmony_ci
311962306a36Sopenharmony_ci						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
312062306a36Sopenharmony_ci						$new_comment = " # $new_comment" if ($new_comment ne "");
312162306a36Sopenharmony_ci						my $new_email = "$email_address$new_comment";
312262306a36Sopenharmony_ci
312362306a36Sopenharmony_ci						if (WARN("BAD_STABLE_ADDRESS_STYLE",
312462306a36Sopenharmony_ci							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
312562306a36Sopenharmony_ci						    $fix) {
312662306a36Sopenharmony_ci							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
312762306a36Sopenharmony_ci						}
312862306a36Sopenharmony_ci					}
312962306a36Sopenharmony_ci				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
313062306a36Sopenharmony_ci					my $new_comment = $comment;
313162306a36Sopenharmony_ci
313262306a36Sopenharmony_ci					# Extract comment text from within brackets or
313362306a36Sopenharmony_ci					# c89 style /*...*/ comments
313462306a36Sopenharmony_ci					$new_comment =~ s/^\[(.*)\]$/$1/;
313562306a36Sopenharmony_ci					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
313662306a36Sopenharmony_ci
313762306a36Sopenharmony_ci					$new_comment = trim($new_comment);
313862306a36Sopenharmony_ci					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
313962306a36Sopenharmony_ci					$new_comment = "($new_comment)" if ($new_comment ne "");
314062306a36Sopenharmony_ci					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
314162306a36Sopenharmony_ci
314262306a36Sopenharmony_ci					if (WARN("BAD_SIGN_OFF",
314362306a36Sopenharmony_ci						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
314462306a36Sopenharmony_ci					    $fix) {
314562306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
314662306a36Sopenharmony_ci					}
314762306a36Sopenharmony_ci				}
314862306a36Sopenharmony_ci			}
314962306a36Sopenharmony_ci
315062306a36Sopenharmony_ci# Check for duplicate signatures
315162306a36Sopenharmony_ci			my $sig_nospace = $line;
315262306a36Sopenharmony_ci			$sig_nospace =~ s/\s//g;
315362306a36Sopenharmony_ci			$sig_nospace = lc($sig_nospace);
315462306a36Sopenharmony_ci			if (defined $signatures{$sig_nospace}) {
315562306a36Sopenharmony_ci				WARN("BAD_SIGN_OFF",
315662306a36Sopenharmony_ci				     "Duplicate signature\n" . $herecurr);
315762306a36Sopenharmony_ci			} else {
315862306a36Sopenharmony_ci				$signatures{$sig_nospace} = 1;
315962306a36Sopenharmony_ci			}
316062306a36Sopenharmony_ci
316162306a36Sopenharmony_ci# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
316262306a36Sopenharmony_ci			if ($sign_off =~ /^co-developed-by:$/i) {
316362306a36Sopenharmony_ci				if ($email eq $author) {
316462306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
316562306a36Sopenharmony_ci					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr);
316662306a36Sopenharmony_ci				}
316762306a36Sopenharmony_ci				if (!defined $lines[$linenr]) {
316862306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
316962306a36Sopenharmony_ci					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
317062306a36Sopenharmony_ci				} elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
317162306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
317262306a36Sopenharmony_ci					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n");
317362306a36Sopenharmony_ci				} elsif ($1 ne $email) {
317462306a36Sopenharmony_ci					WARN("BAD_SIGN_OFF",
317562306a36Sopenharmony_ci					     "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n");
317662306a36Sopenharmony_ci				}
317762306a36Sopenharmony_ci			}
317862306a36Sopenharmony_ci
317962306a36Sopenharmony_ci# check if Reported-by: is followed by a Closes: tag
318062306a36Sopenharmony_ci			if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) {
318162306a36Sopenharmony_ci				if (!defined $lines[$linenr]) {
318262306a36Sopenharmony_ci					WARN("BAD_REPORTED_BY_LINK",
318362306a36Sopenharmony_ci					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n");
318462306a36Sopenharmony_ci				} elsif ($rawlines[$linenr] !~ /^closes:\s*/i) {
318562306a36Sopenharmony_ci					WARN("BAD_REPORTED_BY_LINK",
318662306a36Sopenharmony_ci					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
318762306a36Sopenharmony_ci				}
318862306a36Sopenharmony_ci			}
318962306a36Sopenharmony_ci		}
319062306a36Sopenharmony_ci
319162306a36Sopenharmony_ci
319262306a36Sopenharmony_ci# Check Fixes: styles is correct
319362306a36Sopenharmony_ci		if (!$in_header_lines &&
319462306a36Sopenharmony_ci		    $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
319562306a36Sopenharmony_ci			my $orig_commit = "";
319662306a36Sopenharmony_ci			my $id = "0123456789ab";
319762306a36Sopenharmony_ci			my $title = "commit title";
319862306a36Sopenharmony_ci			my $tag_case = 1;
319962306a36Sopenharmony_ci			my $tag_space = 1;
320062306a36Sopenharmony_ci			my $id_length = 1;
320162306a36Sopenharmony_ci			my $id_case = 1;
320262306a36Sopenharmony_ci			my $title_has_quotes = 0;
320362306a36Sopenharmony_ci
320462306a36Sopenharmony_ci			if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) {
320562306a36Sopenharmony_ci				my $tag = $1;
320662306a36Sopenharmony_ci				$orig_commit = $2;
320762306a36Sopenharmony_ci				$title = $3;
320862306a36Sopenharmony_ci
320962306a36Sopenharmony_ci				$tag_case = 0 if $tag eq "Fixes:";
321062306a36Sopenharmony_ci				$tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i);
321162306a36Sopenharmony_ci
321262306a36Sopenharmony_ci				$id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i);
321362306a36Sopenharmony_ci				$id_case = 0 if ($orig_commit !~ /[A-F]/);
321462306a36Sopenharmony_ci
321562306a36Sopenharmony_ci				# Always strip leading/trailing parens then double quotes if existing
321662306a36Sopenharmony_ci				$title = substr($title, 1, -1);
321762306a36Sopenharmony_ci				if ($title =~ /^".*"$/) {
321862306a36Sopenharmony_ci					$title = substr($title, 1, -1);
321962306a36Sopenharmony_ci					$title_has_quotes = 1;
322062306a36Sopenharmony_ci				}
322162306a36Sopenharmony_ci			}
322262306a36Sopenharmony_ci
322362306a36Sopenharmony_ci			my ($cid, $ctitle) = git_commit_info($orig_commit, $id,
322462306a36Sopenharmony_ci							     $title);
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_ci			if ($ctitle ne $title || $tag_case || $tag_space ||
322762306a36Sopenharmony_ci			    $id_length || $id_case || !$title_has_quotes) {
322862306a36Sopenharmony_ci				if (WARN("BAD_FIXES_TAG",
322962306a36Sopenharmony_ci				     "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) &&
323062306a36Sopenharmony_ci				    $fix) {
323162306a36Sopenharmony_ci					$fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")";
323262306a36Sopenharmony_ci				}
323362306a36Sopenharmony_ci			}
323462306a36Sopenharmony_ci		}
323562306a36Sopenharmony_ci
323662306a36Sopenharmony_ci# Check email subject for common tools that don't need to be mentioned
323762306a36Sopenharmony_ci		if ($in_header_lines &&
323862306a36Sopenharmony_ci		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
323962306a36Sopenharmony_ci			WARN("EMAIL_SUBJECT",
324062306a36Sopenharmony_ci			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
324162306a36Sopenharmony_ci		}
324262306a36Sopenharmony_ci
324362306a36Sopenharmony_ci# Check for Gerrit Change-Ids not in any patch context
324462306a36Sopenharmony_ci		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
324562306a36Sopenharmony_ci			if (ERROR("GERRIT_CHANGE_ID",
324662306a36Sopenharmony_ci			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
324762306a36Sopenharmony_ci			    $fix) {
324862306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
324962306a36Sopenharmony_ci			}
325062306a36Sopenharmony_ci		}
325162306a36Sopenharmony_ci
325262306a36Sopenharmony_ci# Check if the commit log is in a possible stack dump
325362306a36Sopenharmony_ci		if ($in_commit_log && !$commit_log_possible_stack_dump &&
325462306a36Sopenharmony_ci		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
325562306a36Sopenharmony_ci		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
325662306a36Sopenharmony_ci					# timestamp
325762306a36Sopenharmony_ci		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
325862306a36Sopenharmony_ci		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
325962306a36Sopenharmony_ci		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
326062306a36Sopenharmony_ci					# stack dump address styles
326162306a36Sopenharmony_ci			$commit_log_possible_stack_dump = 1;
326262306a36Sopenharmony_ci		}
326362306a36Sopenharmony_ci
326462306a36Sopenharmony_ci# Check for line lengths > 75 in commit log, warn once
326562306a36Sopenharmony_ci		if ($in_commit_log && !$commit_log_long_line &&
326662306a36Sopenharmony_ci		    length($line) > 75 &&
326762306a36Sopenharmony_ci		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
326862306a36Sopenharmony_ci					# file delta changes
326962306a36Sopenharmony_ci		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
327062306a36Sopenharmony_ci					# filename then :
327162306a36Sopenharmony_ci		      $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i ||
327262306a36Sopenharmony_ci					# A Fixes:, link or signature tag line
327362306a36Sopenharmony_ci		      $commit_log_possible_stack_dump)) {
327462306a36Sopenharmony_ci			WARN("COMMIT_LOG_LONG_LINE",
327562306a36Sopenharmony_ci			     "Prefer a maximum 75 chars per line (possible unwrapped commit description?)\n" . $herecurr);
327662306a36Sopenharmony_ci			$commit_log_long_line = 1;
327762306a36Sopenharmony_ci		}
327862306a36Sopenharmony_ci
327962306a36Sopenharmony_ci# Reset possible stack dump if a blank line is found
328062306a36Sopenharmony_ci		if ($in_commit_log && $commit_log_possible_stack_dump &&
328162306a36Sopenharmony_ci		    $line =~ /^\s*$/) {
328262306a36Sopenharmony_ci			$commit_log_possible_stack_dump = 0;
328362306a36Sopenharmony_ci		}
328462306a36Sopenharmony_ci
328562306a36Sopenharmony_ci# Check for odd tags before a URI/URL
328662306a36Sopenharmony_ci		if ($in_commit_log &&
328762306a36Sopenharmony_ci		    $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) {
328862306a36Sopenharmony_ci			if ($1 =~ /^v(?:ersion)?\d+/i) {
328962306a36Sopenharmony_ci				WARN("COMMIT_LOG_VERSIONING",
329062306a36Sopenharmony_ci				     "Patch version information should be after the --- line\n" . $herecurr);
329162306a36Sopenharmony_ci			} else {
329262306a36Sopenharmony_ci				WARN("COMMIT_LOG_USE_LINK",
329362306a36Sopenharmony_ci				     "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr);
329462306a36Sopenharmony_ci			}
329562306a36Sopenharmony_ci		}
329662306a36Sopenharmony_ci
329762306a36Sopenharmony_ci# Check for misuse of the link tags
329862306a36Sopenharmony_ci		if ($in_commit_log &&
329962306a36Sopenharmony_ci		    $line =~ /^\s*(\w+:)\s*(\S+)/) {
330062306a36Sopenharmony_ci			my $tag = $1;
330162306a36Sopenharmony_ci			my $value = $2;
330262306a36Sopenharmony_ci			if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) {
330362306a36Sopenharmony_ci				WARN("COMMIT_LOG_WRONG_LINK",
330462306a36Sopenharmony_ci				     "'$tag' should be followed by a public http(s) link\n" . $herecurr);
330562306a36Sopenharmony_ci			}
330662306a36Sopenharmony_ci		}
330762306a36Sopenharmony_ci
330862306a36Sopenharmony_ci# Check for lines starting with a #
330962306a36Sopenharmony_ci		if ($in_commit_log && $line =~ /^#/) {
331062306a36Sopenharmony_ci			if (WARN("COMMIT_COMMENT_SYMBOL",
331162306a36Sopenharmony_ci				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
331262306a36Sopenharmony_ci			    $fix) {
331362306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^/ /;
331462306a36Sopenharmony_ci			}
331562306a36Sopenharmony_ci		}
331662306a36Sopenharmony_ci
331762306a36Sopenharmony_ci# Check for git id commit length and improperly formed commit descriptions
331862306a36Sopenharmony_ci# A correctly formed commit description is:
331962306a36Sopenharmony_ci#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
332062306a36Sopenharmony_ci# with the commit subject '("' prefix and '")' suffix
332162306a36Sopenharmony_ci# This is a fairly compilicated block as it tests for what appears to be
332262306a36Sopenharmony_ci# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
332362306a36Sopenharmony_ci# possible SHA-1 matches.
332462306a36Sopenharmony_ci# A commit match can span multiple lines so this block attempts to find a
332562306a36Sopenharmony_ci# complete typical commit on a maximum of 3 lines
332662306a36Sopenharmony_ci		if ($perl_version_ok &&
332762306a36Sopenharmony_ci		    $in_commit_log && !$commit_log_possible_stack_dump &&
332862306a36Sopenharmony_ci		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
332962306a36Sopenharmony_ci		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
333062306a36Sopenharmony_ci		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
333162306a36Sopenharmony_ci		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
333262306a36Sopenharmony_ci		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
333362306a36Sopenharmony_ci		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
333462306a36Sopenharmony_ci		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
333562306a36Sopenharmony_ci			my $init_char = "c";
333662306a36Sopenharmony_ci			my $orig_commit = "";
333762306a36Sopenharmony_ci			my $short = 1;
333862306a36Sopenharmony_ci			my $long = 0;
333962306a36Sopenharmony_ci			my $case = 1;
334062306a36Sopenharmony_ci			my $space = 1;
334162306a36Sopenharmony_ci			my $id = '0123456789ab';
334262306a36Sopenharmony_ci			my $orig_desc = "commit description";
334362306a36Sopenharmony_ci			my $description = "";
334462306a36Sopenharmony_ci			my $herectx = $herecurr;
334562306a36Sopenharmony_ci			my $has_parens = 0;
334662306a36Sopenharmony_ci			my $has_quotes = 0;
334762306a36Sopenharmony_ci
334862306a36Sopenharmony_ci			my $input = $line;
334962306a36Sopenharmony_ci			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
335062306a36Sopenharmony_ci				for (my $n = 0; $n < 2; $n++) {
335162306a36Sopenharmony_ci					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
335262306a36Sopenharmony_ci						$orig_desc = $1;
335362306a36Sopenharmony_ci						$has_parens = 1;
335462306a36Sopenharmony_ci						# Always strip leading/trailing parens then double quotes if existing
335562306a36Sopenharmony_ci						$orig_desc = substr($orig_desc, 1, -1);
335662306a36Sopenharmony_ci						if ($orig_desc =~ /^".*"$/) {
335762306a36Sopenharmony_ci							$orig_desc = substr($orig_desc, 1, -1);
335862306a36Sopenharmony_ci							$has_quotes = 1;
335962306a36Sopenharmony_ci						}
336062306a36Sopenharmony_ci						last;
336162306a36Sopenharmony_ci					}
336262306a36Sopenharmony_ci					last if ($#lines < $linenr + $n);
336362306a36Sopenharmony_ci					$input .= " " . trim($rawlines[$linenr + $n]);
336462306a36Sopenharmony_ci					$herectx .= "$rawlines[$linenr + $n]\n";
336562306a36Sopenharmony_ci				}
336662306a36Sopenharmony_ci				$herectx = $herecurr if (!$has_parens);
336762306a36Sopenharmony_ci			}
336862306a36Sopenharmony_ci
336962306a36Sopenharmony_ci			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
337062306a36Sopenharmony_ci				$init_char = $1;
337162306a36Sopenharmony_ci				$orig_commit = lc($2);
337262306a36Sopenharmony_ci				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
337362306a36Sopenharmony_ci				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
337462306a36Sopenharmony_ci				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
337562306a36Sopenharmony_ci				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
337662306a36Sopenharmony_ci			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
337762306a36Sopenharmony_ci				$orig_commit = lc($1);
337862306a36Sopenharmony_ci			}
337962306a36Sopenharmony_ci
338062306a36Sopenharmony_ci			($id, $description) = git_commit_info($orig_commit,
338162306a36Sopenharmony_ci							      $id, $orig_desc);
338262306a36Sopenharmony_ci
338362306a36Sopenharmony_ci			if (defined($id) &&
338462306a36Sopenharmony_ci			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
338562306a36Sopenharmony_ci			    $last_git_commit_id_linenr != $linenr - 1) {
338662306a36Sopenharmony_ci				ERROR("GIT_COMMIT_ID",
338762306a36Sopenharmony_ci				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
338862306a36Sopenharmony_ci			}
338962306a36Sopenharmony_ci			#don't report the next line if this line ends in commit and the sha1 hash is the next line
339062306a36Sopenharmony_ci			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
339162306a36Sopenharmony_ci		}
339262306a36Sopenharmony_ci
339362306a36Sopenharmony_ci# Check for mailing list archives other than lore.kernel.org
339462306a36Sopenharmony_ci		if ($rawline =~ m{http.*\b$obsolete_archives}) {
339562306a36Sopenharmony_ci			WARN("PREFER_LORE_ARCHIVE",
339662306a36Sopenharmony_ci			     "Use lore.kernel.org archive links when possible - see https://lore.kernel.org/lists.html\n" . $herecurr);
339762306a36Sopenharmony_ci		}
339862306a36Sopenharmony_ci
339962306a36Sopenharmony_ci# Check for added, moved or deleted files
340062306a36Sopenharmony_ci		if (!$reported_maintainer_file && !$in_commit_log &&
340162306a36Sopenharmony_ci		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
340262306a36Sopenharmony_ci		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
340362306a36Sopenharmony_ci		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
340462306a36Sopenharmony_ci		      (defined($1) || defined($2))))) {
340562306a36Sopenharmony_ci			$is_patch = 1;
340662306a36Sopenharmony_ci			$reported_maintainer_file = 1;
340762306a36Sopenharmony_ci			WARN("FILE_PATH_CHANGES",
340862306a36Sopenharmony_ci			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
340962306a36Sopenharmony_ci		}
341062306a36Sopenharmony_ci
341162306a36Sopenharmony_ci# Check for adding new DT bindings not in schema format
341262306a36Sopenharmony_ci		if (!$in_commit_log &&
341362306a36Sopenharmony_ci		    ($line =~ /^new file mode\s*\d+\s*$/) &&
341462306a36Sopenharmony_ci		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
341562306a36Sopenharmony_ci			WARN("DT_SCHEMA_BINDING_PATCH",
341662306a36Sopenharmony_ci			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
341762306a36Sopenharmony_ci		}
341862306a36Sopenharmony_ci
341962306a36Sopenharmony_ci# Check for wrappage within a valid hunk of the file
342062306a36Sopenharmony_ci		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
342162306a36Sopenharmony_ci			ERROR("CORRUPTED_PATCH",
342262306a36Sopenharmony_ci			      "patch seems to be corrupt (line wrapped?)\n" .
342362306a36Sopenharmony_ci				$herecurr) if (!$emitted_corrupt++);
342462306a36Sopenharmony_ci		}
342562306a36Sopenharmony_ci
342662306a36Sopenharmony_ci# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
342762306a36Sopenharmony_ci		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
342862306a36Sopenharmony_ci		    $rawline !~ m/^$UTF8*$/) {
342962306a36Sopenharmony_ci			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
343062306a36Sopenharmony_ci
343162306a36Sopenharmony_ci			my $blank = copy_spacing($rawline);
343262306a36Sopenharmony_ci			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
343362306a36Sopenharmony_ci			my $hereptr = "$hereline$ptr\n";
343462306a36Sopenharmony_ci
343562306a36Sopenharmony_ci			CHK("INVALID_UTF8",
343662306a36Sopenharmony_ci			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
343762306a36Sopenharmony_ci		}
343862306a36Sopenharmony_ci
343962306a36Sopenharmony_ci# Check if it's the start of a commit log
344062306a36Sopenharmony_ci# (not a header line and we haven't seen the patch filename)
344162306a36Sopenharmony_ci		if ($in_header_lines && $realfile =~ /^$/ &&
344262306a36Sopenharmony_ci		    !($rawline =~ /^\s+(?:\S|$)/ ||
344362306a36Sopenharmony_ci		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
344462306a36Sopenharmony_ci			$in_header_lines = 0;
344562306a36Sopenharmony_ci			$in_commit_log = 1;
344662306a36Sopenharmony_ci			$has_commit_log = 1;
344762306a36Sopenharmony_ci		}
344862306a36Sopenharmony_ci
344962306a36Sopenharmony_ci# Check if there is UTF-8 in a commit log when a mail header has explicitly
345062306a36Sopenharmony_ci# declined it, i.e defined some charset where it is missing.
345162306a36Sopenharmony_ci		if ($in_header_lines &&
345262306a36Sopenharmony_ci		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
345362306a36Sopenharmony_ci		    $1 !~ /utf-8/i) {
345462306a36Sopenharmony_ci			$non_utf8_charset = 1;
345562306a36Sopenharmony_ci		}
345662306a36Sopenharmony_ci
345762306a36Sopenharmony_ci		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
345862306a36Sopenharmony_ci		    $rawline =~ /$NON_ASCII_UTF8/) {
345962306a36Sopenharmony_ci			WARN("UTF8_BEFORE_PATCH",
346062306a36Sopenharmony_ci			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
346162306a36Sopenharmony_ci		}
346262306a36Sopenharmony_ci
346362306a36Sopenharmony_ci# Check for absolute kernel paths in commit message
346462306a36Sopenharmony_ci		if ($tree && $in_commit_log) {
346562306a36Sopenharmony_ci			while ($line =~ m{(?:^|\s)(/\S*)}g) {
346662306a36Sopenharmony_ci				my $file = $1;
346762306a36Sopenharmony_ci
346862306a36Sopenharmony_ci				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
346962306a36Sopenharmony_ci				    check_absolute_file($1, $herecurr)) {
347062306a36Sopenharmony_ci					#
347162306a36Sopenharmony_ci				} else {
347262306a36Sopenharmony_ci					check_absolute_file($file, $herecurr);
347362306a36Sopenharmony_ci				}
347462306a36Sopenharmony_ci			}
347562306a36Sopenharmony_ci		}
347662306a36Sopenharmony_ci
347762306a36Sopenharmony_ci# Check for various typo / spelling mistakes
347862306a36Sopenharmony_ci		if (defined($misspellings) &&
347962306a36Sopenharmony_ci		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
348062306a36Sopenharmony_ci			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
348162306a36Sopenharmony_ci				my $typo = $1;
348262306a36Sopenharmony_ci				my $blank = copy_spacing($rawline);
348362306a36Sopenharmony_ci				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
348462306a36Sopenharmony_ci				my $hereptr = "$hereline$ptr\n";
348562306a36Sopenharmony_ci				my $typo_fix = $spelling_fix{lc($typo)};
348662306a36Sopenharmony_ci				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
348762306a36Sopenharmony_ci				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
348862306a36Sopenharmony_ci				my $msg_level = \&WARN;
348962306a36Sopenharmony_ci				$msg_level = \&CHK if ($file);
349062306a36Sopenharmony_ci				if (&{$msg_level}("TYPO_SPELLING",
349162306a36Sopenharmony_ci						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
349262306a36Sopenharmony_ci				    $fix) {
349362306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
349462306a36Sopenharmony_ci				}
349562306a36Sopenharmony_ci			}
349662306a36Sopenharmony_ci		}
349762306a36Sopenharmony_ci
349862306a36Sopenharmony_ci# check for invalid commit id
349962306a36Sopenharmony_ci		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
350062306a36Sopenharmony_ci			my $id;
350162306a36Sopenharmony_ci			my $description;
350262306a36Sopenharmony_ci			($id, $description) = git_commit_info($2, undef, undef);
350362306a36Sopenharmony_ci			if (!defined($id)) {
350462306a36Sopenharmony_ci				WARN("UNKNOWN_COMMIT_ID",
350562306a36Sopenharmony_ci				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
350662306a36Sopenharmony_ci			}
350762306a36Sopenharmony_ci		}
350862306a36Sopenharmony_ci
350962306a36Sopenharmony_ci# check for repeated words separated by a single space
351062306a36Sopenharmony_ci# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
351162306a36Sopenharmony_ci		if (($rawline =~ /^\+/ || $in_commit_log) &&
351262306a36Sopenharmony_ci		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
351362306a36Sopenharmony_ci			pos($rawline) = 1 if (!$in_commit_log);
351462306a36Sopenharmony_ci			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
351562306a36Sopenharmony_ci
351662306a36Sopenharmony_ci				my $first = $1;
351762306a36Sopenharmony_ci				my $second = $2;
351862306a36Sopenharmony_ci				my $start_pos = $-[1];
351962306a36Sopenharmony_ci				my $end_pos = $+[2];
352062306a36Sopenharmony_ci				if ($first =~ /(?:struct|union|enum)/) {
352162306a36Sopenharmony_ci					pos($rawline) += length($first) + length($second) + 1;
352262306a36Sopenharmony_ci					next;
352362306a36Sopenharmony_ci				}
352462306a36Sopenharmony_ci
352562306a36Sopenharmony_ci				next if (lc($first) ne lc($second));
352662306a36Sopenharmony_ci				next if ($first eq 'long');
352762306a36Sopenharmony_ci
352862306a36Sopenharmony_ci				# check for character before and after the word matches
352962306a36Sopenharmony_ci				my $start_char = '';
353062306a36Sopenharmony_ci				my $end_char = '';
353162306a36Sopenharmony_ci				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
353262306a36Sopenharmony_ci				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
353362306a36Sopenharmony_ci
353462306a36Sopenharmony_ci				next if ($start_char =~ /^\S$/);
353562306a36Sopenharmony_ci				next if (index(" \t.,;?!", $end_char) == -1);
353662306a36Sopenharmony_ci
353762306a36Sopenharmony_ci				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
353862306a36Sopenharmony_ci				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
353962306a36Sopenharmony_ci					next if (!exists($allow_repeated_words{lc($first)}));
354062306a36Sopenharmony_ci				}
354162306a36Sopenharmony_ci
354262306a36Sopenharmony_ci				if (WARN("REPEATED_WORD",
354362306a36Sopenharmony_ci					 "Possible repeated word: '$first'\n" . $herecurr) &&
354462306a36Sopenharmony_ci				    $fix) {
354562306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
354662306a36Sopenharmony_ci				}
354762306a36Sopenharmony_ci			}
354862306a36Sopenharmony_ci
354962306a36Sopenharmony_ci			# if it's a repeated word on consecutive lines in a comment block
355062306a36Sopenharmony_ci			if ($prevline =~ /$;+\s*$/ &&
355162306a36Sopenharmony_ci			    $prevrawline =~ /($word_pattern)\s*$/) {
355262306a36Sopenharmony_ci				my $last_word = $1;
355362306a36Sopenharmony_ci				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
355462306a36Sopenharmony_ci					if (WARN("REPEATED_WORD",
355562306a36Sopenharmony_ci						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
355662306a36Sopenharmony_ci					    $fix) {
355762306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
355862306a36Sopenharmony_ci					}
355962306a36Sopenharmony_ci				}
356062306a36Sopenharmony_ci			}
356162306a36Sopenharmony_ci		}
356262306a36Sopenharmony_ci
356362306a36Sopenharmony_ci# ignore non-hunk lines and lines being removed
356462306a36Sopenharmony_ci		next if (!$hunk_line || $line =~ /^-/);
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci#trailing whitespace
356762306a36Sopenharmony_ci		if ($line =~ /^\+.*\015/) {
356862306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
356962306a36Sopenharmony_ci			if (ERROR("DOS_LINE_ENDINGS",
357062306a36Sopenharmony_ci				  "DOS line endings\n" . $herevet) &&
357162306a36Sopenharmony_ci			    $fix) {
357262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
357362306a36Sopenharmony_ci			}
357462306a36Sopenharmony_ci		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
357562306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
357662306a36Sopenharmony_ci			if (ERROR("TRAILING_WHITESPACE",
357762306a36Sopenharmony_ci				  "trailing whitespace\n" . $herevet) &&
357862306a36Sopenharmony_ci			    $fix) {
357962306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+$//;
358062306a36Sopenharmony_ci			}
358162306a36Sopenharmony_ci
358262306a36Sopenharmony_ci			$rpt_cleaners = 1;
358362306a36Sopenharmony_ci		}
358462306a36Sopenharmony_ci
358562306a36Sopenharmony_ci# Check for FSF mailing addresses.
358662306a36Sopenharmony_ci		if ($rawline =~ /\bwrite to the Free/i ||
358762306a36Sopenharmony_ci		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
358862306a36Sopenharmony_ci		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
358962306a36Sopenharmony_ci		    $rawline =~ /\b51\s+Franklin\s+St/i) {
359062306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
359162306a36Sopenharmony_ci			my $msg_level = \&ERROR;
359262306a36Sopenharmony_ci			$msg_level = \&CHK if ($file);
359362306a36Sopenharmony_ci			&{$msg_level}("FSF_MAILING_ADDRESS",
359462306a36Sopenharmony_ci				      "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)
359562306a36Sopenharmony_ci		}
359662306a36Sopenharmony_ci
359762306a36Sopenharmony_ci# check for Kconfig help text having a real description
359862306a36Sopenharmony_ci# Only applies when adding the entry originally, after that we do not have
359962306a36Sopenharmony_ci# sufficient context to determine whether it is indeed long enough.
360062306a36Sopenharmony_ci		if ($realfile =~ /Kconfig/ &&
360162306a36Sopenharmony_ci		    # 'choice' is usually the last thing on the line (though
360262306a36Sopenharmony_ci		    # Kconfig supports named choices), so use a word boundary
360362306a36Sopenharmony_ci		    # (\b) rather than a whitespace character (\s)
360462306a36Sopenharmony_ci		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
360562306a36Sopenharmony_ci			my $ln = $linenr;
360662306a36Sopenharmony_ci			my $needs_help = 0;
360762306a36Sopenharmony_ci			my $has_help = 0;
360862306a36Sopenharmony_ci			my $help_length = 0;
360962306a36Sopenharmony_ci			while (defined $lines[$ln]) {
361062306a36Sopenharmony_ci				my $f = $lines[$ln++];
361162306a36Sopenharmony_ci
361262306a36Sopenharmony_ci				next if ($f =~ /^-/);
361362306a36Sopenharmony_ci				last if ($f !~ /^[\+ ]/);	# !patch context
361462306a36Sopenharmony_ci
361562306a36Sopenharmony_ci				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
361662306a36Sopenharmony_ci					$needs_help = 1;
361762306a36Sopenharmony_ci					next;
361862306a36Sopenharmony_ci				}
361962306a36Sopenharmony_ci				if ($f =~ /^\+\s*help\s*$/) {
362062306a36Sopenharmony_ci					$has_help = 1;
362162306a36Sopenharmony_ci					next;
362262306a36Sopenharmony_ci				}
362362306a36Sopenharmony_ci
362462306a36Sopenharmony_ci				$f =~ s/^.//;	# strip patch context [+ ]
362562306a36Sopenharmony_ci				$f =~ s/#.*//;	# strip # directives
362662306a36Sopenharmony_ci				$f =~ s/^\s+//;	# strip leading blanks
362762306a36Sopenharmony_ci				next if ($f =~ /^$/);	# skip blank lines
362862306a36Sopenharmony_ci
362962306a36Sopenharmony_ci				# At the end of this Kconfig block:
363062306a36Sopenharmony_ci				# This only checks context lines in the patch
363162306a36Sopenharmony_ci				# and so hopefully shouldn't trigger false
363262306a36Sopenharmony_ci				# positives, even though some of these are
363362306a36Sopenharmony_ci				# common words in help texts
363462306a36Sopenharmony_ci				if ($f =~ /^(?:config|menuconfig|choice|endchoice|
363562306a36Sopenharmony_ci					       if|endif|menu|endmenu|source)\b/x) {
363662306a36Sopenharmony_ci					last;
363762306a36Sopenharmony_ci				}
363862306a36Sopenharmony_ci				$help_length++ if ($has_help);
363962306a36Sopenharmony_ci			}
364062306a36Sopenharmony_ci			if ($needs_help &&
364162306a36Sopenharmony_ci			    $help_length < $min_conf_desc_length) {
364262306a36Sopenharmony_ci				my $stat_real = get_stat_real($linenr, $ln - 1);
364362306a36Sopenharmony_ci				WARN("CONFIG_DESCRIPTION",
364462306a36Sopenharmony_ci				     "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n");
364562306a36Sopenharmony_ci			}
364662306a36Sopenharmony_ci		}
364762306a36Sopenharmony_ci
364862306a36Sopenharmony_ci# check MAINTAINERS entries
364962306a36Sopenharmony_ci		if ($realfile =~ /^MAINTAINERS$/) {
365062306a36Sopenharmony_ci# check MAINTAINERS entries for the right form
365162306a36Sopenharmony_ci			if ($rawline =~ /^\+[A-Z]:/ &&
365262306a36Sopenharmony_ci			    $rawline !~ /^\+[A-Z]:\t\S/) {
365362306a36Sopenharmony_ci				if (WARN("MAINTAINERS_STYLE",
365462306a36Sopenharmony_ci					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
365562306a36Sopenharmony_ci				    $fix) {
365662306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
365762306a36Sopenharmony_ci				}
365862306a36Sopenharmony_ci			}
365962306a36Sopenharmony_ci# check MAINTAINERS entries for the right ordering too
366062306a36Sopenharmony_ci			my $preferred_order = 'MRLSWQBCPTFXNK';
366162306a36Sopenharmony_ci			if ($rawline =~ /^\+[A-Z]:/ &&
366262306a36Sopenharmony_ci			    $prevrawline =~ /^[\+ ][A-Z]:/) {
366362306a36Sopenharmony_ci				$rawline =~ /^\+([A-Z]):\s*(.*)/;
366462306a36Sopenharmony_ci				my $cur = $1;
366562306a36Sopenharmony_ci				my $curval = $2;
366662306a36Sopenharmony_ci				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
366762306a36Sopenharmony_ci				my $prev = $1;
366862306a36Sopenharmony_ci				my $prevval = $2;
366962306a36Sopenharmony_ci				my $curindex = index($preferred_order, $cur);
367062306a36Sopenharmony_ci				my $previndex = index($preferred_order, $prev);
367162306a36Sopenharmony_ci				if ($curindex < 0) {
367262306a36Sopenharmony_ci					WARN("MAINTAINERS_STYLE",
367362306a36Sopenharmony_ci					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
367462306a36Sopenharmony_ci				} else {
367562306a36Sopenharmony_ci					if ($previndex >= 0 && $curindex < $previndex) {
367662306a36Sopenharmony_ci						WARN("MAINTAINERS_STYLE",
367762306a36Sopenharmony_ci						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
367862306a36Sopenharmony_ci					} elsif ((($prev eq 'F' && $cur eq 'F') ||
367962306a36Sopenharmony_ci						  ($prev eq 'X' && $cur eq 'X')) &&
368062306a36Sopenharmony_ci						 ($prevval cmp $curval) > 0) {
368162306a36Sopenharmony_ci						WARN("MAINTAINERS_STYLE",
368262306a36Sopenharmony_ci						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
368362306a36Sopenharmony_ci					}
368462306a36Sopenharmony_ci				}
368562306a36Sopenharmony_ci			}
368662306a36Sopenharmony_ci		}
368762306a36Sopenharmony_ci
368862306a36Sopenharmony_ci		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
368962306a36Sopenharmony_ci		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
369062306a36Sopenharmony_ci			my $flag = $1;
369162306a36Sopenharmony_ci			my $replacement = {
369262306a36Sopenharmony_ci				'EXTRA_AFLAGS' =>   'asflags-y',
369362306a36Sopenharmony_ci				'EXTRA_CFLAGS' =>   'ccflags-y',
369462306a36Sopenharmony_ci				'EXTRA_CPPFLAGS' => 'cppflags-y',
369562306a36Sopenharmony_ci				'EXTRA_LDFLAGS' =>  'ldflags-y',
369662306a36Sopenharmony_ci			};
369762306a36Sopenharmony_ci
369862306a36Sopenharmony_ci			WARN("DEPRECATED_VARIABLE",
369962306a36Sopenharmony_ci			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
370062306a36Sopenharmony_ci		}
370162306a36Sopenharmony_ci
370262306a36Sopenharmony_ci# check for DT compatible documentation
370362306a36Sopenharmony_ci		if (defined $root &&
370462306a36Sopenharmony_ci			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
370562306a36Sopenharmony_ci			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
370662306a36Sopenharmony_ci
370762306a36Sopenharmony_ci			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
370862306a36Sopenharmony_ci
370962306a36Sopenharmony_ci			my $dt_path = $root . "/Documentation/devicetree/bindings/";
371062306a36Sopenharmony_ci			my $vp_file = $dt_path . "vendor-prefixes.yaml";
371162306a36Sopenharmony_ci
371262306a36Sopenharmony_ci			foreach my $compat (@compats) {
371362306a36Sopenharmony_ci				my $compat2 = $compat;
371462306a36Sopenharmony_ci				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
371562306a36Sopenharmony_ci				my $compat3 = $compat;
371662306a36Sopenharmony_ci				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
371762306a36Sopenharmony_ci				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
371862306a36Sopenharmony_ci				if ( $? >> 8 ) {
371962306a36Sopenharmony_ci					WARN("UNDOCUMENTED_DT_STRING",
372062306a36Sopenharmony_ci					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
372162306a36Sopenharmony_ci				}
372262306a36Sopenharmony_ci
372362306a36Sopenharmony_ci				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
372462306a36Sopenharmony_ci				my $vendor = $1;
372562306a36Sopenharmony_ci				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
372662306a36Sopenharmony_ci				if ( $? >> 8 ) {
372762306a36Sopenharmony_ci					WARN("UNDOCUMENTED_DT_STRING",
372862306a36Sopenharmony_ci					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
372962306a36Sopenharmony_ci				}
373062306a36Sopenharmony_ci			}
373162306a36Sopenharmony_ci		}
373262306a36Sopenharmony_ci
373362306a36Sopenharmony_ci# check for using SPDX license tag at beginning of files
373462306a36Sopenharmony_ci		if ($realline == $checklicenseline) {
373562306a36Sopenharmony_ci			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
373662306a36Sopenharmony_ci				$checklicenseline = 2;
373762306a36Sopenharmony_ci			} elsif ($rawline =~ /^\+/) {
373862306a36Sopenharmony_ci				my $comment = "";
373962306a36Sopenharmony_ci				if ($realfile =~ /\.(h|s|S)$/) {
374062306a36Sopenharmony_ci					$comment = '/*';
374162306a36Sopenharmony_ci				} elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) {
374262306a36Sopenharmony_ci					$comment = '//';
374362306a36Sopenharmony_ci				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
374462306a36Sopenharmony_ci					$comment = '#';
374562306a36Sopenharmony_ci				} elsif ($realfile =~ /\.rst$/) {
374662306a36Sopenharmony_ci					$comment = '..';
374762306a36Sopenharmony_ci				}
374862306a36Sopenharmony_ci
374962306a36Sopenharmony_ci# check SPDX comment style for .[chsS] files
375062306a36Sopenharmony_ci				if ($realfile =~ /\.[chsS]$/ &&
375162306a36Sopenharmony_ci				    $rawline =~ /SPDX-License-Identifier:/ &&
375262306a36Sopenharmony_ci				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
375362306a36Sopenharmony_ci					WARN("SPDX_LICENSE_TAG",
375462306a36Sopenharmony_ci					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
375562306a36Sopenharmony_ci				}
375662306a36Sopenharmony_ci
375762306a36Sopenharmony_ci				if ($comment !~ /^$/ &&
375862306a36Sopenharmony_ci				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
375962306a36Sopenharmony_ci					WARN("SPDX_LICENSE_TAG",
376062306a36Sopenharmony_ci					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
376162306a36Sopenharmony_ci				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
376262306a36Sopenharmony_ci					my $spdx_license = $1;
376362306a36Sopenharmony_ci					if (!is_SPDX_License_valid($spdx_license)) {
376462306a36Sopenharmony_ci						WARN("SPDX_LICENSE_TAG",
376562306a36Sopenharmony_ci						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
376662306a36Sopenharmony_ci					}
376762306a36Sopenharmony_ci					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
376862306a36Sopenharmony_ci					    $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) {
376962306a36Sopenharmony_ci						my $msg_level = \&WARN;
377062306a36Sopenharmony_ci						$msg_level = \&CHK if ($file);
377162306a36Sopenharmony_ci						if (&{$msg_level}("SPDX_LICENSE_TAG",
377262306a36Sopenharmony_ci
377362306a36Sopenharmony_ci								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
377462306a36Sopenharmony_ci						    $fix) {
377562306a36Sopenharmony_ci							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
377662306a36Sopenharmony_ci						}
377762306a36Sopenharmony_ci					}
377862306a36Sopenharmony_ci					if ($realfile =~ m@^include/dt-bindings/@ &&
377962306a36Sopenharmony_ci					    $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) {
378062306a36Sopenharmony_ci						WARN("SPDX_LICENSE_TAG",
378162306a36Sopenharmony_ci						     "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr);
378262306a36Sopenharmony_ci					}
378362306a36Sopenharmony_ci				}
378462306a36Sopenharmony_ci			}
378562306a36Sopenharmony_ci		}
378662306a36Sopenharmony_ci
378762306a36Sopenharmony_ci# check for embedded filenames
378862306a36Sopenharmony_ci		if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
378962306a36Sopenharmony_ci			WARN("EMBEDDED_FILENAME",
379062306a36Sopenharmony_ci			     "It's generally not useful to have the filename in the file\n" . $herecurr);
379162306a36Sopenharmony_ci		}
379262306a36Sopenharmony_ci
379362306a36Sopenharmony_ci# check we are in a valid source file if not then ignore this hunk
379462306a36Sopenharmony_ci		next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/);
379562306a36Sopenharmony_ci
379662306a36Sopenharmony_ci# check for using SPDX-License-Identifier on the wrong line number
379762306a36Sopenharmony_ci		if ($realline != $checklicenseline &&
379862306a36Sopenharmony_ci		    $rawline =~ /\bSPDX-License-Identifier:/ &&
379962306a36Sopenharmony_ci		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
380062306a36Sopenharmony_ci			WARN("SPDX_LICENSE_TAG",
380162306a36Sopenharmony_ci			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
380262306a36Sopenharmony_ci		}
380362306a36Sopenharmony_ci
380462306a36Sopenharmony_ci# line length limit (with some exclusions)
380562306a36Sopenharmony_ci#
380662306a36Sopenharmony_ci# There are a few types of lines that may extend beyond $max_line_length:
380762306a36Sopenharmony_ci#	logging functions like pr_info that end in a string
380862306a36Sopenharmony_ci#	lines with a single string
380962306a36Sopenharmony_ci#	#defines that are a single string
381062306a36Sopenharmony_ci#	lines with an RFC3986 like URL
381162306a36Sopenharmony_ci#
381262306a36Sopenharmony_ci# There are 3 different line length message types:
381362306a36Sopenharmony_ci# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
381462306a36Sopenharmony_ci# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
381562306a36Sopenharmony_ci# LONG_LINE		all other lines longer than $max_line_length
381662306a36Sopenharmony_ci#
381762306a36Sopenharmony_ci# if LONG_LINE is ignored, the other 2 types are also ignored
381862306a36Sopenharmony_ci#
381962306a36Sopenharmony_ci
382062306a36Sopenharmony_ci		if ($line =~ /^\+/ && $length > $max_line_length) {
382162306a36Sopenharmony_ci			my $msg_type = "LONG_LINE";
382262306a36Sopenharmony_ci
382362306a36Sopenharmony_ci			# Check the allowed long line types first
382462306a36Sopenharmony_ci
382562306a36Sopenharmony_ci			# logging functions that end in a string that starts
382662306a36Sopenharmony_ci			# before $max_line_length
382762306a36Sopenharmony_ci			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
382862306a36Sopenharmony_ci			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
382962306a36Sopenharmony_ci				$msg_type = "";
383062306a36Sopenharmony_ci
383162306a36Sopenharmony_ci			# lines with only strings (w/ possible termination)
383262306a36Sopenharmony_ci			# #defines with only strings
383362306a36Sopenharmony_ci			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
383462306a36Sopenharmony_ci				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
383562306a36Sopenharmony_ci				$msg_type = "";
383662306a36Sopenharmony_ci
383762306a36Sopenharmony_ci			# More special cases
383862306a36Sopenharmony_ci			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
383962306a36Sopenharmony_ci				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
384062306a36Sopenharmony_ci				$msg_type = "";
384162306a36Sopenharmony_ci
384262306a36Sopenharmony_ci			# URL ($rawline is used in case the URL is in a comment)
384362306a36Sopenharmony_ci			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
384462306a36Sopenharmony_ci				$msg_type = "";
384562306a36Sopenharmony_ci
384662306a36Sopenharmony_ci			# Otherwise set the alternate message types
384762306a36Sopenharmony_ci
384862306a36Sopenharmony_ci			# a comment starts before $max_line_length
384962306a36Sopenharmony_ci			} elsif ($line =~ /($;[\s$;]*)$/ &&
385062306a36Sopenharmony_ci				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
385162306a36Sopenharmony_ci				$msg_type = "LONG_LINE_COMMENT"
385262306a36Sopenharmony_ci
385362306a36Sopenharmony_ci			# a quoted string starts before $max_line_length
385462306a36Sopenharmony_ci			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
385562306a36Sopenharmony_ci				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
385662306a36Sopenharmony_ci				$msg_type = "LONG_LINE_STRING"
385762306a36Sopenharmony_ci			}
385862306a36Sopenharmony_ci
385962306a36Sopenharmony_ci			if ($msg_type ne "" &&
386062306a36Sopenharmony_ci			    (show_type("LONG_LINE") || show_type($msg_type))) {
386162306a36Sopenharmony_ci				my $msg_level = \&WARN;
386262306a36Sopenharmony_ci				$msg_level = \&CHK if ($file);
386362306a36Sopenharmony_ci				&{$msg_level}($msg_type,
386462306a36Sopenharmony_ci					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
386562306a36Sopenharmony_ci			}
386662306a36Sopenharmony_ci		}
386762306a36Sopenharmony_ci
386862306a36Sopenharmony_ci# check for adding lines without a newline.
386962306a36Sopenharmony_ci		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
387062306a36Sopenharmony_ci			if (WARN("MISSING_EOF_NEWLINE",
387162306a36Sopenharmony_ci			         "adding a line without newline at end of file\n" . $herecurr) &&
387262306a36Sopenharmony_ci			    $fix) {
387362306a36Sopenharmony_ci				fix_delete_line($fixlinenr+1, "No newline at end of file");
387462306a36Sopenharmony_ci			}
387562306a36Sopenharmony_ci		}
387662306a36Sopenharmony_ci
387762306a36Sopenharmony_ci# check for .L prefix local symbols in .S files
387862306a36Sopenharmony_ci		if ($realfile =~ /\.S$/ &&
387962306a36Sopenharmony_ci		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
388062306a36Sopenharmony_ci			WARN("AVOID_L_PREFIX",
388162306a36Sopenharmony_ci			     "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);
388262306a36Sopenharmony_ci		}
388362306a36Sopenharmony_ci
388462306a36Sopenharmony_ci# check we are in a valid source file C or perl if not then ignore this hunk
388562306a36Sopenharmony_ci		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
388662306a36Sopenharmony_ci
388762306a36Sopenharmony_ci# at the beginning of a line any tabs must come first and anything
388862306a36Sopenharmony_ci# more than $tabsize must use tabs.
388962306a36Sopenharmony_ci		if ($rawline =~ /^\+\s* \t\s*\S/ ||
389062306a36Sopenharmony_ci		    $rawline =~ /^\+\s*        \s*/) {
389162306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
389262306a36Sopenharmony_ci			$rpt_cleaners = 1;
389362306a36Sopenharmony_ci			if (ERROR("CODE_INDENT",
389462306a36Sopenharmony_ci				  "code indent should use tabs where possible\n" . $herevet) &&
389562306a36Sopenharmony_ci			    $fix) {
389662306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
389762306a36Sopenharmony_ci			}
389862306a36Sopenharmony_ci		}
389962306a36Sopenharmony_ci
390062306a36Sopenharmony_ci# check for space before tabs.
390162306a36Sopenharmony_ci		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
390262306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
390362306a36Sopenharmony_ci			if (WARN("SPACE_BEFORE_TAB",
390462306a36Sopenharmony_ci				"please, no space before tabs\n" . $herevet) &&
390562306a36Sopenharmony_ci			    $fix) {
390662306a36Sopenharmony_ci				while ($fixed[$fixlinenr] =~
390762306a36Sopenharmony_ci					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
390862306a36Sopenharmony_ci				while ($fixed[$fixlinenr] =~
390962306a36Sopenharmony_ci					   s/(^\+.*) +\t/$1\t/) {}
391062306a36Sopenharmony_ci			}
391162306a36Sopenharmony_ci		}
391262306a36Sopenharmony_ci
391362306a36Sopenharmony_ci# check for assignments on the start of a line
391462306a36Sopenharmony_ci		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
391562306a36Sopenharmony_ci			my $operator = $1;
391662306a36Sopenharmony_ci			if (CHK("ASSIGNMENT_CONTINUATIONS",
391762306a36Sopenharmony_ci				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
391862306a36Sopenharmony_ci			    $fix && $prevrawline =~ /^\+/) {
391962306a36Sopenharmony_ci				# add assignment operator to the previous line, remove from current line
392062306a36Sopenharmony_ci				$fixed[$fixlinenr - 1] .= " $operator";
392162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
392262306a36Sopenharmony_ci			}
392362306a36Sopenharmony_ci		}
392462306a36Sopenharmony_ci
392562306a36Sopenharmony_ci# check for && or || at the start of a line
392662306a36Sopenharmony_ci		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
392762306a36Sopenharmony_ci			my $operator = $1;
392862306a36Sopenharmony_ci			if (CHK("LOGICAL_CONTINUATIONS",
392962306a36Sopenharmony_ci				"Logical continuations should be on the previous line\n" . $hereprev) &&
393062306a36Sopenharmony_ci			    $fix && $prevrawline =~ /^\+/) {
393162306a36Sopenharmony_ci				# insert logical operator at last non-comment, non-whitepsace char on previous line
393262306a36Sopenharmony_ci				$prevline =~ /[\s$;]*$/;
393362306a36Sopenharmony_ci				my $line_end = substr($prevrawline, $-[0]);
393462306a36Sopenharmony_ci				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
393562306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
393662306a36Sopenharmony_ci			}
393762306a36Sopenharmony_ci		}
393862306a36Sopenharmony_ci
393962306a36Sopenharmony_ci# check indentation starts on a tab stop
394062306a36Sopenharmony_ci		if ($perl_version_ok &&
394162306a36Sopenharmony_ci		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
394262306a36Sopenharmony_ci			my $indent = length($1);
394362306a36Sopenharmony_ci			if ($indent % $tabsize) {
394462306a36Sopenharmony_ci				if (WARN("TABSTOP",
394562306a36Sopenharmony_ci					 "Statements should start on a tabstop\n" . $herecurr) &&
394662306a36Sopenharmony_ci				    $fix) {
394762306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
394862306a36Sopenharmony_ci				}
394962306a36Sopenharmony_ci			}
395062306a36Sopenharmony_ci		}
395162306a36Sopenharmony_ci
395262306a36Sopenharmony_ci# check multi-line statement indentation matches previous line
395362306a36Sopenharmony_ci		if ($perl_version_ok &&
395462306a36Sopenharmony_ci		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
395562306a36Sopenharmony_ci			$prevline =~ /^\+(\t*)(.*)$/;
395662306a36Sopenharmony_ci			my $oldindent = $1;
395762306a36Sopenharmony_ci			my $rest = $2;
395862306a36Sopenharmony_ci
395962306a36Sopenharmony_ci			my $pos = pos_last_openparen($rest);
396062306a36Sopenharmony_ci			if ($pos >= 0) {
396162306a36Sopenharmony_ci				$line =~ /^(\+| )([ \t]*)/;
396262306a36Sopenharmony_ci				my $newindent = $2;
396362306a36Sopenharmony_ci
396462306a36Sopenharmony_ci				my $goodtabindent = $oldindent .
396562306a36Sopenharmony_ci					"\t" x ($pos / $tabsize) .
396662306a36Sopenharmony_ci					" "  x ($pos % $tabsize);
396762306a36Sopenharmony_ci				my $goodspaceindent = $oldindent . " "  x $pos;
396862306a36Sopenharmony_ci
396962306a36Sopenharmony_ci				if ($newindent ne $goodtabindent &&
397062306a36Sopenharmony_ci				    $newindent ne $goodspaceindent) {
397162306a36Sopenharmony_ci
397262306a36Sopenharmony_ci					if (CHK("PARENTHESIS_ALIGNMENT",
397362306a36Sopenharmony_ci						"Alignment should match open parenthesis\n" . $hereprev) &&
397462306a36Sopenharmony_ci					    $fix && $line =~ /^\+/) {
397562306a36Sopenharmony_ci						$fixed[$fixlinenr] =~
397662306a36Sopenharmony_ci						    s/^\+[ \t]*/\+$goodtabindent/;
397762306a36Sopenharmony_ci					}
397862306a36Sopenharmony_ci				}
397962306a36Sopenharmony_ci			}
398062306a36Sopenharmony_ci		}
398162306a36Sopenharmony_ci
398262306a36Sopenharmony_ci# check for space after cast like "(int) foo" or "(struct foo) bar"
398362306a36Sopenharmony_ci# avoid checking a few false positives:
398462306a36Sopenharmony_ci#   "sizeof(<type>)" or "__alignof__(<type>)"
398562306a36Sopenharmony_ci#   function pointer declarations like "(*foo)(int) = bar;"
398662306a36Sopenharmony_ci#   structure definitions like "(struct foo) { 0 };"
398762306a36Sopenharmony_ci#   multiline macros that define functions
398862306a36Sopenharmony_ci#   known attributes or the __attribute__ keyword
398962306a36Sopenharmony_ci		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
399062306a36Sopenharmony_ci		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
399162306a36Sopenharmony_ci			if (CHK("SPACING",
399262306a36Sopenharmony_ci				"No space is necessary after a cast\n" . $herecurr) &&
399362306a36Sopenharmony_ci			    $fix) {
399462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
399562306a36Sopenharmony_ci				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
399662306a36Sopenharmony_ci			}
399762306a36Sopenharmony_ci		}
399862306a36Sopenharmony_ci
399962306a36Sopenharmony_ci# Block comment styles
400062306a36Sopenharmony_ci# Networking with an initial /*
400162306a36Sopenharmony_ci		if ($realfile =~ m@^(drivers/net/|net/)@ &&
400262306a36Sopenharmony_ci		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
400362306a36Sopenharmony_ci		    $rawline =~ /^\+[ \t]*\*/ &&
400462306a36Sopenharmony_ci		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
400562306a36Sopenharmony_ci			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
400662306a36Sopenharmony_ci			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
400762306a36Sopenharmony_ci		}
400862306a36Sopenharmony_ci
400962306a36Sopenharmony_ci# Block comments use * on subsequent lines
401062306a36Sopenharmony_ci		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
401162306a36Sopenharmony_ci		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
401262306a36Sopenharmony_ci		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
401362306a36Sopenharmony_ci		    $rawline =~ /^\+/ &&			#line is new
401462306a36Sopenharmony_ci		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
401562306a36Sopenharmony_ci			WARN("BLOCK_COMMENT_STYLE",
401662306a36Sopenharmony_ci			     "Block comments use * on subsequent lines\n" . $hereprev);
401762306a36Sopenharmony_ci		}
401862306a36Sopenharmony_ci
401962306a36Sopenharmony_ci# Block comments use */ on trailing lines
402062306a36Sopenharmony_ci		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
402162306a36Sopenharmony_ci		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
402262306a36Sopenharmony_ci		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
402362306a36Sopenharmony_ci		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
402462306a36Sopenharmony_ci			WARN("BLOCK_COMMENT_STYLE",
402562306a36Sopenharmony_ci			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
402662306a36Sopenharmony_ci		}
402762306a36Sopenharmony_ci
402862306a36Sopenharmony_ci# Block comment * alignment
402962306a36Sopenharmony_ci		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
403062306a36Sopenharmony_ci		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
403162306a36Sopenharmony_ci		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
403262306a36Sopenharmony_ci		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
403362306a36Sopenharmony_ci		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
403462306a36Sopenharmony_ci		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
403562306a36Sopenharmony_ci			my $oldindent;
403662306a36Sopenharmony_ci			$prevrawline =~ m@^\+([ \t]*/?)\*@;
403762306a36Sopenharmony_ci			if (defined($1)) {
403862306a36Sopenharmony_ci				$oldindent = expand_tabs($1);
403962306a36Sopenharmony_ci			} else {
404062306a36Sopenharmony_ci				$prevrawline =~ m@^\+(.*/?)\*@;
404162306a36Sopenharmony_ci				$oldindent = expand_tabs($1);
404262306a36Sopenharmony_ci			}
404362306a36Sopenharmony_ci			$rawline =~ m@^\+([ \t]*)\*@;
404462306a36Sopenharmony_ci			my $newindent = $1;
404562306a36Sopenharmony_ci			$newindent = expand_tabs($newindent);
404662306a36Sopenharmony_ci			if (length($oldindent) ne length($newindent)) {
404762306a36Sopenharmony_ci				WARN("BLOCK_COMMENT_STYLE",
404862306a36Sopenharmony_ci				     "Block comments should align the * on each line\n" . $hereprev);
404962306a36Sopenharmony_ci			}
405062306a36Sopenharmony_ci		}
405162306a36Sopenharmony_ci
405262306a36Sopenharmony_ci# check for missing blank lines after struct/union declarations
405362306a36Sopenharmony_ci# with exceptions for various attributes and macros
405462306a36Sopenharmony_ci		if ($prevline =~ /^[\+ ]};?\s*$/ &&
405562306a36Sopenharmony_ci		    $line =~ /^\+/ &&
405662306a36Sopenharmony_ci		    !($line =~ /^\+\s*$/ ||
405762306a36Sopenharmony_ci		      $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ ||
405862306a36Sopenharmony_ci		      $line =~ /^\+\s*MODULE_/i ||
405962306a36Sopenharmony_ci		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
406062306a36Sopenharmony_ci		      $line =~ /^\+[a-z_]*init/ ||
406162306a36Sopenharmony_ci		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
406262306a36Sopenharmony_ci		      $line =~ /^\+\s*DECLARE/ ||
406362306a36Sopenharmony_ci		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
406462306a36Sopenharmony_ci		      $line =~ /^\+\s*__setup/)) {
406562306a36Sopenharmony_ci			if (CHK("LINE_SPACING",
406662306a36Sopenharmony_ci				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
406762306a36Sopenharmony_ci			    $fix) {
406862306a36Sopenharmony_ci				fix_insert_line($fixlinenr, "\+");
406962306a36Sopenharmony_ci			}
407062306a36Sopenharmony_ci		}
407162306a36Sopenharmony_ci
407262306a36Sopenharmony_ci# check for multiple consecutive blank lines
407362306a36Sopenharmony_ci		if ($prevline =~ /^[\+ ]\s*$/ &&
407462306a36Sopenharmony_ci		    $line =~ /^\+\s*$/ &&
407562306a36Sopenharmony_ci		    $last_blank_line != ($linenr - 1)) {
407662306a36Sopenharmony_ci			if (CHK("LINE_SPACING",
407762306a36Sopenharmony_ci				"Please don't use multiple blank lines\n" . $hereprev) &&
407862306a36Sopenharmony_ci			    $fix) {
407962306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
408062306a36Sopenharmony_ci			}
408162306a36Sopenharmony_ci
408262306a36Sopenharmony_ci			$last_blank_line = $linenr;
408362306a36Sopenharmony_ci		}
408462306a36Sopenharmony_ci
408562306a36Sopenharmony_ci# check for missing blank lines after declarations
408662306a36Sopenharmony_ci# (declarations must have the same indentation and not be at the start of line)
408762306a36Sopenharmony_ci		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
408862306a36Sopenharmony_ci			# use temporaries
408962306a36Sopenharmony_ci			my $sl = $sline;
409062306a36Sopenharmony_ci			my $pl = $prevline;
409162306a36Sopenharmony_ci			# remove $Attribute/$Sparse uses to simplify comparisons
409262306a36Sopenharmony_ci			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
409362306a36Sopenharmony_ci			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
409462306a36Sopenharmony_ci			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
409562306a36Sopenharmony_ci			# function pointer declarations
409662306a36Sopenharmony_ci			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
409762306a36Sopenharmony_ci			# foo bar; where foo is some local typedef or #define
409862306a36Sopenharmony_ci			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
409962306a36Sopenharmony_ci			# known declaration macros
410062306a36Sopenharmony_ci			     $pl =~ /^\+\s+$declaration_macros/) &&
410162306a36Sopenharmony_ci			# for "else if" which can look like "$Ident $Ident"
410262306a36Sopenharmony_ci			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
410362306a36Sopenharmony_ci			# other possible extensions of declaration lines
410462306a36Sopenharmony_ci			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
410562306a36Sopenharmony_ci			# not starting a section or a macro "\" extended line
410662306a36Sopenharmony_ci			      $pl =~ /(?:\{\s*|\\)$/) &&
410762306a36Sopenharmony_ci			# looks like a declaration
410862306a36Sopenharmony_ci			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
410962306a36Sopenharmony_ci			# function pointer declarations
411062306a36Sopenharmony_ci			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
411162306a36Sopenharmony_ci			# foo bar; where foo is some local typedef or #define
411262306a36Sopenharmony_ci			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
411362306a36Sopenharmony_ci			# known declaration macros
411462306a36Sopenharmony_ci			      $sl =~ /^\+\s+$declaration_macros/ ||
411562306a36Sopenharmony_ci			# start of struct or union or enum
411662306a36Sopenharmony_ci			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
411762306a36Sopenharmony_ci			# start or end of block or continuation of declaration
411862306a36Sopenharmony_ci			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
411962306a36Sopenharmony_ci			# bitfield continuation
412062306a36Sopenharmony_ci			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
412162306a36Sopenharmony_ci			# other possible extensions of declaration lines
412262306a36Sopenharmony_ci			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
412362306a36Sopenharmony_ci				if (WARN("LINE_SPACING",
412462306a36Sopenharmony_ci					 "Missing a blank line after declarations\n" . $hereprev) &&
412562306a36Sopenharmony_ci				    $fix) {
412662306a36Sopenharmony_ci					fix_insert_line($fixlinenr, "\+");
412762306a36Sopenharmony_ci				}
412862306a36Sopenharmony_ci			}
412962306a36Sopenharmony_ci		}
413062306a36Sopenharmony_ci
413162306a36Sopenharmony_ci# check for spaces at the beginning of a line.
413262306a36Sopenharmony_ci# Exceptions:
413362306a36Sopenharmony_ci#  1) within comments
413462306a36Sopenharmony_ci#  2) indented preprocessor commands
413562306a36Sopenharmony_ci#  3) hanging labels
413662306a36Sopenharmony_ci		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
413762306a36Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
413862306a36Sopenharmony_ci			if (WARN("LEADING_SPACE",
413962306a36Sopenharmony_ci				 "please, no spaces at the start of a line\n" . $herevet) &&
414062306a36Sopenharmony_ci			    $fix) {
414162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
414262306a36Sopenharmony_ci			}
414362306a36Sopenharmony_ci		}
414462306a36Sopenharmony_ci
414562306a36Sopenharmony_ci# check we are in a valid C source file if not then ignore this hunk
414662306a36Sopenharmony_ci		next if ($realfile !~ /\.(h|c)$/);
414762306a36Sopenharmony_ci
414862306a36Sopenharmony_ci# check for unusual line ending [ or (
414962306a36Sopenharmony_ci		if ($line =~ /^\+.*([\[\(])\s*$/) {
415062306a36Sopenharmony_ci			CHK("OPEN_ENDED_LINE",
415162306a36Sopenharmony_ci			    "Lines should not end with a '$1'\n" . $herecurr);
415262306a36Sopenharmony_ci		}
415362306a36Sopenharmony_ci
415462306a36Sopenharmony_ci# check if this appears to be the start function declaration, save the name
415562306a36Sopenharmony_ci		if ($sline =~ /^\+\{\s*$/ &&
415662306a36Sopenharmony_ci		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
415762306a36Sopenharmony_ci			$context_function = $1;
415862306a36Sopenharmony_ci		}
415962306a36Sopenharmony_ci
416062306a36Sopenharmony_ci# check if this appears to be the end of function declaration
416162306a36Sopenharmony_ci		if ($sline =~ /^\+\}\s*$/) {
416262306a36Sopenharmony_ci			undef $context_function;
416362306a36Sopenharmony_ci		}
416462306a36Sopenharmony_ci
416562306a36Sopenharmony_ci# check indentation of any line with a bare else
416662306a36Sopenharmony_ci# (but not if it is a multiple line "if (foo) return bar; else return baz;")
416762306a36Sopenharmony_ci# if the previous line is a break or return and is indented 1 tab more...
416862306a36Sopenharmony_ci		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
416962306a36Sopenharmony_ci			my $tabs = length($1) + 1;
417062306a36Sopenharmony_ci			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
417162306a36Sopenharmony_ci			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
417262306a36Sopenharmony_ci			     defined $lines[$linenr] &&
417362306a36Sopenharmony_ci			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
417462306a36Sopenharmony_ci				WARN("UNNECESSARY_ELSE",
417562306a36Sopenharmony_ci				     "else is not generally useful after a break or return\n" . $hereprev);
417662306a36Sopenharmony_ci			}
417762306a36Sopenharmony_ci		}
417862306a36Sopenharmony_ci
417962306a36Sopenharmony_ci# check indentation of a line with a break;
418062306a36Sopenharmony_ci# if the previous line is a goto, return or break
418162306a36Sopenharmony_ci# and is indented the same # of tabs
418262306a36Sopenharmony_ci		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
418362306a36Sopenharmony_ci			my $tabs = $1;
418462306a36Sopenharmony_ci			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
418562306a36Sopenharmony_ci				if (WARN("UNNECESSARY_BREAK",
418662306a36Sopenharmony_ci					 "break is not useful after a $1\n" . $hereprev) &&
418762306a36Sopenharmony_ci				    $fix) {
418862306a36Sopenharmony_ci					fix_delete_line($fixlinenr, $rawline);
418962306a36Sopenharmony_ci				}
419062306a36Sopenharmony_ci			}
419162306a36Sopenharmony_ci		}
419262306a36Sopenharmony_ci
419362306a36Sopenharmony_ci# check for RCS/CVS revision markers
419462306a36Sopenharmony_ci		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
419562306a36Sopenharmony_ci			WARN("CVS_KEYWORD",
419662306a36Sopenharmony_ci			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
419762306a36Sopenharmony_ci		}
419862306a36Sopenharmony_ci
419962306a36Sopenharmony_ci# check for old HOTPLUG __dev<foo> section markings
420062306a36Sopenharmony_ci		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
420162306a36Sopenharmony_ci			WARN("HOTPLUG_SECTION",
420262306a36Sopenharmony_ci			     "Using $1 is unnecessary\n" . $herecurr);
420362306a36Sopenharmony_ci		}
420462306a36Sopenharmony_ci
420562306a36Sopenharmony_ci# Check for potential 'bare' types
420662306a36Sopenharmony_ci		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
420762306a36Sopenharmony_ci		    $realline_next);
420862306a36Sopenharmony_ci#print "LINE<$line>\n";
420962306a36Sopenharmony_ci		if ($linenr > $suppress_statement &&
421062306a36Sopenharmony_ci		    $realcnt && $sline =~ /.\s*\S/) {
421162306a36Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
421262306a36Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
421362306a36Sopenharmony_ci			$stat =~ s/\n./\n /g;
421462306a36Sopenharmony_ci			$cond =~ s/\n./\n /g;
421562306a36Sopenharmony_ci
421662306a36Sopenharmony_ci#print "linenr<$linenr> <$stat>\n";
421762306a36Sopenharmony_ci			# If this statement has no statement boundaries within
421862306a36Sopenharmony_ci			# it there is no point in retrying a statement scan
421962306a36Sopenharmony_ci			# until we hit end of it.
422062306a36Sopenharmony_ci			my $frag = $stat; $frag =~ s/;+\s*$//;
422162306a36Sopenharmony_ci			if ($frag !~ /(?:{|;)/) {
422262306a36Sopenharmony_ci#print "skip<$line_nr_next>\n";
422362306a36Sopenharmony_ci				$suppress_statement = $line_nr_next;
422462306a36Sopenharmony_ci			}
422562306a36Sopenharmony_ci
422662306a36Sopenharmony_ci			# Find the real next line.
422762306a36Sopenharmony_ci			$realline_next = $line_nr_next;
422862306a36Sopenharmony_ci			if (defined $realline_next &&
422962306a36Sopenharmony_ci			    (!defined $lines[$realline_next - 1] ||
423062306a36Sopenharmony_ci			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
423162306a36Sopenharmony_ci				$realline_next++;
423262306a36Sopenharmony_ci			}
423362306a36Sopenharmony_ci
423462306a36Sopenharmony_ci			my $s = $stat;
423562306a36Sopenharmony_ci			$s =~ s/{.*$//s;
423662306a36Sopenharmony_ci
423762306a36Sopenharmony_ci			# Ignore goto labels.
423862306a36Sopenharmony_ci			if ($s =~ /$Ident:\*$/s) {
423962306a36Sopenharmony_ci
424062306a36Sopenharmony_ci			# Ignore functions being called
424162306a36Sopenharmony_ci			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
424262306a36Sopenharmony_ci
424362306a36Sopenharmony_ci			} elsif ($s =~ /^.\s*else\b/s) {
424462306a36Sopenharmony_ci
424562306a36Sopenharmony_ci			# declarations always start with types
424662306a36Sopenharmony_ci			} 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) {
424762306a36Sopenharmony_ci				my $type = $1;
424862306a36Sopenharmony_ci				$type =~ s/\s+/ /g;
424962306a36Sopenharmony_ci				possible($type, "A:" . $s);
425062306a36Sopenharmony_ci
425162306a36Sopenharmony_ci			# definitions in global scope can only start with types
425262306a36Sopenharmony_ci			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
425362306a36Sopenharmony_ci				possible($1, "B:" . $s);
425462306a36Sopenharmony_ci			}
425562306a36Sopenharmony_ci
425662306a36Sopenharmony_ci			# any (foo ... *) is a pointer cast, and foo is a type
425762306a36Sopenharmony_ci			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
425862306a36Sopenharmony_ci				possible($1, "C:" . $s);
425962306a36Sopenharmony_ci			}
426062306a36Sopenharmony_ci
426162306a36Sopenharmony_ci			# Check for any sort of function declaration.
426262306a36Sopenharmony_ci			# int foo(something bar, other baz);
426362306a36Sopenharmony_ci			# void (*store_gdt)(x86_descr_ptr *);
426462306a36Sopenharmony_ci			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
426562306a36Sopenharmony_ci				my ($name_len) = length($1);
426662306a36Sopenharmony_ci
426762306a36Sopenharmony_ci				my $ctx = $s;
426862306a36Sopenharmony_ci				substr($ctx, 0, $name_len + 1, '');
426962306a36Sopenharmony_ci				$ctx =~ s/\)[^\)]*$//;
427062306a36Sopenharmony_ci
427162306a36Sopenharmony_ci				for my $arg (split(/\s*,\s*/, $ctx)) {
427262306a36Sopenharmony_ci					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
427362306a36Sopenharmony_ci
427462306a36Sopenharmony_ci						possible($1, "D:" . $s);
427562306a36Sopenharmony_ci					}
427662306a36Sopenharmony_ci				}
427762306a36Sopenharmony_ci			}
427862306a36Sopenharmony_ci
427962306a36Sopenharmony_ci		}
428062306a36Sopenharmony_ci
428162306a36Sopenharmony_ci#
428262306a36Sopenharmony_ci# Checks which may be anchored in the context.
428362306a36Sopenharmony_ci#
428462306a36Sopenharmony_ci
428562306a36Sopenharmony_ci# Check for switch () and associated case and default
428662306a36Sopenharmony_ci# statements should be at the same indent.
428762306a36Sopenharmony_ci		if ($line=~/\bswitch\s*\(.*\)/) {
428862306a36Sopenharmony_ci			my $err = '';
428962306a36Sopenharmony_ci			my $sep = '';
429062306a36Sopenharmony_ci			my @ctx = ctx_block_outer($linenr, $realcnt);
429162306a36Sopenharmony_ci			shift(@ctx);
429262306a36Sopenharmony_ci			for my $ctx (@ctx) {
429362306a36Sopenharmony_ci				my ($clen, $cindent) = line_stats($ctx);
429462306a36Sopenharmony_ci				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
429562306a36Sopenharmony_ci							$indent != $cindent) {
429662306a36Sopenharmony_ci					$err .= "$sep$ctx\n";
429762306a36Sopenharmony_ci					$sep = '';
429862306a36Sopenharmony_ci				} else {
429962306a36Sopenharmony_ci					$sep = "[...]\n";
430062306a36Sopenharmony_ci				}
430162306a36Sopenharmony_ci			}
430262306a36Sopenharmony_ci			if ($err ne '') {
430362306a36Sopenharmony_ci				ERROR("SWITCH_CASE_INDENT_LEVEL",
430462306a36Sopenharmony_ci				      "switch and case should be at the same indent\n$hereline$err");
430562306a36Sopenharmony_ci			}
430662306a36Sopenharmony_ci		}
430762306a36Sopenharmony_ci
430862306a36Sopenharmony_ci# if/while/etc brace do not go on next line, unless defining a do while loop,
430962306a36Sopenharmony_ci# or if that brace on the next line is for something else
431062306a36Sopenharmony_ci		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
431162306a36Sopenharmony_ci			my $pre_ctx = "$1$2";
431262306a36Sopenharmony_ci
431362306a36Sopenharmony_ci			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
431462306a36Sopenharmony_ci
431562306a36Sopenharmony_ci			if ($line =~ /^\+\t{6,}/) {
431662306a36Sopenharmony_ci				WARN("DEEP_INDENTATION",
431762306a36Sopenharmony_ci				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
431862306a36Sopenharmony_ci			}
431962306a36Sopenharmony_ci
432062306a36Sopenharmony_ci			my $ctx_cnt = $realcnt - $#ctx - 1;
432162306a36Sopenharmony_ci			my $ctx = join("\n", @ctx);
432262306a36Sopenharmony_ci
432362306a36Sopenharmony_ci			my $ctx_ln = $linenr;
432462306a36Sopenharmony_ci			my $ctx_skip = $realcnt;
432562306a36Sopenharmony_ci
432662306a36Sopenharmony_ci			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
432762306a36Sopenharmony_ci					defined $lines[$ctx_ln - 1] &&
432862306a36Sopenharmony_ci					$lines[$ctx_ln - 1] =~ /^-/)) {
432962306a36Sopenharmony_ci				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
433062306a36Sopenharmony_ci				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
433162306a36Sopenharmony_ci				$ctx_ln++;
433262306a36Sopenharmony_ci			}
433362306a36Sopenharmony_ci
433462306a36Sopenharmony_ci			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
433562306a36Sopenharmony_ci			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
433662306a36Sopenharmony_ci
433762306a36Sopenharmony_ci			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
433862306a36Sopenharmony_ci				ERROR("OPEN_BRACE",
433962306a36Sopenharmony_ci				      "that open brace { should be on the previous line\n" .
434062306a36Sopenharmony_ci					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
434162306a36Sopenharmony_ci			}
434262306a36Sopenharmony_ci			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
434362306a36Sopenharmony_ci			    $ctx =~ /\)\s*\;\s*$/ &&
434462306a36Sopenharmony_ci			    defined $lines[$ctx_ln - 1])
434562306a36Sopenharmony_ci			{
434662306a36Sopenharmony_ci				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
434762306a36Sopenharmony_ci				if ($nindent > $indent) {
434862306a36Sopenharmony_ci					WARN("TRAILING_SEMICOLON",
434962306a36Sopenharmony_ci					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
435062306a36Sopenharmony_ci						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
435162306a36Sopenharmony_ci				}
435262306a36Sopenharmony_ci			}
435362306a36Sopenharmony_ci		}
435462306a36Sopenharmony_ci
435562306a36Sopenharmony_ci# Check relative indent for conditionals and blocks.
435662306a36Sopenharmony_ci		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
435762306a36Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
435862306a36Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0)
435962306a36Sopenharmony_ci					if (!defined $stat);
436062306a36Sopenharmony_ci			my ($s, $c) = ($stat, $cond);
436162306a36Sopenharmony_ci
436262306a36Sopenharmony_ci			substr($s, 0, length($c), '');
436362306a36Sopenharmony_ci
436462306a36Sopenharmony_ci			# remove inline comments
436562306a36Sopenharmony_ci			$s =~ s/$;/ /g;
436662306a36Sopenharmony_ci			$c =~ s/$;/ /g;
436762306a36Sopenharmony_ci
436862306a36Sopenharmony_ci			# Find out how long the conditional actually is.
436962306a36Sopenharmony_ci			my @newlines = ($c =~ /\n/gs);
437062306a36Sopenharmony_ci			my $cond_lines = 1 + $#newlines;
437162306a36Sopenharmony_ci
437262306a36Sopenharmony_ci			# Make sure we remove the line prefixes as we have
437362306a36Sopenharmony_ci			# none on the first line, and are going to readd them
437462306a36Sopenharmony_ci			# where necessary.
437562306a36Sopenharmony_ci			$s =~ s/\n./\n/gs;
437662306a36Sopenharmony_ci			while ($s =~ /\n\s+\\\n/) {
437762306a36Sopenharmony_ci				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
437862306a36Sopenharmony_ci			}
437962306a36Sopenharmony_ci
438062306a36Sopenharmony_ci			# We want to check the first line inside the block
438162306a36Sopenharmony_ci			# starting at the end of the conditional, so remove:
438262306a36Sopenharmony_ci			#  1) any blank line termination
438362306a36Sopenharmony_ci			#  2) any opening brace { on end of the line
438462306a36Sopenharmony_ci			#  3) any do (...) {
438562306a36Sopenharmony_ci			my $continuation = 0;
438662306a36Sopenharmony_ci			my $check = 0;
438762306a36Sopenharmony_ci			$s =~ s/^.*\bdo\b//;
438862306a36Sopenharmony_ci			$s =~ s/^\s*{//;
438962306a36Sopenharmony_ci			if ($s =~ s/^\s*\\//) {
439062306a36Sopenharmony_ci				$continuation = 1;
439162306a36Sopenharmony_ci			}
439262306a36Sopenharmony_ci			if ($s =~ s/^\s*?\n//) {
439362306a36Sopenharmony_ci				$check = 1;
439462306a36Sopenharmony_ci				$cond_lines++;
439562306a36Sopenharmony_ci			}
439662306a36Sopenharmony_ci
439762306a36Sopenharmony_ci			# Also ignore a loop construct at the end of a
439862306a36Sopenharmony_ci			# preprocessor statement.
439962306a36Sopenharmony_ci			if (($prevline =~ /^.\s*#\s*define\s/ ||
440062306a36Sopenharmony_ci			    $prevline =~ /\\\s*$/) && $continuation == 0) {
440162306a36Sopenharmony_ci				$check = 0;
440262306a36Sopenharmony_ci			}
440362306a36Sopenharmony_ci
440462306a36Sopenharmony_ci			my $cond_ptr = -1;
440562306a36Sopenharmony_ci			$continuation = 0;
440662306a36Sopenharmony_ci			while ($cond_ptr != $cond_lines) {
440762306a36Sopenharmony_ci				$cond_ptr = $cond_lines;
440862306a36Sopenharmony_ci
440962306a36Sopenharmony_ci				# If we see an #else/#elif then the code
441062306a36Sopenharmony_ci				# is not linear.
441162306a36Sopenharmony_ci				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
441262306a36Sopenharmony_ci					$check = 0;
441362306a36Sopenharmony_ci				}
441462306a36Sopenharmony_ci
441562306a36Sopenharmony_ci				# Ignore:
441662306a36Sopenharmony_ci				#  1) blank lines, they should be at 0,
441762306a36Sopenharmony_ci				#  2) preprocessor lines, and
441862306a36Sopenharmony_ci				#  3) labels.
441962306a36Sopenharmony_ci				if ($continuation ||
442062306a36Sopenharmony_ci				    $s =~ /^\s*?\n/ ||
442162306a36Sopenharmony_ci				    $s =~ /^\s*#\s*?/ ||
442262306a36Sopenharmony_ci				    $s =~ /^\s*$Ident\s*:/) {
442362306a36Sopenharmony_ci					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
442462306a36Sopenharmony_ci					if ($s =~ s/^.*?\n//) {
442562306a36Sopenharmony_ci						$cond_lines++;
442662306a36Sopenharmony_ci					}
442762306a36Sopenharmony_ci				}
442862306a36Sopenharmony_ci			}
442962306a36Sopenharmony_ci
443062306a36Sopenharmony_ci			my (undef, $sindent) = line_stats("+" . $s);
443162306a36Sopenharmony_ci			my $stat_real = raw_line($linenr, $cond_lines);
443262306a36Sopenharmony_ci
443362306a36Sopenharmony_ci			# Check if either of these lines are modified, else
443462306a36Sopenharmony_ci			# this is not this patch's fault.
443562306a36Sopenharmony_ci			if (!defined($stat_real) ||
443662306a36Sopenharmony_ci			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
443762306a36Sopenharmony_ci				$check = 0;
443862306a36Sopenharmony_ci			}
443962306a36Sopenharmony_ci			if (defined($stat_real) && $cond_lines > 1) {
444062306a36Sopenharmony_ci				$stat_real = "[...]\n$stat_real";
444162306a36Sopenharmony_ci			}
444262306a36Sopenharmony_ci
444362306a36Sopenharmony_ci			#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";
444462306a36Sopenharmony_ci
444562306a36Sopenharmony_ci			if ($check && $s ne '' &&
444662306a36Sopenharmony_ci			    (($sindent % $tabsize) != 0 ||
444762306a36Sopenharmony_ci			     ($sindent < $indent) ||
444862306a36Sopenharmony_ci			     ($sindent == $indent &&
444962306a36Sopenharmony_ci			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
445062306a36Sopenharmony_ci			     ($sindent > $indent + $tabsize))) {
445162306a36Sopenharmony_ci				WARN("SUSPECT_CODE_INDENT",
445262306a36Sopenharmony_ci				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
445362306a36Sopenharmony_ci			}
445462306a36Sopenharmony_ci		}
445562306a36Sopenharmony_ci
445662306a36Sopenharmony_ci		# Track the 'values' across context and added lines.
445762306a36Sopenharmony_ci		my $opline = $line; $opline =~ s/^./ /;
445862306a36Sopenharmony_ci		my ($curr_values, $curr_vars) =
445962306a36Sopenharmony_ci				annotate_values($opline . "\n", $prev_values);
446062306a36Sopenharmony_ci		$curr_values = $prev_values . $curr_values;
446162306a36Sopenharmony_ci		if ($dbg_values) {
446262306a36Sopenharmony_ci			my $outline = $opline; $outline =~ s/\t/ /g;
446362306a36Sopenharmony_ci			print "$linenr > .$outline\n";
446462306a36Sopenharmony_ci			print "$linenr > $curr_values\n";
446562306a36Sopenharmony_ci			print "$linenr >  $curr_vars\n";
446662306a36Sopenharmony_ci		}
446762306a36Sopenharmony_ci		$prev_values = substr($curr_values, -1);
446862306a36Sopenharmony_ci
446962306a36Sopenharmony_ci#ignore lines not being added
447062306a36Sopenharmony_ci		next if ($line =~ /^[^\+]/);
447162306a36Sopenharmony_ci
447262306a36Sopenharmony_ci# check for self assignments used to avoid compiler warnings
447362306a36Sopenharmony_ci# e.g.:	int foo = foo, *bar = NULL;
447462306a36Sopenharmony_ci#	struct foo bar = *(&(bar));
447562306a36Sopenharmony_ci		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
447662306a36Sopenharmony_ci			my $var = $1;
447762306a36Sopenharmony_ci			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
447862306a36Sopenharmony_ci				WARN("SELF_ASSIGNMENT",
447962306a36Sopenharmony_ci				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
448062306a36Sopenharmony_ci			}
448162306a36Sopenharmony_ci		}
448262306a36Sopenharmony_ci
448362306a36Sopenharmony_ci# check for dereferences that span multiple lines
448462306a36Sopenharmony_ci		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
448562306a36Sopenharmony_ci		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
448662306a36Sopenharmony_ci			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
448762306a36Sopenharmony_ci			my $ref = $1;
448862306a36Sopenharmony_ci			$line =~ /^.\s*($Lval)/;
448962306a36Sopenharmony_ci			$ref .= $1;
449062306a36Sopenharmony_ci			$ref =~ s/\s//g;
449162306a36Sopenharmony_ci			WARN("MULTILINE_DEREFERENCE",
449262306a36Sopenharmony_ci			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
449362306a36Sopenharmony_ci		}
449462306a36Sopenharmony_ci
449562306a36Sopenharmony_ci# check for declarations of signed or unsigned without int
449662306a36Sopenharmony_ci		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
449762306a36Sopenharmony_ci			my $type = $1;
449862306a36Sopenharmony_ci			my $var = $2;
449962306a36Sopenharmony_ci			$var = "" if (!defined $var);
450062306a36Sopenharmony_ci			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
450162306a36Sopenharmony_ci				my $sign = $1;
450262306a36Sopenharmony_ci				my $pointer = $2;
450362306a36Sopenharmony_ci
450462306a36Sopenharmony_ci				$pointer = "" if (!defined $pointer);
450562306a36Sopenharmony_ci
450662306a36Sopenharmony_ci				if (WARN("UNSPECIFIED_INT",
450762306a36Sopenharmony_ci					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
450862306a36Sopenharmony_ci				    $fix) {
450962306a36Sopenharmony_ci					my $decl = trim($sign) . " int ";
451062306a36Sopenharmony_ci					my $comp_pointer = $pointer;
451162306a36Sopenharmony_ci					$comp_pointer =~ s/\s//g;
451262306a36Sopenharmony_ci					$decl .= $comp_pointer;
451362306a36Sopenharmony_ci					$decl = rtrim($decl) if ($var eq "");
451462306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
451562306a36Sopenharmony_ci				}
451662306a36Sopenharmony_ci			}
451762306a36Sopenharmony_ci		}
451862306a36Sopenharmony_ci
451962306a36Sopenharmony_ci# TEST: allow direct testing of the type matcher.
452062306a36Sopenharmony_ci		if ($dbg_type) {
452162306a36Sopenharmony_ci			if ($line =~ /^.\s*$Declare\s*$/) {
452262306a36Sopenharmony_ci				ERROR("TEST_TYPE",
452362306a36Sopenharmony_ci				      "TEST: is type\n" . $herecurr);
452462306a36Sopenharmony_ci			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
452562306a36Sopenharmony_ci				ERROR("TEST_NOT_TYPE",
452662306a36Sopenharmony_ci				      "TEST: is not type ($1 is)\n". $herecurr);
452762306a36Sopenharmony_ci			}
452862306a36Sopenharmony_ci			next;
452962306a36Sopenharmony_ci		}
453062306a36Sopenharmony_ci# TEST: allow direct testing of the attribute matcher.
453162306a36Sopenharmony_ci		if ($dbg_attr) {
453262306a36Sopenharmony_ci			if ($line =~ /^.\s*$Modifier\s*$/) {
453362306a36Sopenharmony_ci				ERROR("TEST_ATTR",
453462306a36Sopenharmony_ci				      "TEST: is attr\n" . $herecurr);
453562306a36Sopenharmony_ci			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
453662306a36Sopenharmony_ci				ERROR("TEST_NOT_ATTR",
453762306a36Sopenharmony_ci				      "TEST: is not attr ($1 is)\n". $herecurr);
453862306a36Sopenharmony_ci			}
453962306a36Sopenharmony_ci			next;
454062306a36Sopenharmony_ci		}
454162306a36Sopenharmony_ci
454262306a36Sopenharmony_ci# check for initialisation to aggregates open brace on the next line
454362306a36Sopenharmony_ci		if ($line =~ /^.\s*{/ &&
454462306a36Sopenharmony_ci		    $prevline =~ /(?:^|[^=])=\s*$/) {
454562306a36Sopenharmony_ci			if (ERROR("OPEN_BRACE",
454662306a36Sopenharmony_ci				  "that open brace { should be on the previous line\n" . $hereprev) &&
454762306a36Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
454862306a36Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
454962306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
455062306a36Sopenharmony_ci				my $fixedline = $prevrawline;
455162306a36Sopenharmony_ci				$fixedline =~ s/\s*=\s*$/ = {/;
455262306a36Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
455362306a36Sopenharmony_ci				$fixedline = $line;
455462306a36Sopenharmony_ci				$fixedline =~ s/^(.\s*)\{\s*/$1/;
455562306a36Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
455662306a36Sopenharmony_ci			}
455762306a36Sopenharmony_ci		}
455862306a36Sopenharmony_ci
455962306a36Sopenharmony_ci#
456062306a36Sopenharmony_ci# Checks which are anchored on the added line.
456162306a36Sopenharmony_ci#
456262306a36Sopenharmony_ci
456362306a36Sopenharmony_ci# check for malformed paths in #include statements (uses RAW line)
456462306a36Sopenharmony_ci		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
456562306a36Sopenharmony_ci			my $path = $1;
456662306a36Sopenharmony_ci			if ($path =~ m{//}) {
456762306a36Sopenharmony_ci				ERROR("MALFORMED_INCLUDE",
456862306a36Sopenharmony_ci				      "malformed #include filename\n" . $herecurr);
456962306a36Sopenharmony_ci			}
457062306a36Sopenharmony_ci			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
457162306a36Sopenharmony_ci				ERROR("UAPI_INCLUDE",
457262306a36Sopenharmony_ci				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
457362306a36Sopenharmony_ci			}
457462306a36Sopenharmony_ci		}
457562306a36Sopenharmony_ci
457662306a36Sopenharmony_ci# no C99 // comments
457762306a36Sopenharmony_ci		if ($line =~ m{//}) {
457862306a36Sopenharmony_ci			if (ERROR("C99_COMMENTS",
457962306a36Sopenharmony_ci				  "do not use C99 // comments\n" . $herecurr) &&
458062306a36Sopenharmony_ci			    $fix) {
458162306a36Sopenharmony_ci				my $line = $fixed[$fixlinenr];
458262306a36Sopenharmony_ci				if ($line =~ /\/\/(.*)$/) {
458362306a36Sopenharmony_ci					my $comment = trim($1);
458462306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
458562306a36Sopenharmony_ci				}
458662306a36Sopenharmony_ci			}
458762306a36Sopenharmony_ci		}
458862306a36Sopenharmony_ci		# Remove C99 comments.
458962306a36Sopenharmony_ci		$line =~ s@//.*@@;
459062306a36Sopenharmony_ci		$opline =~ s@//.*@@;
459162306a36Sopenharmony_ci
459262306a36Sopenharmony_ci# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
459362306a36Sopenharmony_ci# the whole statement.
459462306a36Sopenharmony_ci#print "APW <$lines[$realline_next - 1]>\n";
459562306a36Sopenharmony_ci		if (defined $realline_next &&
459662306a36Sopenharmony_ci		    exists $lines[$realline_next - 1] &&
459762306a36Sopenharmony_ci		    !defined $suppress_export{$realline_next} &&
459862306a36Sopenharmony_ci		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
459962306a36Sopenharmony_ci			# Handle definitions which produce identifiers with
460062306a36Sopenharmony_ci			# a prefix:
460162306a36Sopenharmony_ci			#   XXX(foo);
460262306a36Sopenharmony_ci			#   EXPORT_SYMBOL(something_foo);
460362306a36Sopenharmony_ci			my $name = $1;
460462306a36Sopenharmony_ci			$name =~ s/^\s*($Ident).*/$1/;
460562306a36Sopenharmony_ci			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
460662306a36Sopenharmony_ci			    $name =~ /^${Ident}_$2/) {
460762306a36Sopenharmony_ci#print "FOO C name<$name>\n";
460862306a36Sopenharmony_ci				$suppress_export{$realline_next} = 1;
460962306a36Sopenharmony_ci
461062306a36Sopenharmony_ci			} elsif ($stat !~ /(?:
461162306a36Sopenharmony_ci				\n.}\s*$|
461262306a36Sopenharmony_ci				^.DEFINE_$Ident\(\Q$name\E\)|
461362306a36Sopenharmony_ci				^.DECLARE_$Ident\(\Q$name\E\)|
461462306a36Sopenharmony_ci				^.LIST_HEAD\(\Q$name\E\)|
461562306a36Sopenharmony_ci				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
461662306a36Sopenharmony_ci				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
461762306a36Sopenharmony_ci			    )/x) {
461862306a36Sopenharmony_ci#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
461962306a36Sopenharmony_ci				$suppress_export{$realline_next} = 2;
462062306a36Sopenharmony_ci			} else {
462162306a36Sopenharmony_ci				$suppress_export{$realline_next} = 1;
462262306a36Sopenharmony_ci			}
462362306a36Sopenharmony_ci		}
462462306a36Sopenharmony_ci		if (!defined $suppress_export{$linenr} &&
462562306a36Sopenharmony_ci		    $prevline =~ /^.\s*$/ &&
462662306a36Sopenharmony_ci		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
462762306a36Sopenharmony_ci#print "FOO B <$lines[$linenr - 1]>\n";
462862306a36Sopenharmony_ci			$suppress_export{$linenr} = 2;
462962306a36Sopenharmony_ci		}
463062306a36Sopenharmony_ci		if (defined $suppress_export{$linenr} &&
463162306a36Sopenharmony_ci		    $suppress_export{$linenr} == 2) {
463262306a36Sopenharmony_ci			WARN("EXPORT_SYMBOL",
463362306a36Sopenharmony_ci			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
463462306a36Sopenharmony_ci		}
463562306a36Sopenharmony_ci
463662306a36Sopenharmony_ci# check for global initialisers.
463762306a36Sopenharmony_ci		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
463862306a36Sopenharmony_ci		    !exclude_global_initialisers($realfile)) {
463962306a36Sopenharmony_ci			if (ERROR("GLOBAL_INITIALISERS",
464062306a36Sopenharmony_ci				  "do not initialise globals to $1\n" . $herecurr) &&
464162306a36Sopenharmony_ci			    $fix) {
464262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
464362306a36Sopenharmony_ci			}
464462306a36Sopenharmony_ci		}
464562306a36Sopenharmony_ci# check for static initialisers.
464662306a36Sopenharmony_ci		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
464762306a36Sopenharmony_ci			if (ERROR("INITIALISED_STATIC",
464862306a36Sopenharmony_ci				  "do not initialise statics to $1\n" .
464962306a36Sopenharmony_ci				      $herecurr) &&
465062306a36Sopenharmony_ci			    $fix) {
465162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
465262306a36Sopenharmony_ci			}
465362306a36Sopenharmony_ci		}
465462306a36Sopenharmony_ci
465562306a36Sopenharmony_ci# check for misordered declarations of char/short/int/long with signed/unsigned
465662306a36Sopenharmony_ci		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
465762306a36Sopenharmony_ci			my $tmp = trim($1);
465862306a36Sopenharmony_ci			WARN("MISORDERED_TYPE",
465962306a36Sopenharmony_ci			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
466062306a36Sopenharmony_ci		}
466162306a36Sopenharmony_ci
466262306a36Sopenharmony_ci# check for unnecessary <signed> int declarations of short/long/long long
466362306a36Sopenharmony_ci		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
466462306a36Sopenharmony_ci			my $type = trim($1);
466562306a36Sopenharmony_ci			next if ($type !~ /\bint\b/);
466662306a36Sopenharmony_ci			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
466762306a36Sopenharmony_ci			my $new_type = $type;
466862306a36Sopenharmony_ci			$new_type =~ s/\b\s*int\s*\b/ /;
466962306a36Sopenharmony_ci			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
467062306a36Sopenharmony_ci			$new_type =~ s/^const\s+//;
467162306a36Sopenharmony_ci			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
467262306a36Sopenharmony_ci			$new_type = "const $new_type" if ($type =~ /^const\b/);
467362306a36Sopenharmony_ci			$new_type =~ s/\s+/ /g;
467462306a36Sopenharmony_ci			$new_type = trim($new_type);
467562306a36Sopenharmony_ci			if (WARN("UNNECESSARY_INT",
467662306a36Sopenharmony_ci				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
467762306a36Sopenharmony_ci			    $fix) {
467862306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
467962306a36Sopenharmony_ci			}
468062306a36Sopenharmony_ci		}
468162306a36Sopenharmony_ci
468262306a36Sopenharmony_ci# check for static const char * arrays.
468362306a36Sopenharmony_ci		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
468462306a36Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
468562306a36Sopenharmony_ci			     "static const char * array should probably be static const char * const\n" .
468662306a36Sopenharmony_ci				$herecurr);
468762306a36Sopenharmony_ci		}
468862306a36Sopenharmony_ci
468962306a36Sopenharmony_ci# check for initialized const char arrays that should be static const
469062306a36Sopenharmony_ci		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
469162306a36Sopenharmony_ci			if (WARN("STATIC_CONST_CHAR_ARRAY",
469262306a36Sopenharmony_ci				 "const array should probably be static const\n" . $herecurr) &&
469362306a36Sopenharmony_ci			    $fix) {
469462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
469562306a36Sopenharmony_ci			}
469662306a36Sopenharmony_ci		}
469762306a36Sopenharmony_ci
469862306a36Sopenharmony_ci# check for static char foo[] = "bar" declarations.
469962306a36Sopenharmony_ci		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
470062306a36Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
470162306a36Sopenharmony_ci			     "static char array declaration should probably be static const char\n" .
470262306a36Sopenharmony_ci				$herecurr);
470362306a36Sopenharmony_ci		}
470462306a36Sopenharmony_ci
470562306a36Sopenharmony_ci# check for const <foo> const where <foo> is not a pointer or array type
470662306a36Sopenharmony_ci		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
470762306a36Sopenharmony_ci			my $found = $1;
470862306a36Sopenharmony_ci			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
470962306a36Sopenharmony_ci				WARN("CONST_CONST",
471062306a36Sopenharmony_ci				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
471162306a36Sopenharmony_ci			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
471262306a36Sopenharmony_ci				WARN("CONST_CONST",
471362306a36Sopenharmony_ci				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
471462306a36Sopenharmony_ci			}
471562306a36Sopenharmony_ci		}
471662306a36Sopenharmony_ci
471762306a36Sopenharmony_ci# check for const static or static <non ptr type> const declarations
471862306a36Sopenharmony_ci# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
471962306a36Sopenharmony_ci		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
472062306a36Sopenharmony_ci		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
472162306a36Sopenharmony_ci			if (WARN("STATIC_CONST",
472262306a36Sopenharmony_ci				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
472362306a36Sopenharmony_ci			    $fix) {
472462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
472562306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
472662306a36Sopenharmony_ci			}
472762306a36Sopenharmony_ci		}
472862306a36Sopenharmony_ci
472962306a36Sopenharmony_ci# check for non-global char *foo[] = {"bar", ...} declarations.
473062306a36Sopenharmony_ci		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
473162306a36Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
473262306a36Sopenharmony_ci			     "char * array declaration might be better as static const\n" .
473362306a36Sopenharmony_ci				$herecurr);
473462306a36Sopenharmony_ci		}
473562306a36Sopenharmony_ci
473662306a36Sopenharmony_ci# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
473762306a36Sopenharmony_ci		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
473862306a36Sopenharmony_ci			my $array = $1;
473962306a36Sopenharmony_ci			if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
474062306a36Sopenharmony_ci				my $array_div = $1;
474162306a36Sopenharmony_ci				if (WARN("ARRAY_SIZE",
474262306a36Sopenharmony_ci					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
474362306a36Sopenharmony_ci				    $fix) {
474462306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
474562306a36Sopenharmony_ci				}
474662306a36Sopenharmony_ci			}
474762306a36Sopenharmony_ci		}
474862306a36Sopenharmony_ci
474962306a36Sopenharmony_ci# check for function declarations without arguments like "int foo()"
475062306a36Sopenharmony_ci		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
475162306a36Sopenharmony_ci			if (ERROR("FUNCTION_WITHOUT_ARGS",
475262306a36Sopenharmony_ci				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
475362306a36Sopenharmony_ci			    $fix) {
475462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
475562306a36Sopenharmony_ci			}
475662306a36Sopenharmony_ci		}
475762306a36Sopenharmony_ci
475862306a36Sopenharmony_ci# check for new typedefs, only function parameters and sparse annotations
475962306a36Sopenharmony_ci# make sense.
476062306a36Sopenharmony_ci		if ($line =~ /\btypedef\s/ &&
476162306a36Sopenharmony_ci		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
476262306a36Sopenharmony_ci		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
476362306a36Sopenharmony_ci		    $line !~ /\b$typeTypedefs\b/ &&
476462306a36Sopenharmony_ci		    $line !~ /\b__bitwise\b/) {
476562306a36Sopenharmony_ci			WARN("NEW_TYPEDEFS",
476662306a36Sopenharmony_ci			     "do not add new typedefs\n" . $herecurr);
476762306a36Sopenharmony_ci		}
476862306a36Sopenharmony_ci
476962306a36Sopenharmony_ci# * goes on variable not on type
477062306a36Sopenharmony_ci		# (char*[ const])
477162306a36Sopenharmony_ci		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
477262306a36Sopenharmony_ci			#print "AA<$1>\n";
477362306a36Sopenharmony_ci			my ($ident, $from, $to) = ($1, $2, $2);
477462306a36Sopenharmony_ci
477562306a36Sopenharmony_ci			# Should start with a space.
477662306a36Sopenharmony_ci			$to =~ s/^(\S)/ $1/;
477762306a36Sopenharmony_ci			# Should not end with a space.
477862306a36Sopenharmony_ci			$to =~ s/\s+$//;
477962306a36Sopenharmony_ci			# '*'s should not have spaces between.
478062306a36Sopenharmony_ci			while ($to =~ s/\*\s+\*/\*\*/) {
478162306a36Sopenharmony_ci			}
478262306a36Sopenharmony_ci
478362306a36Sopenharmony_ci##			print "1: from<$from> to<$to> ident<$ident>\n";
478462306a36Sopenharmony_ci			if ($from ne $to) {
478562306a36Sopenharmony_ci				if (ERROR("POINTER_LOCATION",
478662306a36Sopenharmony_ci					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
478762306a36Sopenharmony_ci				    $fix) {
478862306a36Sopenharmony_ci					my $sub_from = $ident;
478962306a36Sopenharmony_ci					my $sub_to = $ident;
479062306a36Sopenharmony_ci					$sub_to =~ s/\Q$from\E/$to/;
479162306a36Sopenharmony_ci					$fixed[$fixlinenr] =~
479262306a36Sopenharmony_ci					    s@\Q$sub_from\E@$sub_to@;
479362306a36Sopenharmony_ci				}
479462306a36Sopenharmony_ci			}
479562306a36Sopenharmony_ci		}
479662306a36Sopenharmony_ci		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
479762306a36Sopenharmony_ci			#print "BB<$1>\n";
479862306a36Sopenharmony_ci			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
479962306a36Sopenharmony_ci
480062306a36Sopenharmony_ci			# Should start with a space.
480162306a36Sopenharmony_ci			$to =~ s/^(\S)/ $1/;
480262306a36Sopenharmony_ci			# Should not end with a space.
480362306a36Sopenharmony_ci			$to =~ s/\s+$//;
480462306a36Sopenharmony_ci			# '*'s should not have spaces between.
480562306a36Sopenharmony_ci			while ($to =~ s/\*\s+\*/\*\*/) {
480662306a36Sopenharmony_ci			}
480762306a36Sopenharmony_ci			# Modifiers should have spaces.
480862306a36Sopenharmony_ci			$to =~ s/(\b$Modifier$)/$1 /;
480962306a36Sopenharmony_ci
481062306a36Sopenharmony_ci##			print "2: from<$from> to<$to> ident<$ident>\n";
481162306a36Sopenharmony_ci			if ($from ne $to && $ident !~ /^$Modifier$/) {
481262306a36Sopenharmony_ci				if (ERROR("POINTER_LOCATION",
481362306a36Sopenharmony_ci					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
481462306a36Sopenharmony_ci				    $fix) {
481562306a36Sopenharmony_ci
481662306a36Sopenharmony_ci					my $sub_from = $match;
481762306a36Sopenharmony_ci					my $sub_to = $match;
481862306a36Sopenharmony_ci					$sub_to =~ s/\Q$from\E/$to/;
481962306a36Sopenharmony_ci					$fixed[$fixlinenr] =~
482062306a36Sopenharmony_ci					    s@\Q$sub_from\E@$sub_to@;
482162306a36Sopenharmony_ci				}
482262306a36Sopenharmony_ci			}
482362306a36Sopenharmony_ci		}
482462306a36Sopenharmony_ci
482562306a36Sopenharmony_ci# do not use BUG() or variants
482662306a36Sopenharmony_ci		if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) {
482762306a36Sopenharmony_ci			my $msg_level = \&WARN;
482862306a36Sopenharmony_ci			$msg_level = \&CHK if ($file);
482962306a36Sopenharmony_ci			&{$msg_level}("AVOID_BUG",
483062306a36Sopenharmony_ci				      "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);
483162306a36Sopenharmony_ci		}
483262306a36Sopenharmony_ci
483362306a36Sopenharmony_ci# avoid LINUX_VERSION_CODE
483462306a36Sopenharmony_ci		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
483562306a36Sopenharmony_ci			WARN("LINUX_VERSION_CODE",
483662306a36Sopenharmony_ci			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
483762306a36Sopenharmony_ci		}
483862306a36Sopenharmony_ci
483962306a36Sopenharmony_ci# check for uses of printk_ratelimit
484062306a36Sopenharmony_ci		if ($line =~ /\bprintk_ratelimit\s*\(/) {
484162306a36Sopenharmony_ci			WARN("PRINTK_RATELIMITED",
484262306a36Sopenharmony_ci			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
484362306a36Sopenharmony_ci		}
484462306a36Sopenharmony_ci
484562306a36Sopenharmony_ci# printk should use KERN_* levels
484662306a36Sopenharmony_ci		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
484762306a36Sopenharmony_ci			WARN("PRINTK_WITHOUT_KERN_LEVEL",
484862306a36Sopenharmony_ci			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
484962306a36Sopenharmony_ci		}
485062306a36Sopenharmony_ci
485162306a36Sopenharmony_ci# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
485262306a36Sopenharmony_ci		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
485362306a36Sopenharmony_ci			my $printk = $1;
485462306a36Sopenharmony_ci			my $modifier = $2;
485562306a36Sopenharmony_ci			my $orig = $3;
485662306a36Sopenharmony_ci			$modifier = "" if (!defined($modifier));
485762306a36Sopenharmony_ci			my $level = lc($orig);
485862306a36Sopenharmony_ci			$level = "warn" if ($level eq "warning");
485962306a36Sopenharmony_ci			my $level2 = $level;
486062306a36Sopenharmony_ci			$level2 = "dbg" if ($level eq "debug");
486162306a36Sopenharmony_ci			$level .= $modifier;
486262306a36Sopenharmony_ci			$level2 .= $modifier;
486362306a36Sopenharmony_ci			WARN("PREFER_PR_LEVEL",
486462306a36Sopenharmony_ci			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
486562306a36Sopenharmony_ci		}
486662306a36Sopenharmony_ci
486762306a36Sopenharmony_ci# prefer dev_<level> to dev_printk(KERN_<LEVEL>
486862306a36Sopenharmony_ci		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
486962306a36Sopenharmony_ci			my $orig = $1;
487062306a36Sopenharmony_ci			my $level = lc($orig);
487162306a36Sopenharmony_ci			$level = "warn" if ($level eq "warning");
487262306a36Sopenharmony_ci			$level = "dbg" if ($level eq "debug");
487362306a36Sopenharmony_ci			WARN("PREFER_DEV_LEVEL",
487462306a36Sopenharmony_ci			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
487562306a36Sopenharmony_ci		}
487662306a36Sopenharmony_ci
487762306a36Sopenharmony_ci# trace_printk should not be used in production code.
487862306a36Sopenharmony_ci		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
487962306a36Sopenharmony_ci			WARN("TRACE_PRINTK",
488062306a36Sopenharmony_ci			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
488162306a36Sopenharmony_ci		}
488262306a36Sopenharmony_ci
488362306a36Sopenharmony_ci# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
488462306a36Sopenharmony_ci# number of false positives, but assembly files are not checked, so at
488562306a36Sopenharmony_ci# least the arch entry code will not trigger this warning.
488662306a36Sopenharmony_ci		if ($line =~ /\bENOSYS\b/) {
488762306a36Sopenharmony_ci			WARN("ENOSYS",
488862306a36Sopenharmony_ci			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
488962306a36Sopenharmony_ci		}
489062306a36Sopenharmony_ci
489162306a36Sopenharmony_ci# ENOTSUPP is not a standard error code and should be avoided in new patches.
489262306a36Sopenharmony_ci# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
489362306a36Sopenharmony_ci# Similarly to ENOSYS warning a small number of false positives is expected.
489462306a36Sopenharmony_ci		if (!$file && $line =~ /\bENOTSUPP\b/) {
489562306a36Sopenharmony_ci			if (WARN("ENOTSUPP",
489662306a36Sopenharmony_ci				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
489762306a36Sopenharmony_ci			    $fix) {
489862306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
489962306a36Sopenharmony_ci			}
490062306a36Sopenharmony_ci		}
490162306a36Sopenharmony_ci
490262306a36Sopenharmony_ci# function brace can't be on same line, except for #defines of do while,
490362306a36Sopenharmony_ci# or if closed on same line
490462306a36Sopenharmony_ci		if ($perl_version_ok &&
490562306a36Sopenharmony_ci		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
490662306a36Sopenharmony_ci		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
490762306a36Sopenharmony_ci		    $sline !~ /}/) {
490862306a36Sopenharmony_ci			if (ERROR("OPEN_BRACE",
490962306a36Sopenharmony_ci				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
491062306a36Sopenharmony_ci			    $fix) {
491162306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
491262306a36Sopenharmony_ci				my $fixed_line = $rawline;
491362306a36Sopenharmony_ci				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
491462306a36Sopenharmony_ci				my $line1 = $1;
491562306a36Sopenharmony_ci				my $line2 = $2;
491662306a36Sopenharmony_ci				fix_insert_line($fixlinenr, ltrim($line1));
491762306a36Sopenharmony_ci				fix_insert_line($fixlinenr, "\+{");
491862306a36Sopenharmony_ci				if ($line2 !~ /^\s*$/) {
491962306a36Sopenharmony_ci					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
492062306a36Sopenharmony_ci				}
492162306a36Sopenharmony_ci			}
492262306a36Sopenharmony_ci		}
492362306a36Sopenharmony_ci
492462306a36Sopenharmony_ci# open braces for enum, union and struct go on the same line.
492562306a36Sopenharmony_ci		if ($line =~ /^.\s*{/ &&
492662306a36Sopenharmony_ci		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
492762306a36Sopenharmony_ci			if (ERROR("OPEN_BRACE",
492862306a36Sopenharmony_ci				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
492962306a36Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
493062306a36Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
493162306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
493262306a36Sopenharmony_ci				my $fixedline = rtrim($prevrawline) . " {";
493362306a36Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
493462306a36Sopenharmony_ci				$fixedline = $rawline;
493562306a36Sopenharmony_ci				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
493662306a36Sopenharmony_ci				if ($fixedline !~ /^\+\s*$/) {
493762306a36Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
493862306a36Sopenharmony_ci				}
493962306a36Sopenharmony_ci			}
494062306a36Sopenharmony_ci		}
494162306a36Sopenharmony_ci
494262306a36Sopenharmony_ci# missing space after union, struct or enum definition
494362306a36Sopenharmony_ci		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
494462306a36Sopenharmony_ci			if (WARN("SPACING",
494562306a36Sopenharmony_ci				 "missing space after $1 definition\n" . $herecurr) &&
494662306a36Sopenharmony_ci			    $fix) {
494762306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
494862306a36Sopenharmony_ci				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
494962306a36Sopenharmony_ci			}
495062306a36Sopenharmony_ci		}
495162306a36Sopenharmony_ci
495262306a36Sopenharmony_ci# Function pointer declarations
495362306a36Sopenharmony_ci# check spacing between type, funcptr, and args
495462306a36Sopenharmony_ci# canonical declaration is "type (*funcptr)(args...)"
495562306a36Sopenharmony_ci		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
495662306a36Sopenharmony_ci			my $declare = $1;
495762306a36Sopenharmony_ci			my $pre_pointer_space = $2;
495862306a36Sopenharmony_ci			my $post_pointer_space = $3;
495962306a36Sopenharmony_ci			my $funcname = $4;
496062306a36Sopenharmony_ci			my $post_funcname_space = $5;
496162306a36Sopenharmony_ci			my $pre_args_space = $6;
496262306a36Sopenharmony_ci
496362306a36Sopenharmony_ci# the $Declare variable will capture all spaces after the type
496462306a36Sopenharmony_ci# so check it for a missing trailing missing space but pointer return types
496562306a36Sopenharmony_ci# don't need a space so don't warn for those.
496662306a36Sopenharmony_ci			my $post_declare_space = "";
496762306a36Sopenharmony_ci			if ($declare =~ /(\s+)$/) {
496862306a36Sopenharmony_ci				$post_declare_space = $1;
496962306a36Sopenharmony_ci				$declare = rtrim($declare);
497062306a36Sopenharmony_ci			}
497162306a36Sopenharmony_ci			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
497262306a36Sopenharmony_ci				WARN("SPACING",
497362306a36Sopenharmony_ci				     "missing space after return type\n" . $herecurr);
497462306a36Sopenharmony_ci				$post_declare_space = " ";
497562306a36Sopenharmony_ci			}
497662306a36Sopenharmony_ci
497762306a36Sopenharmony_ci# unnecessary space "type  (*funcptr)(args...)"
497862306a36Sopenharmony_ci# This test is not currently implemented because these declarations are
497962306a36Sopenharmony_ci# equivalent to
498062306a36Sopenharmony_ci#	int  foo(int bar, ...)
498162306a36Sopenharmony_ci# and this is form shouldn't/doesn't generate a checkpatch warning.
498262306a36Sopenharmony_ci#
498362306a36Sopenharmony_ci#			elsif ($declare =~ /\s{2,}$/) {
498462306a36Sopenharmony_ci#				WARN("SPACING",
498562306a36Sopenharmony_ci#				     "Multiple spaces after return type\n" . $herecurr);
498662306a36Sopenharmony_ci#			}
498762306a36Sopenharmony_ci
498862306a36Sopenharmony_ci# unnecessary space "type ( *funcptr)(args...)"
498962306a36Sopenharmony_ci			if (defined $pre_pointer_space &&
499062306a36Sopenharmony_ci			    $pre_pointer_space =~ /^\s/) {
499162306a36Sopenharmony_ci				WARN("SPACING",
499262306a36Sopenharmony_ci				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
499362306a36Sopenharmony_ci			}
499462306a36Sopenharmony_ci
499562306a36Sopenharmony_ci# unnecessary space "type (* funcptr)(args...)"
499662306a36Sopenharmony_ci			if (defined $post_pointer_space &&
499762306a36Sopenharmony_ci			    $post_pointer_space =~ /^\s/) {
499862306a36Sopenharmony_ci				WARN("SPACING",
499962306a36Sopenharmony_ci				     "Unnecessary space before function pointer name\n" . $herecurr);
500062306a36Sopenharmony_ci			}
500162306a36Sopenharmony_ci
500262306a36Sopenharmony_ci# unnecessary space "type (*funcptr )(args...)"
500362306a36Sopenharmony_ci			if (defined $post_funcname_space &&
500462306a36Sopenharmony_ci			    $post_funcname_space =~ /^\s/) {
500562306a36Sopenharmony_ci				WARN("SPACING",
500662306a36Sopenharmony_ci				     "Unnecessary space after function pointer name\n" . $herecurr);
500762306a36Sopenharmony_ci			}
500862306a36Sopenharmony_ci
500962306a36Sopenharmony_ci# unnecessary space "type (*funcptr) (args...)"
501062306a36Sopenharmony_ci			if (defined $pre_args_space &&
501162306a36Sopenharmony_ci			    $pre_args_space =~ /^\s/) {
501262306a36Sopenharmony_ci				WARN("SPACING",
501362306a36Sopenharmony_ci				     "Unnecessary space before function pointer arguments\n" . $herecurr);
501462306a36Sopenharmony_ci			}
501562306a36Sopenharmony_ci
501662306a36Sopenharmony_ci			if (show_type("SPACING") && $fix) {
501762306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
501862306a36Sopenharmony_ci				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
501962306a36Sopenharmony_ci			}
502062306a36Sopenharmony_ci		}
502162306a36Sopenharmony_ci
502262306a36Sopenharmony_ci# check for spacing round square brackets; allowed:
502362306a36Sopenharmony_ci#  1. with a type on the left -- int [] a;
502462306a36Sopenharmony_ci#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
502562306a36Sopenharmony_ci#  3. inside a curly brace -- = { [0...10] = 5 }
502662306a36Sopenharmony_ci		while ($line =~ /(.*?\s)\[/g) {
502762306a36Sopenharmony_ci			my ($where, $prefix) = ($-[1], $1);
502862306a36Sopenharmony_ci			if ($prefix !~ /$Type\s+$/ &&
502962306a36Sopenharmony_ci			    ($where != 0 || $prefix !~ /^.\s+$/) &&
503062306a36Sopenharmony_ci			    $prefix !~ /[{,:]\s+$/) {
503162306a36Sopenharmony_ci				if (ERROR("BRACKET_SPACE",
503262306a36Sopenharmony_ci					  "space prohibited before open square bracket '['\n" . $herecurr) &&
503362306a36Sopenharmony_ci				    $fix) {
503462306a36Sopenharmony_ci				    $fixed[$fixlinenr] =~
503562306a36Sopenharmony_ci					s/^(\+.*?)\s+\[/$1\[/;
503662306a36Sopenharmony_ci				}
503762306a36Sopenharmony_ci			}
503862306a36Sopenharmony_ci		}
503962306a36Sopenharmony_ci
504062306a36Sopenharmony_ci# check for spaces between functions and their parentheses.
504162306a36Sopenharmony_ci		while ($line =~ /($Ident)\s+\(/g) {
504262306a36Sopenharmony_ci			my $name = $1;
504362306a36Sopenharmony_ci			my $ctx_before = substr($line, 0, $-[1]);
504462306a36Sopenharmony_ci			my $ctx = "$ctx_before$name";
504562306a36Sopenharmony_ci
504662306a36Sopenharmony_ci			# Ignore those directives where spaces _are_ permitted.
504762306a36Sopenharmony_ci			if ($name =~ /^(?:
504862306a36Sopenharmony_ci				if|for|while|switch|return|case|
504962306a36Sopenharmony_ci				volatile|__volatile__|
505062306a36Sopenharmony_ci				__attribute__|format|__extension__|
505162306a36Sopenharmony_ci				asm|__asm__|scoped_guard)$/x)
505262306a36Sopenharmony_ci			{
505362306a36Sopenharmony_ci			# cpp #define statements have non-optional spaces, ie
505462306a36Sopenharmony_ci			# if there is a space between the name and the open
505562306a36Sopenharmony_ci			# parenthesis it is simply not a parameter group.
505662306a36Sopenharmony_ci			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
505762306a36Sopenharmony_ci
505862306a36Sopenharmony_ci			# cpp #elif statement condition may start with a (
505962306a36Sopenharmony_ci			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
506062306a36Sopenharmony_ci
506162306a36Sopenharmony_ci			# If this whole things ends with a type its most
506262306a36Sopenharmony_ci			# likely a typedef for a function.
506362306a36Sopenharmony_ci			} elsif ($ctx =~ /$Type$/) {
506462306a36Sopenharmony_ci
506562306a36Sopenharmony_ci			} else {
506662306a36Sopenharmony_ci				if (WARN("SPACING",
506762306a36Sopenharmony_ci					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
506862306a36Sopenharmony_ci					     $fix) {
506962306a36Sopenharmony_ci					$fixed[$fixlinenr] =~
507062306a36Sopenharmony_ci					    s/\b$name\s+\(/$name\(/;
507162306a36Sopenharmony_ci				}
507262306a36Sopenharmony_ci			}
507362306a36Sopenharmony_ci		}
507462306a36Sopenharmony_ci
507562306a36Sopenharmony_ci# Check operator spacing.
507662306a36Sopenharmony_ci		if (!($line=~/\#\s*include/)) {
507762306a36Sopenharmony_ci			my $fixed_line = "";
507862306a36Sopenharmony_ci			my $line_fixed = 0;
507962306a36Sopenharmony_ci
508062306a36Sopenharmony_ci			my $ops = qr{
508162306a36Sopenharmony_ci				<<=|>>=|<=|>=|==|!=|
508262306a36Sopenharmony_ci				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
508362306a36Sopenharmony_ci				=>|->|<<|>>|<|>|=|!|~|
508462306a36Sopenharmony_ci				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
508562306a36Sopenharmony_ci				\?:|\?|:
508662306a36Sopenharmony_ci			}x;
508762306a36Sopenharmony_ci			my @elements = split(/($ops|;)/, $opline);
508862306a36Sopenharmony_ci
508962306a36Sopenharmony_ci##			print("element count: <" . $#elements . ">\n");
509062306a36Sopenharmony_ci##			foreach my $el (@elements) {
509162306a36Sopenharmony_ci##				print("el: <$el>\n");
509262306a36Sopenharmony_ci##			}
509362306a36Sopenharmony_ci
509462306a36Sopenharmony_ci			my @fix_elements = ();
509562306a36Sopenharmony_ci			my $off = 0;
509662306a36Sopenharmony_ci
509762306a36Sopenharmony_ci			foreach my $el (@elements) {
509862306a36Sopenharmony_ci				push(@fix_elements, substr($rawline, $off, length($el)));
509962306a36Sopenharmony_ci				$off += length($el);
510062306a36Sopenharmony_ci			}
510162306a36Sopenharmony_ci
510262306a36Sopenharmony_ci			$off = 0;
510362306a36Sopenharmony_ci
510462306a36Sopenharmony_ci			my $blank = copy_spacing($opline);
510562306a36Sopenharmony_ci			my $last_after = -1;
510662306a36Sopenharmony_ci
510762306a36Sopenharmony_ci			for (my $n = 0; $n < $#elements; $n += 2) {
510862306a36Sopenharmony_ci
510962306a36Sopenharmony_ci				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
511062306a36Sopenharmony_ci
511162306a36Sopenharmony_ci##				print("n: <$n> good: <$good>\n");
511262306a36Sopenharmony_ci
511362306a36Sopenharmony_ci				$off += length($elements[$n]);
511462306a36Sopenharmony_ci
511562306a36Sopenharmony_ci				# Pick up the preceding and succeeding characters.
511662306a36Sopenharmony_ci				my $ca = substr($opline, 0, $off);
511762306a36Sopenharmony_ci				my $cc = '';
511862306a36Sopenharmony_ci				if (length($opline) >= ($off + length($elements[$n + 1]))) {
511962306a36Sopenharmony_ci					$cc = substr($opline, $off + length($elements[$n + 1]));
512062306a36Sopenharmony_ci				}
512162306a36Sopenharmony_ci				my $cb = "$ca$;$cc";
512262306a36Sopenharmony_ci
512362306a36Sopenharmony_ci				my $a = '';
512462306a36Sopenharmony_ci				$a = 'V' if ($elements[$n] ne '');
512562306a36Sopenharmony_ci				$a = 'W' if ($elements[$n] =~ /\s$/);
512662306a36Sopenharmony_ci				$a = 'C' if ($elements[$n] =~ /$;$/);
512762306a36Sopenharmony_ci				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
512862306a36Sopenharmony_ci				$a = 'O' if ($elements[$n] eq '');
512962306a36Sopenharmony_ci				$a = 'E' if ($ca =~ /^\s*$/);
513062306a36Sopenharmony_ci
513162306a36Sopenharmony_ci				my $op = $elements[$n + 1];
513262306a36Sopenharmony_ci
513362306a36Sopenharmony_ci				my $c = '';
513462306a36Sopenharmony_ci				if (defined $elements[$n + 2]) {
513562306a36Sopenharmony_ci					$c = 'V' if ($elements[$n + 2] ne '');
513662306a36Sopenharmony_ci					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
513762306a36Sopenharmony_ci					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
513862306a36Sopenharmony_ci					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
513962306a36Sopenharmony_ci					$c = 'O' if ($elements[$n + 2] eq '');
514062306a36Sopenharmony_ci					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
514162306a36Sopenharmony_ci				} else {
514262306a36Sopenharmony_ci					$c = 'E';
514362306a36Sopenharmony_ci				}
514462306a36Sopenharmony_ci
514562306a36Sopenharmony_ci				my $ctx = "${a}x${c}";
514662306a36Sopenharmony_ci
514762306a36Sopenharmony_ci				my $at = "(ctx:$ctx)";
514862306a36Sopenharmony_ci
514962306a36Sopenharmony_ci				my $ptr = substr($blank, 0, $off) . "^";
515062306a36Sopenharmony_ci				my $hereptr = "$hereline$ptr\n";
515162306a36Sopenharmony_ci
515262306a36Sopenharmony_ci				# Pull out the value of this operator.
515362306a36Sopenharmony_ci				my $op_type = substr($curr_values, $off + 1, 1);
515462306a36Sopenharmony_ci
515562306a36Sopenharmony_ci				# Get the full operator variant.
515662306a36Sopenharmony_ci				my $opv = $op . substr($curr_vars, $off, 1);
515762306a36Sopenharmony_ci
515862306a36Sopenharmony_ci				# Ignore operators passed as parameters.
515962306a36Sopenharmony_ci				if ($op_type ne 'V' &&
516062306a36Sopenharmony_ci				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
516162306a36Sopenharmony_ci
516262306a36Sopenharmony_ci#				# Ignore comments
516362306a36Sopenharmony_ci#				} elsif ($op =~ /^$;+$/) {
516462306a36Sopenharmony_ci
516562306a36Sopenharmony_ci				# ; should have either the end of line or a space or \ after it
516662306a36Sopenharmony_ci				} elsif ($op eq ';') {
516762306a36Sopenharmony_ci					if ($ctx !~ /.x[WEBC]/ &&
516862306a36Sopenharmony_ci					    $cc !~ /^\\/ && $cc !~ /^;/) {
516962306a36Sopenharmony_ci						if (ERROR("SPACING",
517062306a36Sopenharmony_ci							  "space required after that '$op' $at\n" . $hereptr)) {
517162306a36Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
517262306a36Sopenharmony_ci							$line_fixed = 1;
517362306a36Sopenharmony_ci						}
517462306a36Sopenharmony_ci					}
517562306a36Sopenharmony_ci
517662306a36Sopenharmony_ci				# // is a comment
517762306a36Sopenharmony_ci				} elsif ($op eq '//') {
517862306a36Sopenharmony_ci
517962306a36Sopenharmony_ci				#   :   when part of a bitfield
518062306a36Sopenharmony_ci				} elsif ($opv eq ':B') {
518162306a36Sopenharmony_ci					# skip the bitfield test for now
518262306a36Sopenharmony_ci
518362306a36Sopenharmony_ci				# No spaces for:
518462306a36Sopenharmony_ci				#   ->
518562306a36Sopenharmony_ci				} elsif ($op eq '->') {
518662306a36Sopenharmony_ci					if ($ctx =~ /Wx.|.xW/) {
518762306a36Sopenharmony_ci						if (ERROR("SPACING",
518862306a36Sopenharmony_ci							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
518962306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
519062306a36Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
519162306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
519262306a36Sopenharmony_ci							}
519362306a36Sopenharmony_ci							$line_fixed = 1;
519462306a36Sopenharmony_ci						}
519562306a36Sopenharmony_ci					}
519662306a36Sopenharmony_ci
519762306a36Sopenharmony_ci				# , must not have a space before and must have a space on the right.
519862306a36Sopenharmony_ci				} elsif ($op eq ',') {
519962306a36Sopenharmony_ci					my $rtrim_before = 0;
520062306a36Sopenharmony_ci					my $space_after = 0;
520162306a36Sopenharmony_ci					if ($ctx =~ /Wx./) {
520262306a36Sopenharmony_ci						if (ERROR("SPACING",
520362306a36Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
520462306a36Sopenharmony_ci							$line_fixed = 1;
520562306a36Sopenharmony_ci							$rtrim_before = 1;
520662306a36Sopenharmony_ci						}
520762306a36Sopenharmony_ci					}
520862306a36Sopenharmony_ci					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
520962306a36Sopenharmony_ci						if (ERROR("SPACING",
521062306a36Sopenharmony_ci							  "space required after that '$op' $at\n" . $hereptr)) {
521162306a36Sopenharmony_ci							$line_fixed = 1;
521262306a36Sopenharmony_ci							$last_after = $n;
521362306a36Sopenharmony_ci							$space_after = 1;
521462306a36Sopenharmony_ci						}
521562306a36Sopenharmony_ci					}
521662306a36Sopenharmony_ci					if ($rtrim_before || $space_after) {
521762306a36Sopenharmony_ci						if ($rtrim_before) {
521862306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
521962306a36Sopenharmony_ci						} else {
522062306a36Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
522162306a36Sopenharmony_ci						}
522262306a36Sopenharmony_ci						if ($space_after) {
522362306a36Sopenharmony_ci							$good .= " ";
522462306a36Sopenharmony_ci						}
522562306a36Sopenharmony_ci					}
522662306a36Sopenharmony_ci
522762306a36Sopenharmony_ci				# '*' as part of a type definition -- reported already.
522862306a36Sopenharmony_ci				} elsif ($opv eq '*_') {
522962306a36Sopenharmony_ci					#warn "'*' is part of type\n";
523062306a36Sopenharmony_ci
523162306a36Sopenharmony_ci				# unary operators should have a space before and
523262306a36Sopenharmony_ci				# none after.  May be left adjacent to another
523362306a36Sopenharmony_ci				# unary operator, or a cast
523462306a36Sopenharmony_ci				} elsif ($op eq '!' || $op eq '~' ||
523562306a36Sopenharmony_ci					 $opv eq '*U' || $opv eq '-U' ||
523662306a36Sopenharmony_ci					 $opv eq '&U' || $opv eq '&&U') {
523762306a36Sopenharmony_ci					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
523862306a36Sopenharmony_ci						if (ERROR("SPACING",
523962306a36Sopenharmony_ci							  "space required before that '$op' $at\n" . $hereptr)) {
524062306a36Sopenharmony_ci							if ($n != $last_after + 2) {
524162306a36Sopenharmony_ci								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
524262306a36Sopenharmony_ci								$line_fixed = 1;
524362306a36Sopenharmony_ci							}
524462306a36Sopenharmony_ci						}
524562306a36Sopenharmony_ci					}
524662306a36Sopenharmony_ci					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
524762306a36Sopenharmony_ci						# A unary '*' may be const
524862306a36Sopenharmony_ci
524962306a36Sopenharmony_ci					} elsif ($ctx =~ /.xW/) {
525062306a36Sopenharmony_ci						if (ERROR("SPACING",
525162306a36Sopenharmony_ci							  "space prohibited after that '$op' $at\n" . $hereptr)) {
525262306a36Sopenharmony_ci							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
525362306a36Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
525462306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
525562306a36Sopenharmony_ci							}
525662306a36Sopenharmony_ci							$line_fixed = 1;
525762306a36Sopenharmony_ci						}
525862306a36Sopenharmony_ci					}
525962306a36Sopenharmony_ci
526062306a36Sopenharmony_ci				# unary ++ and unary -- are allowed no space on one side.
526162306a36Sopenharmony_ci				} elsif ($op eq '++' or $op eq '--') {
526262306a36Sopenharmony_ci					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
526362306a36Sopenharmony_ci						if (ERROR("SPACING",
526462306a36Sopenharmony_ci							  "space required one side of that '$op' $at\n" . $hereptr)) {
526562306a36Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
526662306a36Sopenharmony_ci							$line_fixed = 1;
526762306a36Sopenharmony_ci						}
526862306a36Sopenharmony_ci					}
526962306a36Sopenharmony_ci					if ($ctx =~ /Wx[BE]/ ||
527062306a36Sopenharmony_ci					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
527162306a36Sopenharmony_ci						if (ERROR("SPACING",
527262306a36Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
527362306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
527462306a36Sopenharmony_ci							$line_fixed = 1;
527562306a36Sopenharmony_ci						}
527662306a36Sopenharmony_ci					}
527762306a36Sopenharmony_ci					if ($ctx =~ /ExW/) {
527862306a36Sopenharmony_ci						if (ERROR("SPACING",
527962306a36Sopenharmony_ci							  "space prohibited after that '$op' $at\n" . $hereptr)) {
528062306a36Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
528162306a36Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
528262306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
528362306a36Sopenharmony_ci							}
528462306a36Sopenharmony_ci							$line_fixed = 1;
528562306a36Sopenharmony_ci						}
528662306a36Sopenharmony_ci					}
528762306a36Sopenharmony_ci
528862306a36Sopenharmony_ci				# << and >> may either have or not have spaces both sides
528962306a36Sopenharmony_ci				} elsif ($op eq '<<' or $op eq '>>' or
529062306a36Sopenharmony_ci					 $op eq '&' or $op eq '^' or $op eq '|' or
529162306a36Sopenharmony_ci					 $op eq '+' or $op eq '-' or
529262306a36Sopenharmony_ci					 $op eq '*' or $op eq '/' or
529362306a36Sopenharmony_ci					 $op eq '%')
529462306a36Sopenharmony_ci				{
529562306a36Sopenharmony_ci					if ($check) {
529662306a36Sopenharmony_ci						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
529762306a36Sopenharmony_ci							if (CHK("SPACING",
529862306a36Sopenharmony_ci								"spaces preferred around that '$op' $at\n" . $hereptr)) {
529962306a36Sopenharmony_ci								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
530062306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
530162306a36Sopenharmony_ci								$line_fixed = 1;
530262306a36Sopenharmony_ci							}
530362306a36Sopenharmony_ci						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
530462306a36Sopenharmony_ci							if (CHK("SPACING",
530562306a36Sopenharmony_ci								"space preferred before that '$op' $at\n" . $hereptr)) {
530662306a36Sopenharmony_ci								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
530762306a36Sopenharmony_ci								$line_fixed = 1;
530862306a36Sopenharmony_ci							}
530962306a36Sopenharmony_ci						}
531062306a36Sopenharmony_ci					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
531162306a36Sopenharmony_ci						if (ERROR("SPACING",
531262306a36Sopenharmony_ci							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
531362306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
531462306a36Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
531562306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
531662306a36Sopenharmony_ci							}
531762306a36Sopenharmony_ci							$line_fixed = 1;
531862306a36Sopenharmony_ci						}
531962306a36Sopenharmony_ci					}
532062306a36Sopenharmony_ci
532162306a36Sopenharmony_ci				# A colon needs no spaces before when it is
532262306a36Sopenharmony_ci				# terminating a case value or a label.
532362306a36Sopenharmony_ci				} elsif ($opv eq ':C' || $opv eq ':L') {
532462306a36Sopenharmony_ci					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
532562306a36Sopenharmony_ci						if (ERROR("SPACING",
532662306a36Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
532762306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
532862306a36Sopenharmony_ci							$line_fixed = 1;
532962306a36Sopenharmony_ci						}
533062306a36Sopenharmony_ci					}
533162306a36Sopenharmony_ci
533262306a36Sopenharmony_ci				# All the others need spaces both sides.
533362306a36Sopenharmony_ci				} elsif ($ctx !~ /[EWC]x[CWE]/) {
533462306a36Sopenharmony_ci					my $ok = 0;
533562306a36Sopenharmony_ci
533662306a36Sopenharmony_ci					# Ignore email addresses <foo@bar>
533762306a36Sopenharmony_ci					if (($op eq '<' &&
533862306a36Sopenharmony_ci					     $cc =~ /^\S+\@\S+>/) ||
533962306a36Sopenharmony_ci					    ($op eq '>' &&
534062306a36Sopenharmony_ci					     $ca =~ /<\S+\@\S+$/))
534162306a36Sopenharmony_ci					{
534262306a36Sopenharmony_ci						$ok = 1;
534362306a36Sopenharmony_ci					}
534462306a36Sopenharmony_ci
534562306a36Sopenharmony_ci					# for asm volatile statements
534662306a36Sopenharmony_ci					# ignore a colon with another
534762306a36Sopenharmony_ci					# colon immediately before or after
534862306a36Sopenharmony_ci					if (($op eq ':') &&
534962306a36Sopenharmony_ci					    ($ca =~ /:$/ || $cc =~ /^:/)) {
535062306a36Sopenharmony_ci						$ok = 1;
535162306a36Sopenharmony_ci					}
535262306a36Sopenharmony_ci
535362306a36Sopenharmony_ci					# messages are ERROR, but ?: are CHK
535462306a36Sopenharmony_ci					if ($ok == 0) {
535562306a36Sopenharmony_ci						my $msg_level = \&ERROR;
535662306a36Sopenharmony_ci						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
535762306a36Sopenharmony_ci
535862306a36Sopenharmony_ci						if (&{$msg_level}("SPACING",
535962306a36Sopenharmony_ci								  "spaces required around that '$op' $at\n" . $hereptr)) {
536062306a36Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
536162306a36Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
536262306a36Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
536362306a36Sopenharmony_ci							}
536462306a36Sopenharmony_ci							$line_fixed = 1;
536562306a36Sopenharmony_ci						}
536662306a36Sopenharmony_ci					}
536762306a36Sopenharmony_ci				}
536862306a36Sopenharmony_ci				$off += length($elements[$n + 1]);
536962306a36Sopenharmony_ci
537062306a36Sopenharmony_ci##				print("n: <$n> GOOD: <$good>\n");
537162306a36Sopenharmony_ci
537262306a36Sopenharmony_ci				$fixed_line = $fixed_line . $good;
537362306a36Sopenharmony_ci			}
537462306a36Sopenharmony_ci
537562306a36Sopenharmony_ci			if (($#elements % 2) == 0) {
537662306a36Sopenharmony_ci				$fixed_line = $fixed_line . $fix_elements[$#elements];
537762306a36Sopenharmony_ci			}
537862306a36Sopenharmony_ci
537962306a36Sopenharmony_ci			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
538062306a36Sopenharmony_ci				$fixed[$fixlinenr] = $fixed_line;
538162306a36Sopenharmony_ci			}
538262306a36Sopenharmony_ci
538362306a36Sopenharmony_ci
538462306a36Sopenharmony_ci		}
538562306a36Sopenharmony_ci
538662306a36Sopenharmony_ci# check for whitespace before a non-naked semicolon
538762306a36Sopenharmony_ci		if ($line =~ /^\+.*\S\s+;\s*$/) {
538862306a36Sopenharmony_ci			if (WARN("SPACING",
538962306a36Sopenharmony_ci				 "space prohibited before semicolon\n" . $herecurr) &&
539062306a36Sopenharmony_ci			    $fix) {
539162306a36Sopenharmony_ci				1 while $fixed[$fixlinenr] =~
539262306a36Sopenharmony_ci				    s/^(\+.*\S)\s+;/$1;/;
539362306a36Sopenharmony_ci			}
539462306a36Sopenharmony_ci		}
539562306a36Sopenharmony_ci
539662306a36Sopenharmony_ci# check for multiple assignments
539762306a36Sopenharmony_ci		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
539862306a36Sopenharmony_ci			CHK("MULTIPLE_ASSIGNMENTS",
539962306a36Sopenharmony_ci			    "multiple assignments should be avoided\n" . $herecurr);
540062306a36Sopenharmony_ci		}
540162306a36Sopenharmony_ci
540262306a36Sopenharmony_ci## # check for multiple declarations, allowing for a function declaration
540362306a36Sopenharmony_ci## # continuation.
540462306a36Sopenharmony_ci## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
540562306a36Sopenharmony_ci## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
540662306a36Sopenharmony_ci##
540762306a36Sopenharmony_ci## 			# Remove any bracketed sections to ensure we do not
540862306a36Sopenharmony_ci## 			# falsely report the parameters of functions.
540962306a36Sopenharmony_ci## 			my $ln = $line;
541062306a36Sopenharmony_ci## 			while ($ln =~ s/\([^\(\)]*\)//g) {
541162306a36Sopenharmony_ci## 			}
541262306a36Sopenharmony_ci## 			if ($ln =~ /,/) {
541362306a36Sopenharmony_ci## 				WARN("MULTIPLE_DECLARATION",
541462306a36Sopenharmony_ci##				     "declaring multiple variables together should be avoided\n" . $herecurr);
541562306a36Sopenharmony_ci## 			}
541662306a36Sopenharmony_ci## 		}
541762306a36Sopenharmony_ci
541862306a36Sopenharmony_ci#need space before brace following if, while, etc
541962306a36Sopenharmony_ci		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
542062306a36Sopenharmony_ci		    $line =~ /\b(?:else|do)\{/) {
542162306a36Sopenharmony_ci			if (ERROR("SPACING",
542262306a36Sopenharmony_ci				  "space required before the open brace '{'\n" . $herecurr) &&
542362306a36Sopenharmony_ci			    $fix) {
542462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
542562306a36Sopenharmony_ci			}
542662306a36Sopenharmony_ci		}
542762306a36Sopenharmony_ci
542862306a36Sopenharmony_ci## # check for blank lines before declarations
542962306a36Sopenharmony_ci##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
543062306a36Sopenharmony_ci##		    $prevrawline =~ /^.\s*$/) {
543162306a36Sopenharmony_ci##			WARN("SPACING",
543262306a36Sopenharmony_ci##			     "No blank lines before declarations\n" . $hereprev);
543362306a36Sopenharmony_ci##		}
543462306a36Sopenharmony_ci##
543562306a36Sopenharmony_ci
543662306a36Sopenharmony_ci# closing brace should have a space following it when it has anything
543762306a36Sopenharmony_ci# on the line
543862306a36Sopenharmony_ci		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
543962306a36Sopenharmony_ci			if (ERROR("SPACING",
544062306a36Sopenharmony_ci				  "space required after that close brace '}'\n" . $herecurr) &&
544162306a36Sopenharmony_ci			    $fix) {
544262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
544362306a36Sopenharmony_ci				    s/}((?!(?:,|;|\)))\S)/} $1/;
544462306a36Sopenharmony_ci			}
544562306a36Sopenharmony_ci		}
544662306a36Sopenharmony_ci
544762306a36Sopenharmony_ci# check spacing on square brackets
544862306a36Sopenharmony_ci		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
544962306a36Sopenharmony_ci			if (ERROR("SPACING",
545062306a36Sopenharmony_ci				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
545162306a36Sopenharmony_ci			    $fix) {
545262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
545362306a36Sopenharmony_ci				    s/\[\s+/\[/;
545462306a36Sopenharmony_ci			}
545562306a36Sopenharmony_ci		}
545662306a36Sopenharmony_ci		if ($line =~ /\s\]/) {
545762306a36Sopenharmony_ci			if (ERROR("SPACING",
545862306a36Sopenharmony_ci				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
545962306a36Sopenharmony_ci			    $fix) {
546062306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
546162306a36Sopenharmony_ci				    s/\s+\]/\]/;
546262306a36Sopenharmony_ci			}
546362306a36Sopenharmony_ci		}
546462306a36Sopenharmony_ci
546562306a36Sopenharmony_ci# check spacing on parentheses
546662306a36Sopenharmony_ci		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
546762306a36Sopenharmony_ci		    $line !~ /for\s*\(\s+;/) {
546862306a36Sopenharmony_ci			if (ERROR("SPACING",
546962306a36Sopenharmony_ci				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
547062306a36Sopenharmony_ci			    $fix) {
547162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
547262306a36Sopenharmony_ci				    s/\(\s+/\(/;
547362306a36Sopenharmony_ci			}
547462306a36Sopenharmony_ci		}
547562306a36Sopenharmony_ci		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
547662306a36Sopenharmony_ci		    $line !~ /for\s*\(.*;\s+\)/ &&
547762306a36Sopenharmony_ci		    $line !~ /:\s+\)/) {
547862306a36Sopenharmony_ci			if (ERROR("SPACING",
547962306a36Sopenharmony_ci				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
548062306a36Sopenharmony_ci			    $fix) {
548162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
548262306a36Sopenharmony_ci				    s/\s+\)/\)/;
548362306a36Sopenharmony_ci			}
548462306a36Sopenharmony_ci		}
548562306a36Sopenharmony_ci
548662306a36Sopenharmony_ci# check unnecessary parentheses around addressof/dereference single $Lvals
548762306a36Sopenharmony_ci# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
548862306a36Sopenharmony_ci
548962306a36Sopenharmony_ci		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
549062306a36Sopenharmony_ci			my $var = $1;
549162306a36Sopenharmony_ci			if (CHK("UNNECESSARY_PARENTHESES",
549262306a36Sopenharmony_ci				"Unnecessary parentheses around $var\n" . $herecurr) &&
549362306a36Sopenharmony_ci			    $fix) {
549462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
549562306a36Sopenharmony_ci			}
549662306a36Sopenharmony_ci		}
549762306a36Sopenharmony_ci
549862306a36Sopenharmony_ci# check for unnecessary parentheses around function pointer uses
549962306a36Sopenharmony_ci# ie: (foo->bar)(); should be foo->bar();
550062306a36Sopenharmony_ci# but not "if (foo->bar) (" to avoid some false positives
550162306a36Sopenharmony_ci		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
550262306a36Sopenharmony_ci			my $var = $2;
550362306a36Sopenharmony_ci			if (CHK("UNNECESSARY_PARENTHESES",
550462306a36Sopenharmony_ci				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
550562306a36Sopenharmony_ci			    $fix) {
550662306a36Sopenharmony_ci				my $var2 = deparenthesize($var);
550762306a36Sopenharmony_ci				$var2 =~ s/\s//g;
550862306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
550962306a36Sopenharmony_ci			}
551062306a36Sopenharmony_ci		}
551162306a36Sopenharmony_ci
551262306a36Sopenharmony_ci# check for unnecessary parentheses around comparisons in if uses
551362306a36Sopenharmony_ci# when !drivers/staging or command-line uses --strict
551462306a36Sopenharmony_ci		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
551562306a36Sopenharmony_ci		    $perl_version_ok && defined($stat) &&
551662306a36Sopenharmony_ci		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
551762306a36Sopenharmony_ci			my $if_stat = $1;
551862306a36Sopenharmony_ci			my $test = substr($2, 1, -1);
551962306a36Sopenharmony_ci			my $herectx;
552062306a36Sopenharmony_ci			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
552162306a36Sopenharmony_ci				my $match = $1;
552262306a36Sopenharmony_ci				# avoid parentheses around potential macro args
552362306a36Sopenharmony_ci				next if ($match =~ /^\s*\w+\s*$/);
552462306a36Sopenharmony_ci				if (!defined($herectx)) {
552562306a36Sopenharmony_ci					$herectx = $here . "\n";
552662306a36Sopenharmony_ci					my $cnt = statement_rawlines($if_stat);
552762306a36Sopenharmony_ci					for (my $n = 0; $n < $cnt; $n++) {
552862306a36Sopenharmony_ci						my $rl = raw_line($linenr, $n);
552962306a36Sopenharmony_ci						$herectx .=  $rl . "\n";
553062306a36Sopenharmony_ci						last if $rl =~ /^[ \+].*\{/;
553162306a36Sopenharmony_ci					}
553262306a36Sopenharmony_ci				}
553362306a36Sopenharmony_ci				CHK("UNNECESSARY_PARENTHESES",
553462306a36Sopenharmony_ci				    "Unnecessary parentheses around '$match'\n" . $herectx);
553562306a36Sopenharmony_ci			}
553662306a36Sopenharmony_ci		}
553762306a36Sopenharmony_ci
553862306a36Sopenharmony_ci# check that goto labels aren't indented (allow a single space indentation)
553962306a36Sopenharmony_ci# and ignore bitfield definitions like foo:1
554062306a36Sopenharmony_ci# Strictly, labels can have whitespace after the identifier and before the :
554162306a36Sopenharmony_ci# but this is not allowed here as many ?: uses would appear to be labels
554262306a36Sopenharmony_ci		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
554362306a36Sopenharmony_ci		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
554462306a36Sopenharmony_ci		    $sline !~ /^.\s+default:/) {
554562306a36Sopenharmony_ci			if (WARN("INDENTED_LABEL",
554662306a36Sopenharmony_ci				 "labels should not be indented\n" . $herecurr) &&
554762306a36Sopenharmony_ci			    $fix) {
554862306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
554962306a36Sopenharmony_ci				    s/^(.)\s+/$1/;
555062306a36Sopenharmony_ci			}
555162306a36Sopenharmony_ci		}
555262306a36Sopenharmony_ci
555362306a36Sopenharmony_ci# check if a statement with a comma should be two statements like:
555462306a36Sopenharmony_ci#	foo = bar(),	/* comma should be semicolon */
555562306a36Sopenharmony_ci#	bar = baz();
555662306a36Sopenharmony_ci		if (defined($stat) &&
555762306a36Sopenharmony_ci		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
555862306a36Sopenharmony_ci			my $cnt = statement_rawlines($stat);
555962306a36Sopenharmony_ci			my $herectx = get_stat_here($linenr, $cnt, $here);
556062306a36Sopenharmony_ci			WARN("SUSPECT_COMMA_SEMICOLON",
556162306a36Sopenharmony_ci			     "Possible comma where semicolon could be used\n" . $herectx);
556262306a36Sopenharmony_ci		}
556362306a36Sopenharmony_ci
556462306a36Sopenharmony_ci# return is not a function
556562306a36Sopenharmony_ci		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
556662306a36Sopenharmony_ci			my $spacing = $1;
556762306a36Sopenharmony_ci			if ($perl_version_ok &&
556862306a36Sopenharmony_ci			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
556962306a36Sopenharmony_ci				my $value = $1;
557062306a36Sopenharmony_ci				$value = deparenthesize($value);
557162306a36Sopenharmony_ci				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
557262306a36Sopenharmony_ci					ERROR("RETURN_PARENTHESES",
557362306a36Sopenharmony_ci					      "return is not a function, parentheses are not required\n" . $herecurr);
557462306a36Sopenharmony_ci				}
557562306a36Sopenharmony_ci			} elsif ($spacing !~ /\s+/) {
557662306a36Sopenharmony_ci				ERROR("SPACING",
557762306a36Sopenharmony_ci				      "space required before the open parenthesis '('\n" . $herecurr);
557862306a36Sopenharmony_ci			}
557962306a36Sopenharmony_ci		}
558062306a36Sopenharmony_ci
558162306a36Sopenharmony_ci# unnecessary return in a void function
558262306a36Sopenharmony_ci# at end-of-function, with the previous line a single leading tab, then return;
558362306a36Sopenharmony_ci# and the line before that not a goto label target like "out:"
558462306a36Sopenharmony_ci		if ($sline =~ /^[ \+]}\s*$/ &&
558562306a36Sopenharmony_ci		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
558662306a36Sopenharmony_ci		    $linenr >= 3 &&
558762306a36Sopenharmony_ci		    $lines[$linenr - 3] =~ /^[ +]/ &&
558862306a36Sopenharmony_ci		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
558962306a36Sopenharmony_ci			WARN("RETURN_VOID",
559062306a36Sopenharmony_ci			     "void function return statements are not generally useful\n" . $hereprev);
559162306a36Sopenharmony_ci		}
559262306a36Sopenharmony_ci
559362306a36Sopenharmony_ci# if statements using unnecessary parentheses - ie: if ((foo == bar))
559462306a36Sopenharmony_ci		if ($perl_version_ok &&
559562306a36Sopenharmony_ci		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
559662306a36Sopenharmony_ci			my $openparens = $1;
559762306a36Sopenharmony_ci			my $count = $openparens =~ tr@\(@\(@;
559862306a36Sopenharmony_ci			my $msg = "";
559962306a36Sopenharmony_ci			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
560062306a36Sopenharmony_ci				my $comp = $4;	#Not $1 because of $LvalOrFunc
560162306a36Sopenharmony_ci				$msg = " - maybe == should be = ?" if ($comp eq "==");
560262306a36Sopenharmony_ci				WARN("UNNECESSARY_PARENTHESES",
560362306a36Sopenharmony_ci				     "Unnecessary parentheses$msg\n" . $herecurr);
560462306a36Sopenharmony_ci			}
560562306a36Sopenharmony_ci		}
560662306a36Sopenharmony_ci
560762306a36Sopenharmony_ci# comparisons with a constant or upper case identifier on the left
560862306a36Sopenharmony_ci#	avoid cases like "foo + BAR < baz"
560962306a36Sopenharmony_ci#	only fix matches surrounded by parentheses to avoid incorrect
561062306a36Sopenharmony_ci#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
561162306a36Sopenharmony_ci		if ($perl_version_ok &&
561262306a36Sopenharmony_ci		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
561362306a36Sopenharmony_ci			my $lead = $1;
561462306a36Sopenharmony_ci			my $const = $2;
561562306a36Sopenharmony_ci			my $comp = $3;
561662306a36Sopenharmony_ci			my $to = $4;
561762306a36Sopenharmony_ci			my $newcomp = $comp;
561862306a36Sopenharmony_ci			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
561962306a36Sopenharmony_ci			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
562062306a36Sopenharmony_ci			    WARN("CONSTANT_COMPARISON",
562162306a36Sopenharmony_ci				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
562262306a36Sopenharmony_ci			    $fix) {
562362306a36Sopenharmony_ci				if ($comp eq "<") {
562462306a36Sopenharmony_ci					$newcomp = ">";
562562306a36Sopenharmony_ci				} elsif ($comp eq "<=") {
562662306a36Sopenharmony_ci					$newcomp = ">=";
562762306a36Sopenharmony_ci				} elsif ($comp eq ">") {
562862306a36Sopenharmony_ci					$newcomp = "<";
562962306a36Sopenharmony_ci				} elsif ($comp eq ">=") {
563062306a36Sopenharmony_ci					$newcomp = "<=";
563162306a36Sopenharmony_ci				}
563262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
563362306a36Sopenharmony_ci			}
563462306a36Sopenharmony_ci		}
563562306a36Sopenharmony_ci
563662306a36Sopenharmony_ci# Return of what appears to be an errno should normally be negative
563762306a36Sopenharmony_ci		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
563862306a36Sopenharmony_ci			my $name = $1;
563962306a36Sopenharmony_ci			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
564062306a36Sopenharmony_ci				WARN("USE_NEGATIVE_ERRNO",
564162306a36Sopenharmony_ci				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
564262306a36Sopenharmony_ci			}
564362306a36Sopenharmony_ci		}
564462306a36Sopenharmony_ci
564562306a36Sopenharmony_ci# Need a space before open parenthesis after if, while etc
564662306a36Sopenharmony_ci		if ($line =~ /\b(if|while|for|switch)\(/) {
564762306a36Sopenharmony_ci			if (ERROR("SPACING",
564862306a36Sopenharmony_ci				  "space required before the open parenthesis '('\n" . $herecurr) &&
564962306a36Sopenharmony_ci			    $fix) {
565062306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
565162306a36Sopenharmony_ci				    s/\b(if|while|for|switch)\(/$1 \(/;
565262306a36Sopenharmony_ci			}
565362306a36Sopenharmony_ci		}
565462306a36Sopenharmony_ci
565562306a36Sopenharmony_ci# Check for illegal assignment in if conditional -- and check for trailing
565662306a36Sopenharmony_ci# statements after the conditional.
565762306a36Sopenharmony_ci		if ($line =~ /do\s*(?!{)/) {
565862306a36Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
565962306a36Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0)
566062306a36Sopenharmony_ci					if (!defined $stat);
566162306a36Sopenharmony_ci			my ($stat_next) = ctx_statement_block($line_nr_next,
566262306a36Sopenharmony_ci						$remain_next, $off_next);
566362306a36Sopenharmony_ci			$stat_next =~ s/\n./\n /g;
566462306a36Sopenharmony_ci			##print "stat<$stat> stat_next<$stat_next>\n";
566562306a36Sopenharmony_ci
566662306a36Sopenharmony_ci			if ($stat_next =~ /^\s*while\b/) {
566762306a36Sopenharmony_ci				# If the statement carries leading newlines,
566862306a36Sopenharmony_ci				# then count those as offsets.
566962306a36Sopenharmony_ci				my ($whitespace) =
567062306a36Sopenharmony_ci					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
567162306a36Sopenharmony_ci				my $offset =
567262306a36Sopenharmony_ci					statement_rawlines($whitespace) - 1;
567362306a36Sopenharmony_ci
567462306a36Sopenharmony_ci				$suppress_whiletrailers{$line_nr_next +
567562306a36Sopenharmony_ci								$offset} = 1;
567662306a36Sopenharmony_ci			}
567762306a36Sopenharmony_ci		}
567862306a36Sopenharmony_ci		if (!defined $suppress_whiletrailers{$linenr} &&
567962306a36Sopenharmony_ci		    defined($stat) && defined($cond) &&
568062306a36Sopenharmony_ci		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
568162306a36Sopenharmony_ci			my ($s, $c) = ($stat, $cond);
568262306a36Sopenharmony_ci			my $fixed_assign_in_if = 0;
568362306a36Sopenharmony_ci
568462306a36Sopenharmony_ci			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
568562306a36Sopenharmony_ci				if (ERROR("ASSIGN_IN_IF",
568662306a36Sopenharmony_ci					  "do not use assignment in if condition\n" . $herecurr) &&
568762306a36Sopenharmony_ci				    $fix && $perl_version_ok) {
568862306a36Sopenharmony_ci					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
568962306a36Sopenharmony_ci						my $space = $1;
569062306a36Sopenharmony_ci						my $not = $2;
569162306a36Sopenharmony_ci						my $statement = $3;
569262306a36Sopenharmony_ci						my $assigned = $4;
569362306a36Sopenharmony_ci						my $test = $8;
569462306a36Sopenharmony_ci						my $against = $9;
569562306a36Sopenharmony_ci						my $brace = $15;
569662306a36Sopenharmony_ci						fix_delete_line($fixlinenr, $rawline);
569762306a36Sopenharmony_ci						fix_insert_line($fixlinenr, "$space$statement;");
569862306a36Sopenharmony_ci						my $newline = "${space}if (";
569962306a36Sopenharmony_ci						$newline .= '!' if defined($not);
570062306a36Sopenharmony_ci						$newline .= '(' if (defined $not && defined($test) && defined($against));
570162306a36Sopenharmony_ci						$newline .= "$assigned";
570262306a36Sopenharmony_ci						$newline .= " $test $against" if (defined($test) && defined($against));
570362306a36Sopenharmony_ci						$newline .= ')' if (defined $not && defined($test) && defined($against));
570462306a36Sopenharmony_ci						$newline .= ')';
570562306a36Sopenharmony_ci						$newline .= " {" if (defined($brace));
570662306a36Sopenharmony_ci						fix_insert_line($fixlinenr + 1, $newline);
570762306a36Sopenharmony_ci						$fixed_assign_in_if = 1;
570862306a36Sopenharmony_ci					}
570962306a36Sopenharmony_ci				}
571062306a36Sopenharmony_ci			}
571162306a36Sopenharmony_ci
571262306a36Sopenharmony_ci			# Find out what is on the end of the line after the
571362306a36Sopenharmony_ci			# conditional.
571462306a36Sopenharmony_ci			substr($s, 0, length($c), '');
571562306a36Sopenharmony_ci			$s =~ s/\n.*//g;
571662306a36Sopenharmony_ci			$s =~ s/$;//g;	# Remove any comments
571762306a36Sopenharmony_ci			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
571862306a36Sopenharmony_ci			    $c !~ /}\s*while\s*/)
571962306a36Sopenharmony_ci			{
572062306a36Sopenharmony_ci				# Find out how long the conditional actually is.
572162306a36Sopenharmony_ci				my @newlines = ($c =~ /\n/gs);
572262306a36Sopenharmony_ci				my $cond_lines = 1 + $#newlines;
572362306a36Sopenharmony_ci				my $stat_real = '';
572462306a36Sopenharmony_ci
572562306a36Sopenharmony_ci				$stat_real = raw_line($linenr, $cond_lines)
572662306a36Sopenharmony_ci							. "\n" if ($cond_lines);
572762306a36Sopenharmony_ci				if (defined($stat_real) && $cond_lines > 1) {
572862306a36Sopenharmony_ci					$stat_real = "[...]\n$stat_real";
572962306a36Sopenharmony_ci				}
573062306a36Sopenharmony_ci
573162306a36Sopenharmony_ci				if (ERROR("TRAILING_STATEMENTS",
573262306a36Sopenharmony_ci					  "trailing statements should be on next line\n" . $herecurr . $stat_real) &&
573362306a36Sopenharmony_ci				    !$fixed_assign_in_if &&
573462306a36Sopenharmony_ci				    $cond_lines == 0 &&
573562306a36Sopenharmony_ci				    $fix && $perl_version_ok &&
573662306a36Sopenharmony_ci				    $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) {
573762306a36Sopenharmony_ci					my $indent = $1;
573862306a36Sopenharmony_ci					my $test = $2;
573962306a36Sopenharmony_ci					my $rest = rtrim($4);
574062306a36Sopenharmony_ci					if ($rest =~ /;$/) {
574162306a36Sopenharmony_ci						$fixed[$fixlinenr] = "\+$indent$test";
574262306a36Sopenharmony_ci						fix_insert_line($fixlinenr + 1, "$indent\t$rest");
574362306a36Sopenharmony_ci					}
574462306a36Sopenharmony_ci				}
574562306a36Sopenharmony_ci			}
574662306a36Sopenharmony_ci		}
574762306a36Sopenharmony_ci
574862306a36Sopenharmony_ci# Check for bitwise tests written as boolean
574962306a36Sopenharmony_ci		if ($line =~ /
575062306a36Sopenharmony_ci			(?:
575162306a36Sopenharmony_ci				(?:\[|\(|\&\&|\|\|)
575262306a36Sopenharmony_ci				\s*0[xX][0-9]+\s*
575362306a36Sopenharmony_ci				(?:\&\&|\|\|)
575462306a36Sopenharmony_ci			|
575562306a36Sopenharmony_ci				(?:\&\&|\|\|)
575662306a36Sopenharmony_ci				\s*0[xX][0-9]+\s*
575762306a36Sopenharmony_ci				(?:\&\&|\|\||\)|\])
575862306a36Sopenharmony_ci			)/x)
575962306a36Sopenharmony_ci		{
576062306a36Sopenharmony_ci			WARN("HEXADECIMAL_BOOLEAN_TEST",
576162306a36Sopenharmony_ci			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
576262306a36Sopenharmony_ci		}
576362306a36Sopenharmony_ci
576462306a36Sopenharmony_ci# if and else should not have general statements after it
576562306a36Sopenharmony_ci		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
576662306a36Sopenharmony_ci			my $s = $1;
576762306a36Sopenharmony_ci			$s =~ s/$;//g;	# Remove any comments
576862306a36Sopenharmony_ci			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
576962306a36Sopenharmony_ci				ERROR("TRAILING_STATEMENTS",
577062306a36Sopenharmony_ci				      "trailing statements should be on next line\n" . $herecurr);
577162306a36Sopenharmony_ci			}
577262306a36Sopenharmony_ci		}
577362306a36Sopenharmony_ci# if should not continue a brace
577462306a36Sopenharmony_ci		if ($line =~ /}\s*if\b/) {
577562306a36Sopenharmony_ci			ERROR("TRAILING_STATEMENTS",
577662306a36Sopenharmony_ci			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
577762306a36Sopenharmony_ci				$herecurr);
577862306a36Sopenharmony_ci		}
577962306a36Sopenharmony_ci# case and default should not have general statements after them
578062306a36Sopenharmony_ci		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
578162306a36Sopenharmony_ci		    $line !~ /\G(?:
578262306a36Sopenharmony_ci			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
578362306a36Sopenharmony_ci			\s*return\s+
578462306a36Sopenharmony_ci		    )/xg)
578562306a36Sopenharmony_ci		{
578662306a36Sopenharmony_ci			ERROR("TRAILING_STATEMENTS",
578762306a36Sopenharmony_ci			      "trailing statements should be on next line\n" . $herecurr);
578862306a36Sopenharmony_ci		}
578962306a36Sopenharmony_ci
579062306a36Sopenharmony_ci		# Check for }<nl>else {, these must be at the same
579162306a36Sopenharmony_ci		# indent level to be relevant to each other.
579262306a36Sopenharmony_ci		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
579362306a36Sopenharmony_ci		    $previndent == $indent) {
579462306a36Sopenharmony_ci			if (ERROR("ELSE_AFTER_BRACE",
579562306a36Sopenharmony_ci				  "else should follow close brace '}'\n" . $hereprev) &&
579662306a36Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
579762306a36Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
579862306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
579962306a36Sopenharmony_ci				my $fixedline = $prevrawline;
580062306a36Sopenharmony_ci				$fixedline =~ s/}\s*$//;
580162306a36Sopenharmony_ci				if ($fixedline !~ /^\+\s*$/) {
580262306a36Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
580362306a36Sopenharmony_ci				}
580462306a36Sopenharmony_ci				$fixedline = $rawline;
580562306a36Sopenharmony_ci				$fixedline =~ s/^(.\s*)else/$1} else/;
580662306a36Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
580762306a36Sopenharmony_ci			}
580862306a36Sopenharmony_ci		}
580962306a36Sopenharmony_ci
581062306a36Sopenharmony_ci		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
581162306a36Sopenharmony_ci		    $previndent == $indent) {
581262306a36Sopenharmony_ci			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
581362306a36Sopenharmony_ci
581462306a36Sopenharmony_ci			# Find out what is on the end of the line after the
581562306a36Sopenharmony_ci			# conditional.
581662306a36Sopenharmony_ci			substr($s, 0, length($c), '');
581762306a36Sopenharmony_ci			$s =~ s/\n.*//g;
581862306a36Sopenharmony_ci
581962306a36Sopenharmony_ci			if ($s =~ /^\s*;/) {
582062306a36Sopenharmony_ci				if (ERROR("WHILE_AFTER_BRACE",
582162306a36Sopenharmony_ci					  "while should follow close brace '}'\n" . $hereprev) &&
582262306a36Sopenharmony_ci				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
582362306a36Sopenharmony_ci					fix_delete_line($fixlinenr - 1, $prevrawline);
582462306a36Sopenharmony_ci					fix_delete_line($fixlinenr, $rawline);
582562306a36Sopenharmony_ci					my $fixedline = $prevrawline;
582662306a36Sopenharmony_ci					my $trailing = $rawline;
582762306a36Sopenharmony_ci					$trailing =~ s/^\+//;
582862306a36Sopenharmony_ci					$trailing = trim($trailing);
582962306a36Sopenharmony_ci					$fixedline =~ s/}\s*$/} $trailing/;
583062306a36Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
583162306a36Sopenharmony_ci				}
583262306a36Sopenharmony_ci			}
583362306a36Sopenharmony_ci		}
583462306a36Sopenharmony_ci
583562306a36Sopenharmony_ci#Specific variable tests
583662306a36Sopenharmony_ci		while ($line =~ m{($Constant|$Lval)}g) {
583762306a36Sopenharmony_ci			my $var = $1;
583862306a36Sopenharmony_ci
583962306a36Sopenharmony_ci#CamelCase
584062306a36Sopenharmony_ci			if ($var !~ /^$Constant$/ &&
584162306a36Sopenharmony_ci			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
584262306a36Sopenharmony_ci#Ignore some autogenerated defines and enum values
584362306a36Sopenharmony_ci			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
584462306a36Sopenharmony_ci#Ignore Page<foo> variants
584562306a36Sopenharmony_ci			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
584662306a36Sopenharmony_ci#Ignore ETHTOOL_LINK_MODE_<foo> variants
584762306a36Sopenharmony_ci			    $var !~ /^ETHTOOL_LINK_MODE_/ &&
584862306a36Sopenharmony_ci#Ignore SI style variants like nS, mV and dB
584962306a36Sopenharmony_ci#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
585062306a36Sopenharmony_ci			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
585162306a36Sopenharmony_ci#Ignore some three character SI units explicitly, like MiB and KHz
585262306a36Sopenharmony_ci			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
585362306a36Sopenharmony_ci				while ($var =~ m{\b($Ident)}g) {
585462306a36Sopenharmony_ci					my $word = $1;
585562306a36Sopenharmony_ci					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
585662306a36Sopenharmony_ci					if ($check) {
585762306a36Sopenharmony_ci						seed_camelcase_includes();
585862306a36Sopenharmony_ci						if (!$file && !$camelcase_file_seeded) {
585962306a36Sopenharmony_ci							seed_camelcase_file($realfile);
586062306a36Sopenharmony_ci							$camelcase_file_seeded = 1;
586162306a36Sopenharmony_ci						}
586262306a36Sopenharmony_ci					}
586362306a36Sopenharmony_ci					if (!defined $camelcase{$word}) {
586462306a36Sopenharmony_ci						$camelcase{$word} = 1;
586562306a36Sopenharmony_ci						CHK("CAMELCASE",
586662306a36Sopenharmony_ci						    "Avoid CamelCase: <$word>\n" . $herecurr);
586762306a36Sopenharmony_ci					}
586862306a36Sopenharmony_ci				}
586962306a36Sopenharmony_ci			}
587062306a36Sopenharmony_ci		}
587162306a36Sopenharmony_ci
587262306a36Sopenharmony_ci#no spaces allowed after \ in define
587362306a36Sopenharmony_ci		if ($line =~ /\#\s*define.*\\\s+$/) {
587462306a36Sopenharmony_ci			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
587562306a36Sopenharmony_ci				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
587662306a36Sopenharmony_ci			    $fix) {
587762306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+$//;
587862306a36Sopenharmony_ci			}
587962306a36Sopenharmony_ci		}
588062306a36Sopenharmony_ci
588162306a36Sopenharmony_ci# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
588262306a36Sopenharmony_ci# itself <asm/foo.h> (uses RAW line)
588362306a36Sopenharmony_ci		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
588462306a36Sopenharmony_ci			my $file = "$1.h";
588562306a36Sopenharmony_ci			my $checkfile = "include/linux/$file";
588662306a36Sopenharmony_ci			if (-f "$root/$checkfile" &&
588762306a36Sopenharmony_ci			    $realfile ne $checkfile &&
588862306a36Sopenharmony_ci			    $1 !~ /$allowed_asm_includes/)
588962306a36Sopenharmony_ci			{
589062306a36Sopenharmony_ci				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
589162306a36Sopenharmony_ci				if ($asminclude > 0) {
589262306a36Sopenharmony_ci					if ($realfile =~ m{^arch/}) {
589362306a36Sopenharmony_ci						CHK("ARCH_INCLUDE_LINUX",
589462306a36Sopenharmony_ci						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
589562306a36Sopenharmony_ci					} else {
589662306a36Sopenharmony_ci						WARN("INCLUDE_LINUX",
589762306a36Sopenharmony_ci						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
589862306a36Sopenharmony_ci					}
589962306a36Sopenharmony_ci				}
590062306a36Sopenharmony_ci			}
590162306a36Sopenharmony_ci		}
590262306a36Sopenharmony_ci
590362306a36Sopenharmony_ci# multi-statement macros should be enclosed in a do while loop, grab the
590462306a36Sopenharmony_ci# first statement and ensure its the whole macro if its not enclosed
590562306a36Sopenharmony_ci# in a known good container
590662306a36Sopenharmony_ci		if ($realfile !~ m@/vmlinux.lds.h$@ &&
590762306a36Sopenharmony_ci		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
590862306a36Sopenharmony_ci			my $ln = $linenr;
590962306a36Sopenharmony_ci			my $cnt = $realcnt;
591062306a36Sopenharmony_ci			my ($off, $dstat, $dcond, $rest);
591162306a36Sopenharmony_ci			my $ctx = '';
591262306a36Sopenharmony_ci			my $has_flow_statement = 0;
591362306a36Sopenharmony_ci			my $has_arg_concat = 0;
591462306a36Sopenharmony_ci			($dstat, $dcond, $ln, $cnt, $off) =
591562306a36Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
591662306a36Sopenharmony_ci			$ctx = $dstat;
591762306a36Sopenharmony_ci			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
591862306a36Sopenharmony_ci			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
591962306a36Sopenharmony_ci
592062306a36Sopenharmony_ci			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
592162306a36Sopenharmony_ci			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
592262306a36Sopenharmony_ci
592362306a36Sopenharmony_ci			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
592462306a36Sopenharmony_ci			my $define_args = $1;
592562306a36Sopenharmony_ci			my $define_stmt = $dstat;
592662306a36Sopenharmony_ci			my @def_args = ();
592762306a36Sopenharmony_ci
592862306a36Sopenharmony_ci			if (defined $define_args && $define_args ne "") {
592962306a36Sopenharmony_ci				$define_args = substr($define_args, 1, length($define_args) - 2);
593062306a36Sopenharmony_ci				$define_args =~ s/\s*//g;
593162306a36Sopenharmony_ci				$define_args =~ s/\\\+?//g;
593262306a36Sopenharmony_ci				@def_args = split(",", $define_args);
593362306a36Sopenharmony_ci			}
593462306a36Sopenharmony_ci
593562306a36Sopenharmony_ci			$dstat =~ s/$;//g;
593662306a36Sopenharmony_ci			$dstat =~ s/\\\n.//g;
593762306a36Sopenharmony_ci			$dstat =~ s/^\s*//s;
593862306a36Sopenharmony_ci			$dstat =~ s/\s*$//s;
593962306a36Sopenharmony_ci
594062306a36Sopenharmony_ci			# Flatten any parentheses and braces
594162306a36Sopenharmony_ci			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
594262306a36Sopenharmony_ci			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
594362306a36Sopenharmony_ci			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
594462306a36Sopenharmony_ci			{
594562306a36Sopenharmony_ci			}
594662306a36Sopenharmony_ci
594762306a36Sopenharmony_ci			# Flatten any obvious string concatenation.
594862306a36Sopenharmony_ci			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
594962306a36Sopenharmony_ci			       $dstat =~ s/$Ident\s*($String)/$1/)
595062306a36Sopenharmony_ci			{
595162306a36Sopenharmony_ci			}
595262306a36Sopenharmony_ci
595362306a36Sopenharmony_ci			# Make asm volatile uses seem like a generic function
595462306a36Sopenharmony_ci			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
595562306a36Sopenharmony_ci
595662306a36Sopenharmony_ci			my $exceptions = qr{
595762306a36Sopenharmony_ci				$Declare|
595862306a36Sopenharmony_ci				module_param_named|
595962306a36Sopenharmony_ci				MODULE_PARM_DESC|
596062306a36Sopenharmony_ci				DECLARE_PER_CPU|
596162306a36Sopenharmony_ci				DEFINE_PER_CPU|
596262306a36Sopenharmony_ci				__typeof__\(|
596362306a36Sopenharmony_ci				union|
596462306a36Sopenharmony_ci				struct|
596562306a36Sopenharmony_ci				\.$Ident\s*=\s*|
596662306a36Sopenharmony_ci				^\"|\"$|
596762306a36Sopenharmony_ci				^\[
596862306a36Sopenharmony_ci			}x;
596962306a36Sopenharmony_ci			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
597062306a36Sopenharmony_ci
597162306a36Sopenharmony_ci			$ctx =~ s/\n*$//;
597262306a36Sopenharmony_ci			my $stmt_cnt = statement_rawlines($ctx);
597362306a36Sopenharmony_ci			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
597462306a36Sopenharmony_ci
597562306a36Sopenharmony_ci			if ($dstat ne '' &&
597662306a36Sopenharmony_ci			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
597762306a36Sopenharmony_ci			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
597862306a36Sopenharmony_ci			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
597962306a36Sopenharmony_ci			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
598062306a36Sopenharmony_ci			    $dstat !~ /$exceptions/ &&
598162306a36Sopenharmony_ci			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
598262306a36Sopenharmony_ci			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
598362306a36Sopenharmony_ci			    $dstat !~ /^case\b/ &&					# case ...
598462306a36Sopenharmony_ci			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
598562306a36Sopenharmony_ci			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
598662306a36Sopenharmony_ci			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
598762306a36Sopenharmony_ci			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
598862306a36Sopenharmony_ci			    $dstat !~ /^do\s*{/ &&					# do {...
598962306a36Sopenharmony_ci			    $dstat !~ /^\(\{/ &&						# ({...
599062306a36Sopenharmony_ci			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
599162306a36Sopenharmony_ci			{
599262306a36Sopenharmony_ci				if ($dstat =~ /^\s*if\b/) {
599362306a36Sopenharmony_ci					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
599462306a36Sopenharmony_ci					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
599562306a36Sopenharmony_ci				} elsif ($dstat =~ /;/) {
599662306a36Sopenharmony_ci					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
599762306a36Sopenharmony_ci					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
599862306a36Sopenharmony_ci				} else {
599962306a36Sopenharmony_ci					ERROR("COMPLEX_MACRO",
600062306a36Sopenharmony_ci					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
600162306a36Sopenharmony_ci				}
600262306a36Sopenharmony_ci
600362306a36Sopenharmony_ci			}
600462306a36Sopenharmony_ci
600562306a36Sopenharmony_ci			# Make $define_stmt single line, comment-free, etc
600662306a36Sopenharmony_ci			my @stmt_array = split('\n', $define_stmt);
600762306a36Sopenharmony_ci			my $first = 1;
600862306a36Sopenharmony_ci			$define_stmt = "";
600962306a36Sopenharmony_ci			foreach my $l (@stmt_array) {
601062306a36Sopenharmony_ci				$l =~ s/\\$//;
601162306a36Sopenharmony_ci				if ($first) {
601262306a36Sopenharmony_ci					$define_stmt = $l;
601362306a36Sopenharmony_ci					$first = 0;
601462306a36Sopenharmony_ci				} elsif ($l =~ /^[\+ ]/) {
601562306a36Sopenharmony_ci					$define_stmt .= substr($l, 1);
601662306a36Sopenharmony_ci				}
601762306a36Sopenharmony_ci			}
601862306a36Sopenharmony_ci			$define_stmt =~ s/$;//g;
601962306a36Sopenharmony_ci			$define_stmt =~ s/\s+/ /g;
602062306a36Sopenharmony_ci			$define_stmt = trim($define_stmt);
602162306a36Sopenharmony_ci
602262306a36Sopenharmony_ci# check if any macro arguments are reused (ignore '...' and 'type')
602362306a36Sopenharmony_ci			foreach my $arg (@def_args) {
602462306a36Sopenharmony_ci			        next if ($arg =~ /\.\.\./);
602562306a36Sopenharmony_ci			        next if ($arg =~ /^type$/i);
602662306a36Sopenharmony_ci				my $tmp_stmt = $define_stmt;
602762306a36Sopenharmony_ci				$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;
602862306a36Sopenharmony_ci				$tmp_stmt =~ s/\#+\s*$arg\b//g;
602962306a36Sopenharmony_ci				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
603062306a36Sopenharmony_ci				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
603162306a36Sopenharmony_ci				if ($use_cnt > 1) {
603262306a36Sopenharmony_ci					CHK("MACRO_ARG_REUSE",
603362306a36Sopenharmony_ci					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
603462306a36Sopenharmony_ci				    }
603562306a36Sopenharmony_ci# check if any macro arguments may have other precedence issues
603662306a36Sopenharmony_ci				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
603762306a36Sopenharmony_ci				    ((defined($1) && $1 ne ',') ||
603862306a36Sopenharmony_ci				     (defined($2) && $2 ne ','))) {
603962306a36Sopenharmony_ci					CHK("MACRO_ARG_PRECEDENCE",
604062306a36Sopenharmony_ci					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
604162306a36Sopenharmony_ci				}
604262306a36Sopenharmony_ci			}
604362306a36Sopenharmony_ci
604462306a36Sopenharmony_ci# check for macros with flow control, but without ## concatenation
604562306a36Sopenharmony_ci# ## concatenation is commonly a macro that defines a function so ignore those
604662306a36Sopenharmony_ci			if ($has_flow_statement && !$has_arg_concat) {
604762306a36Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
604862306a36Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
604962306a36Sopenharmony_ci
605062306a36Sopenharmony_ci				WARN("MACRO_WITH_FLOW_CONTROL",
605162306a36Sopenharmony_ci				     "Macros with flow control statements should be avoided\n" . "$herectx");
605262306a36Sopenharmony_ci			}
605362306a36Sopenharmony_ci
605462306a36Sopenharmony_ci# check for line continuations outside of #defines, preprocessor #, and asm
605562306a36Sopenharmony_ci
605662306a36Sopenharmony_ci		} elsif ($realfile =~ m@/vmlinux.lds.h$@) {
605762306a36Sopenharmony_ci		    $line =~ s/(\w+)/$maybe_linker_symbol{$1}++/ge;
605862306a36Sopenharmony_ci		    #print "REAL: $realfile\nln: $line\nkeys:", sort keys %maybe_linker_symbol;
605962306a36Sopenharmony_ci		} else {
606062306a36Sopenharmony_ci			if ($prevline !~ /^..*\\$/ &&
606162306a36Sopenharmony_ci			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
606262306a36Sopenharmony_ci			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
606362306a36Sopenharmony_ci			    $line =~ /^\+.*\\$/) {
606462306a36Sopenharmony_ci				WARN("LINE_CONTINUATIONS",
606562306a36Sopenharmony_ci				     "Avoid unnecessary line continuations\n" . $herecurr);
606662306a36Sopenharmony_ci			}
606762306a36Sopenharmony_ci		}
606862306a36Sopenharmony_ci
606962306a36Sopenharmony_ci# do {} while (0) macro tests:
607062306a36Sopenharmony_ci# single-statement macros do not need to be enclosed in do while (0) loop,
607162306a36Sopenharmony_ci# macro should not end with a semicolon
607262306a36Sopenharmony_ci		if ($perl_version_ok &&
607362306a36Sopenharmony_ci		    $realfile !~ m@/vmlinux.lds.h$@ &&
607462306a36Sopenharmony_ci		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
607562306a36Sopenharmony_ci			my $ln = $linenr;
607662306a36Sopenharmony_ci			my $cnt = $realcnt;
607762306a36Sopenharmony_ci			my ($off, $dstat, $dcond, $rest);
607862306a36Sopenharmony_ci			my $ctx = '';
607962306a36Sopenharmony_ci			($dstat, $dcond, $ln, $cnt, $off) =
608062306a36Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
608162306a36Sopenharmony_ci			$ctx = $dstat;
608262306a36Sopenharmony_ci
608362306a36Sopenharmony_ci			$dstat =~ s/\\\n.//g;
608462306a36Sopenharmony_ci			$dstat =~ s/$;/ /g;
608562306a36Sopenharmony_ci
608662306a36Sopenharmony_ci			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
608762306a36Sopenharmony_ci				my $stmts = $2;
608862306a36Sopenharmony_ci				my $semis = $3;
608962306a36Sopenharmony_ci
609062306a36Sopenharmony_ci				$ctx =~ s/\n*$//;
609162306a36Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
609262306a36Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
609362306a36Sopenharmony_ci
609462306a36Sopenharmony_ci				if (($stmts =~ tr/;/;/) == 1 &&
609562306a36Sopenharmony_ci				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
609662306a36Sopenharmony_ci					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
609762306a36Sopenharmony_ci					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
609862306a36Sopenharmony_ci				}
609962306a36Sopenharmony_ci				if (defined $semis && $semis ne "") {
610062306a36Sopenharmony_ci					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
610162306a36Sopenharmony_ci					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
610262306a36Sopenharmony_ci				}
610362306a36Sopenharmony_ci			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
610462306a36Sopenharmony_ci				$ctx =~ s/\n*$//;
610562306a36Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
610662306a36Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
610762306a36Sopenharmony_ci
610862306a36Sopenharmony_ci				WARN("TRAILING_SEMICOLON",
610962306a36Sopenharmony_ci				     "macros should not use a trailing semicolon\n" . "$herectx");
611062306a36Sopenharmony_ci			}
611162306a36Sopenharmony_ci		}
611262306a36Sopenharmony_ci
611362306a36Sopenharmony_ci# check for redundant bracing round if etc
611462306a36Sopenharmony_ci		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
611562306a36Sopenharmony_ci			my ($level, $endln, @chunks) =
611662306a36Sopenharmony_ci				ctx_statement_full($linenr, $realcnt, 1);
611762306a36Sopenharmony_ci			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
611862306a36Sopenharmony_ci			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
611962306a36Sopenharmony_ci			if ($#chunks > 0 && $level == 0) {
612062306a36Sopenharmony_ci				my @allowed = ();
612162306a36Sopenharmony_ci				my $allow = 0;
612262306a36Sopenharmony_ci				my $seen = 0;
612362306a36Sopenharmony_ci				my $herectx = $here . "\n";
612462306a36Sopenharmony_ci				my $ln = $linenr - 1;
612562306a36Sopenharmony_ci				for my $chunk (@chunks) {
612662306a36Sopenharmony_ci					my ($cond, $block) = @{$chunk};
612762306a36Sopenharmony_ci
612862306a36Sopenharmony_ci					# If the condition carries leading newlines, then count those as offsets.
612962306a36Sopenharmony_ci					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
613062306a36Sopenharmony_ci					my $offset = statement_rawlines($whitespace) - 1;
613162306a36Sopenharmony_ci
613262306a36Sopenharmony_ci					$allowed[$allow] = 0;
613362306a36Sopenharmony_ci					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
613462306a36Sopenharmony_ci
613562306a36Sopenharmony_ci					# We have looked at and allowed this specific line.
613662306a36Sopenharmony_ci					$suppress_ifbraces{$ln + $offset} = 1;
613762306a36Sopenharmony_ci
613862306a36Sopenharmony_ci					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
613962306a36Sopenharmony_ci					$ln += statement_rawlines($block) - 1;
614062306a36Sopenharmony_ci
614162306a36Sopenharmony_ci					substr($block, 0, length($cond), '');
614262306a36Sopenharmony_ci
614362306a36Sopenharmony_ci					$seen++ if ($block =~ /^\s*{/);
614462306a36Sopenharmony_ci
614562306a36Sopenharmony_ci					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
614662306a36Sopenharmony_ci					if (statement_lines($cond) > 1) {
614762306a36Sopenharmony_ci						#print "APW: ALLOWED: cond<$cond>\n";
614862306a36Sopenharmony_ci						$allowed[$allow] = 1;
614962306a36Sopenharmony_ci					}
615062306a36Sopenharmony_ci					if ($block =~/\b(?:if|for|while)\b/) {
615162306a36Sopenharmony_ci						#print "APW: ALLOWED: block<$block>\n";
615262306a36Sopenharmony_ci						$allowed[$allow] = 1;
615362306a36Sopenharmony_ci					}
615462306a36Sopenharmony_ci					if (statement_block_size($block) > 1) {
615562306a36Sopenharmony_ci						#print "APW: ALLOWED: lines block<$block>\n";
615662306a36Sopenharmony_ci						$allowed[$allow] = 1;
615762306a36Sopenharmony_ci					}
615862306a36Sopenharmony_ci					$allow++;
615962306a36Sopenharmony_ci				}
616062306a36Sopenharmony_ci				if ($seen) {
616162306a36Sopenharmony_ci					my $sum_allowed = 0;
616262306a36Sopenharmony_ci					foreach (@allowed) {
616362306a36Sopenharmony_ci						$sum_allowed += $_;
616462306a36Sopenharmony_ci					}
616562306a36Sopenharmony_ci					if ($sum_allowed == 0) {
616662306a36Sopenharmony_ci						WARN("BRACES",
616762306a36Sopenharmony_ci						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
616862306a36Sopenharmony_ci					} elsif ($sum_allowed != $allow &&
616962306a36Sopenharmony_ci						 $seen != $allow) {
617062306a36Sopenharmony_ci						CHK("BRACES",
617162306a36Sopenharmony_ci						    "braces {} should be used on all arms of this statement\n" . $herectx);
617262306a36Sopenharmony_ci					}
617362306a36Sopenharmony_ci				}
617462306a36Sopenharmony_ci			}
617562306a36Sopenharmony_ci		}
617662306a36Sopenharmony_ci		if (!defined $suppress_ifbraces{$linenr - 1} &&
617762306a36Sopenharmony_ci					$line =~ /\b(if|while|for|else)\b/) {
617862306a36Sopenharmony_ci			my $allowed = 0;
617962306a36Sopenharmony_ci
618062306a36Sopenharmony_ci			# Check the pre-context.
618162306a36Sopenharmony_ci			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
618262306a36Sopenharmony_ci				#print "APW: ALLOWED: pre<$1>\n";
618362306a36Sopenharmony_ci				$allowed = 1;
618462306a36Sopenharmony_ci			}
618562306a36Sopenharmony_ci
618662306a36Sopenharmony_ci			my ($level, $endln, @chunks) =
618762306a36Sopenharmony_ci				ctx_statement_full($linenr, $realcnt, $-[0]);
618862306a36Sopenharmony_ci
618962306a36Sopenharmony_ci			# Check the condition.
619062306a36Sopenharmony_ci			my ($cond, $block) = @{$chunks[0]};
619162306a36Sopenharmony_ci			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
619262306a36Sopenharmony_ci			if (defined $cond) {
619362306a36Sopenharmony_ci				substr($block, 0, length($cond), '');
619462306a36Sopenharmony_ci			}
619562306a36Sopenharmony_ci			if (statement_lines($cond) > 1) {
619662306a36Sopenharmony_ci				#print "APW: ALLOWED: cond<$cond>\n";
619762306a36Sopenharmony_ci				$allowed = 1;
619862306a36Sopenharmony_ci			}
619962306a36Sopenharmony_ci			if ($block =~/\b(?:if|for|while)\b/) {
620062306a36Sopenharmony_ci				#print "APW: ALLOWED: block<$block>\n";
620162306a36Sopenharmony_ci				$allowed = 1;
620262306a36Sopenharmony_ci			}
620362306a36Sopenharmony_ci			if (statement_block_size($block) > 1) {
620462306a36Sopenharmony_ci				#print "APW: ALLOWED: lines block<$block>\n";
620562306a36Sopenharmony_ci				$allowed = 1;
620662306a36Sopenharmony_ci			}
620762306a36Sopenharmony_ci			# Check the post-context.
620862306a36Sopenharmony_ci			if (defined $chunks[1]) {
620962306a36Sopenharmony_ci				my ($cond, $block) = @{$chunks[1]};
621062306a36Sopenharmony_ci				if (defined $cond) {
621162306a36Sopenharmony_ci					substr($block, 0, length($cond), '');
621262306a36Sopenharmony_ci				}
621362306a36Sopenharmony_ci				if ($block =~ /^\s*\{/) {
621462306a36Sopenharmony_ci					#print "APW: ALLOWED: chunk-1 block<$block>\n";
621562306a36Sopenharmony_ci					$allowed = 1;
621662306a36Sopenharmony_ci				}
621762306a36Sopenharmony_ci			}
621862306a36Sopenharmony_ci			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
621962306a36Sopenharmony_ci				my $cnt = statement_rawlines($block);
622062306a36Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
622162306a36Sopenharmony_ci
622262306a36Sopenharmony_ci				WARN("BRACES",
622362306a36Sopenharmony_ci				     "braces {} are not necessary for single statement blocks\n" . $herectx);
622462306a36Sopenharmony_ci			}
622562306a36Sopenharmony_ci		}
622662306a36Sopenharmony_ci
622762306a36Sopenharmony_ci# check for single line unbalanced braces
622862306a36Sopenharmony_ci		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
622962306a36Sopenharmony_ci		    $sline =~ /^.\s*else\s*\{\s*$/) {
623062306a36Sopenharmony_ci			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
623162306a36Sopenharmony_ci		}
623262306a36Sopenharmony_ci
623362306a36Sopenharmony_ci# check for unnecessary blank lines around braces
623462306a36Sopenharmony_ci		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
623562306a36Sopenharmony_ci			if (CHK("BRACES",
623662306a36Sopenharmony_ci				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
623762306a36Sopenharmony_ci			    $fix && $prevrawline =~ /^\+/) {
623862306a36Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
623962306a36Sopenharmony_ci			}
624062306a36Sopenharmony_ci		}
624162306a36Sopenharmony_ci		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
624262306a36Sopenharmony_ci			if (CHK("BRACES",
624362306a36Sopenharmony_ci				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
624462306a36Sopenharmony_ci			    $fix) {
624562306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
624662306a36Sopenharmony_ci			}
624762306a36Sopenharmony_ci		}
624862306a36Sopenharmony_ci
624962306a36Sopenharmony_ci# no volatiles please
625062306a36Sopenharmony_ci		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
625162306a36Sopenharmony_ci		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
625262306a36Sopenharmony_ci			WARN("VOLATILE",
625362306a36Sopenharmony_ci			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
625462306a36Sopenharmony_ci		}
625562306a36Sopenharmony_ci
625662306a36Sopenharmony_ci# Check for user-visible strings broken across lines, which breaks the ability
625762306a36Sopenharmony_ci# to grep for the string.  Make exceptions when the previous string ends in a
625862306a36Sopenharmony_ci# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
625962306a36Sopenharmony_ci# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
626062306a36Sopenharmony_ci		if ($line =~ /^\+\s*$String/ &&
626162306a36Sopenharmony_ci		    $prevline =~ /"\s*$/ &&
626262306a36Sopenharmony_ci		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
626362306a36Sopenharmony_ci			if (WARN("SPLIT_STRING",
626462306a36Sopenharmony_ci				 "quoted string split across lines\n" . $hereprev) &&
626562306a36Sopenharmony_ci				     $fix &&
626662306a36Sopenharmony_ci				     $prevrawline =~ /^\+.*"\s*$/ &&
626762306a36Sopenharmony_ci				     $last_coalesced_string_linenr != $linenr - 1) {
626862306a36Sopenharmony_ci				my $extracted_string = get_quoted_string($line, $rawline);
626962306a36Sopenharmony_ci				my $comma_close = "";
627062306a36Sopenharmony_ci				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
627162306a36Sopenharmony_ci					$comma_close = $1;
627262306a36Sopenharmony_ci				}
627362306a36Sopenharmony_ci
627462306a36Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
627562306a36Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
627662306a36Sopenharmony_ci				my $fixedline = $prevrawline;
627762306a36Sopenharmony_ci				$fixedline =~ s/"\s*$//;
627862306a36Sopenharmony_ci				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
627962306a36Sopenharmony_ci				fix_insert_line($fixlinenr - 1, $fixedline);
628062306a36Sopenharmony_ci				$fixedline = $rawline;
628162306a36Sopenharmony_ci				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
628262306a36Sopenharmony_ci				if ($fixedline !~ /\+\s*$/) {
628362306a36Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
628462306a36Sopenharmony_ci				}
628562306a36Sopenharmony_ci				$last_coalesced_string_linenr = $linenr;
628662306a36Sopenharmony_ci			}
628762306a36Sopenharmony_ci		}
628862306a36Sopenharmony_ci
628962306a36Sopenharmony_ci# check for missing a space in a string concatenation
629062306a36Sopenharmony_ci		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
629162306a36Sopenharmony_ci			WARN('MISSING_SPACE',
629262306a36Sopenharmony_ci			     "break quoted strings at a space character\n" . $hereprev);
629362306a36Sopenharmony_ci		}
629462306a36Sopenharmony_ci
629562306a36Sopenharmony_ci# check for an embedded function name in a string when the function is known
629662306a36Sopenharmony_ci# This does not work very well for -f --file checking as it depends on patch
629762306a36Sopenharmony_ci# context providing the function name or a single line form for in-file
629862306a36Sopenharmony_ci# function declarations
629962306a36Sopenharmony_ci		if ($line =~ /^\+.*$String/ &&
630062306a36Sopenharmony_ci		    defined($context_function) &&
630162306a36Sopenharmony_ci		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
630262306a36Sopenharmony_ci		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
630362306a36Sopenharmony_ci			WARN("EMBEDDED_FUNCTION_NAME",
630462306a36Sopenharmony_ci			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
630562306a36Sopenharmony_ci		}
630662306a36Sopenharmony_ci
630762306a36Sopenharmony_ci# check for unnecessary function tracing like uses
630862306a36Sopenharmony_ci# This does not use $logFunctions because there are many instances like
630962306a36Sopenharmony_ci# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
631062306a36Sopenharmony_ci		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
631162306a36Sopenharmony_ci			if (WARN("TRACING_LOGGING",
631262306a36Sopenharmony_ci				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
631362306a36Sopenharmony_ci			    $fix) {
631462306a36Sopenharmony_ci                                fix_delete_line($fixlinenr, $rawline);
631562306a36Sopenharmony_ci			}
631662306a36Sopenharmony_ci		}
631762306a36Sopenharmony_ci
631862306a36Sopenharmony_ci# check for spaces before a quoted newline
631962306a36Sopenharmony_ci		if ($rawline =~ /^.*\".*\s\\n/) {
632062306a36Sopenharmony_ci			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
632162306a36Sopenharmony_ci				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
632262306a36Sopenharmony_ci			    $fix) {
632362306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
632462306a36Sopenharmony_ci			}
632562306a36Sopenharmony_ci
632662306a36Sopenharmony_ci		}
632762306a36Sopenharmony_ci
632862306a36Sopenharmony_ci# concatenated string without spaces between elements
632962306a36Sopenharmony_ci		if ($line =~ /$String[A-Z_]/ ||
633062306a36Sopenharmony_ci		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
633162306a36Sopenharmony_ci			if (CHK("CONCATENATED_STRING",
633262306a36Sopenharmony_ci				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
633362306a36Sopenharmony_ci			    $fix) {
633462306a36Sopenharmony_ci				while ($line =~ /($String)/g) {
633562306a36Sopenharmony_ci					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
633662306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
633762306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
633862306a36Sopenharmony_ci				}
633962306a36Sopenharmony_ci			}
634062306a36Sopenharmony_ci		}
634162306a36Sopenharmony_ci
634262306a36Sopenharmony_ci# uncoalesced string fragments
634362306a36Sopenharmony_ci		if ($line =~ /$String\s*[Lu]?"/) {
634462306a36Sopenharmony_ci			if (WARN("STRING_FRAGMENTS",
634562306a36Sopenharmony_ci				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
634662306a36Sopenharmony_ci			    $fix) {
634762306a36Sopenharmony_ci				while ($line =~ /($String)(?=\s*")/g) {
634862306a36Sopenharmony_ci					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
634962306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
635062306a36Sopenharmony_ci				}
635162306a36Sopenharmony_ci			}
635262306a36Sopenharmony_ci		}
635362306a36Sopenharmony_ci
635462306a36Sopenharmony_ci# check for non-standard and hex prefixed decimal printf formats
635562306a36Sopenharmony_ci		my $show_L = 1;	#don't show the same defect twice
635662306a36Sopenharmony_ci		my $show_Z = 1;
635762306a36Sopenharmony_ci		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
635862306a36Sopenharmony_ci			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
635962306a36Sopenharmony_ci			$string =~ s/%%/__/g;
636062306a36Sopenharmony_ci			# check for %L
636162306a36Sopenharmony_ci			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
636262306a36Sopenharmony_ci				WARN("PRINTF_L",
636362306a36Sopenharmony_ci				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
636462306a36Sopenharmony_ci				$show_L = 0;
636562306a36Sopenharmony_ci			}
636662306a36Sopenharmony_ci			# check for %Z
636762306a36Sopenharmony_ci			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
636862306a36Sopenharmony_ci				WARN("PRINTF_Z",
636962306a36Sopenharmony_ci				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
637062306a36Sopenharmony_ci				$show_Z = 0;
637162306a36Sopenharmony_ci			}
637262306a36Sopenharmony_ci			# check for 0x<decimal>
637362306a36Sopenharmony_ci			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
637462306a36Sopenharmony_ci				ERROR("PRINTF_0XDECIMAL",
637562306a36Sopenharmony_ci				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
637662306a36Sopenharmony_ci			}
637762306a36Sopenharmony_ci		}
637862306a36Sopenharmony_ci
637962306a36Sopenharmony_ci# check for line continuations in quoted strings with odd counts of "
638062306a36Sopenharmony_ci		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
638162306a36Sopenharmony_ci			WARN("LINE_CONTINUATIONS",
638262306a36Sopenharmony_ci			     "Avoid line continuations in quoted strings\n" . $herecurr);
638362306a36Sopenharmony_ci		}
638462306a36Sopenharmony_ci
638562306a36Sopenharmony_ci# warn about #if 0
638662306a36Sopenharmony_ci		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
638762306a36Sopenharmony_ci			WARN("IF_0",
638862306a36Sopenharmony_ci			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
638962306a36Sopenharmony_ci		}
639062306a36Sopenharmony_ci
639162306a36Sopenharmony_ci# warn about #if 1
639262306a36Sopenharmony_ci		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
639362306a36Sopenharmony_ci			WARN("IF_1",
639462306a36Sopenharmony_ci			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
639562306a36Sopenharmony_ci		}
639662306a36Sopenharmony_ci
639762306a36Sopenharmony_ci# check for needless "if (<foo>) fn(<foo>)" uses
639862306a36Sopenharmony_ci		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
639962306a36Sopenharmony_ci			my $tested = quotemeta($1);
640062306a36Sopenharmony_ci			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
640162306a36Sopenharmony_ci			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
640262306a36Sopenharmony_ci				my $func = $1;
640362306a36Sopenharmony_ci				if (WARN('NEEDLESS_IF',
640462306a36Sopenharmony_ci					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
640562306a36Sopenharmony_ci				    $fix) {
640662306a36Sopenharmony_ci					my $do_fix = 1;
640762306a36Sopenharmony_ci					my $leading_tabs = "";
640862306a36Sopenharmony_ci					my $new_leading_tabs = "";
640962306a36Sopenharmony_ci					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
641062306a36Sopenharmony_ci						$leading_tabs = $1;
641162306a36Sopenharmony_ci					} else {
641262306a36Sopenharmony_ci						$do_fix = 0;
641362306a36Sopenharmony_ci					}
641462306a36Sopenharmony_ci					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
641562306a36Sopenharmony_ci						$new_leading_tabs = $1;
641662306a36Sopenharmony_ci						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
641762306a36Sopenharmony_ci							$do_fix = 0;
641862306a36Sopenharmony_ci						}
641962306a36Sopenharmony_ci					} else {
642062306a36Sopenharmony_ci						$do_fix = 0;
642162306a36Sopenharmony_ci					}
642262306a36Sopenharmony_ci					if ($do_fix) {
642362306a36Sopenharmony_ci						fix_delete_line($fixlinenr - 1, $prevrawline);
642462306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
642562306a36Sopenharmony_ci					}
642662306a36Sopenharmony_ci				}
642762306a36Sopenharmony_ci			}
642862306a36Sopenharmony_ci		}
642962306a36Sopenharmony_ci
643062306a36Sopenharmony_ci# check for soon-to-be-deprecated single-argument k[v]free_rcu() API
643162306a36Sopenharmony_ci		if ($line =~ /\bk[v]?free_rcu\s*\([^(]+\)/) {
643262306a36Sopenharmony_ci			if ($line =~ /\bk[v]?free_rcu\s*\([^,]+\)/) {
643362306a36Sopenharmony_ci				ERROR("DEPRECATED_API",
643462306a36Sopenharmony_ci				      "Single-argument k[v]free_rcu() API is deprecated, please pass rcu_head object or call k[v]free_rcu_mightsleep()." . $herecurr);
643562306a36Sopenharmony_ci			}
643662306a36Sopenharmony_ci		}
643762306a36Sopenharmony_ci
643862306a36Sopenharmony_ci
643962306a36Sopenharmony_ci# check for unnecessary "Out of Memory" messages
644062306a36Sopenharmony_ci		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
644162306a36Sopenharmony_ci		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
644262306a36Sopenharmony_ci		    (defined $1 || defined $3) &&
644362306a36Sopenharmony_ci		    $linenr > 3) {
644462306a36Sopenharmony_ci			my $testval = $2;
644562306a36Sopenharmony_ci			my $testline = $lines[$linenr - 3];
644662306a36Sopenharmony_ci
644762306a36Sopenharmony_ci			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
644862306a36Sopenharmony_ci#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
644962306a36Sopenharmony_ci
645062306a36Sopenharmony_ci			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
645162306a36Sopenharmony_ci			    $s !~ /\b__GFP_NOWARN\b/ ) {
645262306a36Sopenharmony_ci				WARN("OOM_MESSAGE",
645362306a36Sopenharmony_ci				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
645462306a36Sopenharmony_ci			}
645562306a36Sopenharmony_ci		}
645662306a36Sopenharmony_ci
645762306a36Sopenharmony_ci# check for logging functions with KERN_<LEVEL>
645862306a36Sopenharmony_ci		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
645962306a36Sopenharmony_ci		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
646062306a36Sopenharmony_ci			my $level = $1;
646162306a36Sopenharmony_ci			if (WARN("UNNECESSARY_KERN_LEVEL",
646262306a36Sopenharmony_ci				 "Possible unnecessary $level\n" . $herecurr) &&
646362306a36Sopenharmony_ci			    $fix) {
646462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
646562306a36Sopenharmony_ci			}
646662306a36Sopenharmony_ci		}
646762306a36Sopenharmony_ci
646862306a36Sopenharmony_ci# check for logging continuations
646962306a36Sopenharmony_ci		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
647062306a36Sopenharmony_ci			WARN("LOGGING_CONTINUATION",
647162306a36Sopenharmony_ci			     "Avoid logging continuation uses where feasible\n" . $herecurr);
647262306a36Sopenharmony_ci		}
647362306a36Sopenharmony_ci
647462306a36Sopenharmony_ci# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
647562306a36Sopenharmony_ci		if (defined $stat &&
647662306a36Sopenharmony_ci		    $line =~ /\b$logFunctions\s*\(/ &&
647762306a36Sopenharmony_ci		    index($stat, '"') >= 0) {
647862306a36Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
647962306a36Sopenharmony_ci			$lc = $lc + $linenr;
648062306a36Sopenharmony_ci			my $stat_real = get_stat_real($linenr, $lc);
648162306a36Sopenharmony_ci			pos($stat_real) = index($stat_real, '"');
648262306a36Sopenharmony_ci			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
648362306a36Sopenharmony_ci				my $pspec = $1;
648462306a36Sopenharmony_ci				my $h = $2;
648562306a36Sopenharmony_ci				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
648662306a36Sopenharmony_ci				if (WARN("UNNECESSARY_MODIFIER",
648762306a36Sopenharmony_ci					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
648862306a36Sopenharmony_ci				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
648962306a36Sopenharmony_ci					my $nspec = $pspec;
649062306a36Sopenharmony_ci					$nspec =~ s/h//g;
649162306a36Sopenharmony_ci					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
649262306a36Sopenharmony_ci				}
649362306a36Sopenharmony_ci			}
649462306a36Sopenharmony_ci		}
649562306a36Sopenharmony_ci
649662306a36Sopenharmony_ci# check for mask then right shift without a parentheses
649762306a36Sopenharmony_ci		if ($perl_version_ok &&
649862306a36Sopenharmony_ci		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
649962306a36Sopenharmony_ci		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
650062306a36Sopenharmony_ci			WARN("MASK_THEN_SHIFT",
650162306a36Sopenharmony_ci			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
650262306a36Sopenharmony_ci		}
650362306a36Sopenharmony_ci
650462306a36Sopenharmony_ci# check for pointer comparisons to NULL
650562306a36Sopenharmony_ci		if ($perl_version_ok) {
650662306a36Sopenharmony_ci			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
650762306a36Sopenharmony_ci				my $val = $1;
650862306a36Sopenharmony_ci				my $equal = "!";
650962306a36Sopenharmony_ci				$equal = "" if ($4 eq "!=");
651062306a36Sopenharmony_ci				if (CHK("COMPARISON_TO_NULL",
651162306a36Sopenharmony_ci					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
651262306a36Sopenharmony_ci					    $fix) {
651362306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
651462306a36Sopenharmony_ci				}
651562306a36Sopenharmony_ci			}
651662306a36Sopenharmony_ci		}
651762306a36Sopenharmony_ci
651862306a36Sopenharmony_ci# check for bad placement of section $InitAttribute (e.g.: __initdata)
651962306a36Sopenharmony_ci		if ($line =~ /(\b$InitAttribute\b)/) {
652062306a36Sopenharmony_ci			my $attr = $1;
652162306a36Sopenharmony_ci			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
652262306a36Sopenharmony_ci				my $ptr = $1;
652362306a36Sopenharmony_ci				my $var = $2;
652462306a36Sopenharmony_ci				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
652562306a36Sopenharmony_ci				      ERROR("MISPLACED_INIT",
652662306a36Sopenharmony_ci					    "$attr should be placed after $var\n" . $herecurr)) ||
652762306a36Sopenharmony_ci				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
652862306a36Sopenharmony_ci				      WARN("MISPLACED_INIT",
652962306a36Sopenharmony_ci					   "$attr should be placed after $var\n" . $herecurr))) &&
653062306a36Sopenharmony_ci				    $fix) {
653162306a36Sopenharmony_ci					$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;
653262306a36Sopenharmony_ci				}
653362306a36Sopenharmony_ci			}
653462306a36Sopenharmony_ci		}
653562306a36Sopenharmony_ci
653662306a36Sopenharmony_ci# check for $InitAttributeData (ie: __initdata) with const
653762306a36Sopenharmony_ci		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
653862306a36Sopenharmony_ci			my $attr = $1;
653962306a36Sopenharmony_ci			$attr =~ /($InitAttributePrefix)(.*)/;
654062306a36Sopenharmony_ci			my $attr_prefix = $1;
654162306a36Sopenharmony_ci			my $attr_type = $2;
654262306a36Sopenharmony_ci			if (ERROR("INIT_ATTRIBUTE",
654362306a36Sopenharmony_ci				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
654462306a36Sopenharmony_ci			    $fix) {
654562306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
654662306a36Sopenharmony_ci				    s/$InitAttributeData/${attr_prefix}initconst/;
654762306a36Sopenharmony_ci			}
654862306a36Sopenharmony_ci		}
654962306a36Sopenharmony_ci
655062306a36Sopenharmony_ci# check for $InitAttributeConst (ie: __initconst) without const
655162306a36Sopenharmony_ci		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
655262306a36Sopenharmony_ci			my $attr = $1;
655362306a36Sopenharmony_ci			if (ERROR("INIT_ATTRIBUTE",
655462306a36Sopenharmony_ci				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
655562306a36Sopenharmony_ci			    $fix) {
655662306a36Sopenharmony_ci				my $lead = $fixed[$fixlinenr] =~
655762306a36Sopenharmony_ci				    /(^\+\s*(?:static\s+))/;
655862306a36Sopenharmony_ci				$lead = rtrim($1);
655962306a36Sopenharmony_ci				$lead = "$lead " if ($lead !~ /^\+$/);
656062306a36Sopenharmony_ci				$lead = "${lead}const ";
656162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
656262306a36Sopenharmony_ci			}
656362306a36Sopenharmony_ci		}
656462306a36Sopenharmony_ci
656562306a36Sopenharmony_ci# check for __read_mostly with const non-pointer (should just be const)
656662306a36Sopenharmony_ci		if ($line =~ /\b__read_mostly\b/ &&
656762306a36Sopenharmony_ci		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
656862306a36Sopenharmony_ci			if (ERROR("CONST_READ_MOSTLY",
656962306a36Sopenharmony_ci				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
657062306a36Sopenharmony_ci			    $fix) {
657162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
657262306a36Sopenharmony_ci			}
657362306a36Sopenharmony_ci		}
657462306a36Sopenharmony_ci
657562306a36Sopenharmony_ci# don't use __constant_<foo> functions outside of include/uapi/
657662306a36Sopenharmony_ci		if ($realfile !~ m@^include/uapi/@ &&
657762306a36Sopenharmony_ci		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
657862306a36Sopenharmony_ci			my $constant_func = $1;
657962306a36Sopenharmony_ci			my $func = $constant_func;
658062306a36Sopenharmony_ci			$func =~ s/^__constant_//;
658162306a36Sopenharmony_ci			if (WARN("CONSTANT_CONVERSION",
658262306a36Sopenharmony_ci				 "$constant_func should be $func\n" . $herecurr) &&
658362306a36Sopenharmony_ci			    $fix) {
658462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
658562306a36Sopenharmony_ci			}
658662306a36Sopenharmony_ci		}
658762306a36Sopenharmony_ci
658862306a36Sopenharmony_ci# prefer usleep_range over udelay
658962306a36Sopenharmony_ci		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
659062306a36Sopenharmony_ci			my $delay = $1;
659162306a36Sopenharmony_ci			# ignore udelay's < 10, however
659262306a36Sopenharmony_ci			if (! ($delay < 10) ) {
659362306a36Sopenharmony_ci				CHK("USLEEP_RANGE",
659462306a36Sopenharmony_ci				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
659562306a36Sopenharmony_ci			}
659662306a36Sopenharmony_ci			if ($delay > 2000) {
659762306a36Sopenharmony_ci				WARN("LONG_UDELAY",
659862306a36Sopenharmony_ci				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
659962306a36Sopenharmony_ci			}
660062306a36Sopenharmony_ci		}
660162306a36Sopenharmony_ci
660262306a36Sopenharmony_ci# warn about unexpectedly long msleep's
660362306a36Sopenharmony_ci		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
660462306a36Sopenharmony_ci			if ($1 < 20) {
660562306a36Sopenharmony_ci				WARN("MSLEEP",
660662306a36Sopenharmony_ci				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
660762306a36Sopenharmony_ci			}
660862306a36Sopenharmony_ci		}
660962306a36Sopenharmony_ci
661062306a36Sopenharmony_ci# check for comparisons of jiffies
661162306a36Sopenharmony_ci		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
661262306a36Sopenharmony_ci			WARN("JIFFIES_COMPARISON",
661362306a36Sopenharmony_ci			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
661462306a36Sopenharmony_ci		}
661562306a36Sopenharmony_ci
661662306a36Sopenharmony_ci# check for comparisons of get_jiffies_64()
661762306a36Sopenharmony_ci		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
661862306a36Sopenharmony_ci			WARN("JIFFIES_COMPARISON",
661962306a36Sopenharmony_ci			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
662062306a36Sopenharmony_ci		}
662162306a36Sopenharmony_ci
662262306a36Sopenharmony_ci# warn about #ifdefs in C files
662362306a36Sopenharmony_ci#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
662462306a36Sopenharmony_ci#			print "#ifdef in C files should be avoided\n";
662562306a36Sopenharmony_ci#			print "$herecurr";
662662306a36Sopenharmony_ci#			$clean = 0;
662762306a36Sopenharmony_ci#		}
662862306a36Sopenharmony_ci
662962306a36Sopenharmony_ci# warn about spacing in #ifdefs
663062306a36Sopenharmony_ci		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
663162306a36Sopenharmony_ci			if (ERROR("SPACING",
663262306a36Sopenharmony_ci				  "exactly one space required after that #$1\n" . $herecurr) &&
663362306a36Sopenharmony_ci			    $fix) {
663462306a36Sopenharmony_ci				$fixed[$fixlinenr] =~
663562306a36Sopenharmony_ci				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
663662306a36Sopenharmony_ci			}
663762306a36Sopenharmony_ci
663862306a36Sopenharmony_ci		}
663962306a36Sopenharmony_ci
664062306a36Sopenharmony_ci# check for spinlock_t definitions without a comment.
664162306a36Sopenharmony_ci		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
664262306a36Sopenharmony_ci		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
664362306a36Sopenharmony_ci			my $which = $1;
664462306a36Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
664562306a36Sopenharmony_ci				CHK("UNCOMMENTED_DEFINITION",
664662306a36Sopenharmony_ci				    "$1 definition without comment\n" . $herecurr);
664762306a36Sopenharmony_ci			}
664862306a36Sopenharmony_ci		}
664962306a36Sopenharmony_ci# check for memory barriers without a comment.
665062306a36Sopenharmony_ci
665162306a36Sopenharmony_ci		my $barriers = qr{
665262306a36Sopenharmony_ci			mb|
665362306a36Sopenharmony_ci			rmb|
665462306a36Sopenharmony_ci			wmb
665562306a36Sopenharmony_ci		}x;
665662306a36Sopenharmony_ci		my $barrier_stems = qr{
665762306a36Sopenharmony_ci			mb__before_atomic|
665862306a36Sopenharmony_ci			mb__after_atomic|
665962306a36Sopenharmony_ci			store_release|
666062306a36Sopenharmony_ci			load_acquire|
666162306a36Sopenharmony_ci			store_mb|
666262306a36Sopenharmony_ci			(?:$barriers)
666362306a36Sopenharmony_ci		}x;
666462306a36Sopenharmony_ci		my $all_barriers = qr{
666562306a36Sopenharmony_ci			(?:$barriers)|
666662306a36Sopenharmony_ci			smp_(?:$barrier_stems)|
666762306a36Sopenharmony_ci			virt_(?:$barrier_stems)
666862306a36Sopenharmony_ci		}x;
666962306a36Sopenharmony_ci
667062306a36Sopenharmony_ci		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
667162306a36Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
667262306a36Sopenharmony_ci				WARN("MEMORY_BARRIER",
667362306a36Sopenharmony_ci				     "memory barrier without comment\n" . $herecurr);
667462306a36Sopenharmony_ci			}
667562306a36Sopenharmony_ci		}
667662306a36Sopenharmony_ci
667762306a36Sopenharmony_ci		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
667862306a36Sopenharmony_ci
667962306a36Sopenharmony_ci		if ($realfile !~ m@^include/asm-generic/@ &&
668062306a36Sopenharmony_ci		    $realfile !~ m@/barrier\.h$@ &&
668162306a36Sopenharmony_ci		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
668262306a36Sopenharmony_ci		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
668362306a36Sopenharmony_ci			WARN("MEMORY_BARRIER",
668462306a36Sopenharmony_ci			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
668562306a36Sopenharmony_ci		}
668662306a36Sopenharmony_ci
668762306a36Sopenharmony_ci# check for waitqueue_active without a comment.
668862306a36Sopenharmony_ci		if ($line =~ /\bwaitqueue_active\s*\(/) {
668962306a36Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
669062306a36Sopenharmony_ci				WARN("WAITQUEUE_ACTIVE",
669162306a36Sopenharmony_ci				     "waitqueue_active without comment\n" . $herecurr);
669262306a36Sopenharmony_ci			}
669362306a36Sopenharmony_ci		}
669462306a36Sopenharmony_ci
669562306a36Sopenharmony_ci# check for data_race without a comment.
669662306a36Sopenharmony_ci		if ($line =~ /\bdata_race\s*\(/) {
669762306a36Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
669862306a36Sopenharmony_ci				WARN("DATA_RACE",
669962306a36Sopenharmony_ci				     "data_race without comment\n" . $herecurr);
670062306a36Sopenharmony_ci			}
670162306a36Sopenharmony_ci		}
670262306a36Sopenharmony_ci
670362306a36Sopenharmony_ci# check of hardware specific defines
670462306a36Sopenharmony_ci		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
670562306a36Sopenharmony_ci			CHK("ARCH_DEFINES",
670662306a36Sopenharmony_ci			    "architecture specific defines should be avoided\n" .  $herecurr);
670762306a36Sopenharmony_ci		}
670862306a36Sopenharmony_ci
670962306a36Sopenharmony_ci# check that the storage class is not after a type
671062306a36Sopenharmony_ci		if ($line =~ /\b($Type)\s+($Storage)\b/) {
671162306a36Sopenharmony_ci			WARN("STORAGE_CLASS",
671262306a36Sopenharmony_ci			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
671362306a36Sopenharmony_ci		}
671462306a36Sopenharmony_ci# Check that the storage class is at the beginning of a declaration
671562306a36Sopenharmony_ci		if ($line =~ /\b$Storage\b/ &&
671662306a36Sopenharmony_ci		    $line !~ /^.\s*$Storage/ &&
671762306a36Sopenharmony_ci		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
671862306a36Sopenharmony_ci		    $1 !~ /[\,\)]\s*$/) {
671962306a36Sopenharmony_ci			WARN("STORAGE_CLASS",
672062306a36Sopenharmony_ci			     "storage class should be at the beginning of the declaration\n" . $herecurr);
672162306a36Sopenharmony_ci		}
672262306a36Sopenharmony_ci
672362306a36Sopenharmony_ci# check the location of the inline attribute, that it is between
672462306a36Sopenharmony_ci# storage class and type.
672562306a36Sopenharmony_ci		if ($line =~ /\b$Type\s+$Inline\b/ ||
672662306a36Sopenharmony_ci		    $line =~ /\b$Inline\s+$Storage\b/) {
672762306a36Sopenharmony_ci			ERROR("INLINE_LOCATION",
672862306a36Sopenharmony_ci			      "inline keyword should sit between storage class and type\n" . $herecurr);
672962306a36Sopenharmony_ci		}
673062306a36Sopenharmony_ci
673162306a36Sopenharmony_ci# Check for __inline__ and __inline, prefer inline
673262306a36Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
673362306a36Sopenharmony_ci		    $line =~ /\b(__inline__|__inline)\b/) {
673462306a36Sopenharmony_ci			if (WARN("INLINE",
673562306a36Sopenharmony_ci				 "plain inline is preferred over $1\n" . $herecurr) &&
673662306a36Sopenharmony_ci			    $fix) {
673762306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
673862306a36Sopenharmony_ci
673962306a36Sopenharmony_ci			}
674062306a36Sopenharmony_ci		}
674162306a36Sopenharmony_ci
674262306a36Sopenharmony_ci# Check for compiler attributes
674362306a36Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
674462306a36Sopenharmony_ci		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
674562306a36Sopenharmony_ci			my $attr = $1;
674662306a36Sopenharmony_ci			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
674762306a36Sopenharmony_ci
674862306a36Sopenharmony_ci			my %attr_list = (
674962306a36Sopenharmony_ci				"alias"				=> "__alias",
675062306a36Sopenharmony_ci				"aligned"			=> "__aligned",
675162306a36Sopenharmony_ci				"always_inline"			=> "__always_inline",
675262306a36Sopenharmony_ci				"assume_aligned"		=> "__assume_aligned",
675362306a36Sopenharmony_ci				"cold"				=> "__cold",
675462306a36Sopenharmony_ci				"const"				=> "__attribute_const__",
675562306a36Sopenharmony_ci				"copy"				=> "__copy",
675662306a36Sopenharmony_ci				"designated_init"		=> "__designated_init",
675762306a36Sopenharmony_ci				"externally_visible"		=> "__visible",
675862306a36Sopenharmony_ci				"format"			=> "printf|scanf",
675962306a36Sopenharmony_ci				"gnu_inline"			=> "__gnu_inline",
676062306a36Sopenharmony_ci				"malloc"			=> "__malloc",
676162306a36Sopenharmony_ci				"mode"				=> "__mode",
676262306a36Sopenharmony_ci				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
676362306a36Sopenharmony_ci				"noclone"			=> "__noclone",
676462306a36Sopenharmony_ci				"noinline"			=> "noinline",
676562306a36Sopenharmony_ci				"nonstring"			=> "__nonstring",
676662306a36Sopenharmony_ci				"noreturn"			=> "__noreturn",
676762306a36Sopenharmony_ci				"packed"			=> "__packed",
676862306a36Sopenharmony_ci				"pure"				=> "__pure",
676962306a36Sopenharmony_ci				"section"			=> "__section",
677062306a36Sopenharmony_ci				"used"				=> "__used",
677162306a36Sopenharmony_ci				"weak"				=> "__weak"
677262306a36Sopenharmony_ci			);
677362306a36Sopenharmony_ci
677462306a36Sopenharmony_ci			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
677562306a36Sopenharmony_ci				my $orig_attr = $1;
677662306a36Sopenharmony_ci				my $params = '';
677762306a36Sopenharmony_ci				$params = $2 if defined($2);
677862306a36Sopenharmony_ci				my $curr_attr = $orig_attr;
677962306a36Sopenharmony_ci				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
678062306a36Sopenharmony_ci				if (exists($attr_list{$curr_attr})) {
678162306a36Sopenharmony_ci					my $new = $attr_list{$curr_attr};
678262306a36Sopenharmony_ci					if ($curr_attr eq "format" && $params) {
678362306a36Sopenharmony_ci						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
678462306a36Sopenharmony_ci						$new = "__$1\($2";
678562306a36Sopenharmony_ci					} else {
678662306a36Sopenharmony_ci						$new = "$new$params";
678762306a36Sopenharmony_ci					}
678862306a36Sopenharmony_ci					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
678962306a36Sopenharmony_ci						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
679062306a36Sopenharmony_ci					    $fix) {
679162306a36Sopenharmony_ci						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
679262306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/$remove//;
679362306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
679462306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
679562306a36Sopenharmony_ci						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
679662306a36Sopenharmony_ci					}
679762306a36Sopenharmony_ci				}
679862306a36Sopenharmony_ci			}
679962306a36Sopenharmony_ci
680062306a36Sopenharmony_ci			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
680162306a36Sopenharmony_ci			if ($attr =~ /^_*unused/) {
680262306a36Sopenharmony_ci				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
680362306a36Sopenharmony_ci				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
680462306a36Sopenharmony_ci			}
680562306a36Sopenharmony_ci		}
680662306a36Sopenharmony_ci
680762306a36Sopenharmony_ci# Check for __attribute__ weak, or __weak declarations (may have link issues)
680862306a36Sopenharmony_ci		if ($perl_version_ok &&
680962306a36Sopenharmony_ci		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
681062306a36Sopenharmony_ci		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
681162306a36Sopenharmony_ci		     $line =~ /\b__weak\b/)) {
681262306a36Sopenharmony_ci			ERROR("WEAK_DECLARATION",
681362306a36Sopenharmony_ci			      "Using weak declarations can have unintended link defects\n" . $herecurr);
681462306a36Sopenharmony_ci		}
681562306a36Sopenharmony_ci
681662306a36Sopenharmony_ci# check for c99 types like uint8_t used outside of uapi/ and tools/
681762306a36Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
681862306a36Sopenharmony_ci		    $realfile !~ m@\btools/@ &&
681962306a36Sopenharmony_ci		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
682062306a36Sopenharmony_ci			my $type = $1;
682162306a36Sopenharmony_ci			if ($type =~ /\b($typeC99Typedefs)\b/) {
682262306a36Sopenharmony_ci				$type = $1;
682362306a36Sopenharmony_ci				my $kernel_type = 'u';
682462306a36Sopenharmony_ci				$kernel_type = 's' if ($type =~ /^_*[si]/);
682562306a36Sopenharmony_ci				$type =~ /(\d+)/;
682662306a36Sopenharmony_ci				$kernel_type .= $1;
682762306a36Sopenharmony_ci				if (CHK("PREFER_KERNEL_TYPES",
682862306a36Sopenharmony_ci					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
682962306a36Sopenharmony_ci				    $fix) {
683062306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
683162306a36Sopenharmony_ci				}
683262306a36Sopenharmony_ci			}
683362306a36Sopenharmony_ci		}
683462306a36Sopenharmony_ci
683562306a36Sopenharmony_ci# check for cast of C90 native int or longer types constants
683662306a36Sopenharmony_ci		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
683762306a36Sopenharmony_ci			my $cast = $1;
683862306a36Sopenharmony_ci			my $const = $2;
683962306a36Sopenharmony_ci			my $suffix = "";
684062306a36Sopenharmony_ci			my $newconst = $const;
684162306a36Sopenharmony_ci			$newconst =~ s/${Int_type}$//;
684262306a36Sopenharmony_ci			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
684362306a36Sopenharmony_ci			if ($cast =~ /\blong\s+long\b/) {
684462306a36Sopenharmony_ci			    $suffix .= 'LL';
684562306a36Sopenharmony_ci			} elsif ($cast =~ /\blong\b/) {
684662306a36Sopenharmony_ci			    $suffix .= 'L';
684762306a36Sopenharmony_ci			}
684862306a36Sopenharmony_ci			if (WARN("TYPECAST_INT_CONSTANT",
684962306a36Sopenharmony_ci				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
685062306a36Sopenharmony_ci			    $fix) {
685162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
685262306a36Sopenharmony_ci			}
685362306a36Sopenharmony_ci		}
685462306a36Sopenharmony_ci
685562306a36Sopenharmony_ci# check for sizeof(&)
685662306a36Sopenharmony_ci		if ($line =~ /\bsizeof\s*\(\s*\&/) {
685762306a36Sopenharmony_ci			WARN("SIZEOF_ADDRESS",
685862306a36Sopenharmony_ci			     "sizeof(& should be avoided\n" . $herecurr);
685962306a36Sopenharmony_ci		}
686062306a36Sopenharmony_ci
686162306a36Sopenharmony_ci# check for sizeof without parenthesis
686262306a36Sopenharmony_ci		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
686362306a36Sopenharmony_ci			if (WARN("SIZEOF_PARENTHESIS",
686462306a36Sopenharmony_ci				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
686562306a36Sopenharmony_ci			    $fix) {
686662306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
686762306a36Sopenharmony_ci			}
686862306a36Sopenharmony_ci		}
686962306a36Sopenharmony_ci
687062306a36Sopenharmony_ci# check for struct spinlock declarations
687162306a36Sopenharmony_ci		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
687262306a36Sopenharmony_ci			WARN("USE_SPINLOCK_T",
687362306a36Sopenharmony_ci			     "struct spinlock should be spinlock_t\n" . $herecurr);
687462306a36Sopenharmony_ci		}
687562306a36Sopenharmony_ci
687662306a36Sopenharmony_ci# check for seq_printf uses that could be seq_puts
687762306a36Sopenharmony_ci		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
687862306a36Sopenharmony_ci			my $fmt = get_quoted_string($line, $rawline);
687962306a36Sopenharmony_ci			$fmt =~ s/%%//g;
688062306a36Sopenharmony_ci			if ($fmt !~ /%/) {
688162306a36Sopenharmony_ci				if (WARN("PREFER_SEQ_PUTS",
688262306a36Sopenharmony_ci					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
688362306a36Sopenharmony_ci				    $fix) {
688462306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
688562306a36Sopenharmony_ci				}
688662306a36Sopenharmony_ci			}
688762306a36Sopenharmony_ci		}
688862306a36Sopenharmony_ci
688962306a36Sopenharmony_ci# check for vsprintf extension %p<foo> misuses
689062306a36Sopenharmony_ci		if ($perl_version_ok &&
689162306a36Sopenharmony_ci		    defined $stat &&
689262306a36Sopenharmony_ci		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
689362306a36Sopenharmony_ci		    $1 !~ /^_*volatile_*$/) {
689462306a36Sopenharmony_ci			my $stat_real;
689562306a36Sopenharmony_ci
689662306a36Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
689762306a36Sopenharmony_ci			$lc = $lc + $linenr;
689862306a36Sopenharmony_ci		        for (my $count = $linenr; $count <= $lc; $count++) {
689962306a36Sopenharmony_ci				my $specifier;
690062306a36Sopenharmony_ci				my $extension;
690162306a36Sopenharmony_ci				my $qualifier;
690262306a36Sopenharmony_ci				my $bad_specifier = "";
690362306a36Sopenharmony_ci				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
690462306a36Sopenharmony_ci				$fmt =~ s/%%//g;
690562306a36Sopenharmony_ci
690662306a36Sopenharmony_ci				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
690762306a36Sopenharmony_ci					$specifier = $1;
690862306a36Sopenharmony_ci					$extension = $2;
690962306a36Sopenharmony_ci					$qualifier = $3;
691062306a36Sopenharmony_ci					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
691162306a36Sopenharmony_ci					    ($extension eq "f" &&
691262306a36Sopenharmony_ci					     defined $qualifier && $qualifier !~ /^w/) ||
691362306a36Sopenharmony_ci					    ($extension eq "4" &&
691462306a36Sopenharmony_ci					     defined $qualifier && $qualifier !~ /^cc/)) {
691562306a36Sopenharmony_ci						$bad_specifier = $specifier;
691662306a36Sopenharmony_ci						last;
691762306a36Sopenharmony_ci					}
691862306a36Sopenharmony_ci					if ($extension eq "x" && !defined($stat_real)) {
691962306a36Sopenharmony_ci						if (!defined($stat_real)) {
692062306a36Sopenharmony_ci							$stat_real = get_stat_real($linenr, $lc);
692162306a36Sopenharmony_ci						}
692262306a36Sopenharmony_ci						WARN("VSPRINTF_SPECIFIER_PX",
692362306a36Sopenharmony_ci						     "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");
692462306a36Sopenharmony_ci					}
692562306a36Sopenharmony_ci				}
692662306a36Sopenharmony_ci				if ($bad_specifier ne "") {
692762306a36Sopenharmony_ci					my $stat_real = get_stat_real($linenr, $lc);
692862306a36Sopenharmony_ci					my $msg_level = \&WARN;
692962306a36Sopenharmony_ci					my $ext_type = "Invalid";
693062306a36Sopenharmony_ci					my $use = "";
693162306a36Sopenharmony_ci					if ($bad_specifier =~ /p[Ff]/) {
693262306a36Sopenharmony_ci						$use = " - use %pS instead";
693362306a36Sopenharmony_ci						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
693462306a36Sopenharmony_ci					} elsif ($bad_specifier =~ /pA/) {
693562306a36Sopenharmony_ci						$use =  " - '%pA' is only intended to be used from Rust code";
693662306a36Sopenharmony_ci						$msg_level = \&ERROR;
693762306a36Sopenharmony_ci					}
693862306a36Sopenharmony_ci
693962306a36Sopenharmony_ci					&{$msg_level}("VSPRINTF_POINTER_EXTENSION",
694062306a36Sopenharmony_ci						      "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
694162306a36Sopenharmony_ci				}
694262306a36Sopenharmony_ci			}
694362306a36Sopenharmony_ci		}
694462306a36Sopenharmony_ci
694562306a36Sopenharmony_ci# Check for misused memsets
694662306a36Sopenharmony_ci		if ($perl_version_ok &&
694762306a36Sopenharmony_ci		    defined $stat &&
694862306a36Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
694962306a36Sopenharmony_ci
695062306a36Sopenharmony_ci			my $ms_addr = $2;
695162306a36Sopenharmony_ci			my $ms_val = $7;
695262306a36Sopenharmony_ci			my $ms_size = $12;
695362306a36Sopenharmony_ci
695462306a36Sopenharmony_ci			if ($ms_size =~ /^(0x|)0$/i) {
695562306a36Sopenharmony_ci				ERROR("MEMSET",
695662306a36Sopenharmony_ci				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
695762306a36Sopenharmony_ci			} elsif ($ms_size =~ /^(0x|)1$/i) {
695862306a36Sopenharmony_ci				WARN("MEMSET",
695962306a36Sopenharmony_ci				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
696062306a36Sopenharmony_ci			}
696162306a36Sopenharmony_ci		}
696262306a36Sopenharmony_ci
696362306a36Sopenharmony_ci# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
696462306a36Sopenharmony_ci#		if ($perl_version_ok &&
696562306a36Sopenharmony_ci#		    defined $stat &&
696662306a36Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
696762306a36Sopenharmony_ci#			if (WARN("PREFER_ETHER_ADDR_COPY",
696862306a36Sopenharmony_ci#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
696962306a36Sopenharmony_ci#			    $fix) {
697062306a36Sopenharmony_ci#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
697162306a36Sopenharmony_ci#			}
697262306a36Sopenharmony_ci#		}
697362306a36Sopenharmony_ci
697462306a36Sopenharmony_ci# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
697562306a36Sopenharmony_ci#		if ($perl_version_ok &&
697662306a36Sopenharmony_ci#		    defined $stat &&
697762306a36Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
697862306a36Sopenharmony_ci#			WARN("PREFER_ETHER_ADDR_EQUAL",
697962306a36Sopenharmony_ci#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
698062306a36Sopenharmony_ci#		}
698162306a36Sopenharmony_ci
698262306a36Sopenharmony_ci# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
698362306a36Sopenharmony_ci# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
698462306a36Sopenharmony_ci#		if ($perl_version_ok &&
698562306a36Sopenharmony_ci#		    defined $stat &&
698662306a36Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
698762306a36Sopenharmony_ci#
698862306a36Sopenharmony_ci#			my $ms_val = $7;
698962306a36Sopenharmony_ci#
699062306a36Sopenharmony_ci#			if ($ms_val =~ /^(?:0x|)0+$/i) {
699162306a36Sopenharmony_ci#				if (WARN("PREFER_ETH_ZERO_ADDR",
699262306a36Sopenharmony_ci#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
699362306a36Sopenharmony_ci#				    $fix) {
699462306a36Sopenharmony_ci#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
699562306a36Sopenharmony_ci#				}
699662306a36Sopenharmony_ci#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
699762306a36Sopenharmony_ci#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
699862306a36Sopenharmony_ci#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
699962306a36Sopenharmony_ci#				    $fix) {
700062306a36Sopenharmony_ci#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
700162306a36Sopenharmony_ci#				}
700262306a36Sopenharmony_ci#			}
700362306a36Sopenharmony_ci#		}
700462306a36Sopenharmony_ci
700562306a36Sopenharmony_ci# strcpy uses that should likely be strscpy
700662306a36Sopenharmony_ci		if ($line =~ /\bstrcpy\s*\(/) {
700762306a36Sopenharmony_ci			WARN("STRCPY",
700862306a36Sopenharmony_ci			     "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr);
700962306a36Sopenharmony_ci		}
701062306a36Sopenharmony_ci
701162306a36Sopenharmony_ci# strlcpy uses that should likely be strscpy
701262306a36Sopenharmony_ci		if ($line =~ /\bstrlcpy\s*\(/) {
701362306a36Sopenharmony_ci			WARN("STRLCPY",
701462306a36Sopenharmony_ci			     "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr);
701562306a36Sopenharmony_ci		}
701662306a36Sopenharmony_ci
701762306a36Sopenharmony_ci# strncpy uses that should likely be strscpy or strscpy_pad
701862306a36Sopenharmony_ci		if ($line =~ /\bstrncpy\s*\(/) {
701962306a36Sopenharmony_ci			WARN("STRNCPY",
702062306a36Sopenharmony_ci			     "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr);
702162306a36Sopenharmony_ci		}
702262306a36Sopenharmony_ci
702362306a36Sopenharmony_ci# typecasts on min/max could be min_t/max_t
702462306a36Sopenharmony_ci		if ($perl_version_ok &&
702562306a36Sopenharmony_ci		    defined $stat &&
702662306a36Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
702762306a36Sopenharmony_ci			if (defined $2 || defined $7) {
702862306a36Sopenharmony_ci				my $call = $1;
702962306a36Sopenharmony_ci				my $cast1 = deparenthesize($2);
703062306a36Sopenharmony_ci				my $arg1 = $3;
703162306a36Sopenharmony_ci				my $cast2 = deparenthesize($7);
703262306a36Sopenharmony_ci				my $arg2 = $8;
703362306a36Sopenharmony_ci				my $cast;
703462306a36Sopenharmony_ci
703562306a36Sopenharmony_ci				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
703662306a36Sopenharmony_ci					$cast = "$cast1 or $cast2";
703762306a36Sopenharmony_ci				} elsif ($cast1 ne "") {
703862306a36Sopenharmony_ci					$cast = $cast1;
703962306a36Sopenharmony_ci				} else {
704062306a36Sopenharmony_ci					$cast = $cast2;
704162306a36Sopenharmony_ci				}
704262306a36Sopenharmony_ci				WARN("MINMAX",
704362306a36Sopenharmony_ci				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
704462306a36Sopenharmony_ci			}
704562306a36Sopenharmony_ci		}
704662306a36Sopenharmony_ci
704762306a36Sopenharmony_ci# check usleep_range arguments
704862306a36Sopenharmony_ci		if ($perl_version_ok &&
704962306a36Sopenharmony_ci		    defined $stat &&
705062306a36Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
705162306a36Sopenharmony_ci			my $min = $1;
705262306a36Sopenharmony_ci			my $max = $7;
705362306a36Sopenharmony_ci			if ($min eq $max) {
705462306a36Sopenharmony_ci				WARN("USLEEP_RANGE",
705562306a36Sopenharmony_ci				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
705662306a36Sopenharmony_ci			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
705762306a36Sopenharmony_ci				 $min > $max) {
705862306a36Sopenharmony_ci				WARN("USLEEP_RANGE",
705962306a36Sopenharmony_ci				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
706062306a36Sopenharmony_ci			}
706162306a36Sopenharmony_ci		}
706262306a36Sopenharmony_ci
706362306a36Sopenharmony_ci# check for naked sscanf
706462306a36Sopenharmony_ci		if ($perl_version_ok &&
706562306a36Sopenharmony_ci		    defined $stat &&
706662306a36Sopenharmony_ci		    $line =~ /\bsscanf\b/ &&
706762306a36Sopenharmony_ci		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
706862306a36Sopenharmony_ci		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
706962306a36Sopenharmony_ci		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
707062306a36Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
707162306a36Sopenharmony_ci			$lc = $lc + $linenr;
707262306a36Sopenharmony_ci			my $stat_real = get_stat_real($linenr, $lc);
707362306a36Sopenharmony_ci			WARN("NAKED_SSCANF",
707462306a36Sopenharmony_ci			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
707562306a36Sopenharmony_ci		}
707662306a36Sopenharmony_ci
707762306a36Sopenharmony_ci# check for simple sscanf that should be kstrto<foo>
707862306a36Sopenharmony_ci		if ($perl_version_ok &&
707962306a36Sopenharmony_ci		    defined $stat &&
708062306a36Sopenharmony_ci		    $line =~ /\bsscanf\b/) {
708162306a36Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
708262306a36Sopenharmony_ci			$lc = $lc + $linenr;
708362306a36Sopenharmony_ci			my $stat_real = get_stat_real($linenr, $lc);
708462306a36Sopenharmony_ci			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
708562306a36Sopenharmony_ci				my $format = $6;
708662306a36Sopenharmony_ci				my $count = $format =~ tr@%@%@;
708762306a36Sopenharmony_ci				if ($count == 1 &&
708862306a36Sopenharmony_ci				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
708962306a36Sopenharmony_ci					WARN("SSCANF_TO_KSTRTO",
709062306a36Sopenharmony_ci					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
709162306a36Sopenharmony_ci				}
709262306a36Sopenharmony_ci			}
709362306a36Sopenharmony_ci		}
709462306a36Sopenharmony_ci
709562306a36Sopenharmony_ci# check for new externs in .h files.
709662306a36Sopenharmony_ci		if ($realfile =~ /\.h$/ &&
709762306a36Sopenharmony_ci		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
709862306a36Sopenharmony_ci			if (CHK("AVOID_EXTERNS",
709962306a36Sopenharmony_ci				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
710062306a36Sopenharmony_ci			    $fix) {
710162306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
710262306a36Sopenharmony_ci			}
710362306a36Sopenharmony_ci		}
710462306a36Sopenharmony_ci
710562306a36Sopenharmony_ci# check for new externs in .c files.
710662306a36Sopenharmony_ci		if ($realfile =~ /\.c$/ && defined $stat &&
710762306a36Sopenharmony_ci		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
710862306a36Sopenharmony_ci		{
710962306a36Sopenharmony_ci			my $function_name = $1;
711062306a36Sopenharmony_ci			my $paren_space = $2;
711162306a36Sopenharmony_ci
711262306a36Sopenharmony_ci			my $s = $stat;
711362306a36Sopenharmony_ci			if (defined $cond) {
711462306a36Sopenharmony_ci				substr($s, 0, length($cond), '');
711562306a36Sopenharmony_ci			}
711662306a36Sopenharmony_ci			if ($s =~ /^\s*;/)
711762306a36Sopenharmony_ci			{
711862306a36Sopenharmony_ci				WARN("AVOID_EXTERNS",
711962306a36Sopenharmony_ci				     "externs should be avoided in .c files\n" .  $herecurr);
712062306a36Sopenharmony_ci			}
712162306a36Sopenharmony_ci
712262306a36Sopenharmony_ci			if ($paren_space =~ /\n/) {
712362306a36Sopenharmony_ci				WARN("FUNCTION_ARGUMENTS",
712462306a36Sopenharmony_ci				     "arguments for function declarations should follow identifier\n" . $herecurr);
712562306a36Sopenharmony_ci			}
712662306a36Sopenharmony_ci
712762306a36Sopenharmony_ci		} elsif ($realfile =~ /\.c$/ && defined $stat &&
712862306a36Sopenharmony_ci		    $stat =~ /^\+extern struct\s+(\w+)\s+(\w+)\[\];/)
712962306a36Sopenharmony_ci		{
713062306a36Sopenharmony_ci			my ($st_type, $st_name) = ($1, $2);
713162306a36Sopenharmony_ci
713262306a36Sopenharmony_ci			for my $s (keys %maybe_linker_symbol) {
713362306a36Sopenharmony_ci			    #print "Linker symbol? $st_name : $s\n";
713462306a36Sopenharmony_ci			    goto LIKELY_LINKER_SYMBOL
713562306a36Sopenharmony_ci				if $st_name =~ /$s/;
713662306a36Sopenharmony_ci			}
713762306a36Sopenharmony_ci			WARN("AVOID_EXTERNS",
713862306a36Sopenharmony_ci			     "found a file-scoped extern type:$st_type name:$st_name in .c file\n"
713962306a36Sopenharmony_ci			     . "is this a linker symbol ?\n" . $herecurr);
714062306a36Sopenharmony_ci		  LIKELY_LINKER_SYMBOL:
714162306a36Sopenharmony_ci
714262306a36Sopenharmony_ci		} elsif ($realfile =~ /\.c$/ && defined $stat &&
714362306a36Sopenharmony_ci		    $stat =~ /^.\s*extern\s+/)
714462306a36Sopenharmony_ci		{
714562306a36Sopenharmony_ci			WARN("AVOID_EXTERNS",
714662306a36Sopenharmony_ci			     "externs should be avoided in .c files\n" .  $herecurr);
714762306a36Sopenharmony_ci		}
714862306a36Sopenharmony_ci
714962306a36Sopenharmony_ci# check for function declarations that have arguments without identifier names
715062306a36Sopenharmony_ci		if (defined $stat &&
715162306a36Sopenharmony_ci		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
715262306a36Sopenharmony_ci		    $1 ne "void") {
715362306a36Sopenharmony_ci			my $args = trim($1);
715462306a36Sopenharmony_ci			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
715562306a36Sopenharmony_ci				my $arg = trim($1);
715662306a36Sopenharmony_ci				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
715762306a36Sopenharmony_ci					WARN("FUNCTION_ARGUMENTS",
715862306a36Sopenharmony_ci					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
715962306a36Sopenharmony_ci				}
716062306a36Sopenharmony_ci			}
716162306a36Sopenharmony_ci		}
716262306a36Sopenharmony_ci
716362306a36Sopenharmony_ci# check for function definitions
716462306a36Sopenharmony_ci		if ($perl_version_ok &&
716562306a36Sopenharmony_ci		    defined $stat &&
716662306a36Sopenharmony_ci		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
716762306a36Sopenharmony_ci			$context_function = $1;
716862306a36Sopenharmony_ci
716962306a36Sopenharmony_ci# check for multiline function definition with misplaced open brace
717062306a36Sopenharmony_ci			my $ok = 0;
717162306a36Sopenharmony_ci			my $cnt = statement_rawlines($stat);
717262306a36Sopenharmony_ci			my $herectx = $here . "\n";
717362306a36Sopenharmony_ci			for (my $n = 0; $n < $cnt; $n++) {
717462306a36Sopenharmony_ci				my $rl = raw_line($linenr, $n);
717562306a36Sopenharmony_ci				$herectx .=  $rl . "\n";
717662306a36Sopenharmony_ci				$ok = 1 if ($rl =~ /^[ \+]\{/);
717762306a36Sopenharmony_ci				$ok = 1 if ($rl =~ /\{/ && $n == 0);
717862306a36Sopenharmony_ci				last if $rl =~ /^[ \+].*\{/;
717962306a36Sopenharmony_ci			}
718062306a36Sopenharmony_ci			if (!$ok) {
718162306a36Sopenharmony_ci				ERROR("OPEN_BRACE",
718262306a36Sopenharmony_ci				      "open brace '{' following function definitions go on the next line\n" . $herectx);
718362306a36Sopenharmony_ci			}
718462306a36Sopenharmony_ci		}
718562306a36Sopenharmony_ci
718662306a36Sopenharmony_ci# checks for new __setup's
718762306a36Sopenharmony_ci		if ($rawline =~ /\b__setup\("([^"]*)"/) {
718862306a36Sopenharmony_ci			my $name = $1;
718962306a36Sopenharmony_ci
719062306a36Sopenharmony_ci			if (!grep(/$name/, @setup_docs)) {
719162306a36Sopenharmony_ci				CHK("UNDOCUMENTED_SETUP",
719262306a36Sopenharmony_ci				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
719362306a36Sopenharmony_ci			}
719462306a36Sopenharmony_ci		}
719562306a36Sopenharmony_ci
719662306a36Sopenharmony_ci# check for pointless casting of alloc functions
719762306a36Sopenharmony_ci		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
719862306a36Sopenharmony_ci			WARN("UNNECESSARY_CASTS",
719962306a36Sopenharmony_ci			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
720062306a36Sopenharmony_ci		}
720162306a36Sopenharmony_ci
720262306a36Sopenharmony_ci# alloc style
720362306a36Sopenharmony_ci# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
720462306a36Sopenharmony_ci		if ($perl_version_ok &&
720562306a36Sopenharmony_ci		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
720662306a36Sopenharmony_ci			CHK("ALLOC_SIZEOF_STRUCT",
720762306a36Sopenharmony_ci			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
720862306a36Sopenharmony_ci		}
720962306a36Sopenharmony_ci
721062306a36Sopenharmony_ci# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc
721162306a36Sopenharmony_ci		if ($perl_version_ok &&
721262306a36Sopenharmony_ci		    defined $stat &&
721362306a36Sopenharmony_ci		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
721462306a36Sopenharmony_ci			my $oldfunc = $3;
721562306a36Sopenharmony_ci			my $a1 = $4;
721662306a36Sopenharmony_ci			my $a2 = $10;
721762306a36Sopenharmony_ci			my $newfunc = "kmalloc_array";
721862306a36Sopenharmony_ci			$newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");
721962306a36Sopenharmony_ci			$newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");
722062306a36Sopenharmony_ci			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
722162306a36Sopenharmony_ci			my $r1 = $a1;
722262306a36Sopenharmony_ci			my $r2 = $a2;
722362306a36Sopenharmony_ci			if ($a1 =~ /^sizeof\s*\S/) {
722462306a36Sopenharmony_ci				$r1 = $a2;
722562306a36Sopenharmony_ci				$r2 = $a1;
722662306a36Sopenharmony_ci			}
722762306a36Sopenharmony_ci			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
722862306a36Sopenharmony_ci			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
722962306a36Sopenharmony_ci				my $cnt = statement_rawlines($stat);
723062306a36Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
723162306a36Sopenharmony_ci
723262306a36Sopenharmony_ci				if (WARN("ALLOC_WITH_MULTIPLY",
723362306a36Sopenharmony_ci					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
723462306a36Sopenharmony_ci				    $cnt == 1 &&
723562306a36Sopenharmony_ci				    $fix) {
723662306a36Sopenharmony_ci					$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;
723762306a36Sopenharmony_ci				}
723862306a36Sopenharmony_ci			}
723962306a36Sopenharmony_ci		}
724062306a36Sopenharmony_ci
724162306a36Sopenharmony_ci# check for krealloc arg reuse
724262306a36Sopenharmony_ci		if ($perl_version_ok &&
724362306a36Sopenharmony_ci		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
724462306a36Sopenharmony_ci		    $1 eq $3) {
724562306a36Sopenharmony_ci			WARN("KREALLOC_ARG_REUSE",
724662306a36Sopenharmony_ci			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
724762306a36Sopenharmony_ci		}
724862306a36Sopenharmony_ci
724962306a36Sopenharmony_ci# check for alloc argument mismatch
725062306a36Sopenharmony_ci		if ($line =~ /\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/) {
725162306a36Sopenharmony_ci			WARN("ALLOC_ARRAY_ARGS",
725262306a36Sopenharmony_ci			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
725362306a36Sopenharmony_ci		}
725462306a36Sopenharmony_ci
725562306a36Sopenharmony_ci# check for multiple semicolons
725662306a36Sopenharmony_ci		if ($line =~ /;\s*;\s*$/) {
725762306a36Sopenharmony_ci			if (WARN("ONE_SEMICOLON",
725862306a36Sopenharmony_ci				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
725962306a36Sopenharmony_ci			    $fix) {
726062306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
726162306a36Sopenharmony_ci			}
726262306a36Sopenharmony_ci		}
726362306a36Sopenharmony_ci
726462306a36Sopenharmony_ci# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
726562306a36Sopenharmony_ci		if ($realfile !~ m@^include/uapi/@ &&
726662306a36Sopenharmony_ci		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
726762306a36Sopenharmony_ci			my $ull = "";
726862306a36Sopenharmony_ci			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
726962306a36Sopenharmony_ci			if (CHK("BIT_MACRO",
727062306a36Sopenharmony_ci				"Prefer using the BIT$ull macro\n" . $herecurr) &&
727162306a36Sopenharmony_ci			    $fix) {
727262306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
727362306a36Sopenharmony_ci			}
727462306a36Sopenharmony_ci		}
727562306a36Sopenharmony_ci
727662306a36Sopenharmony_ci# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
727762306a36Sopenharmony_ci		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
727862306a36Sopenharmony_ci			WARN("IS_ENABLED_CONFIG",
727962306a36Sopenharmony_ci			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
728062306a36Sopenharmony_ci		}
728162306a36Sopenharmony_ci
728262306a36Sopenharmony_ci# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
728362306a36Sopenharmony_ci		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
728462306a36Sopenharmony_ci			my $config = $1;
728562306a36Sopenharmony_ci			if (WARN("PREFER_IS_ENABLED",
728662306a36Sopenharmony_ci				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
728762306a36Sopenharmony_ci			    $fix) {
728862306a36Sopenharmony_ci				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
728962306a36Sopenharmony_ci			}
729062306a36Sopenharmony_ci		}
729162306a36Sopenharmony_ci
729262306a36Sopenharmony_ci# check for /* fallthrough */ like comment, prefer fallthrough;
729362306a36Sopenharmony_ci		my @fallthroughs = (
729462306a36Sopenharmony_ci			'fallthrough',
729562306a36Sopenharmony_ci			'@fallthrough@',
729662306a36Sopenharmony_ci			'lint -fallthrough[ \t]*',
729762306a36Sopenharmony_ci			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
729862306a36Sopenharmony_ci			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
729962306a36Sopenharmony_ci			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
730062306a36Sopenharmony_ci			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
730162306a36Sopenharmony_ci		    );
730262306a36Sopenharmony_ci		if ($raw_comment ne '') {
730362306a36Sopenharmony_ci			foreach my $ft (@fallthroughs) {
730462306a36Sopenharmony_ci				if ($raw_comment =~ /$ft/) {
730562306a36Sopenharmony_ci					my $msg_level = \&WARN;
730662306a36Sopenharmony_ci					$msg_level = \&CHK if ($file);
730762306a36Sopenharmony_ci					&{$msg_level}("PREFER_FALLTHROUGH",
730862306a36Sopenharmony_ci						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
730962306a36Sopenharmony_ci					last;
731062306a36Sopenharmony_ci				}
731162306a36Sopenharmony_ci			}
731262306a36Sopenharmony_ci		}
731362306a36Sopenharmony_ci
731462306a36Sopenharmony_ci# check for switch/default statements without a break;
731562306a36Sopenharmony_ci		if ($perl_version_ok &&
731662306a36Sopenharmony_ci		    defined $stat &&
731762306a36Sopenharmony_ci		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
731862306a36Sopenharmony_ci			my $cnt = statement_rawlines($stat);
731962306a36Sopenharmony_ci			my $herectx = get_stat_here($linenr, $cnt, $here);
732062306a36Sopenharmony_ci
732162306a36Sopenharmony_ci			WARN("DEFAULT_NO_BREAK",
732262306a36Sopenharmony_ci			     "switch default: should use break\n" . $herectx);
732362306a36Sopenharmony_ci		}
732462306a36Sopenharmony_ci
732562306a36Sopenharmony_ci# check for gcc specific __FUNCTION__
732662306a36Sopenharmony_ci		if ($line =~ /\b__FUNCTION__\b/) {
732762306a36Sopenharmony_ci			if (WARN("USE_FUNC",
732862306a36Sopenharmony_ci				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
732962306a36Sopenharmony_ci			    $fix) {
733062306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
733162306a36Sopenharmony_ci			}
733262306a36Sopenharmony_ci		}
733362306a36Sopenharmony_ci
733462306a36Sopenharmony_ci# check for uses of __DATE__, __TIME__, __TIMESTAMP__
733562306a36Sopenharmony_ci		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
733662306a36Sopenharmony_ci			ERROR("DATE_TIME",
733762306a36Sopenharmony_ci			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
733862306a36Sopenharmony_ci		}
733962306a36Sopenharmony_ci
734062306a36Sopenharmony_ci# check for use of yield()
734162306a36Sopenharmony_ci		if ($line =~ /\byield\s*\(\s*\)/) {
734262306a36Sopenharmony_ci			WARN("YIELD",
734362306a36Sopenharmony_ci			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
734462306a36Sopenharmony_ci		}
734562306a36Sopenharmony_ci
734662306a36Sopenharmony_ci# check for comparisons against true and false
734762306a36Sopenharmony_ci		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
734862306a36Sopenharmony_ci			my $lead = $1;
734962306a36Sopenharmony_ci			my $arg = $2;
735062306a36Sopenharmony_ci			my $test = $3;
735162306a36Sopenharmony_ci			my $otype = $4;
735262306a36Sopenharmony_ci			my $trail = $5;
735362306a36Sopenharmony_ci			my $op = "!";
735462306a36Sopenharmony_ci
735562306a36Sopenharmony_ci			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
735662306a36Sopenharmony_ci
735762306a36Sopenharmony_ci			my $type = lc($otype);
735862306a36Sopenharmony_ci			if ($type =~ /^(?:true|false)$/) {
735962306a36Sopenharmony_ci				if (("$test" eq "==" && "$type" eq "true") ||
736062306a36Sopenharmony_ci				    ("$test" eq "!=" && "$type" eq "false")) {
736162306a36Sopenharmony_ci					$op = "";
736262306a36Sopenharmony_ci				}
736362306a36Sopenharmony_ci
736462306a36Sopenharmony_ci				CHK("BOOL_COMPARISON",
736562306a36Sopenharmony_ci				    "Using comparison to $otype is error prone\n" . $herecurr);
736662306a36Sopenharmony_ci
736762306a36Sopenharmony_ci## maybe suggesting a correct construct would better
736862306a36Sopenharmony_ci##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
736962306a36Sopenharmony_ci
737062306a36Sopenharmony_ci			}
737162306a36Sopenharmony_ci		}
737262306a36Sopenharmony_ci
737362306a36Sopenharmony_ci# check for semaphores initialized locked
737462306a36Sopenharmony_ci		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
737562306a36Sopenharmony_ci			WARN("CONSIDER_COMPLETION",
737662306a36Sopenharmony_ci			     "consider using a completion\n" . $herecurr);
737762306a36Sopenharmony_ci		}
737862306a36Sopenharmony_ci
737962306a36Sopenharmony_ci# recommend kstrto* over simple_strto* and strict_strto*
738062306a36Sopenharmony_ci		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
738162306a36Sopenharmony_ci			WARN("CONSIDER_KSTRTO",
738262306a36Sopenharmony_ci			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
738362306a36Sopenharmony_ci		}
738462306a36Sopenharmony_ci
738562306a36Sopenharmony_ci# check for __initcall(), use device_initcall() explicitly or more appropriate function please
738662306a36Sopenharmony_ci		if ($line =~ /^.\s*__initcall\s*\(/) {
738762306a36Sopenharmony_ci			WARN("USE_DEVICE_INITCALL",
738862306a36Sopenharmony_ci			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
738962306a36Sopenharmony_ci		}
739062306a36Sopenharmony_ci
739162306a36Sopenharmony_ci# check for spin_is_locked(), suggest lockdep instead
739262306a36Sopenharmony_ci		if ($line =~ /\bspin_is_locked\(/) {
739362306a36Sopenharmony_ci			WARN("USE_LOCKDEP",
739462306a36Sopenharmony_ci			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
739562306a36Sopenharmony_ci		}
739662306a36Sopenharmony_ci
739762306a36Sopenharmony_ci# check for deprecated apis
739862306a36Sopenharmony_ci		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
739962306a36Sopenharmony_ci			my $deprecated_api = $1;
740062306a36Sopenharmony_ci			my $new_api = $deprecated_apis{$deprecated_api};
740162306a36Sopenharmony_ci			WARN("DEPRECATED_API",
740262306a36Sopenharmony_ci			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
740362306a36Sopenharmony_ci		}
740462306a36Sopenharmony_ci
740562306a36Sopenharmony_ci# check for various structs that are normally const (ops, kgdb, device_tree)
740662306a36Sopenharmony_ci# and avoid what seem like struct definitions 'struct foo {'
740762306a36Sopenharmony_ci		if (defined($const_structs) &&
740862306a36Sopenharmony_ci		    $line !~ /\bconst\b/ &&
740962306a36Sopenharmony_ci		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
741062306a36Sopenharmony_ci			WARN("CONST_STRUCT",
741162306a36Sopenharmony_ci			     "struct $1 should normally be const\n" . $herecurr);
741262306a36Sopenharmony_ci		}
741362306a36Sopenharmony_ci
741462306a36Sopenharmony_ci# use of NR_CPUS is usually wrong
741562306a36Sopenharmony_ci# ignore definitions of NR_CPUS and usage to define arrays as likely right
741662306a36Sopenharmony_ci# ignore designated initializers using NR_CPUS
741762306a36Sopenharmony_ci		if ($line =~ /\bNR_CPUS\b/ &&
741862306a36Sopenharmony_ci		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
741962306a36Sopenharmony_ci		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
742062306a36Sopenharmony_ci		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
742162306a36Sopenharmony_ci		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
742262306a36Sopenharmony_ci		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
742362306a36Sopenharmony_ci		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
742462306a36Sopenharmony_ci		{
742562306a36Sopenharmony_ci			WARN("NR_CPUS",
742662306a36Sopenharmony_ci			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
742762306a36Sopenharmony_ci		}
742862306a36Sopenharmony_ci
742962306a36Sopenharmony_ci# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
743062306a36Sopenharmony_ci		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
743162306a36Sopenharmony_ci			ERROR("DEFINE_ARCH_HAS",
743262306a36Sopenharmony_ci			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
743362306a36Sopenharmony_ci		}
743462306a36Sopenharmony_ci
743562306a36Sopenharmony_ci# likely/unlikely comparisons similar to "(likely(foo) > 0)"
743662306a36Sopenharmony_ci		if ($perl_version_ok &&
743762306a36Sopenharmony_ci		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
743862306a36Sopenharmony_ci			WARN("LIKELY_MISUSE",
743962306a36Sopenharmony_ci			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
744062306a36Sopenharmony_ci		}
744162306a36Sopenharmony_ci
744262306a36Sopenharmony_ci# return sysfs_emit(foo, fmt, ...) fmt without newline
744362306a36Sopenharmony_ci		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
744462306a36Sopenharmony_ci		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
744562306a36Sopenharmony_ci			my $offset = $+[6] - 1;
744662306a36Sopenharmony_ci			if (WARN("SYSFS_EMIT",
744762306a36Sopenharmony_ci				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
744862306a36Sopenharmony_ci			    $fix) {
744962306a36Sopenharmony_ci				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
745062306a36Sopenharmony_ci			}
745162306a36Sopenharmony_ci		}
745262306a36Sopenharmony_ci
745362306a36Sopenharmony_ci# check for array definition/declarations that should use flexible arrays instead
745462306a36Sopenharmony_ci		if ($sline =~ /^[\+ ]\s*\}(?:\s*__packed)?\s*;\s*$/ &&
745562306a36Sopenharmony_ci		    $prevline =~ /^\+\s*(?:\}(?:\s*__packed\s*)?|$Type)\s*$Ident\s*\[\s*(0|1)\s*\]\s*;\s*$/) {
745662306a36Sopenharmony_ci			if (ERROR("FLEXIBLE_ARRAY",
745762306a36Sopenharmony_ci				  "Use C99 flexible arrays - see https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays\n" . $hereprev) &&
745862306a36Sopenharmony_ci			    $1 == '0' && $fix) {
745962306a36Sopenharmony_ci				$fixed[$fixlinenr - 1] =~ s/\[\s*0\s*\]/[]/;
746062306a36Sopenharmony_ci			}
746162306a36Sopenharmony_ci		}
746262306a36Sopenharmony_ci
746362306a36Sopenharmony_ci# nested likely/unlikely calls
746462306a36Sopenharmony_ci		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
746562306a36Sopenharmony_ci			WARN("LIKELY_MISUSE",
746662306a36Sopenharmony_ci			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
746762306a36Sopenharmony_ci		}
746862306a36Sopenharmony_ci
746962306a36Sopenharmony_ci# whine mightly about in_atomic
747062306a36Sopenharmony_ci		if ($line =~ /\bin_atomic\s*\(/) {
747162306a36Sopenharmony_ci			if ($realfile =~ m@^drivers/@) {
747262306a36Sopenharmony_ci				ERROR("IN_ATOMIC",
747362306a36Sopenharmony_ci				      "do not use in_atomic in drivers\n" . $herecurr);
747462306a36Sopenharmony_ci			} elsif ($realfile !~ m@^kernel/@) {
747562306a36Sopenharmony_ci				WARN("IN_ATOMIC",
747662306a36Sopenharmony_ci				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
747762306a36Sopenharmony_ci			}
747862306a36Sopenharmony_ci		}
747962306a36Sopenharmony_ci
748062306a36Sopenharmony_ci# Complain about RCU Tasks Trace used outside of BPF (and of course, RCU).
748162306a36Sopenharmony_ci		our $rcu_trace_funcs = qr{(?x:
748262306a36Sopenharmony_ci			rcu_read_lock_trace |
748362306a36Sopenharmony_ci			rcu_read_lock_trace_held |
748462306a36Sopenharmony_ci			rcu_read_unlock_trace |
748562306a36Sopenharmony_ci			call_rcu_tasks_trace |
748662306a36Sopenharmony_ci			synchronize_rcu_tasks_trace |
748762306a36Sopenharmony_ci			rcu_barrier_tasks_trace |
748862306a36Sopenharmony_ci			rcu_request_urgent_qs_task
748962306a36Sopenharmony_ci		)};
749062306a36Sopenharmony_ci		our $rcu_trace_paths = qr{(?x:
749162306a36Sopenharmony_ci			kernel/bpf/ |
749262306a36Sopenharmony_ci			include/linux/bpf |
749362306a36Sopenharmony_ci			net/bpf/ |
749462306a36Sopenharmony_ci			kernel/rcu/ |
749562306a36Sopenharmony_ci			include/linux/rcu
749662306a36Sopenharmony_ci		)};
749762306a36Sopenharmony_ci		if ($line =~ /\b($rcu_trace_funcs)\s*\(/) {
749862306a36Sopenharmony_ci			if ($realfile !~ m{^$rcu_trace_paths}) {
749962306a36Sopenharmony_ci				WARN("RCU_TASKS_TRACE",
750062306a36Sopenharmony_ci				     "use of RCU tasks trace is incorrect outside BPF or core RCU code\n" . $herecurr);
750162306a36Sopenharmony_ci			}
750262306a36Sopenharmony_ci		}
750362306a36Sopenharmony_ci
750462306a36Sopenharmony_ci# check for lockdep_set_novalidate_class
750562306a36Sopenharmony_ci		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
750662306a36Sopenharmony_ci		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
750762306a36Sopenharmony_ci			if ($realfile !~ m@^kernel/lockdep@ &&
750862306a36Sopenharmony_ci			    $realfile !~ m@^include/linux/lockdep@ &&
750962306a36Sopenharmony_ci			    $realfile !~ m@^drivers/base/core@) {
751062306a36Sopenharmony_ci				ERROR("LOCKDEP",
751162306a36Sopenharmony_ci				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
751262306a36Sopenharmony_ci			}
751362306a36Sopenharmony_ci		}
751462306a36Sopenharmony_ci
751562306a36Sopenharmony_ci		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
751662306a36Sopenharmony_ci		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
751762306a36Sopenharmony_ci			WARN("EXPORTED_WORLD_WRITABLE",
751862306a36Sopenharmony_ci			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
751962306a36Sopenharmony_ci		}
752062306a36Sopenharmony_ci
752162306a36Sopenharmony_ci# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
752262306a36Sopenharmony_ci# and whether or not function naming is typical and if
752362306a36Sopenharmony_ci# DEVICE_ATTR permissions uses are unusual too
752462306a36Sopenharmony_ci		if ($perl_version_ok &&
752562306a36Sopenharmony_ci		    defined $stat &&
752662306a36Sopenharmony_ci		    $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*\)/) {
752762306a36Sopenharmony_ci			my $var = $1;
752862306a36Sopenharmony_ci			my $perms = $2;
752962306a36Sopenharmony_ci			my $show = $3;
753062306a36Sopenharmony_ci			my $store = $4;
753162306a36Sopenharmony_ci			my $octal_perms = perms_to_octal($perms);
753262306a36Sopenharmony_ci			if ($show =~ /^${var}_show$/ &&
753362306a36Sopenharmony_ci			    $store =~ /^${var}_store$/ &&
753462306a36Sopenharmony_ci			    $octal_perms eq "0644") {
753562306a36Sopenharmony_ci				if (WARN("DEVICE_ATTR_RW",
753662306a36Sopenharmony_ci					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
753762306a36Sopenharmony_ci				    $fix) {
753862306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
753962306a36Sopenharmony_ci				}
754062306a36Sopenharmony_ci			} elsif ($show =~ /^${var}_show$/ &&
754162306a36Sopenharmony_ci				 $store =~ /^NULL$/ &&
754262306a36Sopenharmony_ci				 $octal_perms eq "0444") {
754362306a36Sopenharmony_ci				if (WARN("DEVICE_ATTR_RO",
754462306a36Sopenharmony_ci					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
754562306a36Sopenharmony_ci				    $fix) {
754662306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
754762306a36Sopenharmony_ci				}
754862306a36Sopenharmony_ci			} elsif ($show =~ /^NULL$/ &&
754962306a36Sopenharmony_ci				 $store =~ /^${var}_store$/ &&
755062306a36Sopenharmony_ci				 $octal_perms eq "0200") {
755162306a36Sopenharmony_ci				if (WARN("DEVICE_ATTR_WO",
755262306a36Sopenharmony_ci					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
755362306a36Sopenharmony_ci				    $fix) {
755462306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
755562306a36Sopenharmony_ci				}
755662306a36Sopenharmony_ci			} elsif ($octal_perms eq "0644" ||
755762306a36Sopenharmony_ci				 $octal_perms eq "0444" ||
755862306a36Sopenharmony_ci				 $octal_perms eq "0200") {
755962306a36Sopenharmony_ci				my $newshow = "$show";
756062306a36Sopenharmony_ci				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
756162306a36Sopenharmony_ci				my $newstore = $store;
756262306a36Sopenharmony_ci				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
756362306a36Sopenharmony_ci				my $rename = "";
756462306a36Sopenharmony_ci				if ($show ne $newshow) {
756562306a36Sopenharmony_ci					$rename .= " '$show' to '$newshow'";
756662306a36Sopenharmony_ci				}
756762306a36Sopenharmony_ci				if ($store ne $newstore) {
756862306a36Sopenharmony_ci					$rename .= " '$store' to '$newstore'";
756962306a36Sopenharmony_ci				}
757062306a36Sopenharmony_ci				WARN("DEVICE_ATTR_FUNCTIONS",
757162306a36Sopenharmony_ci				     "Consider renaming function(s)$rename\n" . $herecurr);
757262306a36Sopenharmony_ci			} else {
757362306a36Sopenharmony_ci				WARN("DEVICE_ATTR_PERMS",
757462306a36Sopenharmony_ci				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
757562306a36Sopenharmony_ci			}
757662306a36Sopenharmony_ci		}
757762306a36Sopenharmony_ci
757862306a36Sopenharmony_ci# Mode permission misuses where it seems decimal should be octal
757962306a36Sopenharmony_ci# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
758062306a36Sopenharmony_ci# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
758162306a36Sopenharmony_ci#   specific definition of not visible in sysfs.
758262306a36Sopenharmony_ci# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
758362306a36Sopenharmony_ci#   use the default permissions
758462306a36Sopenharmony_ci		if ($perl_version_ok &&
758562306a36Sopenharmony_ci		    defined $stat &&
758662306a36Sopenharmony_ci		    $line =~ /$mode_perms_search/) {
758762306a36Sopenharmony_ci			foreach my $entry (@mode_permission_funcs) {
758862306a36Sopenharmony_ci				my $func = $entry->[0];
758962306a36Sopenharmony_ci				my $arg_pos = $entry->[1];
759062306a36Sopenharmony_ci
759162306a36Sopenharmony_ci				my $lc = $stat =~ tr@\n@@;
759262306a36Sopenharmony_ci				$lc = $lc + $linenr;
759362306a36Sopenharmony_ci				my $stat_real = get_stat_real($linenr, $lc);
759462306a36Sopenharmony_ci
759562306a36Sopenharmony_ci				my $skip_args = "";
759662306a36Sopenharmony_ci				if ($arg_pos > 1) {
759762306a36Sopenharmony_ci					$arg_pos--;
759862306a36Sopenharmony_ci					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
759962306a36Sopenharmony_ci				}
760062306a36Sopenharmony_ci				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
760162306a36Sopenharmony_ci				if ($stat =~ /$test/) {
760262306a36Sopenharmony_ci					my $val = $1;
760362306a36Sopenharmony_ci					$val = $6 if ($skip_args ne "");
760462306a36Sopenharmony_ci					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
760562306a36Sopenharmony_ci					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
760662306a36Sopenharmony_ci					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
760762306a36Sopenharmony_ci						ERROR("NON_OCTAL_PERMISSIONS",
760862306a36Sopenharmony_ci						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
760962306a36Sopenharmony_ci					}
761062306a36Sopenharmony_ci					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
761162306a36Sopenharmony_ci						ERROR("EXPORTED_WORLD_WRITABLE",
761262306a36Sopenharmony_ci						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
761362306a36Sopenharmony_ci					}
761462306a36Sopenharmony_ci				}
761562306a36Sopenharmony_ci			}
761662306a36Sopenharmony_ci		}
761762306a36Sopenharmony_ci
761862306a36Sopenharmony_ci# check for uses of S_<PERMS> that could be octal for readability
761962306a36Sopenharmony_ci		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
762062306a36Sopenharmony_ci			my $oval = $1;
762162306a36Sopenharmony_ci			my $octal = perms_to_octal($oval);
762262306a36Sopenharmony_ci			if (WARN("SYMBOLIC_PERMS",
762362306a36Sopenharmony_ci				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
762462306a36Sopenharmony_ci			    $fix) {
762562306a36Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
762662306a36Sopenharmony_ci			}
762762306a36Sopenharmony_ci		}
762862306a36Sopenharmony_ci
762962306a36Sopenharmony_ci# validate content of MODULE_LICENSE against list from include/linux/module.h
763062306a36Sopenharmony_ci		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
763162306a36Sopenharmony_ci			my $extracted_string = get_quoted_string($line, $rawline);
763262306a36Sopenharmony_ci			my $valid_licenses = qr{
763362306a36Sopenharmony_ci						GPL|
763462306a36Sopenharmony_ci						GPL\ v2|
763562306a36Sopenharmony_ci						GPL\ and\ additional\ rights|
763662306a36Sopenharmony_ci						Dual\ BSD/GPL|
763762306a36Sopenharmony_ci						Dual\ MIT/GPL|
763862306a36Sopenharmony_ci						Dual\ MPL/GPL|
763962306a36Sopenharmony_ci						Proprietary
764062306a36Sopenharmony_ci					}x;
764162306a36Sopenharmony_ci			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
764262306a36Sopenharmony_ci				WARN("MODULE_LICENSE",
764362306a36Sopenharmony_ci				     "unknown module license " . $extracted_string . "\n" . $herecurr);
764462306a36Sopenharmony_ci			}
764562306a36Sopenharmony_ci			if (!$file && $extracted_string eq '"GPL v2"') {
764662306a36Sopenharmony_ci				if (WARN("MODULE_LICENSE",
764762306a36Sopenharmony_ci				     "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&
764862306a36Sopenharmony_ci				    $fix) {
764962306a36Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;
765062306a36Sopenharmony_ci				}
765162306a36Sopenharmony_ci			}
765262306a36Sopenharmony_ci		}
765362306a36Sopenharmony_ci
765462306a36Sopenharmony_ci# check for sysctl duplicate constants
765562306a36Sopenharmony_ci		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
765662306a36Sopenharmony_ci			WARN("DUPLICATED_SYSCTL_CONST",
765762306a36Sopenharmony_ci				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
765862306a36Sopenharmony_ci		}
765962306a36Sopenharmony_ci	}
766062306a36Sopenharmony_ci
766162306a36Sopenharmony_ci	# If we have no input at all, then there is nothing to report on
766262306a36Sopenharmony_ci	# so just keep quiet.
766362306a36Sopenharmony_ci	if ($#rawlines == -1) {
766462306a36Sopenharmony_ci		exit(0);
766562306a36Sopenharmony_ci	}
766662306a36Sopenharmony_ci
766762306a36Sopenharmony_ci	# In mailback mode only produce a report in the negative, for
766862306a36Sopenharmony_ci	# things that appear to be patches.
766962306a36Sopenharmony_ci	if ($mailback && ($clean == 1 || !$is_patch)) {
767062306a36Sopenharmony_ci		exit(0);
767162306a36Sopenharmony_ci	}
767262306a36Sopenharmony_ci
767362306a36Sopenharmony_ci	# This is not a patch, and we are in 'no-patch' mode so
767462306a36Sopenharmony_ci	# just keep quiet.
767562306a36Sopenharmony_ci	if (!$chk_patch && !$is_patch) {
767662306a36Sopenharmony_ci		exit(0);
767762306a36Sopenharmony_ci	}
767862306a36Sopenharmony_ci
767962306a36Sopenharmony_ci	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
768062306a36Sopenharmony_ci		ERROR("NOT_UNIFIED_DIFF",
768162306a36Sopenharmony_ci		      "Does not appear to be a unified-diff format patch\n");
768262306a36Sopenharmony_ci	}
768362306a36Sopenharmony_ci	if ($is_patch && $has_commit_log && $chk_signoff) {
768462306a36Sopenharmony_ci		if ($signoff == 0) {
768562306a36Sopenharmony_ci			ERROR("MISSING_SIGN_OFF",
768662306a36Sopenharmony_ci			      "Missing Signed-off-by: line(s)\n");
768762306a36Sopenharmony_ci		} elsif ($authorsignoff != 1) {
768862306a36Sopenharmony_ci			# authorsignoff values:
768962306a36Sopenharmony_ci			# 0 -> missing sign off
769062306a36Sopenharmony_ci			# 1 -> sign off identical
769162306a36Sopenharmony_ci			# 2 -> names and addresses match, comments mismatch
769262306a36Sopenharmony_ci			# 3 -> addresses match, names different
769362306a36Sopenharmony_ci			# 4 -> names match, addresses different
769462306a36Sopenharmony_ci			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
769562306a36Sopenharmony_ci
769662306a36Sopenharmony_ci			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
769762306a36Sopenharmony_ci
769862306a36Sopenharmony_ci			if ($authorsignoff == 0) {
769962306a36Sopenharmony_ci				ERROR("NO_AUTHOR_SIGN_OFF",
770062306a36Sopenharmony_ci				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
770162306a36Sopenharmony_ci			} elsif ($authorsignoff == 2) {
770262306a36Sopenharmony_ci				CHK("FROM_SIGN_OFF_MISMATCH",
770362306a36Sopenharmony_ci				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
770462306a36Sopenharmony_ci			} elsif ($authorsignoff == 3) {
770562306a36Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
770662306a36Sopenharmony_ci				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
770762306a36Sopenharmony_ci			} elsif ($authorsignoff == 4) {
770862306a36Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
770962306a36Sopenharmony_ci				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
771062306a36Sopenharmony_ci			} elsif ($authorsignoff == 5) {
771162306a36Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
771262306a36Sopenharmony_ci				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
771362306a36Sopenharmony_ci			}
771462306a36Sopenharmony_ci		}
771562306a36Sopenharmony_ci	}
771662306a36Sopenharmony_ci
771762306a36Sopenharmony_ci	print report_dump();
771862306a36Sopenharmony_ci	if ($summary && !($clean == 1 && $quiet == 1)) {
771962306a36Sopenharmony_ci		print "$filename " if ($summary_file);
772062306a36Sopenharmony_ci		print "total: $cnt_error errors, $cnt_warn warnings, " .
772162306a36Sopenharmony_ci			(($check)? "$cnt_chk checks, " : "") .
772262306a36Sopenharmony_ci			"$cnt_lines lines checked\n";
772362306a36Sopenharmony_ci	}
772462306a36Sopenharmony_ci
772562306a36Sopenharmony_ci	if ($quiet == 0) {
772662306a36Sopenharmony_ci		# If there were any defects found and not already fixing them
772762306a36Sopenharmony_ci		if (!$clean and !$fix) {
772862306a36Sopenharmony_ci			print << "EOM"
772962306a36Sopenharmony_ci
773062306a36Sopenharmony_ciNOTE: For some of the reported defects, checkpatch may be able to
773162306a36Sopenharmony_ci      mechanically convert to the typical style using --fix or --fix-inplace.
773262306a36Sopenharmony_ciEOM
773362306a36Sopenharmony_ci		}
773462306a36Sopenharmony_ci		# If there were whitespace errors which cleanpatch can fix
773562306a36Sopenharmony_ci		# then suggest that.
773662306a36Sopenharmony_ci		if ($rpt_cleaners) {
773762306a36Sopenharmony_ci			$rpt_cleaners = 0;
773862306a36Sopenharmony_ci			print << "EOM"
773962306a36Sopenharmony_ci
774062306a36Sopenharmony_ciNOTE: Whitespace errors detected.
774162306a36Sopenharmony_ci      You may wish to use scripts/cleanpatch or scripts/cleanfile
774262306a36Sopenharmony_ciEOM
774362306a36Sopenharmony_ci		}
774462306a36Sopenharmony_ci	}
774562306a36Sopenharmony_ci
774662306a36Sopenharmony_ci	if ($clean == 0 && $fix &&
774762306a36Sopenharmony_ci	    ("@rawlines" ne "@fixed" ||
774862306a36Sopenharmony_ci	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
774962306a36Sopenharmony_ci		my $newfile = $filename;
775062306a36Sopenharmony_ci		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
775162306a36Sopenharmony_ci		my $linecount = 0;
775262306a36Sopenharmony_ci		my $f;
775362306a36Sopenharmony_ci
775462306a36Sopenharmony_ci		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
775562306a36Sopenharmony_ci
775662306a36Sopenharmony_ci		open($f, '>', $newfile)
775762306a36Sopenharmony_ci		    or die "$P: Can't open $newfile for write\n";
775862306a36Sopenharmony_ci		foreach my $fixed_line (@fixed) {
775962306a36Sopenharmony_ci			$linecount++;
776062306a36Sopenharmony_ci			if ($file) {
776162306a36Sopenharmony_ci				if ($linecount > 3) {
776262306a36Sopenharmony_ci					$fixed_line =~ s/^\+//;
776362306a36Sopenharmony_ci					print $f $fixed_line . "\n";
776462306a36Sopenharmony_ci				}
776562306a36Sopenharmony_ci			} else {
776662306a36Sopenharmony_ci				print $f $fixed_line . "\n";
776762306a36Sopenharmony_ci			}
776862306a36Sopenharmony_ci		}
776962306a36Sopenharmony_ci		close($f);
777062306a36Sopenharmony_ci
777162306a36Sopenharmony_ci		if (!$quiet) {
777262306a36Sopenharmony_ci			print << "EOM";
777362306a36Sopenharmony_ci
777462306a36Sopenharmony_ciWrote EXPERIMENTAL --fix correction(s) to '$newfile'
777562306a36Sopenharmony_ci
777662306a36Sopenharmony_ciDo _NOT_ trust the results written to this file.
777762306a36Sopenharmony_ciDo _NOT_ submit these changes without inspecting them for correctness.
777862306a36Sopenharmony_ci
777962306a36Sopenharmony_ciThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
778062306a36Sopenharmony_ciNo warranties, expressed or implied...
778162306a36Sopenharmony_ciEOM
778262306a36Sopenharmony_ci		}
778362306a36Sopenharmony_ci	}
778462306a36Sopenharmony_ci
778562306a36Sopenharmony_ci	if ($quiet == 0) {
778662306a36Sopenharmony_ci		print "\n";
778762306a36Sopenharmony_ci		if ($clean == 1) {
778862306a36Sopenharmony_ci			print "$vname has no obvious style problems and is ready for submission.\n";
778962306a36Sopenharmony_ci		} else {
779062306a36Sopenharmony_ci			print "$vname has style problems, please review.\n";
779162306a36Sopenharmony_ci		}
779262306a36Sopenharmony_ci	}
779362306a36Sopenharmony_ci	return $clean;
779462306a36Sopenharmony_ci}
7795