18c2ecf20Sopenharmony_ci#!/usr/bin/env perl
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
38c2ecf20Sopenharmony_ci#
48c2ecf20Sopenharmony_ci# (c) 2001, Dave Jones. (the file handling bit)
58c2ecf20Sopenharmony_ci# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
68c2ecf20Sopenharmony_ci# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
78c2ecf20Sopenharmony_ci# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
88c2ecf20Sopenharmony_ci# (c) 2010-2018 Joe Perches <joe@perches.com>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciuse strict;
118c2ecf20Sopenharmony_ciuse warnings;
128c2ecf20Sopenharmony_ciuse POSIX;
138c2ecf20Sopenharmony_ciuse File::Basename;
148c2ecf20Sopenharmony_ciuse Cwd 'abs_path';
158c2ecf20Sopenharmony_ciuse Term::ANSIColor qw(:constants);
168c2ecf20Sopenharmony_ciuse Encode qw(decode encode);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cimy $P = $0;
198c2ecf20Sopenharmony_cimy $D = dirname(abs_path($P));
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cimy $V = '0.32';
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciuse Getopt::Long qw(:config no_auto_abbrev);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cimy $quiet = 0;
268c2ecf20Sopenharmony_cimy $tree = 1;
278c2ecf20Sopenharmony_cimy $chk_signoff = 1;
288c2ecf20Sopenharmony_cimy $chk_patch = 1;
298c2ecf20Sopenharmony_cimy $tst_only;
308c2ecf20Sopenharmony_cimy $emacs = 0;
318c2ecf20Sopenharmony_cimy $terse = 0;
328c2ecf20Sopenharmony_cimy $showfile = 0;
338c2ecf20Sopenharmony_cimy $file = 0;
348c2ecf20Sopenharmony_cimy $git = 0;
358c2ecf20Sopenharmony_cimy %git_commits = ();
368c2ecf20Sopenharmony_cimy $check = 0;
378c2ecf20Sopenharmony_cimy $check_orig = 0;
388c2ecf20Sopenharmony_cimy $summary = 1;
398c2ecf20Sopenharmony_cimy $mailback = 0;
408c2ecf20Sopenharmony_cimy $summary_file = 0;
418c2ecf20Sopenharmony_cimy $show_types = 0;
428c2ecf20Sopenharmony_cimy $list_types = 0;
438c2ecf20Sopenharmony_cimy $fix = 0;
448c2ecf20Sopenharmony_cimy $fix_inplace = 0;
458c2ecf20Sopenharmony_cimy $root;
468c2ecf20Sopenharmony_cimy $gitroot = $ENV{'GIT_DIR'};
478c2ecf20Sopenharmony_ci$gitroot = ".git" if !defined($gitroot);
488c2ecf20Sopenharmony_cimy %debug;
498c2ecf20Sopenharmony_cimy %camelcase = ();
508c2ecf20Sopenharmony_cimy %use_type = ();
518c2ecf20Sopenharmony_cimy @use = ();
528c2ecf20Sopenharmony_cimy %ignore_type = ();
538c2ecf20Sopenharmony_cimy @ignore = ();
548c2ecf20Sopenharmony_cimy $help = 0;
558c2ecf20Sopenharmony_cimy $configuration_file = ".checkpatch.conf";
568c2ecf20Sopenharmony_cimy $max_line_length = 100;
578c2ecf20Sopenharmony_cimy $ignore_perl_version = 0;
588c2ecf20Sopenharmony_cimy $minimum_perl_version = 5.10.0;
598c2ecf20Sopenharmony_cimy $min_conf_desc_length = 4;
608c2ecf20Sopenharmony_cimy $spelling_file = "$D/spelling.txt";
618c2ecf20Sopenharmony_cimy $codespell = 0;
628c2ecf20Sopenharmony_cimy $codespellfile = "/usr/share/codespell/dictionary.txt";
638c2ecf20Sopenharmony_cimy $conststructsfile = "$D/const_structs.checkpatch";
648c2ecf20Sopenharmony_cimy $typedefsfile;
658c2ecf20Sopenharmony_cimy $color = "auto";
668c2ecf20Sopenharmony_cimy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
678c2ecf20Sopenharmony_ci# git output parsing needs US English output, so first set backtick child process LANGUAGE
688c2ecf20Sopenharmony_cimy $git_command ='export LANGUAGE=en_US.UTF-8; git';
698c2ecf20Sopenharmony_cimy $tabsize = 8;
708c2ecf20Sopenharmony_cimy ${CONFIG_} = "CONFIG_";
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cisub help {
738c2ecf20Sopenharmony_ci	my ($exitcode) = @_;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	print << "EOM";
768c2ecf20Sopenharmony_ciUsage: $P [OPTION]... [FILE]...
778c2ecf20Sopenharmony_ciVersion: $V
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ciOptions:
808c2ecf20Sopenharmony_ci  -q, --quiet                quiet
818c2ecf20Sopenharmony_ci  --no-tree                  run without a kernel tree
828c2ecf20Sopenharmony_ci  --no-signoff               do not check for 'Signed-off-by' line
838c2ecf20Sopenharmony_ci  --patch                    treat FILE as patchfile (default)
848c2ecf20Sopenharmony_ci  --emacs                    emacs compile window format
858c2ecf20Sopenharmony_ci  --terse                    one line per report
868c2ecf20Sopenharmony_ci  --showfile                 emit diffed file position, not input file position
878c2ecf20Sopenharmony_ci  -g, --git                  treat FILE as a single commit or git revision range
888c2ecf20Sopenharmony_ci                             single git commit with:
898c2ecf20Sopenharmony_ci                               <rev>
908c2ecf20Sopenharmony_ci                               <rev>^
918c2ecf20Sopenharmony_ci                               <rev>~n
928c2ecf20Sopenharmony_ci                             multiple git commits with:
938c2ecf20Sopenharmony_ci                               <rev1>..<rev2>
948c2ecf20Sopenharmony_ci                               <rev1>...<rev2>
958c2ecf20Sopenharmony_ci                               <rev>-<count>
968c2ecf20Sopenharmony_ci                             git merges are ignored
978c2ecf20Sopenharmony_ci  -f, --file                 treat FILE as regular source file
988c2ecf20Sopenharmony_ci  --subjective, --strict     enable more subjective tests
998c2ecf20Sopenharmony_ci  --list-types               list the possible message types
1008c2ecf20Sopenharmony_ci  --types TYPE(,TYPE2...)    show only these comma separated message types
1018c2ecf20Sopenharmony_ci  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1028c2ecf20Sopenharmony_ci  --show-types               show the specific message type in the output
1038c2ecf20Sopenharmony_ci  --max-line-length=n        set the maximum line length, (default $max_line_length)
1048c2ecf20Sopenharmony_ci                             if exceeded, warn on patches
1058c2ecf20Sopenharmony_ci                             requires --strict for use with --file
1068c2ecf20Sopenharmony_ci  --min-conf-desc-length=n   set the min description length, if shorter, warn
1078c2ecf20Sopenharmony_ci  --tab-size=n               set the number of spaces for tab (default $tabsize)
1088c2ecf20Sopenharmony_ci  --root=PATH                PATH to the kernel tree root
1098c2ecf20Sopenharmony_ci  --no-summary               suppress the per-file summary
1108c2ecf20Sopenharmony_ci  --mailback                 only produce a report in case of warnings/errors
1118c2ecf20Sopenharmony_ci  --summary-file             include the filename in summary
1128c2ecf20Sopenharmony_ci  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
1138c2ecf20Sopenharmony_ci                             'values', 'possible', 'type', and 'attr' (default
1148c2ecf20Sopenharmony_ci                             is all off)
1158c2ecf20Sopenharmony_ci  --test-only=WORD           report only warnings/errors containing WORD
1168c2ecf20Sopenharmony_ci                             literally
1178c2ecf20Sopenharmony_ci  --fix                      EXPERIMENTAL - may create horrible results
1188c2ecf20Sopenharmony_ci                             If correctable single-line errors exist, create
1198c2ecf20Sopenharmony_ci                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1208c2ecf20Sopenharmony_ci                             with potential errors corrected to the preferred
1218c2ecf20Sopenharmony_ci                             checkpatch style
1228c2ecf20Sopenharmony_ci  --fix-inplace              EXPERIMENTAL - may create horrible results
1238c2ecf20Sopenharmony_ci                             Is the same as --fix, but overwrites the input
1248c2ecf20Sopenharmony_ci                             file.  It's your fault if there's no backup or git
1258c2ecf20Sopenharmony_ci  --ignore-perl-version      override checking of perl version.  expect
1268c2ecf20Sopenharmony_ci                             runtime errors.
1278c2ecf20Sopenharmony_ci  --codespell                Use the codespell dictionary for spelling/typos
1288c2ecf20Sopenharmony_ci                             (default:/usr/share/codespell/dictionary.txt)
1298c2ecf20Sopenharmony_ci  --codespellfile            Use this codespell dictionary
1308c2ecf20Sopenharmony_ci  --typedefsfile             Read additional types from this file
1318c2ecf20Sopenharmony_ci  --color[=WHEN]             Use colors 'always', 'never', or only when output
1328c2ecf20Sopenharmony_ci                             is a terminal ('auto'). Default is 'auto'.
1338c2ecf20Sopenharmony_ci  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1348c2ecf20Sopenharmony_ci                             ${CONFIG_})
1358c2ecf20Sopenharmony_ci  -h, --help, --version      display this help and exit
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciWhen FILE is - read standard input.
1388c2ecf20Sopenharmony_ciEOM
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	exit($exitcode);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cisub uniq {
1448c2ecf20Sopenharmony_ci	my %seen;
1458c2ecf20Sopenharmony_ci	return grep { !$seen{$_}++ } @_;
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cisub list_types {
1498c2ecf20Sopenharmony_ci	my ($exitcode) = @_;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	my $count = 0;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	local $/ = undef;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	open(my $script, '<', abs_path($P)) or
1568c2ecf20Sopenharmony_ci	    die "$P: Can't read '$P' $!\n";
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	my $text = <$script>;
1598c2ecf20Sopenharmony_ci	close($script);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	my @types = ();
1628c2ecf20Sopenharmony_ci	# Also catch when type or level is passed through a variable
1638c2ecf20Sopenharmony_ci	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
1648c2ecf20Sopenharmony_ci		push (@types, $_);
1658c2ecf20Sopenharmony_ci	}
1668c2ecf20Sopenharmony_ci	@types = sort(uniq(@types));
1678c2ecf20Sopenharmony_ci	print("#\tMessage type\n\n");
1688c2ecf20Sopenharmony_ci	foreach my $type (@types) {
1698c2ecf20Sopenharmony_ci		print(++$count . "\t" . $type . "\n");
1708c2ecf20Sopenharmony_ci	}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	exit($exitcode);
1738c2ecf20Sopenharmony_ci}
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cimy $conf = which_conf($configuration_file);
1768c2ecf20Sopenharmony_ciif (-f $conf) {
1778c2ecf20Sopenharmony_ci	my @conf_args;
1788c2ecf20Sopenharmony_ci	open(my $conffile, '<', "$conf")
1798c2ecf20Sopenharmony_ci	    or warn "$P: Can't find a readable $configuration_file file $!\n";
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	while (<$conffile>) {
1828c2ecf20Sopenharmony_ci		my $line = $_;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci		$line =~ s/\s*\n?$//g;
1858c2ecf20Sopenharmony_ci		$line =~ s/^\s*//g;
1868c2ecf20Sopenharmony_ci		$line =~ s/\s+/ /g;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci		next if ($line =~ m/^\s*#/);
1898c2ecf20Sopenharmony_ci		next if ($line =~ m/^\s*$/);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci		my @words = split(" ", $line);
1928c2ecf20Sopenharmony_ci		foreach my $word (@words) {
1938c2ecf20Sopenharmony_ci			last if ($word =~ m/^#/);
1948c2ecf20Sopenharmony_ci			push (@conf_args, $word);
1958c2ecf20Sopenharmony_ci		}
1968c2ecf20Sopenharmony_ci	}
1978c2ecf20Sopenharmony_ci	close($conffile);
1988c2ecf20Sopenharmony_ci	unshift(@ARGV, @conf_args) if @conf_args;
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci# Perl's Getopt::Long allows options to take optional arguments after a space.
2028c2ecf20Sopenharmony_ci# Prevent --color by itself from consuming other arguments
2038c2ecf20Sopenharmony_ciforeach (@ARGV) {
2048c2ecf20Sopenharmony_ci	if ($_ eq "--color" || $_ eq "-color") {
2058c2ecf20Sopenharmony_ci		$_ = "--color=$color";
2068c2ecf20Sopenharmony_ci	}
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ciGetOptions(
2108c2ecf20Sopenharmony_ci	'q|quiet+'	=> \$quiet,
2118c2ecf20Sopenharmony_ci	'tree!'		=> \$tree,
2128c2ecf20Sopenharmony_ci	'signoff!'	=> \$chk_signoff,
2138c2ecf20Sopenharmony_ci	'patch!'	=> \$chk_patch,
2148c2ecf20Sopenharmony_ci	'emacs!'	=> \$emacs,
2158c2ecf20Sopenharmony_ci	'terse!'	=> \$terse,
2168c2ecf20Sopenharmony_ci	'showfile!'	=> \$showfile,
2178c2ecf20Sopenharmony_ci	'f|file!'	=> \$file,
2188c2ecf20Sopenharmony_ci	'g|git!'	=> \$git,
2198c2ecf20Sopenharmony_ci	'subjective!'	=> \$check,
2208c2ecf20Sopenharmony_ci	'strict!'	=> \$check,
2218c2ecf20Sopenharmony_ci	'ignore=s'	=> \@ignore,
2228c2ecf20Sopenharmony_ci	'types=s'	=> \@use,
2238c2ecf20Sopenharmony_ci	'show-types!'	=> \$show_types,
2248c2ecf20Sopenharmony_ci	'list-types!'	=> \$list_types,
2258c2ecf20Sopenharmony_ci	'max-line-length=i' => \$max_line_length,
2268c2ecf20Sopenharmony_ci	'min-conf-desc-length=i' => \$min_conf_desc_length,
2278c2ecf20Sopenharmony_ci	'tab-size=i'	=> \$tabsize,
2288c2ecf20Sopenharmony_ci	'root=s'	=> \$root,
2298c2ecf20Sopenharmony_ci	'summary!'	=> \$summary,
2308c2ecf20Sopenharmony_ci	'mailback!'	=> \$mailback,
2318c2ecf20Sopenharmony_ci	'summary-file!'	=> \$summary_file,
2328c2ecf20Sopenharmony_ci	'fix!'		=> \$fix,
2338c2ecf20Sopenharmony_ci	'fix-inplace!'	=> \$fix_inplace,
2348c2ecf20Sopenharmony_ci	'ignore-perl-version!' => \$ignore_perl_version,
2358c2ecf20Sopenharmony_ci	'debug=s'	=> \%debug,
2368c2ecf20Sopenharmony_ci	'test-only=s'	=> \$tst_only,
2378c2ecf20Sopenharmony_ci	'codespell!'	=> \$codespell,
2388c2ecf20Sopenharmony_ci	'codespellfile=s'	=> \$codespellfile,
2398c2ecf20Sopenharmony_ci	'typedefsfile=s'	=> \$typedefsfile,
2408c2ecf20Sopenharmony_ci	'color=s'	=> \$color,
2418c2ecf20Sopenharmony_ci	'no-color'	=> \$color,	#keep old behaviors of -nocolor
2428c2ecf20Sopenharmony_ci	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
2438c2ecf20Sopenharmony_ci	'kconfig-prefix=s'	=> \${CONFIG_},
2448c2ecf20Sopenharmony_ci	'h|help'	=> \$help,
2458c2ecf20Sopenharmony_ci	'version'	=> \$help
2468c2ecf20Sopenharmony_ci) or help(1);
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cihelp(0) if ($help);
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_cilist_types(0) if ($list_types);
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci$fix = 1 if ($fix_inplace);
2538c2ecf20Sopenharmony_ci$check_orig = $check;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cidie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cimy $exit = 0;
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_cimy $perl_version_ok = 1;
2608c2ecf20Sopenharmony_ciif ($^V && $^V lt $minimum_perl_version) {
2618c2ecf20Sopenharmony_ci	$perl_version_ok = 0;
2628c2ecf20Sopenharmony_ci	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
2638c2ecf20Sopenharmony_ci	exit(1) if (!$ignore_perl_version);
2648c2ecf20Sopenharmony_ci}
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci#if no filenames are given, push '-' to read patch from stdin
2678c2ecf20Sopenharmony_ciif ($#ARGV < 0) {
2688c2ecf20Sopenharmony_ci	push(@ARGV, '-');
2698c2ecf20Sopenharmony_ci}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ciif ($color =~ /^[01]$/) {
2728c2ecf20Sopenharmony_ci	$color = !$color;
2738c2ecf20Sopenharmony_ci} elsif ($color =~ /^always$/i) {
2748c2ecf20Sopenharmony_ci	$color = 1;
2758c2ecf20Sopenharmony_ci} elsif ($color =~ /^never$/i) {
2768c2ecf20Sopenharmony_ci	$color = 0;
2778c2ecf20Sopenharmony_ci} elsif ($color =~ /^auto$/i) {
2788c2ecf20Sopenharmony_ci	$color = (-t STDOUT);
2798c2ecf20Sopenharmony_ci} else {
2808c2ecf20Sopenharmony_ci	die "$P: Invalid color mode: $color\n";
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci# skip TAB size 1 to avoid additional checks on $tabsize - 1
2848c2ecf20Sopenharmony_cidie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_cisub hash_save_array_words {
2878c2ecf20Sopenharmony_ci	my ($hashRef, $arrayRef) = @_;
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	my @array = split(/,/, join(',', @$arrayRef));
2908c2ecf20Sopenharmony_ci	foreach my $word (@array) {
2918c2ecf20Sopenharmony_ci		$word =~ s/\s*\n?$//g;
2928c2ecf20Sopenharmony_ci		$word =~ s/^\s*//g;
2938c2ecf20Sopenharmony_ci		$word =~ s/\s+/ /g;
2948c2ecf20Sopenharmony_ci		$word =~ tr/[a-z]/[A-Z]/;
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci		next if ($word =~ m/^\s*#/);
2978c2ecf20Sopenharmony_ci		next if ($word =~ m/^\s*$/);
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci		$hashRef->{$word}++;
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_cisub hash_show_words {
3048c2ecf20Sopenharmony_ci	my ($hashRef, $prefix) = @_;
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	if (keys %$hashRef) {
3078c2ecf20Sopenharmony_ci		print "\nNOTE: $prefix message types:";
3088c2ecf20Sopenharmony_ci		foreach my $word (sort keys %$hashRef) {
3098c2ecf20Sopenharmony_ci			print " $word";
3108c2ecf20Sopenharmony_ci		}
3118c2ecf20Sopenharmony_ci		print "\n";
3128c2ecf20Sopenharmony_ci	}
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_cihash_save_array_words(\%ignore_type, \@ignore);
3168c2ecf20Sopenharmony_cihash_save_array_words(\%use_type, \@use);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cimy $dbg_values = 0;
3198c2ecf20Sopenharmony_cimy $dbg_possible = 0;
3208c2ecf20Sopenharmony_cimy $dbg_type = 0;
3218c2ecf20Sopenharmony_cimy $dbg_attr = 0;
3228c2ecf20Sopenharmony_cifor my $key (keys %debug) {
3238c2ecf20Sopenharmony_ci	## no critic
3248c2ecf20Sopenharmony_ci	eval "\${dbg_$key} = '$debug{$key}';";
3258c2ecf20Sopenharmony_ci	die "$@" if ($@);
3268c2ecf20Sopenharmony_ci}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_cimy $rpt_cleaners = 0;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ciif ($terse) {
3318c2ecf20Sopenharmony_ci	$emacs = 1;
3328c2ecf20Sopenharmony_ci	$quiet++;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ciif ($tree) {
3368c2ecf20Sopenharmony_ci	if (defined $root) {
3378c2ecf20Sopenharmony_ci		if (!top_of_kernel_tree($root)) {
3388c2ecf20Sopenharmony_ci			die "$P: $root: --root does not point at a valid tree\n";
3398c2ecf20Sopenharmony_ci		}
3408c2ecf20Sopenharmony_ci	} else {
3418c2ecf20Sopenharmony_ci		if (top_of_kernel_tree('.')) {
3428c2ecf20Sopenharmony_ci			$root = '.';
3438c2ecf20Sopenharmony_ci		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
3448c2ecf20Sopenharmony_ci						top_of_kernel_tree($1)) {
3458c2ecf20Sopenharmony_ci			$root = $1;
3468c2ecf20Sopenharmony_ci		}
3478c2ecf20Sopenharmony_ci	}
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	if (!defined $root) {
3508c2ecf20Sopenharmony_ci		print "Must be run from the top-level dir. of a kernel tree\n";
3518c2ecf20Sopenharmony_ci		exit(2);
3528c2ecf20Sopenharmony_ci	}
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cimy $emitted_corrupt = 0;
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ciour $Ident	= qr{
3588c2ecf20Sopenharmony_ci			[A-Za-z_][A-Za-z\d_]*
3598c2ecf20Sopenharmony_ci			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3608c2ecf20Sopenharmony_ci		}x;
3618c2ecf20Sopenharmony_ciour $Storage	= qr{extern|static|asmlinkage};
3628c2ecf20Sopenharmony_ciour $Sparse	= qr{
3638c2ecf20Sopenharmony_ci			__user|
3648c2ecf20Sopenharmony_ci			__kernel|
3658c2ecf20Sopenharmony_ci			__force|
3668c2ecf20Sopenharmony_ci			__iomem|
3678c2ecf20Sopenharmony_ci			__must_check|
3688c2ecf20Sopenharmony_ci			__kprobes|
3698c2ecf20Sopenharmony_ci			__ref|
3708c2ecf20Sopenharmony_ci			__refconst|
3718c2ecf20Sopenharmony_ci			__refdata|
3728c2ecf20Sopenharmony_ci			__rcu|
3738c2ecf20Sopenharmony_ci			__private
3748c2ecf20Sopenharmony_ci		}x;
3758c2ecf20Sopenharmony_ciour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
3768c2ecf20Sopenharmony_ciour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
3778c2ecf20Sopenharmony_ciour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
3788c2ecf20Sopenharmony_ciour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
3798c2ecf20Sopenharmony_ciour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci# Notes to $Attribute:
3828c2ecf20Sopenharmony_ci# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3838c2ecf20Sopenharmony_ciour $Attribute	= qr{
3848c2ecf20Sopenharmony_ci			const|
3858c2ecf20Sopenharmony_ci			__percpu|
3868c2ecf20Sopenharmony_ci			__nocast|
3878c2ecf20Sopenharmony_ci			__safe|
3888c2ecf20Sopenharmony_ci			__bitwise|
3898c2ecf20Sopenharmony_ci			__packed__|
3908c2ecf20Sopenharmony_ci			__packed2__|
3918c2ecf20Sopenharmony_ci			__naked|
3928c2ecf20Sopenharmony_ci			__maybe_unused|
3938c2ecf20Sopenharmony_ci			__always_unused|
3948c2ecf20Sopenharmony_ci			__noreturn|
3958c2ecf20Sopenharmony_ci			__used|
3968c2ecf20Sopenharmony_ci			__cold|
3978c2ecf20Sopenharmony_ci			__pure|
3988c2ecf20Sopenharmony_ci			__noclone|
3998c2ecf20Sopenharmony_ci			__deprecated|
4008c2ecf20Sopenharmony_ci			__read_mostly|
4018c2ecf20Sopenharmony_ci			__ro_after_init|
4028c2ecf20Sopenharmony_ci			__kprobes|
4038c2ecf20Sopenharmony_ci			$InitAttribute|
4048c2ecf20Sopenharmony_ci			____cacheline_aligned|
4058c2ecf20Sopenharmony_ci			____cacheline_aligned_in_smp|
4068c2ecf20Sopenharmony_ci			____cacheline_internodealigned_in_smp|
4078c2ecf20Sopenharmony_ci			__weak
4088c2ecf20Sopenharmony_ci		  }x;
4098c2ecf20Sopenharmony_ciour $Modifier;
4108c2ecf20Sopenharmony_ciour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
4118c2ecf20Sopenharmony_ciour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
4128c2ecf20Sopenharmony_ciour $Lval	= qr{$Ident(?:$Member)*};
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ciour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
4158c2ecf20Sopenharmony_ciour $Binary	= qr{(?i)0b[01]+$Int_type?};
4168c2ecf20Sopenharmony_ciour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
4178c2ecf20Sopenharmony_ciour $Int	= qr{[0-9]+$Int_type?};
4188c2ecf20Sopenharmony_ciour $Octal	= qr{0[0-7]+$Int_type?};
4198c2ecf20Sopenharmony_ciour $String	= qr{"[X\t]*"};
4208c2ecf20Sopenharmony_ciour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
4218c2ecf20Sopenharmony_ciour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
4228c2ecf20Sopenharmony_ciour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
4238c2ecf20Sopenharmony_ciour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
4248c2ecf20Sopenharmony_ciour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
4258c2ecf20Sopenharmony_ciour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
4268c2ecf20Sopenharmony_ciour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
4278c2ecf20Sopenharmony_ciour $Arithmetic = qr{\+|-|\*|\/|%};
4288c2ecf20Sopenharmony_ciour $Operators	= qr{
4298c2ecf20Sopenharmony_ci			<=|>=|==|!=|
4308c2ecf20Sopenharmony_ci			=>|->|<<|>>|<|>|!|~|
4318c2ecf20Sopenharmony_ci			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
4328c2ecf20Sopenharmony_ci		  }x;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ciour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ciour $BasicType;
4378c2ecf20Sopenharmony_ciour $NonptrType;
4388c2ecf20Sopenharmony_ciour $NonptrTypeMisordered;
4398c2ecf20Sopenharmony_ciour $NonptrTypeWithAttr;
4408c2ecf20Sopenharmony_ciour $Type;
4418c2ecf20Sopenharmony_ciour $TypeMisordered;
4428c2ecf20Sopenharmony_ciour $Declare;
4438c2ecf20Sopenharmony_ciour $DeclareMisordered;
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ciour $NON_ASCII_UTF8	= qr{
4468c2ecf20Sopenharmony_ci	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
4478c2ecf20Sopenharmony_ci	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
4488c2ecf20Sopenharmony_ci	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
4498c2ecf20Sopenharmony_ci	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
4508c2ecf20Sopenharmony_ci	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
4518c2ecf20Sopenharmony_ci	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
4528c2ecf20Sopenharmony_ci	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
4538c2ecf20Sopenharmony_ci}x;
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ciour $UTF8	= qr{
4568c2ecf20Sopenharmony_ci	[\x09\x0A\x0D\x20-\x7E]              # ASCII
4578c2ecf20Sopenharmony_ci	| $NON_ASCII_UTF8
4588c2ecf20Sopenharmony_ci}x;
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ciour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
4618c2ecf20Sopenharmony_ciour $typeOtherOSTypedefs = qr{(?x:
4628c2ecf20Sopenharmony_ci	u_(?:char|short|int|long) |          # bsd
4638c2ecf20Sopenharmony_ci	u(?:nchar|short|int|long)            # sysv
4648c2ecf20Sopenharmony_ci)};
4658c2ecf20Sopenharmony_ciour $typeKernelTypedefs = qr{(?x:
4668c2ecf20Sopenharmony_ci	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4678c2ecf20Sopenharmony_ci	atomic_t
4688c2ecf20Sopenharmony_ci)};
4698c2ecf20Sopenharmony_ciour $typeTypedefs = qr{(?x:
4708c2ecf20Sopenharmony_ci	$typeC99Typedefs\b|
4718c2ecf20Sopenharmony_ci	$typeOtherOSTypedefs\b|
4728c2ecf20Sopenharmony_ci	$typeKernelTypedefs\b
4738c2ecf20Sopenharmony_ci)};
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ciour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ciour $logFunctions = qr{(?x:
4788c2ecf20Sopenharmony_ci	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4798c2ecf20Sopenharmony_ci	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
4808c2ecf20Sopenharmony_ci	TP_printk|
4818c2ecf20Sopenharmony_ci	WARN(?:_RATELIMIT|_ONCE|)|
4828c2ecf20Sopenharmony_ci	panic|
4838c2ecf20Sopenharmony_ci	MODULE_[A-Z_]+|
4848c2ecf20Sopenharmony_ci	seq_vprintf|seq_printf|seq_puts
4858c2ecf20Sopenharmony_ci)};
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ciour $allocFunctions = qr{(?x:
4888c2ecf20Sopenharmony_ci	(?:(?:devm_)?
4898c2ecf20Sopenharmony_ci		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
4908c2ecf20Sopenharmony_ci		kstrdup(?:_const)? |
4918c2ecf20Sopenharmony_ci		kmemdup(?:_nul)?) |
4928c2ecf20Sopenharmony_ci	(?:\w+)?alloc_skb(?:_ip_align)? |
4938c2ecf20Sopenharmony_ci				# dev_alloc_skb/netdev_alloc_skb, et al
4948c2ecf20Sopenharmony_ci	dma_alloc_coherent
4958c2ecf20Sopenharmony_ci)};
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ciour $signature_tags = qr{(?xi:
4988c2ecf20Sopenharmony_ci	Signed-off-by:|
4998c2ecf20Sopenharmony_ci	Co-developed-by:|
5008c2ecf20Sopenharmony_ci	Acked-by:|
5018c2ecf20Sopenharmony_ci	Tested-by:|
5028c2ecf20Sopenharmony_ci	Reviewed-by:|
5038c2ecf20Sopenharmony_ci	Reported-by:|
5048c2ecf20Sopenharmony_ci	Suggested-by:|
5058c2ecf20Sopenharmony_ci	To:|
5068c2ecf20Sopenharmony_ci	Cc:
5078c2ecf20Sopenharmony_ci)};
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ciour @typeListMisordered = (
5108c2ecf20Sopenharmony_ci	qr{char\s+(?:un)?signed},
5118c2ecf20Sopenharmony_ci	qr{int\s+(?:(?:un)?signed\s+)?short\s},
5128c2ecf20Sopenharmony_ci	qr{int\s+short(?:\s+(?:un)?signed)},
5138c2ecf20Sopenharmony_ci	qr{short\s+int(?:\s+(?:un)?signed)},
5148c2ecf20Sopenharmony_ci	qr{(?:un)?signed\s+int\s+short},
5158c2ecf20Sopenharmony_ci	qr{short\s+(?:un)?signed},
5168c2ecf20Sopenharmony_ci	qr{long\s+int\s+(?:un)?signed},
5178c2ecf20Sopenharmony_ci	qr{int\s+long\s+(?:un)?signed},
5188c2ecf20Sopenharmony_ci	qr{long\s+(?:un)?signed\s+int},
5198c2ecf20Sopenharmony_ci	qr{int\s+(?:un)?signed\s+long},
5208c2ecf20Sopenharmony_ci	qr{int\s+(?:un)?signed},
5218c2ecf20Sopenharmony_ci	qr{int\s+long\s+long\s+(?:un)?signed},
5228c2ecf20Sopenharmony_ci	qr{long\s+long\s+int\s+(?:un)?signed},
5238c2ecf20Sopenharmony_ci	qr{long\s+long\s+(?:un)?signed\s+int},
5248c2ecf20Sopenharmony_ci	qr{long\s+long\s+(?:un)?signed},
5258c2ecf20Sopenharmony_ci	qr{long\s+(?:un)?signed},
5268c2ecf20Sopenharmony_ci);
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ciour @typeList = (
5298c2ecf20Sopenharmony_ci	qr{void},
5308c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?char},
5318c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?short\s+int},
5328c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?short},
5338c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?int},
5348c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+int},
5358c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
5368c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long\s+long},
5378c2ecf20Sopenharmony_ci	qr{(?:(?:un)?signed\s+)?long},
5388c2ecf20Sopenharmony_ci	qr{(?:un)?signed},
5398c2ecf20Sopenharmony_ci	qr{float},
5408c2ecf20Sopenharmony_ci	qr{double},
5418c2ecf20Sopenharmony_ci	qr{bool},
5428c2ecf20Sopenharmony_ci	qr{struct\s+$Ident},
5438c2ecf20Sopenharmony_ci	qr{union\s+$Ident},
5448c2ecf20Sopenharmony_ci	qr{enum\s+$Ident},
5458c2ecf20Sopenharmony_ci	qr{${Ident}_t},
5468c2ecf20Sopenharmony_ci	qr{${Ident}_handler},
5478c2ecf20Sopenharmony_ci	qr{${Ident}_handler_fn},
5488c2ecf20Sopenharmony_ci	@typeListMisordered,
5498c2ecf20Sopenharmony_ci);
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_ciour $C90_int_types = qr{(?x:
5528c2ecf20Sopenharmony_ci	long\s+long\s+int\s+(?:un)?signed|
5538c2ecf20Sopenharmony_ci	long\s+long\s+(?:un)?signed\s+int|
5548c2ecf20Sopenharmony_ci	long\s+long\s+(?:un)?signed|
5558c2ecf20Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+long\s+int|
5568c2ecf20Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+long|
5578c2ecf20Sopenharmony_ci	int\s+long\s+long\s+(?:un)?signed|
5588c2ecf20Sopenharmony_ci	int\s+(?:(?:un)?signed\s+)?long\s+long|
5598c2ecf20Sopenharmony_ci
5608c2ecf20Sopenharmony_ci	long\s+int\s+(?:un)?signed|
5618c2ecf20Sopenharmony_ci	long\s+(?:un)?signed\s+int|
5628c2ecf20Sopenharmony_ci	long\s+(?:un)?signed|
5638c2ecf20Sopenharmony_ci	(?:(?:un)?signed\s+)?long\s+int|
5648c2ecf20Sopenharmony_ci	(?:(?:un)?signed\s+)?long|
5658c2ecf20Sopenharmony_ci	int\s+long\s+(?:un)?signed|
5668c2ecf20Sopenharmony_ci	int\s+(?:(?:un)?signed\s+)?long|
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	int\s+(?:un)?signed|
5698c2ecf20Sopenharmony_ci	(?:(?:un)?signed\s+)?int
5708c2ecf20Sopenharmony_ci)};
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ciour @typeListFile = ();
5738c2ecf20Sopenharmony_ciour @typeListWithAttr = (
5748c2ecf20Sopenharmony_ci	@typeList,
5758c2ecf20Sopenharmony_ci	qr{struct\s+$InitAttribute\s+$Ident},
5768c2ecf20Sopenharmony_ci	qr{union\s+$InitAttribute\s+$Ident},
5778c2ecf20Sopenharmony_ci);
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_ciour @modifierList = (
5808c2ecf20Sopenharmony_ci	qr{fastcall},
5818c2ecf20Sopenharmony_ci);
5828c2ecf20Sopenharmony_ciour @modifierListFile = ();
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ciour @mode_permission_funcs = (
5858c2ecf20Sopenharmony_ci	["module_param", 3],
5868c2ecf20Sopenharmony_ci	["module_param_(?:array|named|string)", 4],
5878c2ecf20Sopenharmony_ci	["module_param_array_named", 5],
5888c2ecf20Sopenharmony_ci	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5898c2ecf20Sopenharmony_ci	["proc_create(?:_data|)", 2],
5908c2ecf20Sopenharmony_ci	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
5918c2ecf20Sopenharmony_ci	["IIO_DEV_ATTR_[A-Z_]+", 1],
5928c2ecf20Sopenharmony_ci	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
5938c2ecf20Sopenharmony_ci	["SENSOR_TEMPLATE(?:_2|)", 3],
5948c2ecf20Sopenharmony_ci	["__ATTR", 2],
5958c2ecf20Sopenharmony_ci);
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_cimy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci#Create a search pattern for all these functions to speed up a loop below
6008c2ecf20Sopenharmony_ciour $mode_perms_search = "";
6018c2ecf20Sopenharmony_ciforeach my $entry (@mode_permission_funcs) {
6028c2ecf20Sopenharmony_ci	$mode_perms_search .= '|' if ($mode_perms_search ne "");
6038c2ecf20Sopenharmony_ci	$mode_perms_search .= $entry->[0];
6048c2ecf20Sopenharmony_ci}
6058c2ecf20Sopenharmony_ci$mode_perms_search = "(?:${mode_perms_search})";
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ciour %deprecated_apis = (
6088c2ecf20Sopenharmony_ci	"synchronize_rcu_bh"			=> "synchronize_rcu",
6098c2ecf20Sopenharmony_ci	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
6108c2ecf20Sopenharmony_ci	"call_rcu_bh"				=> "call_rcu",
6118c2ecf20Sopenharmony_ci	"rcu_barrier_bh"			=> "rcu_barrier",
6128c2ecf20Sopenharmony_ci	"synchronize_sched"			=> "synchronize_rcu",
6138c2ecf20Sopenharmony_ci	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
6148c2ecf20Sopenharmony_ci	"call_rcu_sched"			=> "call_rcu",
6158c2ecf20Sopenharmony_ci	"rcu_barrier_sched"			=> "rcu_barrier",
6168c2ecf20Sopenharmony_ci	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
6178c2ecf20Sopenharmony_ci	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
6188c2ecf20Sopenharmony_ci);
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci#Create a search pattern for all these strings to speed up a loop below
6218c2ecf20Sopenharmony_ciour $deprecated_apis_search = "";
6228c2ecf20Sopenharmony_ciforeach my $entry (keys %deprecated_apis) {
6238c2ecf20Sopenharmony_ci	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
6248c2ecf20Sopenharmony_ci	$deprecated_apis_search .= $entry;
6258c2ecf20Sopenharmony_ci}
6268c2ecf20Sopenharmony_ci$deprecated_apis_search = "(?:${deprecated_apis_search})";
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ciour $mode_perms_world_writable = qr{
6298c2ecf20Sopenharmony_ci	S_IWUGO		|
6308c2ecf20Sopenharmony_ci	S_IWOTH		|
6318c2ecf20Sopenharmony_ci	S_IRWXUGO	|
6328c2ecf20Sopenharmony_ci	S_IALLUGO	|
6338c2ecf20Sopenharmony_ci	0[0-7][0-7][2367]
6348c2ecf20Sopenharmony_ci}x;
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_ciour %mode_permission_string_types = (
6378c2ecf20Sopenharmony_ci	"S_IRWXU" => 0700,
6388c2ecf20Sopenharmony_ci	"S_IRUSR" => 0400,
6398c2ecf20Sopenharmony_ci	"S_IWUSR" => 0200,
6408c2ecf20Sopenharmony_ci	"S_IXUSR" => 0100,
6418c2ecf20Sopenharmony_ci	"S_IRWXG" => 0070,
6428c2ecf20Sopenharmony_ci	"S_IRGRP" => 0040,
6438c2ecf20Sopenharmony_ci	"S_IWGRP" => 0020,
6448c2ecf20Sopenharmony_ci	"S_IXGRP" => 0010,
6458c2ecf20Sopenharmony_ci	"S_IRWXO" => 0007,
6468c2ecf20Sopenharmony_ci	"S_IROTH" => 0004,
6478c2ecf20Sopenharmony_ci	"S_IWOTH" => 0002,
6488c2ecf20Sopenharmony_ci	"S_IXOTH" => 0001,
6498c2ecf20Sopenharmony_ci	"S_IRWXUGO" => 0777,
6508c2ecf20Sopenharmony_ci	"S_IRUGO" => 0444,
6518c2ecf20Sopenharmony_ci	"S_IWUGO" => 0222,
6528c2ecf20Sopenharmony_ci	"S_IXUGO" => 0111,
6538c2ecf20Sopenharmony_ci);
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ci#Create a search pattern for all these strings to speed up a loop below
6568c2ecf20Sopenharmony_ciour $mode_perms_string_search = "";
6578c2ecf20Sopenharmony_ciforeach my $entry (keys %mode_permission_string_types) {
6588c2ecf20Sopenharmony_ci	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
6598c2ecf20Sopenharmony_ci	$mode_perms_string_search .= $entry;
6608c2ecf20Sopenharmony_ci}
6618c2ecf20Sopenharmony_ciour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
6628c2ecf20Sopenharmony_ciour $multi_mode_perms_string_search = qr{
6638c2ecf20Sopenharmony_ci	${single_mode_perms_string_search}
6648c2ecf20Sopenharmony_ci	(?:\s*\|\s*${single_mode_perms_string_search})*
6658c2ecf20Sopenharmony_ci}x;
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_cisub perms_to_octal {
6688c2ecf20Sopenharmony_ci	my ($string) = @_;
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci	my $val = "";
6738c2ecf20Sopenharmony_ci	my $oval = "";
6748c2ecf20Sopenharmony_ci	my $to = 0;
6758c2ecf20Sopenharmony_ci	my $curpos = 0;
6768c2ecf20Sopenharmony_ci	my $lastpos = 0;
6778c2ecf20Sopenharmony_ci	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6788c2ecf20Sopenharmony_ci		$curpos = pos($string);
6798c2ecf20Sopenharmony_ci		my $match = $2;
6808c2ecf20Sopenharmony_ci		my $omatch = $1;
6818c2ecf20Sopenharmony_ci		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6828c2ecf20Sopenharmony_ci		$lastpos = $curpos;
6838c2ecf20Sopenharmony_ci		$to |= $mode_permission_string_types{$match};
6848c2ecf20Sopenharmony_ci		$val .= '\s*\|\s*' if ($val ne "");
6858c2ecf20Sopenharmony_ci		$val .= $match;
6868c2ecf20Sopenharmony_ci		$oval .= $omatch;
6878c2ecf20Sopenharmony_ci	}
6888c2ecf20Sopenharmony_ci	$oval =~ s/^\s*\|\s*//;
6898c2ecf20Sopenharmony_ci	$oval =~ s/\s*\|\s*$//;
6908c2ecf20Sopenharmony_ci	return sprintf("%04o", $to);
6918c2ecf20Sopenharmony_ci}
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ciour $allowed_asm_includes = qr{(?x:
6948c2ecf20Sopenharmony_ci	irq|
6958c2ecf20Sopenharmony_ci	memory|
6968c2ecf20Sopenharmony_ci	time|
6978c2ecf20Sopenharmony_ci	reboot
6988c2ecf20Sopenharmony_ci)};
6998c2ecf20Sopenharmony_ci# memory.h: ARM has a custom one
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci# Load common spelling mistakes and build regular expression list.
7028c2ecf20Sopenharmony_cimy $misspellings;
7038c2ecf20Sopenharmony_cimy %spelling_fix;
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ciif (open(my $spelling, '<', $spelling_file)) {
7068c2ecf20Sopenharmony_ci	while (<$spelling>) {
7078c2ecf20Sopenharmony_ci		my $line = $_;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		$line =~ s/\s*\n?$//g;
7108c2ecf20Sopenharmony_ci		$line =~ s/^\s*//g;
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci		next if ($line =~ m/^\s*#/);
7138c2ecf20Sopenharmony_ci		next if ($line =~ m/^\s*$/);
7148c2ecf20Sopenharmony_ci
7158c2ecf20Sopenharmony_ci		my ($suspect, $fix) = split(/\|\|/, $line);
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci		$spelling_fix{$suspect} = $fix;
7188c2ecf20Sopenharmony_ci	}
7198c2ecf20Sopenharmony_ci	close($spelling);
7208c2ecf20Sopenharmony_ci} else {
7218c2ecf20Sopenharmony_ci	warn "No typos will be found - file '$spelling_file': $!\n";
7228c2ecf20Sopenharmony_ci}
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ciif ($codespell) {
7258c2ecf20Sopenharmony_ci	if (open(my $spelling, '<', $codespellfile)) {
7268c2ecf20Sopenharmony_ci		while (<$spelling>) {
7278c2ecf20Sopenharmony_ci			my $line = $_;
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci			$line =~ s/\s*\n?$//g;
7308c2ecf20Sopenharmony_ci			$line =~ s/^\s*//g;
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci			next if ($line =~ m/^\s*#/);
7338c2ecf20Sopenharmony_ci			next if ($line =~ m/^\s*$/);
7348c2ecf20Sopenharmony_ci			next if ($line =~ m/, disabled/i);
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci			$line =~ s/,.*$//;
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci			my ($suspect, $fix) = split(/->/, $line);
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci			$spelling_fix{$suspect} = $fix;
7418c2ecf20Sopenharmony_ci		}
7428c2ecf20Sopenharmony_ci		close($spelling);
7438c2ecf20Sopenharmony_ci	} else {
7448c2ecf20Sopenharmony_ci		warn "No codespell typos will be found - file '$codespellfile': $!\n";
7458c2ecf20Sopenharmony_ci	}
7468c2ecf20Sopenharmony_ci}
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_cisub read_words {
7518c2ecf20Sopenharmony_ci	my ($wordsRef, $file) = @_;
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci	if (open(my $words, '<', $file)) {
7548c2ecf20Sopenharmony_ci		while (<$words>) {
7558c2ecf20Sopenharmony_ci			my $line = $_;
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci			$line =~ s/\s*\n?$//g;
7588c2ecf20Sopenharmony_ci			$line =~ s/^\s*//g;
7598c2ecf20Sopenharmony_ci
7608c2ecf20Sopenharmony_ci			next if ($line =~ m/^\s*#/);
7618c2ecf20Sopenharmony_ci			next if ($line =~ m/^\s*$/);
7628c2ecf20Sopenharmony_ci			if ($line =~ /\s/) {
7638c2ecf20Sopenharmony_ci				print("$file: '$line' invalid - ignored\n");
7648c2ecf20Sopenharmony_ci				next;
7658c2ecf20Sopenharmony_ci			}
7668c2ecf20Sopenharmony_ci
7678c2ecf20Sopenharmony_ci			$$wordsRef .= '|' if (defined $$wordsRef);
7688c2ecf20Sopenharmony_ci			$$wordsRef .= $line;
7698c2ecf20Sopenharmony_ci		}
7708c2ecf20Sopenharmony_ci		close($file);
7718c2ecf20Sopenharmony_ci		return 1;
7728c2ecf20Sopenharmony_ci	}
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci	return 0;
7758c2ecf20Sopenharmony_ci}
7768c2ecf20Sopenharmony_ci
7778c2ecf20Sopenharmony_cimy $const_structs;
7788c2ecf20Sopenharmony_ciif (show_type("CONST_STRUCT")) {
7798c2ecf20Sopenharmony_ci	read_words(\$const_structs, $conststructsfile)
7808c2ecf20Sopenharmony_ci	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
7818c2ecf20Sopenharmony_ci}
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ciif (defined($typedefsfile)) {
7848c2ecf20Sopenharmony_ci	my $typeOtherTypedefs;
7858c2ecf20Sopenharmony_ci	read_words(\$typeOtherTypedefs, $typedefsfile)
7868c2ecf20Sopenharmony_ci	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
7878c2ecf20Sopenharmony_ci	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
7888c2ecf20Sopenharmony_ci}
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_cisub build_types {
7918c2ecf20Sopenharmony_ci	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
7928c2ecf20Sopenharmony_ci	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
7938c2ecf20Sopenharmony_ci	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
7948c2ecf20Sopenharmony_ci	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
7958c2ecf20Sopenharmony_ci	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
7968c2ecf20Sopenharmony_ci	$BasicType	= qr{
7978c2ecf20Sopenharmony_ci				(?:$typeTypedefs\b)|
7988c2ecf20Sopenharmony_ci				(?:${all}\b)
7998c2ecf20Sopenharmony_ci		}x;
8008c2ecf20Sopenharmony_ci	$NonptrType	= qr{
8018c2ecf20Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
8028c2ecf20Sopenharmony_ci			(?:
8038c2ecf20Sopenharmony_ci				(?:typeof|__typeof__)\s*\([^\)]*\)|
8048c2ecf20Sopenharmony_ci				(?:$typeTypedefs\b)|
8058c2ecf20Sopenharmony_ci				(?:${all}\b)
8068c2ecf20Sopenharmony_ci			)
8078c2ecf20Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
8088c2ecf20Sopenharmony_ci		  }x;
8098c2ecf20Sopenharmony_ci	$NonptrTypeMisordered	= qr{
8108c2ecf20Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
8118c2ecf20Sopenharmony_ci			(?:
8128c2ecf20Sopenharmony_ci				(?:${Misordered}\b)
8138c2ecf20Sopenharmony_ci			)
8148c2ecf20Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
8158c2ecf20Sopenharmony_ci		  }x;
8168c2ecf20Sopenharmony_ci	$NonptrTypeWithAttr	= qr{
8178c2ecf20Sopenharmony_ci			(?:$Modifier\s+|const\s+)*
8188c2ecf20Sopenharmony_ci			(?:
8198c2ecf20Sopenharmony_ci				(?:typeof|__typeof__)\s*\([^\)]*\)|
8208c2ecf20Sopenharmony_ci				(?:$typeTypedefs\b)|
8218c2ecf20Sopenharmony_ci				(?:${allWithAttr}\b)
8228c2ecf20Sopenharmony_ci			)
8238c2ecf20Sopenharmony_ci			(?:\s+$Modifier|\s+const)*
8248c2ecf20Sopenharmony_ci		  }x;
8258c2ecf20Sopenharmony_ci	$Type	= qr{
8268c2ecf20Sopenharmony_ci			$NonptrType
8278c2ecf20Sopenharmony_ci			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
8288c2ecf20Sopenharmony_ci			(?:\s+$Inline|\s+$Modifier)*
8298c2ecf20Sopenharmony_ci		  }x;
8308c2ecf20Sopenharmony_ci	$TypeMisordered	= qr{
8318c2ecf20Sopenharmony_ci			$NonptrTypeMisordered
8328c2ecf20Sopenharmony_ci			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
8338c2ecf20Sopenharmony_ci			(?:\s+$Inline|\s+$Modifier)*
8348c2ecf20Sopenharmony_ci		  }x;
8358c2ecf20Sopenharmony_ci	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
8368c2ecf20Sopenharmony_ci	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
8378c2ecf20Sopenharmony_ci}
8388c2ecf20Sopenharmony_cibuild_types();
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ciour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci# Using $balanced_parens, $LvalOrFunc, or $FuncArg
8438c2ecf20Sopenharmony_ci# requires at least perl version v5.10.0
8448c2ecf20Sopenharmony_ci# Any use must be runtime checked with $^V
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ciour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
8478c2ecf20Sopenharmony_ciour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
8488c2ecf20Sopenharmony_ciour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_ciour $declaration_macros = qr{(?x:
8518c2ecf20Sopenharmony_ci	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
8528c2ecf20Sopenharmony_ci	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
8538c2ecf20Sopenharmony_ci	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
8548c2ecf20Sopenharmony_ci)};
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_cisub deparenthesize {
8578c2ecf20Sopenharmony_ci	my ($string) = @_;
8588c2ecf20Sopenharmony_ci	return "" if (!defined($string));
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci	while ($string =~ /^\s*\(.*\)\s*$/) {
8618c2ecf20Sopenharmony_ci		$string =~ s@^\s*\(\s*@@;
8628c2ecf20Sopenharmony_ci		$string =~ s@\s*\)\s*$@@;
8638c2ecf20Sopenharmony_ci	}
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	$string =~ s@\s+@ @g;
8668c2ecf20Sopenharmony_ci
8678c2ecf20Sopenharmony_ci	return $string;
8688c2ecf20Sopenharmony_ci}
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_cisub seed_camelcase_file {
8718c2ecf20Sopenharmony_ci	my ($file) = @_;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	return if (!(-f $file));
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci	local $/;
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci	open(my $include_file, '<', "$file")
8788c2ecf20Sopenharmony_ci	    or warn "$P: Can't read '$file' $!\n";
8798c2ecf20Sopenharmony_ci	my $text = <$include_file>;
8808c2ecf20Sopenharmony_ci	close($include_file);
8818c2ecf20Sopenharmony_ci
8828c2ecf20Sopenharmony_ci	my @lines = split('\n', $text);
8838c2ecf20Sopenharmony_ci
8848c2ecf20Sopenharmony_ci	foreach my $line (@lines) {
8858c2ecf20Sopenharmony_ci		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
8868c2ecf20Sopenharmony_ci		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
8878c2ecf20Sopenharmony_ci			$camelcase{$1} = 1;
8888c2ecf20Sopenharmony_ci		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
8898c2ecf20Sopenharmony_ci			$camelcase{$1} = 1;
8908c2ecf20Sopenharmony_ci		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
8918c2ecf20Sopenharmony_ci			$camelcase{$1} = 1;
8928c2ecf20Sopenharmony_ci		}
8938c2ecf20Sopenharmony_ci	}
8948c2ecf20Sopenharmony_ci}
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_ciour %maintained_status = ();
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_cisub is_maintained_obsolete {
8998c2ecf20Sopenharmony_ci	my ($filename) = @_;
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ci	if (!exists($maintained_status{$filename})) {
9048c2ecf20Sopenharmony_ci		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
9058c2ecf20Sopenharmony_ci	}
9068c2ecf20Sopenharmony_ci
9078c2ecf20Sopenharmony_ci	return $maintained_status{$filename} =~ /obsolete/i;
9088c2ecf20Sopenharmony_ci}
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_cisub is_SPDX_License_valid {
9118c2ecf20Sopenharmony_ci	my ($license) = @_;
9128c2ecf20Sopenharmony_ci
9138c2ecf20Sopenharmony_ci	return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_ci	my $root_path = abs_path($root);
9168c2ecf20Sopenharmony_ci	my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
9178c2ecf20Sopenharmony_ci	return 0 if ($status ne "");
9188c2ecf20Sopenharmony_ci	return 1;
9198c2ecf20Sopenharmony_ci}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_cimy $camelcase_seeded = 0;
9228c2ecf20Sopenharmony_cisub seed_camelcase_includes {
9238c2ecf20Sopenharmony_ci	return if ($camelcase_seeded);
9248c2ecf20Sopenharmony_ci
9258c2ecf20Sopenharmony_ci	my $files;
9268c2ecf20Sopenharmony_ci	my $camelcase_cache = "";
9278c2ecf20Sopenharmony_ci	my @include_files = ();
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_ci	$camelcase_seeded = 1;
9308c2ecf20Sopenharmony_ci
9318c2ecf20Sopenharmony_ci	if (-e "$gitroot") {
9328c2ecf20Sopenharmony_ci		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
9338c2ecf20Sopenharmony_ci		chomp $git_last_include_commit;
9348c2ecf20Sopenharmony_ci		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
9358c2ecf20Sopenharmony_ci	} else {
9368c2ecf20Sopenharmony_ci		my $last_mod_date = 0;
9378c2ecf20Sopenharmony_ci		$files = `find $root/include -name "*.h"`;
9388c2ecf20Sopenharmony_ci		@include_files = split('\n', $files);
9398c2ecf20Sopenharmony_ci		foreach my $file (@include_files) {
9408c2ecf20Sopenharmony_ci			my $date = POSIX::strftime("%Y%m%d%H%M",
9418c2ecf20Sopenharmony_ci						   localtime((stat $file)[9]));
9428c2ecf20Sopenharmony_ci			$last_mod_date = $date if ($last_mod_date < $date);
9438c2ecf20Sopenharmony_ci		}
9448c2ecf20Sopenharmony_ci		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
9458c2ecf20Sopenharmony_ci	}
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci	if ($camelcase_cache ne "" && -f $camelcase_cache) {
9488c2ecf20Sopenharmony_ci		open(my $camelcase_file, '<', "$camelcase_cache")
9498c2ecf20Sopenharmony_ci		    or warn "$P: Can't read '$camelcase_cache' $!\n";
9508c2ecf20Sopenharmony_ci		while (<$camelcase_file>) {
9518c2ecf20Sopenharmony_ci			chomp;
9528c2ecf20Sopenharmony_ci			$camelcase{$_} = 1;
9538c2ecf20Sopenharmony_ci		}
9548c2ecf20Sopenharmony_ci		close($camelcase_file);
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci		return;
9578c2ecf20Sopenharmony_ci	}
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_ci	if (-e "$gitroot") {
9608c2ecf20Sopenharmony_ci		$files = `${git_command} ls-files "include/*.h"`;
9618c2ecf20Sopenharmony_ci		@include_files = split('\n', $files);
9628c2ecf20Sopenharmony_ci	}
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	foreach my $file (@include_files) {
9658c2ecf20Sopenharmony_ci		seed_camelcase_file($file);
9668c2ecf20Sopenharmony_ci	}
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	if ($camelcase_cache ne "") {
9698c2ecf20Sopenharmony_ci		unlink glob ".checkpatch-camelcase.*";
9708c2ecf20Sopenharmony_ci		open(my $camelcase_file, '>', "$camelcase_cache")
9718c2ecf20Sopenharmony_ci		    or warn "$P: Can't write '$camelcase_cache' $!\n";
9728c2ecf20Sopenharmony_ci		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
9738c2ecf20Sopenharmony_ci			print $camelcase_file ("$_\n");
9748c2ecf20Sopenharmony_ci		}
9758c2ecf20Sopenharmony_ci		close($camelcase_file);
9768c2ecf20Sopenharmony_ci	}
9778c2ecf20Sopenharmony_ci}
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_cisub git_is_single_file {
9808c2ecf20Sopenharmony_ci	my ($filename) = @_;
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_ci	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
9858c2ecf20Sopenharmony_ci	my $count = $output =~ tr/\n//;
9868c2ecf20Sopenharmony_ci	return $count eq 1 && $output =~ m{^${filename}$};
9878c2ecf20Sopenharmony_ci}
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_cisub git_commit_info {
9908c2ecf20Sopenharmony_ci	my ($commit, $id, $desc) = @_;
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_ci	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
9958c2ecf20Sopenharmony_ci	$output =~ s/^\s*//gm;
9968c2ecf20Sopenharmony_ci	my @lines = split("\n", $output);
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci	return ($id, $desc) if ($#lines < 0);
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
10018c2ecf20Sopenharmony_ci# Maybe one day convert this block of bash into something that returns
10028c2ecf20Sopenharmony_ci# all matching commit ids, but it's very slow...
10038c2ecf20Sopenharmony_ci#
10048c2ecf20Sopenharmony_ci#		echo "checking commits $1..."
10058c2ecf20Sopenharmony_ci#		git rev-list --remotes | grep -i "^$1" |
10068c2ecf20Sopenharmony_ci#		while read line ; do
10078c2ecf20Sopenharmony_ci#		    git log --format='%H %s' -1 $line |
10088c2ecf20Sopenharmony_ci#		    echo "commit $(cut -c 1-12,41-)"
10098c2ecf20Sopenharmony_ci#		done
10108c2ecf20Sopenharmony_ci	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
10118c2ecf20Sopenharmony_ci		$id = undef;
10128c2ecf20Sopenharmony_ci	} else {
10138c2ecf20Sopenharmony_ci		$id = substr($lines[0], 0, 12);
10148c2ecf20Sopenharmony_ci		$desc = substr($lines[0], 41);
10158c2ecf20Sopenharmony_ci	}
10168c2ecf20Sopenharmony_ci
10178c2ecf20Sopenharmony_ci	return ($id, $desc);
10188c2ecf20Sopenharmony_ci}
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_ci$chk_signoff = 0 if ($file);
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_cimy @rawlines = ();
10238c2ecf20Sopenharmony_cimy @lines = ();
10248c2ecf20Sopenharmony_cimy @fixed = ();
10258c2ecf20Sopenharmony_cimy @fixed_inserted = ();
10268c2ecf20Sopenharmony_cimy @fixed_deleted = ();
10278c2ecf20Sopenharmony_cimy $fixlinenr = -1;
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci# If input is git commits, extract all commits from the commit expressions.
10308c2ecf20Sopenharmony_ci# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
10318c2ecf20Sopenharmony_cidie "$P: No git repository found\n" if ($git && !-e "$gitroot");
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ciif ($git) {
10348c2ecf20Sopenharmony_ci	my @commits = ();
10358c2ecf20Sopenharmony_ci	foreach my $commit_expr (@ARGV) {
10368c2ecf20Sopenharmony_ci		my $git_range;
10378c2ecf20Sopenharmony_ci		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
10388c2ecf20Sopenharmony_ci			$git_range = "-$2 $1";
10398c2ecf20Sopenharmony_ci		} elsif ($commit_expr =~ m/\.\./) {
10408c2ecf20Sopenharmony_ci			$git_range = "$commit_expr";
10418c2ecf20Sopenharmony_ci		} else {
10428c2ecf20Sopenharmony_ci			$git_range = "-1 $commit_expr";
10438c2ecf20Sopenharmony_ci		}
10448c2ecf20Sopenharmony_ci		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
10458c2ecf20Sopenharmony_ci		foreach my $line (split(/\n/, $lines)) {
10468c2ecf20Sopenharmony_ci			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
10478c2ecf20Sopenharmony_ci			next if (!defined($1) || !defined($2));
10488c2ecf20Sopenharmony_ci			my $sha1 = $1;
10498c2ecf20Sopenharmony_ci			my $subject = $2;
10508c2ecf20Sopenharmony_ci			unshift(@commits, $sha1);
10518c2ecf20Sopenharmony_ci			$git_commits{$sha1} = $subject;
10528c2ecf20Sopenharmony_ci		}
10538c2ecf20Sopenharmony_ci	}
10548c2ecf20Sopenharmony_ci	die "$P: no git commits after extraction!\n" if (@commits == 0);
10558c2ecf20Sopenharmony_ci	@ARGV = @commits;
10568c2ecf20Sopenharmony_ci}
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_cimy $vname;
10598c2ecf20Sopenharmony_ci$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
10608c2ecf20Sopenharmony_cifor my $filename (@ARGV) {
10618c2ecf20Sopenharmony_ci	my $FILE;
10628c2ecf20Sopenharmony_ci	my $is_git_file = git_is_single_file($filename);
10638c2ecf20Sopenharmony_ci	my $oldfile = $file;
10648c2ecf20Sopenharmony_ci	$file = 1 if ($is_git_file);
10658c2ecf20Sopenharmony_ci	if ($git) {
10668c2ecf20Sopenharmony_ci		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
10678c2ecf20Sopenharmony_ci			die "$P: $filename: git format-patch failed - $!\n";
10688c2ecf20Sopenharmony_ci	} elsif ($file) {
10698c2ecf20Sopenharmony_ci		open($FILE, '-|', "diff -u /dev/null $filename") ||
10708c2ecf20Sopenharmony_ci			die "$P: $filename: diff failed - $!\n";
10718c2ecf20Sopenharmony_ci	} elsif ($filename eq '-') {
10728c2ecf20Sopenharmony_ci		open($FILE, '<&STDIN');
10738c2ecf20Sopenharmony_ci	} else {
10748c2ecf20Sopenharmony_ci		open($FILE, '<', "$filename") ||
10758c2ecf20Sopenharmony_ci			die "$P: $filename: open failed - $!\n";
10768c2ecf20Sopenharmony_ci	}
10778c2ecf20Sopenharmony_ci	if ($filename eq '-') {
10788c2ecf20Sopenharmony_ci		$vname = 'Your patch';
10798c2ecf20Sopenharmony_ci	} elsif ($git) {
10808c2ecf20Sopenharmony_ci		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
10818c2ecf20Sopenharmony_ci	} else {
10828c2ecf20Sopenharmony_ci		$vname = $filename;
10838c2ecf20Sopenharmony_ci	}
10848c2ecf20Sopenharmony_ci	while (<$FILE>) {
10858c2ecf20Sopenharmony_ci		chomp;
10868c2ecf20Sopenharmony_ci		push(@rawlines, $_);
10878c2ecf20Sopenharmony_ci		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
10888c2ecf20Sopenharmony_ci	}
10898c2ecf20Sopenharmony_ci	close($FILE);
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_ci	if ($#ARGV > 0 && $quiet == 0) {
10928c2ecf20Sopenharmony_ci		print '-' x length($vname) . "\n";
10938c2ecf20Sopenharmony_ci		print "$vname\n";
10948c2ecf20Sopenharmony_ci		print '-' x length($vname) . "\n";
10958c2ecf20Sopenharmony_ci	}
10968c2ecf20Sopenharmony_ci
10978c2ecf20Sopenharmony_ci	if (!process($filename)) {
10988c2ecf20Sopenharmony_ci		$exit = 1;
10998c2ecf20Sopenharmony_ci	}
11008c2ecf20Sopenharmony_ci	@rawlines = ();
11018c2ecf20Sopenharmony_ci	@lines = ();
11028c2ecf20Sopenharmony_ci	@fixed = ();
11038c2ecf20Sopenharmony_ci	@fixed_inserted = ();
11048c2ecf20Sopenharmony_ci	@fixed_deleted = ();
11058c2ecf20Sopenharmony_ci	$fixlinenr = -1;
11068c2ecf20Sopenharmony_ci	@modifierListFile = ();
11078c2ecf20Sopenharmony_ci	@typeListFile = ();
11088c2ecf20Sopenharmony_ci	build_types();
11098c2ecf20Sopenharmony_ci	$file = $oldfile if ($is_git_file);
11108c2ecf20Sopenharmony_ci}
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_ciif (!$quiet) {
11138c2ecf20Sopenharmony_ci	hash_show_words(\%use_type, "Used");
11148c2ecf20Sopenharmony_ci	hash_show_words(\%ignore_type, "Ignored");
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_ci	if (!$perl_version_ok) {
11178c2ecf20Sopenharmony_ci		print << "EOM"
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ciNOTE: perl $^V is not modern enough to detect all possible issues.
11208c2ecf20Sopenharmony_ci      An upgrade to at least perl $minimum_perl_version is suggested.
11218c2ecf20Sopenharmony_ciEOM
11228c2ecf20Sopenharmony_ci	}
11238c2ecf20Sopenharmony_ci	if ($exit) {
11248c2ecf20Sopenharmony_ci		print << "EOM"
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ciNOTE: If any of the errors are false positives, please report
11278c2ecf20Sopenharmony_ci      them to the maintainer, see CHECKPATCH in MAINTAINERS.
11288c2ecf20Sopenharmony_ciEOM
11298c2ecf20Sopenharmony_ci	}
11308c2ecf20Sopenharmony_ci}
11318c2ecf20Sopenharmony_ci
11328c2ecf20Sopenharmony_ciexit($exit);
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_cisub top_of_kernel_tree {
11358c2ecf20Sopenharmony_ci	my ($root) = @_;
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_ci	my @tree_check = (
11388c2ecf20Sopenharmony_ci		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
11398c2ecf20Sopenharmony_ci		"README", "Documentation", "arch", "include", "drivers",
11408c2ecf20Sopenharmony_ci		"fs", "init", "ipc", "kernel", "lib", "scripts",
11418c2ecf20Sopenharmony_ci	);
11428c2ecf20Sopenharmony_ci
11438c2ecf20Sopenharmony_ci	foreach my $check (@tree_check) {
11448c2ecf20Sopenharmony_ci		if (! -e $root . '/' . $check) {
11458c2ecf20Sopenharmony_ci			return 0;
11468c2ecf20Sopenharmony_ci		}
11478c2ecf20Sopenharmony_ci	}
11488c2ecf20Sopenharmony_ci	return 1;
11498c2ecf20Sopenharmony_ci}
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_cisub parse_email {
11528c2ecf20Sopenharmony_ci	my ($formatted_email) = @_;
11538c2ecf20Sopenharmony_ci
11548c2ecf20Sopenharmony_ci	my $name = "";
11558c2ecf20Sopenharmony_ci	my $name_comment = "";
11568c2ecf20Sopenharmony_ci	my $address = "";
11578c2ecf20Sopenharmony_ci	my $comment = "";
11588c2ecf20Sopenharmony_ci
11598c2ecf20Sopenharmony_ci	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
11608c2ecf20Sopenharmony_ci		$name = $1;
11618c2ecf20Sopenharmony_ci		$address = $2;
11628c2ecf20Sopenharmony_ci		$comment = $3 if defined $3;
11638c2ecf20Sopenharmony_ci	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
11648c2ecf20Sopenharmony_ci		$address = $1;
11658c2ecf20Sopenharmony_ci		$comment = $2 if defined $2;
11668c2ecf20Sopenharmony_ci	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
11678c2ecf20Sopenharmony_ci		$address = $1;
11688c2ecf20Sopenharmony_ci		$comment = $2 if defined $2;
11698c2ecf20Sopenharmony_ci		$formatted_email =~ s/\Q$address\E.*$//;
11708c2ecf20Sopenharmony_ci		$name = $formatted_email;
11718c2ecf20Sopenharmony_ci		$name = trim($name);
11728c2ecf20Sopenharmony_ci		$name =~ s/^\"|\"$//g;
11738c2ecf20Sopenharmony_ci		# If there's a name left after stripping spaces and
11748c2ecf20Sopenharmony_ci		# leading quotes, and the address doesn't have both
11758c2ecf20Sopenharmony_ci		# leading and trailing angle brackets, the address
11768c2ecf20Sopenharmony_ci		# is invalid. ie:
11778c2ecf20Sopenharmony_ci		#   "joe smith joe@smith.com" bad
11788c2ecf20Sopenharmony_ci		#   "joe smith <joe@smith.com" bad
11798c2ecf20Sopenharmony_ci		if ($name ne "" && $address !~ /^<[^>]+>$/) {
11808c2ecf20Sopenharmony_ci			$name = "";
11818c2ecf20Sopenharmony_ci			$address = "";
11828c2ecf20Sopenharmony_ci			$comment = "";
11838c2ecf20Sopenharmony_ci		}
11848c2ecf20Sopenharmony_ci	}
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_ci	$comment = trim($comment);
11878c2ecf20Sopenharmony_ci	$name = trim($name);
11888c2ecf20Sopenharmony_ci	$name =~ s/^\"|\"$//g;
11898c2ecf20Sopenharmony_ci	if ($name =~ s/(\s*\([^\)]+\))\s*//) {
11908c2ecf20Sopenharmony_ci		$name_comment = trim($1);
11918c2ecf20Sopenharmony_ci	}
11928c2ecf20Sopenharmony_ci	$address = trim($address);
11938c2ecf20Sopenharmony_ci	$address =~ s/^\<|\>$//g;
11948c2ecf20Sopenharmony_ci
11958c2ecf20Sopenharmony_ci	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
11968c2ecf20Sopenharmony_ci		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
11978c2ecf20Sopenharmony_ci		$name = "\"$name\"";
11988c2ecf20Sopenharmony_ci	}
11998c2ecf20Sopenharmony_ci
12008c2ecf20Sopenharmony_ci	return ($name, $name_comment, $address, $comment);
12018c2ecf20Sopenharmony_ci}
12028c2ecf20Sopenharmony_ci
12038c2ecf20Sopenharmony_cisub format_email {
12048c2ecf20Sopenharmony_ci	my ($name, $name_comment, $address, $comment) = @_;
12058c2ecf20Sopenharmony_ci
12068c2ecf20Sopenharmony_ci	my $formatted_email;
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci	$name_comment = trim($name_comment);
12098c2ecf20Sopenharmony_ci	$comment = trim($comment);
12108c2ecf20Sopenharmony_ci	$name = trim($name);
12118c2ecf20Sopenharmony_ci	$name =~ s/^\"|\"$//g;
12128c2ecf20Sopenharmony_ci	$address = trim($address);
12138c2ecf20Sopenharmony_ci
12148c2ecf20Sopenharmony_ci	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
12158c2ecf20Sopenharmony_ci		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
12168c2ecf20Sopenharmony_ci		$name = "\"$name\"";
12178c2ecf20Sopenharmony_ci	}
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci	if ("$name" eq "") {
12208c2ecf20Sopenharmony_ci		$formatted_email = "$address";
12218c2ecf20Sopenharmony_ci	} else {
12228c2ecf20Sopenharmony_ci		$formatted_email = "$name$name_comment <$address>";
12238c2ecf20Sopenharmony_ci	}
12248c2ecf20Sopenharmony_ci	$formatted_email .= "$comment";
12258c2ecf20Sopenharmony_ci	return $formatted_email;
12268c2ecf20Sopenharmony_ci}
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_cisub reformat_email {
12298c2ecf20Sopenharmony_ci	my ($email) = @_;
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
12328c2ecf20Sopenharmony_ci	return format_email($email_name, $name_comment, $email_address, $comment);
12338c2ecf20Sopenharmony_ci}
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_cisub same_email_addresses {
12368c2ecf20Sopenharmony_ci	my ($email1, $email2, $match_comment) = @_;
12378c2ecf20Sopenharmony_ci
12388c2ecf20Sopenharmony_ci	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
12398c2ecf20Sopenharmony_ci	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
12408c2ecf20Sopenharmony_ci
12418c2ecf20Sopenharmony_ci	if ($match_comment != 1) {
12428c2ecf20Sopenharmony_ci		return $email1_name eq $email2_name &&
12438c2ecf20Sopenharmony_ci		       $email1_address eq $email2_address;
12448c2ecf20Sopenharmony_ci	}
12458c2ecf20Sopenharmony_ci	return $email1_name eq $email2_name &&
12468c2ecf20Sopenharmony_ci	       $email1_address eq $email2_address &&
12478c2ecf20Sopenharmony_ci	       $name1_comment eq $name2_comment &&
12488c2ecf20Sopenharmony_ci	       $comment1 eq $comment2;
12498c2ecf20Sopenharmony_ci}
12508c2ecf20Sopenharmony_ci
12518c2ecf20Sopenharmony_cisub which {
12528c2ecf20Sopenharmony_ci	my ($bin) = @_;
12538c2ecf20Sopenharmony_ci
12548c2ecf20Sopenharmony_ci	foreach my $path (split(/:/, $ENV{PATH})) {
12558c2ecf20Sopenharmony_ci		if (-e "$path/$bin") {
12568c2ecf20Sopenharmony_ci			return "$path/$bin";
12578c2ecf20Sopenharmony_ci		}
12588c2ecf20Sopenharmony_ci	}
12598c2ecf20Sopenharmony_ci
12608c2ecf20Sopenharmony_ci	return "";
12618c2ecf20Sopenharmony_ci}
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_cisub which_conf {
12648c2ecf20Sopenharmony_ci	my ($conf) = @_;
12658c2ecf20Sopenharmony_ci
12668c2ecf20Sopenharmony_ci	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
12678c2ecf20Sopenharmony_ci		if (-e "$path/$conf") {
12688c2ecf20Sopenharmony_ci			return "$path/$conf";
12698c2ecf20Sopenharmony_ci		}
12708c2ecf20Sopenharmony_ci	}
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_ci	return "";
12738c2ecf20Sopenharmony_ci}
12748c2ecf20Sopenharmony_ci
12758c2ecf20Sopenharmony_cisub expand_tabs {
12768c2ecf20Sopenharmony_ci	my ($str) = @_;
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ci	my $res = '';
12798c2ecf20Sopenharmony_ci	my $n = 0;
12808c2ecf20Sopenharmony_ci	for my $c (split(//, $str)) {
12818c2ecf20Sopenharmony_ci		if ($c eq "\t") {
12828c2ecf20Sopenharmony_ci			$res .= ' ';
12838c2ecf20Sopenharmony_ci			$n++;
12848c2ecf20Sopenharmony_ci			for (; ($n % $tabsize) != 0; $n++) {
12858c2ecf20Sopenharmony_ci				$res .= ' ';
12868c2ecf20Sopenharmony_ci			}
12878c2ecf20Sopenharmony_ci			next;
12888c2ecf20Sopenharmony_ci		}
12898c2ecf20Sopenharmony_ci		$res .= $c;
12908c2ecf20Sopenharmony_ci		$n++;
12918c2ecf20Sopenharmony_ci	}
12928c2ecf20Sopenharmony_ci
12938c2ecf20Sopenharmony_ci	return $res;
12948c2ecf20Sopenharmony_ci}
12958c2ecf20Sopenharmony_cisub copy_spacing {
12968c2ecf20Sopenharmony_ci	(my $res = shift) =~ tr/\t/ /c;
12978c2ecf20Sopenharmony_ci	return $res;
12988c2ecf20Sopenharmony_ci}
12998c2ecf20Sopenharmony_ci
13008c2ecf20Sopenharmony_cisub line_stats {
13018c2ecf20Sopenharmony_ci	my ($line) = @_;
13028c2ecf20Sopenharmony_ci
13038c2ecf20Sopenharmony_ci	# Drop the diff line leader and expand tabs
13048c2ecf20Sopenharmony_ci	$line =~ s/^.//;
13058c2ecf20Sopenharmony_ci	$line = expand_tabs($line);
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci	# Pick the indent from the front of the line.
13088c2ecf20Sopenharmony_ci	my ($white) = ($line =~ /^(\s*)/);
13098c2ecf20Sopenharmony_ci
13108c2ecf20Sopenharmony_ci	return (length($line), length($white));
13118c2ecf20Sopenharmony_ci}
13128c2ecf20Sopenharmony_ci
13138c2ecf20Sopenharmony_cimy $sanitise_quote = '';
13148c2ecf20Sopenharmony_ci
13158c2ecf20Sopenharmony_cisub sanitise_line_reset {
13168c2ecf20Sopenharmony_ci	my ($in_comment) = @_;
13178c2ecf20Sopenharmony_ci
13188c2ecf20Sopenharmony_ci	if ($in_comment) {
13198c2ecf20Sopenharmony_ci		$sanitise_quote = '*/';
13208c2ecf20Sopenharmony_ci	} else {
13218c2ecf20Sopenharmony_ci		$sanitise_quote = '';
13228c2ecf20Sopenharmony_ci	}
13238c2ecf20Sopenharmony_ci}
13248c2ecf20Sopenharmony_cisub sanitise_line {
13258c2ecf20Sopenharmony_ci	my ($line) = @_;
13268c2ecf20Sopenharmony_ci
13278c2ecf20Sopenharmony_ci	my $res = '';
13288c2ecf20Sopenharmony_ci	my $l = '';
13298c2ecf20Sopenharmony_ci
13308c2ecf20Sopenharmony_ci	my $qlen = 0;
13318c2ecf20Sopenharmony_ci	my $off = 0;
13328c2ecf20Sopenharmony_ci	my $c;
13338c2ecf20Sopenharmony_ci
13348c2ecf20Sopenharmony_ci	# Always copy over the diff marker.
13358c2ecf20Sopenharmony_ci	$res = substr($line, 0, 1);
13368c2ecf20Sopenharmony_ci
13378c2ecf20Sopenharmony_ci	for ($off = 1; $off < length($line); $off++) {
13388c2ecf20Sopenharmony_ci		$c = substr($line, $off, 1);
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci		# Comments we are whacking completely including the begin
13418c2ecf20Sopenharmony_ci		# and end, all to $;.
13428c2ecf20Sopenharmony_ci		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
13438c2ecf20Sopenharmony_ci			$sanitise_quote = '*/';
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_ci			substr($res, $off, 2, "$;$;");
13468c2ecf20Sopenharmony_ci			$off++;
13478c2ecf20Sopenharmony_ci			next;
13488c2ecf20Sopenharmony_ci		}
13498c2ecf20Sopenharmony_ci		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
13508c2ecf20Sopenharmony_ci			$sanitise_quote = '';
13518c2ecf20Sopenharmony_ci			substr($res, $off, 2, "$;$;");
13528c2ecf20Sopenharmony_ci			$off++;
13538c2ecf20Sopenharmony_ci			next;
13548c2ecf20Sopenharmony_ci		}
13558c2ecf20Sopenharmony_ci		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
13568c2ecf20Sopenharmony_ci			$sanitise_quote = '//';
13578c2ecf20Sopenharmony_ci
13588c2ecf20Sopenharmony_ci			substr($res, $off, 2, $sanitise_quote);
13598c2ecf20Sopenharmony_ci			$off++;
13608c2ecf20Sopenharmony_ci			next;
13618c2ecf20Sopenharmony_ci		}
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_ci		# A \ in a string means ignore the next character.
13648c2ecf20Sopenharmony_ci		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
13658c2ecf20Sopenharmony_ci		    $c eq "\\") {
13668c2ecf20Sopenharmony_ci			substr($res, $off, 2, 'XX');
13678c2ecf20Sopenharmony_ci			$off++;
13688c2ecf20Sopenharmony_ci			next;
13698c2ecf20Sopenharmony_ci		}
13708c2ecf20Sopenharmony_ci		# Regular quotes.
13718c2ecf20Sopenharmony_ci		if ($c eq "'" || $c eq '"') {
13728c2ecf20Sopenharmony_ci			if ($sanitise_quote eq '') {
13738c2ecf20Sopenharmony_ci				$sanitise_quote = $c;
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_ci				substr($res, $off, 1, $c);
13768c2ecf20Sopenharmony_ci				next;
13778c2ecf20Sopenharmony_ci			} elsif ($sanitise_quote eq $c) {
13788c2ecf20Sopenharmony_ci				$sanitise_quote = '';
13798c2ecf20Sopenharmony_ci			}
13808c2ecf20Sopenharmony_ci		}
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci		#print "c<$c> SQ<$sanitise_quote>\n";
13838c2ecf20Sopenharmony_ci		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
13848c2ecf20Sopenharmony_ci			substr($res, $off, 1, $;);
13858c2ecf20Sopenharmony_ci		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
13868c2ecf20Sopenharmony_ci			substr($res, $off, 1, $;);
13878c2ecf20Sopenharmony_ci		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
13888c2ecf20Sopenharmony_ci			substr($res, $off, 1, 'X');
13898c2ecf20Sopenharmony_ci		} else {
13908c2ecf20Sopenharmony_ci			substr($res, $off, 1, $c);
13918c2ecf20Sopenharmony_ci		}
13928c2ecf20Sopenharmony_ci	}
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_ci	if ($sanitise_quote eq '//') {
13958c2ecf20Sopenharmony_ci		$sanitise_quote = '';
13968c2ecf20Sopenharmony_ci	}
13978c2ecf20Sopenharmony_ci
13988c2ecf20Sopenharmony_ci	# The pathname on a #include may be surrounded by '<' and '>'.
13998c2ecf20Sopenharmony_ci	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
14008c2ecf20Sopenharmony_ci		my $clean = 'X' x length($1);
14018c2ecf20Sopenharmony_ci		$res =~ s@\<.*\>@<$clean>@;
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	# The whole of a #error is a string.
14048c2ecf20Sopenharmony_ci	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
14058c2ecf20Sopenharmony_ci		my $clean = 'X' x length($1);
14068c2ecf20Sopenharmony_ci		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
14078c2ecf20Sopenharmony_ci	}
14088c2ecf20Sopenharmony_ci
14098c2ecf20Sopenharmony_ci	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
14108c2ecf20Sopenharmony_ci		my $match = $1;
14118c2ecf20Sopenharmony_ci		$res =~ s/\Q$match\E/"$;" x length($match)/e;
14128c2ecf20Sopenharmony_ci	}
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci	return $res;
14158c2ecf20Sopenharmony_ci}
14168c2ecf20Sopenharmony_ci
14178c2ecf20Sopenharmony_cisub get_quoted_string {
14188c2ecf20Sopenharmony_ci	my ($line, $rawline) = @_;
14198c2ecf20Sopenharmony_ci
14208c2ecf20Sopenharmony_ci	return "" if (!defined($line) || !defined($rawline));
14218c2ecf20Sopenharmony_ci	return "" if ($line !~ m/($String)/g);
14228c2ecf20Sopenharmony_ci	return substr($rawline, $-[0], $+[0] - $-[0]);
14238c2ecf20Sopenharmony_ci}
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_cisub ctx_statement_block {
14268c2ecf20Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
14278c2ecf20Sopenharmony_ci	my $line = $linenr - 1;
14288c2ecf20Sopenharmony_ci	my $blk = '';
14298c2ecf20Sopenharmony_ci	my $soff = $off;
14308c2ecf20Sopenharmony_ci	my $coff = $off - 1;
14318c2ecf20Sopenharmony_ci	my $coff_set = 0;
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci	my $loff = 0;
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci	my $type = '';
14368c2ecf20Sopenharmony_ci	my $level = 0;
14378c2ecf20Sopenharmony_ci	my @stack = ();
14388c2ecf20Sopenharmony_ci	my $p;
14398c2ecf20Sopenharmony_ci	my $c;
14408c2ecf20Sopenharmony_ci	my $len = 0;
14418c2ecf20Sopenharmony_ci
14428c2ecf20Sopenharmony_ci	my $remainder;
14438c2ecf20Sopenharmony_ci	while (1) {
14448c2ecf20Sopenharmony_ci		@stack = (['', 0]) if ($#stack == -1);
14458c2ecf20Sopenharmony_ci
14468c2ecf20Sopenharmony_ci		#warn "CSB: blk<$blk> remain<$remain>\n";
14478c2ecf20Sopenharmony_ci		# If we are about to drop off the end, pull in more
14488c2ecf20Sopenharmony_ci		# context.
14498c2ecf20Sopenharmony_ci		if ($off >= $len) {
14508c2ecf20Sopenharmony_ci			for (; $remain > 0; $line++) {
14518c2ecf20Sopenharmony_ci				last if (!defined $lines[$line]);
14528c2ecf20Sopenharmony_ci				next if ($lines[$line] =~ /^-/);
14538c2ecf20Sopenharmony_ci				$remain--;
14548c2ecf20Sopenharmony_ci				$loff = $len;
14558c2ecf20Sopenharmony_ci				$blk .= $lines[$line] . "\n";
14568c2ecf20Sopenharmony_ci				$len = length($blk);
14578c2ecf20Sopenharmony_ci				$line++;
14588c2ecf20Sopenharmony_ci				last;
14598c2ecf20Sopenharmony_ci			}
14608c2ecf20Sopenharmony_ci			# Bail if there is no further context.
14618c2ecf20Sopenharmony_ci			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
14628c2ecf20Sopenharmony_ci			if ($off >= $len) {
14638c2ecf20Sopenharmony_ci				last;
14648c2ecf20Sopenharmony_ci			}
14658c2ecf20Sopenharmony_ci			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
14668c2ecf20Sopenharmony_ci				$level++;
14678c2ecf20Sopenharmony_ci				$type = '#';
14688c2ecf20Sopenharmony_ci			}
14698c2ecf20Sopenharmony_ci		}
14708c2ecf20Sopenharmony_ci		$p = $c;
14718c2ecf20Sopenharmony_ci		$c = substr($blk, $off, 1);
14728c2ecf20Sopenharmony_ci		$remainder = substr($blk, $off);
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
14758c2ecf20Sopenharmony_ci
14768c2ecf20Sopenharmony_ci		# Handle nested #if/#else.
14778c2ecf20Sopenharmony_ci		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
14788c2ecf20Sopenharmony_ci			push(@stack, [ $type, $level ]);
14798c2ecf20Sopenharmony_ci		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
14808c2ecf20Sopenharmony_ci			($type, $level) = @{$stack[$#stack - 1]};
14818c2ecf20Sopenharmony_ci		} elsif ($remainder =~ /^#\s*endif\b/) {
14828c2ecf20Sopenharmony_ci			($type, $level) = @{pop(@stack)};
14838c2ecf20Sopenharmony_ci		}
14848c2ecf20Sopenharmony_ci
14858c2ecf20Sopenharmony_ci		# Statement ends at the ';' or a close '}' at the
14868c2ecf20Sopenharmony_ci		# outermost level.
14878c2ecf20Sopenharmony_ci		if ($level == 0 && $c eq ';') {
14888c2ecf20Sopenharmony_ci			last;
14898c2ecf20Sopenharmony_ci		}
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_ci		# An else is really a conditional as long as its not else if
14928c2ecf20Sopenharmony_ci		if ($level == 0 && $coff_set == 0 &&
14938c2ecf20Sopenharmony_ci				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
14948c2ecf20Sopenharmony_ci				$remainder =~ /^(else)(?:\s|{)/ &&
14958c2ecf20Sopenharmony_ci				$remainder !~ /^else\s+if\b/) {
14968c2ecf20Sopenharmony_ci			$coff = $off + length($1) - 1;
14978c2ecf20Sopenharmony_ci			$coff_set = 1;
14988c2ecf20Sopenharmony_ci			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
14998c2ecf20Sopenharmony_ci			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
15008c2ecf20Sopenharmony_ci		}
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci		if (($type eq '' || $type eq '(') && $c eq '(') {
15038c2ecf20Sopenharmony_ci			$level++;
15048c2ecf20Sopenharmony_ci			$type = '(';
15058c2ecf20Sopenharmony_ci		}
15068c2ecf20Sopenharmony_ci		if ($type eq '(' && $c eq ')') {
15078c2ecf20Sopenharmony_ci			$level--;
15088c2ecf20Sopenharmony_ci			$type = ($level != 0)? '(' : '';
15098c2ecf20Sopenharmony_ci
15108c2ecf20Sopenharmony_ci			if ($level == 0 && $coff < $soff) {
15118c2ecf20Sopenharmony_ci				$coff = $off;
15128c2ecf20Sopenharmony_ci				$coff_set = 1;
15138c2ecf20Sopenharmony_ci				#warn "CSB: mark coff<$coff>\n";
15148c2ecf20Sopenharmony_ci			}
15158c2ecf20Sopenharmony_ci		}
15168c2ecf20Sopenharmony_ci		if (($type eq '' || $type eq '{') && $c eq '{') {
15178c2ecf20Sopenharmony_ci			$level++;
15188c2ecf20Sopenharmony_ci			$type = '{';
15198c2ecf20Sopenharmony_ci		}
15208c2ecf20Sopenharmony_ci		if ($type eq '{' && $c eq '}') {
15218c2ecf20Sopenharmony_ci			$level--;
15228c2ecf20Sopenharmony_ci			$type = ($level != 0)? '{' : '';
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci			if ($level == 0) {
15258c2ecf20Sopenharmony_ci				if (substr($blk, $off + 1, 1) eq ';') {
15268c2ecf20Sopenharmony_ci					$off++;
15278c2ecf20Sopenharmony_ci				}
15288c2ecf20Sopenharmony_ci				last;
15298c2ecf20Sopenharmony_ci			}
15308c2ecf20Sopenharmony_ci		}
15318c2ecf20Sopenharmony_ci		# Preprocessor commands end at the newline unless escaped.
15328c2ecf20Sopenharmony_ci		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
15338c2ecf20Sopenharmony_ci			$level--;
15348c2ecf20Sopenharmony_ci			$type = '';
15358c2ecf20Sopenharmony_ci			$off++;
15368c2ecf20Sopenharmony_ci			last;
15378c2ecf20Sopenharmony_ci		}
15388c2ecf20Sopenharmony_ci		$off++;
15398c2ecf20Sopenharmony_ci	}
15408c2ecf20Sopenharmony_ci	# We are truly at the end, so shuffle to the next line.
15418c2ecf20Sopenharmony_ci	if ($off == $len) {
15428c2ecf20Sopenharmony_ci		$loff = $len + 1;
15438c2ecf20Sopenharmony_ci		$line++;
15448c2ecf20Sopenharmony_ci		$remain--;
15458c2ecf20Sopenharmony_ci	}
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci	my $statement = substr($blk, $soff, $off - $soff + 1);
15488c2ecf20Sopenharmony_ci	my $condition = substr($blk, $soff, $coff - $soff + 1);
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_ci	#warn "STATEMENT<$statement>\n";
15518c2ecf20Sopenharmony_ci	#warn "CONDITION<$condition>\n";
15528c2ecf20Sopenharmony_ci
15538c2ecf20Sopenharmony_ci	#print "coff<$coff> soff<$off> loff<$loff>\n";
15548c2ecf20Sopenharmony_ci
15558c2ecf20Sopenharmony_ci	return ($statement, $condition,
15568c2ecf20Sopenharmony_ci			$line, $remain + 1, $off - $loff + 1, $level);
15578c2ecf20Sopenharmony_ci}
15588c2ecf20Sopenharmony_ci
15598c2ecf20Sopenharmony_cisub statement_lines {
15608c2ecf20Sopenharmony_ci	my ($stmt) = @_;
15618c2ecf20Sopenharmony_ci
15628c2ecf20Sopenharmony_ci	# Strip the diff line prefixes and rip blank lines at start and end.
15638c2ecf20Sopenharmony_ci	$stmt =~ s/(^|\n)./$1/g;
15648c2ecf20Sopenharmony_ci	$stmt =~ s/^\s*//;
15658c2ecf20Sopenharmony_ci	$stmt =~ s/\s*$//;
15668c2ecf20Sopenharmony_ci
15678c2ecf20Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
15688c2ecf20Sopenharmony_ci
15698c2ecf20Sopenharmony_ci	return $#stmt_lines + 2;
15708c2ecf20Sopenharmony_ci}
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_cisub statement_rawlines {
15738c2ecf20Sopenharmony_ci	my ($stmt) = @_;
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_ci	return $#stmt_lines + 2;
15788c2ecf20Sopenharmony_ci}
15798c2ecf20Sopenharmony_ci
15808c2ecf20Sopenharmony_cisub statement_block_size {
15818c2ecf20Sopenharmony_ci	my ($stmt) = @_;
15828c2ecf20Sopenharmony_ci
15838c2ecf20Sopenharmony_ci	$stmt =~ s/(^|\n)./$1/g;
15848c2ecf20Sopenharmony_ci	$stmt =~ s/^\s*{//;
15858c2ecf20Sopenharmony_ci	$stmt =~ s/}\s*$//;
15868c2ecf20Sopenharmony_ci	$stmt =~ s/^\s*//;
15878c2ecf20Sopenharmony_ci	$stmt =~ s/\s*$//;
15888c2ecf20Sopenharmony_ci
15898c2ecf20Sopenharmony_ci	my @stmt_lines = ($stmt =~ /\n/g);
15908c2ecf20Sopenharmony_ci	my @stmt_statements = ($stmt =~ /;/g);
15918c2ecf20Sopenharmony_ci
15928c2ecf20Sopenharmony_ci	my $stmt_lines = $#stmt_lines + 2;
15938c2ecf20Sopenharmony_ci	my $stmt_statements = $#stmt_statements + 1;
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_ci	if ($stmt_lines > $stmt_statements) {
15968c2ecf20Sopenharmony_ci		return $stmt_lines;
15978c2ecf20Sopenharmony_ci	} else {
15988c2ecf20Sopenharmony_ci		return $stmt_statements;
15998c2ecf20Sopenharmony_ci	}
16008c2ecf20Sopenharmony_ci}
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_cisub ctx_statement_full {
16038c2ecf20Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
16048c2ecf20Sopenharmony_ci	my ($statement, $condition, $level);
16058c2ecf20Sopenharmony_ci
16068c2ecf20Sopenharmony_ci	my (@chunks);
16078c2ecf20Sopenharmony_ci
16088c2ecf20Sopenharmony_ci	# Grab the first conditional/block pair.
16098c2ecf20Sopenharmony_ci	($statement, $condition, $linenr, $remain, $off, $level) =
16108c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $remain, $off);
16118c2ecf20Sopenharmony_ci	#print "F: c<$condition> s<$statement> remain<$remain>\n";
16128c2ecf20Sopenharmony_ci	push(@chunks, [ $condition, $statement ]);
16138c2ecf20Sopenharmony_ci	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
16148c2ecf20Sopenharmony_ci		return ($level, $linenr, @chunks);
16158c2ecf20Sopenharmony_ci	}
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_ci	# Pull in the following conditional/block pairs and see if they
16188c2ecf20Sopenharmony_ci	# could continue the statement.
16198c2ecf20Sopenharmony_ci	for (;;) {
16208c2ecf20Sopenharmony_ci		($statement, $condition, $linenr, $remain, $off, $level) =
16218c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $remain, $off);
16228c2ecf20Sopenharmony_ci		#print "C: c<$condition> s<$statement> remain<$remain>\n";
16238c2ecf20Sopenharmony_ci		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
16248c2ecf20Sopenharmony_ci		#print "C: push\n";
16258c2ecf20Sopenharmony_ci		push(@chunks, [ $condition, $statement ]);
16268c2ecf20Sopenharmony_ci	}
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci	return ($level, $linenr, @chunks);
16298c2ecf20Sopenharmony_ci}
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_cisub ctx_block_get {
16328c2ecf20Sopenharmony_ci	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
16338c2ecf20Sopenharmony_ci	my $line;
16348c2ecf20Sopenharmony_ci	my $start = $linenr - 1;
16358c2ecf20Sopenharmony_ci	my $blk = '';
16368c2ecf20Sopenharmony_ci	my @o;
16378c2ecf20Sopenharmony_ci	my @c;
16388c2ecf20Sopenharmony_ci	my @res = ();
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_ci	my $level = 0;
16418c2ecf20Sopenharmony_ci	my @stack = ($level);
16428c2ecf20Sopenharmony_ci	for ($line = $start; $remain > 0; $line++) {
16438c2ecf20Sopenharmony_ci		next if ($rawlines[$line] =~ /^-/);
16448c2ecf20Sopenharmony_ci		$remain--;
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_ci		$blk .= $rawlines[$line];
16478c2ecf20Sopenharmony_ci
16488c2ecf20Sopenharmony_ci		# Handle nested #if/#else.
16498c2ecf20Sopenharmony_ci		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
16508c2ecf20Sopenharmony_ci			push(@stack, $level);
16518c2ecf20Sopenharmony_ci		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
16528c2ecf20Sopenharmony_ci			$level = $stack[$#stack - 1];
16538c2ecf20Sopenharmony_ci		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
16548c2ecf20Sopenharmony_ci			$level = pop(@stack);
16558c2ecf20Sopenharmony_ci		}
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci		foreach my $c (split(//, $lines[$line])) {
16588c2ecf20Sopenharmony_ci			##print "C<$c>L<$level><$open$close>O<$off>\n";
16598c2ecf20Sopenharmony_ci			if ($off > 0) {
16608c2ecf20Sopenharmony_ci				$off--;
16618c2ecf20Sopenharmony_ci				next;
16628c2ecf20Sopenharmony_ci			}
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci			if ($c eq $close && $level > 0) {
16658c2ecf20Sopenharmony_ci				$level--;
16668c2ecf20Sopenharmony_ci				last if ($level == 0);
16678c2ecf20Sopenharmony_ci			} elsif ($c eq $open) {
16688c2ecf20Sopenharmony_ci				$level++;
16698c2ecf20Sopenharmony_ci			}
16708c2ecf20Sopenharmony_ci		}
16718c2ecf20Sopenharmony_ci
16728c2ecf20Sopenharmony_ci		if (!$outer || $level <= 1) {
16738c2ecf20Sopenharmony_ci			push(@res, $rawlines[$line]);
16748c2ecf20Sopenharmony_ci		}
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci		last if ($level == 0);
16778c2ecf20Sopenharmony_ci	}
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci	return ($level, @res);
16808c2ecf20Sopenharmony_ci}
16818c2ecf20Sopenharmony_cisub ctx_block_outer {
16828c2ecf20Sopenharmony_ci	my ($linenr, $remain) = @_;
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
16858c2ecf20Sopenharmony_ci	return @r;
16868c2ecf20Sopenharmony_ci}
16878c2ecf20Sopenharmony_cisub ctx_block {
16888c2ecf20Sopenharmony_ci	my ($linenr, $remain) = @_;
16898c2ecf20Sopenharmony_ci
16908c2ecf20Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
16918c2ecf20Sopenharmony_ci	return @r;
16928c2ecf20Sopenharmony_ci}
16938c2ecf20Sopenharmony_cisub ctx_statement {
16948c2ecf20Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_ci	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
16978c2ecf20Sopenharmony_ci	return @r;
16988c2ecf20Sopenharmony_ci}
16998c2ecf20Sopenharmony_cisub ctx_block_level {
17008c2ecf20Sopenharmony_ci	my ($linenr, $remain) = @_;
17018c2ecf20Sopenharmony_ci
17028c2ecf20Sopenharmony_ci	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
17038c2ecf20Sopenharmony_ci}
17048c2ecf20Sopenharmony_cisub ctx_statement_level {
17058c2ecf20Sopenharmony_ci	my ($linenr, $remain, $off) = @_;
17068c2ecf20Sopenharmony_ci
17078c2ecf20Sopenharmony_ci	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
17088c2ecf20Sopenharmony_ci}
17098c2ecf20Sopenharmony_ci
17108c2ecf20Sopenharmony_cisub ctx_locate_comment {
17118c2ecf20Sopenharmony_ci	my ($first_line, $end_line) = @_;
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	# If c99 comment on the current line, or the line before or after
17148c2ecf20Sopenharmony_ci	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
17158c2ecf20Sopenharmony_ci	return $current_comment if (defined $current_comment);
17168c2ecf20Sopenharmony_ci	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
17178c2ecf20Sopenharmony_ci	return $current_comment if (defined $current_comment);
17188c2ecf20Sopenharmony_ci	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
17198c2ecf20Sopenharmony_ci	return $current_comment if (defined $current_comment);
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci	# Catch a comment on the end of the line itself.
17228c2ecf20Sopenharmony_ci	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
17238c2ecf20Sopenharmony_ci	return $current_comment if (defined $current_comment);
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	# Look through the context and try and figure out if there is a
17268c2ecf20Sopenharmony_ci	# comment.
17278c2ecf20Sopenharmony_ci	my $in_comment = 0;
17288c2ecf20Sopenharmony_ci	$current_comment = '';
17298c2ecf20Sopenharmony_ci	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
17308c2ecf20Sopenharmony_ci		my $line = $rawlines[$linenr - 1];
17318c2ecf20Sopenharmony_ci		#warn "           $line\n";
17328c2ecf20Sopenharmony_ci		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
17338c2ecf20Sopenharmony_ci			$in_comment = 1;
17348c2ecf20Sopenharmony_ci		}
17358c2ecf20Sopenharmony_ci		if ($line =~ m@/\*@) {
17368c2ecf20Sopenharmony_ci			$in_comment = 1;
17378c2ecf20Sopenharmony_ci		}
17388c2ecf20Sopenharmony_ci		if (!$in_comment && $current_comment ne '') {
17398c2ecf20Sopenharmony_ci			$current_comment = '';
17408c2ecf20Sopenharmony_ci		}
17418c2ecf20Sopenharmony_ci		$current_comment .= $line . "\n" if ($in_comment);
17428c2ecf20Sopenharmony_ci		if ($line =~ m@\*/@) {
17438c2ecf20Sopenharmony_ci			$in_comment = 0;
17448c2ecf20Sopenharmony_ci		}
17458c2ecf20Sopenharmony_ci	}
17468c2ecf20Sopenharmony_ci
17478c2ecf20Sopenharmony_ci	chomp($current_comment);
17488c2ecf20Sopenharmony_ci	return($current_comment);
17498c2ecf20Sopenharmony_ci}
17508c2ecf20Sopenharmony_cisub ctx_has_comment {
17518c2ecf20Sopenharmony_ci	my ($first_line, $end_line) = @_;
17528c2ecf20Sopenharmony_ci	my $cmt = ctx_locate_comment($first_line, $end_line);
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci	##print "LINE: $rawlines[$end_line - 1 ]\n";
17558c2ecf20Sopenharmony_ci	##print "CMMT: $cmt\n";
17568c2ecf20Sopenharmony_ci
17578c2ecf20Sopenharmony_ci	return ($cmt ne '');
17588c2ecf20Sopenharmony_ci}
17598c2ecf20Sopenharmony_ci
17608c2ecf20Sopenharmony_cisub raw_line {
17618c2ecf20Sopenharmony_ci	my ($linenr, $cnt) = @_;
17628c2ecf20Sopenharmony_ci
17638c2ecf20Sopenharmony_ci	my $offset = $linenr - 1;
17648c2ecf20Sopenharmony_ci	$cnt++;
17658c2ecf20Sopenharmony_ci
17668c2ecf20Sopenharmony_ci	my $line;
17678c2ecf20Sopenharmony_ci	while ($cnt) {
17688c2ecf20Sopenharmony_ci		$line = $rawlines[$offset++];
17698c2ecf20Sopenharmony_ci		next if (defined($line) && $line =~ /^-/);
17708c2ecf20Sopenharmony_ci		$cnt--;
17718c2ecf20Sopenharmony_ci	}
17728c2ecf20Sopenharmony_ci
17738c2ecf20Sopenharmony_ci	return $line;
17748c2ecf20Sopenharmony_ci}
17758c2ecf20Sopenharmony_ci
17768c2ecf20Sopenharmony_cisub get_stat_real {
17778c2ecf20Sopenharmony_ci	my ($linenr, $lc) = @_;
17788c2ecf20Sopenharmony_ci
17798c2ecf20Sopenharmony_ci	my $stat_real = raw_line($linenr, 0);
17808c2ecf20Sopenharmony_ci	for (my $count = $linenr + 1; $count <= $lc; $count++) {
17818c2ecf20Sopenharmony_ci		$stat_real = $stat_real . "\n" . raw_line($count, 0);
17828c2ecf20Sopenharmony_ci	}
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_ci	return $stat_real;
17858c2ecf20Sopenharmony_ci}
17868c2ecf20Sopenharmony_ci
17878c2ecf20Sopenharmony_cisub get_stat_here {
17888c2ecf20Sopenharmony_ci	my ($linenr, $cnt, $here) = @_;
17898c2ecf20Sopenharmony_ci
17908c2ecf20Sopenharmony_ci	my $herectx = $here . "\n";
17918c2ecf20Sopenharmony_ci	for (my $n = 0; $n < $cnt; $n++) {
17928c2ecf20Sopenharmony_ci		$herectx .= raw_line($linenr, $n) . "\n";
17938c2ecf20Sopenharmony_ci	}
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_ci	return $herectx;
17968c2ecf20Sopenharmony_ci}
17978c2ecf20Sopenharmony_ci
17988c2ecf20Sopenharmony_cisub cat_vet {
17998c2ecf20Sopenharmony_ci	my ($vet) = @_;
18008c2ecf20Sopenharmony_ci	my ($res, $coded);
18018c2ecf20Sopenharmony_ci
18028c2ecf20Sopenharmony_ci	$res = '';
18038c2ecf20Sopenharmony_ci	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
18048c2ecf20Sopenharmony_ci		$res .= $1;
18058c2ecf20Sopenharmony_ci		if ($2 ne '') {
18068c2ecf20Sopenharmony_ci			$coded = sprintf("^%c", unpack('C', $2) + 64);
18078c2ecf20Sopenharmony_ci			$res .= $coded;
18088c2ecf20Sopenharmony_ci		}
18098c2ecf20Sopenharmony_ci	}
18108c2ecf20Sopenharmony_ci	$res =~ s/$/\$/;
18118c2ecf20Sopenharmony_ci
18128c2ecf20Sopenharmony_ci	return $res;
18138c2ecf20Sopenharmony_ci}
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_cimy $av_preprocessor = 0;
18168c2ecf20Sopenharmony_cimy $av_pending;
18178c2ecf20Sopenharmony_cimy @av_paren_type;
18188c2ecf20Sopenharmony_cimy $av_pend_colon;
18198c2ecf20Sopenharmony_ci
18208c2ecf20Sopenharmony_cisub annotate_reset {
18218c2ecf20Sopenharmony_ci	$av_preprocessor = 0;
18228c2ecf20Sopenharmony_ci	$av_pending = '_';
18238c2ecf20Sopenharmony_ci	@av_paren_type = ('E');
18248c2ecf20Sopenharmony_ci	$av_pend_colon = 'O';
18258c2ecf20Sopenharmony_ci}
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_cisub annotate_values {
18288c2ecf20Sopenharmony_ci	my ($stream, $type) = @_;
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_ci	my $res;
18318c2ecf20Sopenharmony_ci	my $var = '_' x length($stream);
18328c2ecf20Sopenharmony_ci	my $cur = $stream;
18338c2ecf20Sopenharmony_ci
18348c2ecf20Sopenharmony_ci	print "$stream\n" if ($dbg_values > 1);
18358c2ecf20Sopenharmony_ci
18368c2ecf20Sopenharmony_ci	while (length($cur)) {
18378c2ecf20Sopenharmony_ci		@av_paren_type = ('E') if ($#av_paren_type < 0);
18388c2ecf20Sopenharmony_ci		print " <" . join('', @av_paren_type) .
18398c2ecf20Sopenharmony_ci				"> <$type> <$av_pending>" if ($dbg_values > 1);
18408c2ecf20Sopenharmony_ci		if ($cur =~ /^(\s+)/o) {
18418c2ecf20Sopenharmony_ci			print "WS($1)\n" if ($dbg_values > 1);
18428c2ecf20Sopenharmony_ci			if ($1 =~ /\n/ && $av_preprocessor) {
18438c2ecf20Sopenharmony_ci				$type = pop(@av_paren_type);
18448c2ecf20Sopenharmony_ci				$av_preprocessor = 0;
18458c2ecf20Sopenharmony_ci			}
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
18488c2ecf20Sopenharmony_ci			print "CAST($1)\n" if ($dbg_values > 1);
18498c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18508c2ecf20Sopenharmony_ci			$type = 'c';
18518c2ecf20Sopenharmony_ci
18528c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
18538c2ecf20Sopenharmony_ci			print "DECLARE($1)\n" if ($dbg_values > 1);
18548c2ecf20Sopenharmony_ci			$type = 'T';
18558c2ecf20Sopenharmony_ci
18568c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Modifier)\s*/) {
18578c2ecf20Sopenharmony_ci			print "MODIFIER($1)\n" if ($dbg_values > 1);
18588c2ecf20Sopenharmony_ci			$type = 'T';
18598c2ecf20Sopenharmony_ci
18608c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
18618c2ecf20Sopenharmony_ci			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
18628c2ecf20Sopenharmony_ci			$av_preprocessor = 1;
18638c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18648c2ecf20Sopenharmony_ci			if ($2 ne '') {
18658c2ecf20Sopenharmony_ci				$av_pending = 'N';
18668c2ecf20Sopenharmony_ci			}
18678c2ecf20Sopenharmony_ci			$type = 'E';
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
18708c2ecf20Sopenharmony_ci			print "UNDEF($1)\n" if ($dbg_values > 1);
18718c2ecf20Sopenharmony_ci			$av_preprocessor = 1;
18728c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18738c2ecf20Sopenharmony_ci
18748c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
18758c2ecf20Sopenharmony_ci			print "PRE_START($1)\n" if ($dbg_values > 1);
18768c2ecf20Sopenharmony_ci			$av_preprocessor = 1;
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18798c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18808c2ecf20Sopenharmony_ci			$type = 'E';
18818c2ecf20Sopenharmony_ci
18828c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
18838c2ecf20Sopenharmony_ci			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
18848c2ecf20Sopenharmony_ci			$av_preprocessor = 1;
18858c2ecf20Sopenharmony_ci
18868c2ecf20Sopenharmony_ci			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
18878c2ecf20Sopenharmony_ci
18888c2ecf20Sopenharmony_ci			$type = 'E';
18898c2ecf20Sopenharmony_ci
18908c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
18918c2ecf20Sopenharmony_ci			print "PRE_END($1)\n" if ($dbg_values > 1);
18928c2ecf20Sopenharmony_ci
18938c2ecf20Sopenharmony_ci			$av_preprocessor = 1;
18948c2ecf20Sopenharmony_ci
18958c2ecf20Sopenharmony_ci			# Assume all arms of the conditional end as this
18968c2ecf20Sopenharmony_ci			# one does, and continue as if the #endif was not here.
18978c2ecf20Sopenharmony_ci			pop(@av_paren_type);
18988c2ecf20Sopenharmony_ci			push(@av_paren_type, $type);
18998c2ecf20Sopenharmony_ci			$type = 'E';
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\\\n)/o) {
19028c2ecf20Sopenharmony_ci			print "PRECONT($1)\n" if ($dbg_values > 1);
19038c2ecf20Sopenharmony_ci
19048c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
19058c2ecf20Sopenharmony_ci			print "ATTR($1)\n" if ($dbg_values > 1);
19068c2ecf20Sopenharmony_ci			$av_pending = $type;
19078c2ecf20Sopenharmony_ci			$type = 'N';
19088c2ecf20Sopenharmony_ci
19098c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
19108c2ecf20Sopenharmony_ci			print "SIZEOF($1)\n" if ($dbg_values > 1);
19118c2ecf20Sopenharmony_ci			if (defined $2) {
19128c2ecf20Sopenharmony_ci				$av_pending = 'V';
19138c2ecf20Sopenharmony_ci			}
19148c2ecf20Sopenharmony_ci			$type = 'N';
19158c2ecf20Sopenharmony_ci
19168c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(if|while|for)\b/o) {
19178c2ecf20Sopenharmony_ci			print "COND($1)\n" if ($dbg_values > 1);
19188c2ecf20Sopenharmony_ci			$av_pending = 'E';
19198c2ecf20Sopenharmony_ci			$type = 'N';
19208c2ecf20Sopenharmony_ci
19218c2ecf20Sopenharmony_ci		} elsif ($cur =~/^(case)/o) {
19228c2ecf20Sopenharmony_ci			print "CASE($1)\n" if ($dbg_values > 1);
19238c2ecf20Sopenharmony_ci			$av_pend_colon = 'C';
19248c2ecf20Sopenharmony_ci			$type = 'N';
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
19278c2ecf20Sopenharmony_ci			print "KEYWORD($1)\n" if ($dbg_values > 1);
19288c2ecf20Sopenharmony_ci			$type = 'N';
19298c2ecf20Sopenharmony_ci
19308c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\()/o) {
19318c2ecf20Sopenharmony_ci			print "PAREN('$1')\n" if ($dbg_values > 1);
19328c2ecf20Sopenharmony_ci			push(@av_paren_type, $av_pending);
19338c2ecf20Sopenharmony_ci			$av_pending = '_';
19348c2ecf20Sopenharmony_ci			$type = 'N';
19358c2ecf20Sopenharmony_ci
19368c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\))/o) {
19378c2ecf20Sopenharmony_ci			my $new_type = pop(@av_paren_type);
19388c2ecf20Sopenharmony_ci			if ($new_type ne '_') {
19398c2ecf20Sopenharmony_ci				$type = $new_type;
19408c2ecf20Sopenharmony_ci				print "PAREN('$1') -> $type\n"
19418c2ecf20Sopenharmony_ci							if ($dbg_values > 1);
19428c2ecf20Sopenharmony_ci			} else {
19438c2ecf20Sopenharmony_ci				print "PAREN('$1')\n" if ($dbg_values > 1);
19448c2ecf20Sopenharmony_ci			}
19458c2ecf20Sopenharmony_ci
19468c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Ident)\s*\(/o) {
19478c2ecf20Sopenharmony_ci			print "FUNC($1)\n" if ($dbg_values > 1);
19488c2ecf20Sopenharmony_ci			$type = 'V';
19498c2ecf20Sopenharmony_ci			$av_pending = 'V';
19508c2ecf20Sopenharmony_ci
19518c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
19528c2ecf20Sopenharmony_ci			if (defined $2 && $type eq 'C' || $type eq 'T') {
19538c2ecf20Sopenharmony_ci				$av_pend_colon = 'B';
19548c2ecf20Sopenharmony_ci			} elsif ($type eq 'E') {
19558c2ecf20Sopenharmony_ci				$av_pend_colon = 'L';
19568c2ecf20Sopenharmony_ci			}
19578c2ecf20Sopenharmony_ci			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
19588c2ecf20Sopenharmony_ci			$type = 'V';
19598c2ecf20Sopenharmony_ci
19608c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Ident|$Constant)/o) {
19618c2ecf20Sopenharmony_ci			print "IDENT($1)\n" if ($dbg_values > 1);
19628c2ecf20Sopenharmony_ci			$type = 'V';
19638c2ecf20Sopenharmony_ci
19648c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Assignment)/o) {
19658c2ecf20Sopenharmony_ci			print "ASSIGN($1)\n" if ($dbg_values > 1);
19668c2ecf20Sopenharmony_ci			$type = 'N';
19678c2ecf20Sopenharmony_ci
19688c2ecf20Sopenharmony_ci		} elsif ($cur =~/^(;|{|})/) {
19698c2ecf20Sopenharmony_ci			print "END($1)\n" if ($dbg_values > 1);
19708c2ecf20Sopenharmony_ci			$type = 'E';
19718c2ecf20Sopenharmony_ci			$av_pend_colon = 'O';
19728c2ecf20Sopenharmony_ci
19738c2ecf20Sopenharmony_ci		} elsif ($cur =~/^(,)/) {
19748c2ecf20Sopenharmony_ci			print "COMMA($1)\n" if ($dbg_values > 1);
19758c2ecf20Sopenharmony_ci			$type = 'C';
19768c2ecf20Sopenharmony_ci
19778c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\?)/o) {
19788c2ecf20Sopenharmony_ci			print "QUESTION($1)\n" if ($dbg_values > 1);
19798c2ecf20Sopenharmony_ci			$type = 'N';
19808c2ecf20Sopenharmony_ci
19818c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(:)/o) {
19828c2ecf20Sopenharmony_ci			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
19838c2ecf20Sopenharmony_ci
19848c2ecf20Sopenharmony_ci			substr($var, length($res), 1, $av_pend_colon);
19858c2ecf20Sopenharmony_ci			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
19868c2ecf20Sopenharmony_ci				$type = 'E';
19878c2ecf20Sopenharmony_ci			} else {
19888c2ecf20Sopenharmony_ci				$type = 'N';
19898c2ecf20Sopenharmony_ci			}
19908c2ecf20Sopenharmony_ci			$av_pend_colon = 'O';
19918c2ecf20Sopenharmony_ci
19928c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(\[)/o) {
19938c2ecf20Sopenharmony_ci			print "CLOSE($1)\n" if ($dbg_values > 1);
19948c2ecf20Sopenharmony_ci			$type = 'N';
19958c2ecf20Sopenharmony_ci
19968c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
19978c2ecf20Sopenharmony_ci			my $variant;
19988c2ecf20Sopenharmony_ci
19998c2ecf20Sopenharmony_ci			print "OPV($1)\n" if ($dbg_values > 1);
20008c2ecf20Sopenharmony_ci			if ($type eq 'V') {
20018c2ecf20Sopenharmony_ci				$variant = 'B';
20028c2ecf20Sopenharmony_ci			} else {
20038c2ecf20Sopenharmony_ci				$variant = 'U';
20048c2ecf20Sopenharmony_ci			}
20058c2ecf20Sopenharmony_ci
20068c2ecf20Sopenharmony_ci			substr($var, length($res), 1, $variant);
20078c2ecf20Sopenharmony_ci			$type = 'N';
20088c2ecf20Sopenharmony_ci
20098c2ecf20Sopenharmony_ci		} elsif ($cur =~ /^($Operators)/o) {
20108c2ecf20Sopenharmony_ci			print "OP($1)\n" if ($dbg_values > 1);
20118c2ecf20Sopenharmony_ci			if ($1 ne '++' && $1 ne '--') {
20128c2ecf20Sopenharmony_ci				$type = 'N';
20138c2ecf20Sopenharmony_ci			}
20148c2ecf20Sopenharmony_ci
20158c2ecf20Sopenharmony_ci		} elsif ($cur =~ /(^.)/o) {
20168c2ecf20Sopenharmony_ci			print "C($1)\n" if ($dbg_values > 1);
20178c2ecf20Sopenharmony_ci		}
20188c2ecf20Sopenharmony_ci		if (defined $1) {
20198c2ecf20Sopenharmony_ci			$cur = substr($cur, length($1));
20208c2ecf20Sopenharmony_ci			$res .= $type x length($1);
20218c2ecf20Sopenharmony_ci		}
20228c2ecf20Sopenharmony_ci	}
20238c2ecf20Sopenharmony_ci
20248c2ecf20Sopenharmony_ci	return ($res, $var);
20258c2ecf20Sopenharmony_ci}
20268c2ecf20Sopenharmony_ci
20278c2ecf20Sopenharmony_cisub possible {
20288c2ecf20Sopenharmony_ci	my ($possible, $line) = @_;
20298c2ecf20Sopenharmony_ci	my $notPermitted = qr{(?:
20308c2ecf20Sopenharmony_ci		^(?:
20318c2ecf20Sopenharmony_ci			$Modifier|
20328c2ecf20Sopenharmony_ci			$Storage|
20338c2ecf20Sopenharmony_ci			$Type|
20348c2ecf20Sopenharmony_ci			DEFINE_\S+
20358c2ecf20Sopenharmony_ci		)$|
20368c2ecf20Sopenharmony_ci		^(?:
20378c2ecf20Sopenharmony_ci			goto|
20388c2ecf20Sopenharmony_ci			return|
20398c2ecf20Sopenharmony_ci			case|
20408c2ecf20Sopenharmony_ci			else|
20418c2ecf20Sopenharmony_ci			asm|__asm__|
20428c2ecf20Sopenharmony_ci			do|
20438c2ecf20Sopenharmony_ci			\#|
20448c2ecf20Sopenharmony_ci			\#\#|
20458c2ecf20Sopenharmony_ci		)(?:\s|$)|
20468c2ecf20Sopenharmony_ci		^(?:typedef|struct|enum)\b
20478c2ecf20Sopenharmony_ci	    )}x;
20488c2ecf20Sopenharmony_ci	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
20498c2ecf20Sopenharmony_ci	if ($possible !~ $notPermitted) {
20508c2ecf20Sopenharmony_ci		# Check for modifiers.
20518c2ecf20Sopenharmony_ci		$possible =~ s/\s*$Storage\s*//g;
20528c2ecf20Sopenharmony_ci		$possible =~ s/\s*$Sparse\s*//g;
20538c2ecf20Sopenharmony_ci		if ($possible =~ /^\s*$/) {
20548c2ecf20Sopenharmony_ci
20558c2ecf20Sopenharmony_ci		} elsif ($possible =~ /\s/) {
20568c2ecf20Sopenharmony_ci			$possible =~ s/\s*$Type\s*//g;
20578c2ecf20Sopenharmony_ci			for my $modifier (split(' ', $possible)) {
20588c2ecf20Sopenharmony_ci				if ($modifier !~ $notPermitted) {
20598c2ecf20Sopenharmony_ci					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
20608c2ecf20Sopenharmony_ci					push(@modifierListFile, $modifier);
20618c2ecf20Sopenharmony_ci				}
20628c2ecf20Sopenharmony_ci			}
20638c2ecf20Sopenharmony_ci
20648c2ecf20Sopenharmony_ci		} else {
20658c2ecf20Sopenharmony_ci			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
20668c2ecf20Sopenharmony_ci			push(@typeListFile, $possible);
20678c2ecf20Sopenharmony_ci		}
20688c2ecf20Sopenharmony_ci		build_types();
20698c2ecf20Sopenharmony_ci	} else {
20708c2ecf20Sopenharmony_ci		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
20718c2ecf20Sopenharmony_ci	}
20728c2ecf20Sopenharmony_ci}
20738c2ecf20Sopenharmony_ci
20748c2ecf20Sopenharmony_cimy $prefix = '';
20758c2ecf20Sopenharmony_ci
20768c2ecf20Sopenharmony_cisub show_type {
20778c2ecf20Sopenharmony_ci	my ($type) = @_;
20788c2ecf20Sopenharmony_ci
20798c2ecf20Sopenharmony_ci	$type =~ tr/[a-z]/[A-Z]/;
20808c2ecf20Sopenharmony_ci
20818c2ecf20Sopenharmony_ci	return defined $use_type{$type} if (scalar keys %use_type > 0);
20828c2ecf20Sopenharmony_ci
20838c2ecf20Sopenharmony_ci	return !defined $ignore_type{$type};
20848c2ecf20Sopenharmony_ci}
20858c2ecf20Sopenharmony_ci
20868c2ecf20Sopenharmony_cisub report {
20878c2ecf20Sopenharmony_ci	my ($level, $type, $msg) = @_;
20888c2ecf20Sopenharmony_ci
20898c2ecf20Sopenharmony_ci	if (!show_type($type) ||
20908c2ecf20Sopenharmony_ci	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
20918c2ecf20Sopenharmony_ci		return 0;
20928c2ecf20Sopenharmony_ci	}
20938c2ecf20Sopenharmony_ci	my $output = '';
20948c2ecf20Sopenharmony_ci	if ($color) {
20958c2ecf20Sopenharmony_ci		if ($level eq 'ERROR') {
20968c2ecf20Sopenharmony_ci			$output .= RED;
20978c2ecf20Sopenharmony_ci		} elsif ($level eq 'WARNING') {
20988c2ecf20Sopenharmony_ci			$output .= YELLOW;
20998c2ecf20Sopenharmony_ci		} else {
21008c2ecf20Sopenharmony_ci			$output .= GREEN;
21018c2ecf20Sopenharmony_ci		}
21028c2ecf20Sopenharmony_ci	}
21038c2ecf20Sopenharmony_ci	$output .= $prefix . $level . ':';
21048c2ecf20Sopenharmony_ci	if ($show_types) {
21058c2ecf20Sopenharmony_ci		$output .= BLUE if ($color);
21068c2ecf20Sopenharmony_ci		$output .= "$type:";
21078c2ecf20Sopenharmony_ci	}
21088c2ecf20Sopenharmony_ci	$output .= RESET if ($color);
21098c2ecf20Sopenharmony_ci	$output .= ' ' . $msg . "\n";
21108c2ecf20Sopenharmony_ci
21118c2ecf20Sopenharmony_ci	if ($showfile) {
21128c2ecf20Sopenharmony_ci		my @lines = split("\n", $output, -1);
21138c2ecf20Sopenharmony_ci		splice(@lines, 1, 1);
21148c2ecf20Sopenharmony_ci		$output = join("\n", @lines);
21158c2ecf20Sopenharmony_ci	}
21168c2ecf20Sopenharmony_ci	$output = (split('\n', $output))[0] . "\n" if ($terse);
21178c2ecf20Sopenharmony_ci
21188c2ecf20Sopenharmony_ci	push(our @report, $output);
21198c2ecf20Sopenharmony_ci
21208c2ecf20Sopenharmony_ci	return 1;
21218c2ecf20Sopenharmony_ci}
21228c2ecf20Sopenharmony_ci
21238c2ecf20Sopenharmony_cisub report_dump {
21248c2ecf20Sopenharmony_ci	our @report;
21258c2ecf20Sopenharmony_ci}
21268c2ecf20Sopenharmony_ci
21278c2ecf20Sopenharmony_cisub fixup_current_range {
21288c2ecf20Sopenharmony_ci	my ($lineRef, $offset, $length) = @_;
21298c2ecf20Sopenharmony_ci
21308c2ecf20Sopenharmony_ci	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
21318c2ecf20Sopenharmony_ci		my $o = $1;
21328c2ecf20Sopenharmony_ci		my $l = $2;
21338c2ecf20Sopenharmony_ci		my $no = $o + $offset;
21348c2ecf20Sopenharmony_ci		my $nl = $l + $length;
21358c2ecf20Sopenharmony_ci		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
21368c2ecf20Sopenharmony_ci	}
21378c2ecf20Sopenharmony_ci}
21388c2ecf20Sopenharmony_ci
21398c2ecf20Sopenharmony_cisub fix_inserted_deleted_lines {
21408c2ecf20Sopenharmony_ci	my ($linesRef, $insertedRef, $deletedRef) = @_;
21418c2ecf20Sopenharmony_ci
21428c2ecf20Sopenharmony_ci	my $range_last_linenr = 0;
21438c2ecf20Sopenharmony_ci	my $delta_offset = 0;
21448c2ecf20Sopenharmony_ci
21458c2ecf20Sopenharmony_ci	my $old_linenr = 0;
21468c2ecf20Sopenharmony_ci	my $new_linenr = 0;
21478c2ecf20Sopenharmony_ci
21488c2ecf20Sopenharmony_ci	my $next_insert = 0;
21498c2ecf20Sopenharmony_ci	my $next_delete = 0;
21508c2ecf20Sopenharmony_ci
21518c2ecf20Sopenharmony_ci	my @lines = ();
21528c2ecf20Sopenharmony_ci
21538c2ecf20Sopenharmony_ci	my $inserted = @{$insertedRef}[$next_insert++];
21548c2ecf20Sopenharmony_ci	my $deleted = @{$deletedRef}[$next_delete++];
21558c2ecf20Sopenharmony_ci
21568c2ecf20Sopenharmony_ci	foreach my $old_line (@{$linesRef}) {
21578c2ecf20Sopenharmony_ci		my $save_line = 1;
21588c2ecf20Sopenharmony_ci		my $line = $old_line;	#don't modify the array
21598c2ecf20Sopenharmony_ci		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
21608c2ecf20Sopenharmony_ci			$delta_offset = 0;
21618c2ecf20Sopenharmony_ci		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
21628c2ecf20Sopenharmony_ci			$range_last_linenr = $new_linenr;
21638c2ecf20Sopenharmony_ci			fixup_current_range(\$line, $delta_offset, 0);
21648c2ecf20Sopenharmony_ci		}
21658c2ecf20Sopenharmony_ci
21668c2ecf20Sopenharmony_ci		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
21678c2ecf20Sopenharmony_ci			$deleted = @{$deletedRef}[$next_delete++];
21688c2ecf20Sopenharmony_ci			$save_line = 0;
21698c2ecf20Sopenharmony_ci			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
21708c2ecf20Sopenharmony_ci		}
21718c2ecf20Sopenharmony_ci
21728c2ecf20Sopenharmony_ci		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
21738c2ecf20Sopenharmony_ci			push(@lines, ${$inserted}{'LINE'});
21748c2ecf20Sopenharmony_ci			$inserted = @{$insertedRef}[$next_insert++];
21758c2ecf20Sopenharmony_ci			$new_linenr++;
21768c2ecf20Sopenharmony_ci			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
21778c2ecf20Sopenharmony_ci		}
21788c2ecf20Sopenharmony_ci
21798c2ecf20Sopenharmony_ci		if ($save_line) {
21808c2ecf20Sopenharmony_ci			push(@lines, $line);
21818c2ecf20Sopenharmony_ci			$new_linenr++;
21828c2ecf20Sopenharmony_ci		}
21838c2ecf20Sopenharmony_ci
21848c2ecf20Sopenharmony_ci		$old_linenr++;
21858c2ecf20Sopenharmony_ci	}
21868c2ecf20Sopenharmony_ci
21878c2ecf20Sopenharmony_ci	return @lines;
21888c2ecf20Sopenharmony_ci}
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_cisub fix_insert_line {
21918c2ecf20Sopenharmony_ci	my ($linenr, $line) = @_;
21928c2ecf20Sopenharmony_ci
21938c2ecf20Sopenharmony_ci	my $inserted = {
21948c2ecf20Sopenharmony_ci		LINENR => $linenr,
21958c2ecf20Sopenharmony_ci		LINE => $line,
21968c2ecf20Sopenharmony_ci	};
21978c2ecf20Sopenharmony_ci	push(@fixed_inserted, $inserted);
21988c2ecf20Sopenharmony_ci}
21998c2ecf20Sopenharmony_ci
22008c2ecf20Sopenharmony_cisub fix_delete_line {
22018c2ecf20Sopenharmony_ci	my ($linenr, $line) = @_;
22028c2ecf20Sopenharmony_ci
22038c2ecf20Sopenharmony_ci	my $deleted = {
22048c2ecf20Sopenharmony_ci		LINENR => $linenr,
22058c2ecf20Sopenharmony_ci		LINE => $line,
22068c2ecf20Sopenharmony_ci	};
22078c2ecf20Sopenharmony_ci
22088c2ecf20Sopenharmony_ci	push(@fixed_deleted, $deleted);
22098c2ecf20Sopenharmony_ci}
22108c2ecf20Sopenharmony_ci
22118c2ecf20Sopenharmony_cisub ERROR {
22128c2ecf20Sopenharmony_ci	my ($type, $msg) = @_;
22138c2ecf20Sopenharmony_ci
22148c2ecf20Sopenharmony_ci	if (report("ERROR", $type, $msg)) {
22158c2ecf20Sopenharmony_ci		our $clean = 0;
22168c2ecf20Sopenharmony_ci		our $cnt_error++;
22178c2ecf20Sopenharmony_ci		return 1;
22188c2ecf20Sopenharmony_ci	}
22198c2ecf20Sopenharmony_ci	return 0;
22208c2ecf20Sopenharmony_ci}
22218c2ecf20Sopenharmony_cisub WARN {
22228c2ecf20Sopenharmony_ci	my ($type, $msg) = @_;
22238c2ecf20Sopenharmony_ci
22248c2ecf20Sopenharmony_ci	if (report("WARNING", $type, $msg)) {
22258c2ecf20Sopenharmony_ci		our $clean = 0;
22268c2ecf20Sopenharmony_ci		our $cnt_warn++;
22278c2ecf20Sopenharmony_ci		return 1;
22288c2ecf20Sopenharmony_ci	}
22298c2ecf20Sopenharmony_ci	return 0;
22308c2ecf20Sopenharmony_ci}
22318c2ecf20Sopenharmony_cisub CHK {
22328c2ecf20Sopenharmony_ci	my ($type, $msg) = @_;
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_ci	if ($check && report("CHECK", $type, $msg)) {
22358c2ecf20Sopenharmony_ci		our $clean = 0;
22368c2ecf20Sopenharmony_ci		our $cnt_chk++;
22378c2ecf20Sopenharmony_ci		return 1;
22388c2ecf20Sopenharmony_ci	}
22398c2ecf20Sopenharmony_ci	return 0;
22408c2ecf20Sopenharmony_ci}
22418c2ecf20Sopenharmony_ci
22428c2ecf20Sopenharmony_cisub check_absolute_file {
22438c2ecf20Sopenharmony_ci	my ($absolute, $herecurr) = @_;
22448c2ecf20Sopenharmony_ci	my $file = $absolute;
22458c2ecf20Sopenharmony_ci
22468c2ecf20Sopenharmony_ci	##print "absolute<$absolute>\n";
22478c2ecf20Sopenharmony_ci
22488c2ecf20Sopenharmony_ci	# See if any suffix of this path is a path within the tree.
22498c2ecf20Sopenharmony_ci	while ($file =~ s@^[^/]*/@@) {
22508c2ecf20Sopenharmony_ci		if (-f "$root/$file") {
22518c2ecf20Sopenharmony_ci			##print "file<$file>\n";
22528c2ecf20Sopenharmony_ci			last;
22538c2ecf20Sopenharmony_ci		}
22548c2ecf20Sopenharmony_ci	}
22558c2ecf20Sopenharmony_ci	if (! -f _)  {
22568c2ecf20Sopenharmony_ci		return 0;
22578c2ecf20Sopenharmony_ci	}
22588c2ecf20Sopenharmony_ci
22598c2ecf20Sopenharmony_ci	# It is, so see if the prefix is acceptable.
22608c2ecf20Sopenharmony_ci	my $prefix = $absolute;
22618c2ecf20Sopenharmony_ci	substr($prefix, -length($file)) = '';
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_ci	##print "prefix<$prefix>\n";
22648c2ecf20Sopenharmony_ci	if ($prefix ne ".../") {
22658c2ecf20Sopenharmony_ci		WARN("USE_RELATIVE_PATH",
22668c2ecf20Sopenharmony_ci		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
22678c2ecf20Sopenharmony_ci	}
22688c2ecf20Sopenharmony_ci}
22698c2ecf20Sopenharmony_ci
22708c2ecf20Sopenharmony_cisub trim {
22718c2ecf20Sopenharmony_ci	my ($string) = @_;
22728c2ecf20Sopenharmony_ci
22738c2ecf20Sopenharmony_ci	$string =~ s/^\s+|\s+$//g;
22748c2ecf20Sopenharmony_ci
22758c2ecf20Sopenharmony_ci	return $string;
22768c2ecf20Sopenharmony_ci}
22778c2ecf20Sopenharmony_ci
22788c2ecf20Sopenharmony_cisub ltrim {
22798c2ecf20Sopenharmony_ci	my ($string) = @_;
22808c2ecf20Sopenharmony_ci
22818c2ecf20Sopenharmony_ci	$string =~ s/^\s+//;
22828c2ecf20Sopenharmony_ci
22838c2ecf20Sopenharmony_ci	return $string;
22848c2ecf20Sopenharmony_ci}
22858c2ecf20Sopenharmony_ci
22868c2ecf20Sopenharmony_cisub rtrim {
22878c2ecf20Sopenharmony_ci	my ($string) = @_;
22888c2ecf20Sopenharmony_ci
22898c2ecf20Sopenharmony_ci	$string =~ s/\s+$//;
22908c2ecf20Sopenharmony_ci
22918c2ecf20Sopenharmony_ci	return $string;
22928c2ecf20Sopenharmony_ci}
22938c2ecf20Sopenharmony_ci
22948c2ecf20Sopenharmony_cisub string_find_replace {
22958c2ecf20Sopenharmony_ci	my ($string, $find, $replace) = @_;
22968c2ecf20Sopenharmony_ci
22978c2ecf20Sopenharmony_ci	$string =~ s/$find/$replace/g;
22988c2ecf20Sopenharmony_ci
22998c2ecf20Sopenharmony_ci	return $string;
23008c2ecf20Sopenharmony_ci}
23018c2ecf20Sopenharmony_ci
23028c2ecf20Sopenharmony_cisub tabify {
23038c2ecf20Sopenharmony_ci	my ($leading) = @_;
23048c2ecf20Sopenharmony_ci
23058c2ecf20Sopenharmony_ci	my $source_indent = $tabsize;
23068c2ecf20Sopenharmony_ci	my $max_spaces_before_tab = $source_indent - 1;
23078c2ecf20Sopenharmony_ci	my $spaces_to_tab = " " x $source_indent;
23088c2ecf20Sopenharmony_ci
23098c2ecf20Sopenharmony_ci	#convert leading spaces to tabs
23108c2ecf20Sopenharmony_ci	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
23118c2ecf20Sopenharmony_ci	#Remove spaces before a tab
23128c2ecf20Sopenharmony_ci	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
23138c2ecf20Sopenharmony_ci
23148c2ecf20Sopenharmony_ci	return "$leading";
23158c2ecf20Sopenharmony_ci}
23168c2ecf20Sopenharmony_ci
23178c2ecf20Sopenharmony_cisub pos_last_openparen {
23188c2ecf20Sopenharmony_ci	my ($line) = @_;
23198c2ecf20Sopenharmony_ci
23208c2ecf20Sopenharmony_ci	my $pos = 0;
23218c2ecf20Sopenharmony_ci
23228c2ecf20Sopenharmony_ci	my $opens = $line =~ tr/\(/\(/;
23238c2ecf20Sopenharmony_ci	my $closes = $line =~ tr/\)/\)/;
23248c2ecf20Sopenharmony_ci
23258c2ecf20Sopenharmony_ci	my $last_openparen = 0;
23268c2ecf20Sopenharmony_ci
23278c2ecf20Sopenharmony_ci	if (($opens == 0) || ($closes >= $opens)) {
23288c2ecf20Sopenharmony_ci		return -1;
23298c2ecf20Sopenharmony_ci	}
23308c2ecf20Sopenharmony_ci
23318c2ecf20Sopenharmony_ci	my $len = length($line);
23328c2ecf20Sopenharmony_ci
23338c2ecf20Sopenharmony_ci	for ($pos = 0; $pos < $len; $pos++) {
23348c2ecf20Sopenharmony_ci		my $string = substr($line, $pos);
23358c2ecf20Sopenharmony_ci		if ($string =~ /^($FuncArg|$balanced_parens)/) {
23368c2ecf20Sopenharmony_ci			$pos += length($1) - 1;
23378c2ecf20Sopenharmony_ci		} elsif (substr($line, $pos, 1) eq '(') {
23388c2ecf20Sopenharmony_ci			$last_openparen = $pos;
23398c2ecf20Sopenharmony_ci		} elsif (index($string, '(') == -1) {
23408c2ecf20Sopenharmony_ci			last;
23418c2ecf20Sopenharmony_ci		}
23428c2ecf20Sopenharmony_ci	}
23438c2ecf20Sopenharmony_ci
23448c2ecf20Sopenharmony_ci	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
23458c2ecf20Sopenharmony_ci}
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_cisub get_raw_comment {
23488c2ecf20Sopenharmony_ci	my ($line, $rawline) = @_;
23498c2ecf20Sopenharmony_ci	my $comment = '';
23508c2ecf20Sopenharmony_ci
23518c2ecf20Sopenharmony_ci	for my $i (0 .. (length($line) - 1)) {
23528c2ecf20Sopenharmony_ci		if (substr($line, $i, 1) eq "$;") {
23538c2ecf20Sopenharmony_ci			$comment .= substr($rawline, $i, 1);
23548c2ecf20Sopenharmony_ci		}
23558c2ecf20Sopenharmony_ci	}
23568c2ecf20Sopenharmony_ci
23578c2ecf20Sopenharmony_ci	return $comment;
23588c2ecf20Sopenharmony_ci}
23598c2ecf20Sopenharmony_ci
23608c2ecf20Sopenharmony_cisub process {
23618c2ecf20Sopenharmony_ci	my $filename = shift;
23628c2ecf20Sopenharmony_ci
23638c2ecf20Sopenharmony_ci	my $linenr=0;
23648c2ecf20Sopenharmony_ci	my $prevline="";
23658c2ecf20Sopenharmony_ci	my $prevrawline="";
23668c2ecf20Sopenharmony_ci	my $stashline="";
23678c2ecf20Sopenharmony_ci	my $stashrawline="";
23688c2ecf20Sopenharmony_ci
23698c2ecf20Sopenharmony_ci	my $length;
23708c2ecf20Sopenharmony_ci	my $indent;
23718c2ecf20Sopenharmony_ci	my $previndent=0;
23728c2ecf20Sopenharmony_ci	my $stashindent=0;
23738c2ecf20Sopenharmony_ci
23748c2ecf20Sopenharmony_ci	our $clean = 1;
23758c2ecf20Sopenharmony_ci	my $signoff = 0;
23768c2ecf20Sopenharmony_ci	my $author = '';
23778c2ecf20Sopenharmony_ci	my $authorsignoff = 0;
23788c2ecf20Sopenharmony_ci	my $author_sob = '';
23798c2ecf20Sopenharmony_ci	my $is_patch = 0;
23808c2ecf20Sopenharmony_ci	my $is_binding_patch = -1;
23818c2ecf20Sopenharmony_ci	my $in_header_lines = $file ? 0 : 1;
23828c2ecf20Sopenharmony_ci	my $in_commit_log = 0;		#Scanning lines before patch
23838c2ecf20Sopenharmony_ci	my $has_patch_separator = 0;	#Found a --- line
23848c2ecf20Sopenharmony_ci	my $has_commit_log = 0;		#Encountered lines before patch
23858c2ecf20Sopenharmony_ci	my $commit_log_lines = 0;	#Number of commit log lines
23868c2ecf20Sopenharmony_ci	my $commit_log_possible_stack_dump = 0;
23878c2ecf20Sopenharmony_ci	my $commit_log_long_line = 0;
23888c2ecf20Sopenharmony_ci	my $commit_log_has_diff = 0;
23898c2ecf20Sopenharmony_ci	my $reported_maintainer_file = 0;
23908c2ecf20Sopenharmony_ci	my $non_utf8_charset = 0;
23918c2ecf20Sopenharmony_ci
23928c2ecf20Sopenharmony_ci	my $last_blank_line = 0;
23938c2ecf20Sopenharmony_ci	my $last_coalesced_string_linenr = -1;
23948c2ecf20Sopenharmony_ci
23958c2ecf20Sopenharmony_ci	our @report = ();
23968c2ecf20Sopenharmony_ci	our $cnt_lines = 0;
23978c2ecf20Sopenharmony_ci	our $cnt_error = 0;
23988c2ecf20Sopenharmony_ci	our $cnt_warn = 0;
23998c2ecf20Sopenharmony_ci	our $cnt_chk = 0;
24008c2ecf20Sopenharmony_ci
24018c2ecf20Sopenharmony_ci	# Trace the real file/line as we go.
24028c2ecf20Sopenharmony_ci	my $realfile = '';
24038c2ecf20Sopenharmony_ci	my $realline = 0;
24048c2ecf20Sopenharmony_ci	my $realcnt = 0;
24058c2ecf20Sopenharmony_ci	my $here = '';
24068c2ecf20Sopenharmony_ci	my $context_function;		#undef'd unless there's a known function
24078c2ecf20Sopenharmony_ci	my $in_comment = 0;
24088c2ecf20Sopenharmony_ci	my $comment_edge = 0;
24098c2ecf20Sopenharmony_ci	my $first_line = 0;
24108c2ecf20Sopenharmony_ci	my $p1_prefix = '';
24118c2ecf20Sopenharmony_ci
24128c2ecf20Sopenharmony_ci	my $prev_values = 'E';
24138c2ecf20Sopenharmony_ci
24148c2ecf20Sopenharmony_ci	# suppression flags
24158c2ecf20Sopenharmony_ci	my %suppress_ifbraces;
24168c2ecf20Sopenharmony_ci	my %suppress_whiletrailers;
24178c2ecf20Sopenharmony_ci	my %suppress_export;
24188c2ecf20Sopenharmony_ci	my $suppress_statement = 0;
24198c2ecf20Sopenharmony_ci
24208c2ecf20Sopenharmony_ci	my %signatures = ();
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci	# Pre-scan the patch sanitizing the lines.
24238c2ecf20Sopenharmony_ci	# Pre-scan the patch looking for any __setup documentation.
24248c2ecf20Sopenharmony_ci	#
24258c2ecf20Sopenharmony_ci	my @setup_docs = ();
24268c2ecf20Sopenharmony_ci	my $setup_docs = 0;
24278c2ecf20Sopenharmony_ci
24288c2ecf20Sopenharmony_ci	my $camelcase_file_seeded = 0;
24298c2ecf20Sopenharmony_ci
24308c2ecf20Sopenharmony_ci	my $checklicenseline = 1;
24318c2ecf20Sopenharmony_ci
24328c2ecf20Sopenharmony_ci	sanitise_line_reset();
24338c2ecf20Sopenharmony_ci	my $line;
24348c2ecf20Sopenharmony_ci	foreach my $rawline (@rawlines) {
24358c2ecf20Sopenharmony_ci		$linenr++;
24368c2ecf20Sopenharmony_ci		$line = $rawline;
24378c2ecf20Sopenharmony_ci
24388c2ecf20Sopenharmony_ci		push(@fixed, $rawline) if ($fix);
24398c2ecf20Sopenharmony_ci
24408c2ecf20Sopenharmony_ci		if ($rawline=~/^\+\+\+\s+(\S+)/) {
24418c2ecf20Sopenharmony_ci			$setup_docs = 0;
24428c2ecf20Sopenharmony_ci			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
24438c2ecf20Sopenharmony_ci				$setup_docs = 1;
24448c2ecf20Sopenharmony_ci			}
24458c2ecf20Sopenharmony_ci			#next;
24468c2ecf20Sopenharmony_ci		}
24478c2ecf20Sopenharmony_ci		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
24488c2ecf20Sopenharmony_ci			$realline=$1-1;
24498c2ecf20Sopenharmony_ci			if (defined $2) {
24508c2ecf20Sopenharmony_ci				$realcnt=$3+1;
24518c2ecf20Sopenharmony_ci			} else {
24528c2ecf20Sopenharmony_ci				$realcnt=1+1;
24538c2ecf20Sopenharmony_ci			}
24548c2ecf20Sopenharmony_ci			$in_comment = 0;
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci			# Guestimate if this is a continuing comment.  Run
24578c2ecf20Sopenharmony_ci			# the context looking for a comment "edge".  If this
24588c2ecf20Sopenharmony_ci			# edge is a close comment then we must be in a comment
24598c2ecf20Sopenharmony_ci			# at context start.
24608c2ecf20Sopenharmony_ci			my $edge;
24618c2ecf20Sopenharmony_ci			my $cnt = $realcnt;
24628c2ecf20Sopenharmony_ci			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
24638c2ecf20Sopenharmony_ci				next if (defined $rawlines[$ln - 1] &&
24648c2ecf20Sopenharmony_ci					 $rawlines[$ln - 1] =~ /^-/);
24658c2ecf20Sopenharmony_ci				$cnt--;
24668c2ecf20Sopenharmony_ci				#print "RAW<$rawlines[$ln - 1]>\n";
24678c2ecf20Sopenharmony_ci				last if (!defined $rawlines[$ln - 1]);
24688c2ecf20Sopenharmony_ci				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
24698c2ecf20Sopenharmony_ci				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
24708c2ecf20Sopenharmony_ci					($edge) = $1;
24718c2ecf20Sopenharmony_ci					last;
24728c2ecf20Sopenharmony_ci				}
24738c2ecf20Sopenharmony_ci			}
24748c2ecf20Sopenharmony_ci			if (defined $edge && $edge eq '*/') {
24758c2ecf20Sopenharmony_ci				$in_comment = 1;
24768c2ecf20Sopenharmony_ci			}
24778c2ecf20Sopenharmony_ci
24788c2ecf20Sopenharmony_ci			# Guestimate if this is a continuing comment.  If this
24798c2ecf20Sopenharmony_ci			# is the start of a diff block and this line starts
24808c2ecf20Sopenharmony_ci			# ' *' then it is very likely a comment.
24818c2ecf20Sopenharmony_ci			if (!defined $edge &&
24828c2ecf20Sopenharmony_ci			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
24838c2ecf20Sopenharmony_ci			{
24848c2ecf20Sopenharmony_ci				$in_comment = 1;
24858c2ecf20Sopenharmony_ci			}
24868c2ecf20Sopenharmony_ci
24878c2ecf20Sopenharmony_ci			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
24888c2ecf20Sopenharmony_ci			sanitise_line_reset($in_comment);
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
24918c2ecf20Sopenharmony_ci			# Standardise the strings and chars within the input to
24928c2ecf20Sopenharmony_ci			# simplify matching -- only bother with positive lines.
24938c2ecf20Sopenharmony_ci			$line = sanitise_line($rawline);
24948c2ecf20Sopenharmony_ci		}
24958c2ecf20Sopenharmony_ci		push(@lines, $line);
24968c2ecf20Sopenharmony_ci
24978c2ecf20Sopenharmony_ci		if ($realcnt > 1) {
24988c2ecf20Sopenharmony_ci			$realcnt-- if ($line =~ /^(?:\+| |$)/);
24998c2ecf20Sopenharmony_ci		} else {
25008c2ecf20Sopenharmony_ci			$realcnt = 0;
25018c2ecf20Sopenharmony_ci		}
25028c2ecf20Sopenharmony_ci
25038c2ecf20Sopenharmony_ci		#print "==>$rawline\n";
25048c2ecf20Sopenharmony_ci		#print "-->$line\n";
25058c2ecf20Sopenharmony_ci
25068c2ecf20Sopenharmony_ci		if ($setup_docs && $line =~ /^\+/) {
25078c2ecf20Sopenharmony_ci			push(@setup_docs, $line);
25088c2ecf20Sopenharmony_ci		}
25098c2ecf20Sopenharmony_ci	}
25108c2ecf20Sopenharmony_ci
25118c2ecf20Sopenharmony_ci	$prefix = '';
25128c2ecf20Sopenharmony_ci
25138c2ecf20Sopenharmony_ci	$realcnt = 0;
25148c2ecf20Sopenharmony_ci	$linenr = 0;
25158c2ecf20Sopenharmony_ci	$fixlinenr = -1;
25168c2ecf20Sopenharmony_ci	foreach my $line (@lines) {
25178c2ecf20Sopenharmony_ci		$linenr++;
25188c2ecf20Sopenharmony_ci		$fixlinenr++;
25198c2ecf20Sopenharmony_ci		my $sline = $line;	#copy of $line
25208c2ecf20Sopenharmony_ci		$sline =~ s/$;/ /g;	#with comments as spaces
25218c2ecf20Sopenharmony_ci
25228c2ecf20Sopenharmony_ci		my $rawline = $rawlines[$linenr - 1];
25238c2ecf20Sopenharmony_ci		my $raw_comment = get_raw_comment($line, $rawline);
25248c2ecf20Sopenharmony_ci
25258c2ecf20Sopenharmony_ci# check if it's a mode change, rename or start of a patch
25268c2ecf20Sopenharmony_ci		if (!$in_commit_log &&
25278c2ecf20Sopenharmony_ci		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
25288c2ecf20Sopenharmony_ci		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
25298c2ecf20Sopenharmony_ci		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
25308c2ecf20Sopenharmony_ci			$is_patch = 1;
25318c2ecf20Sopenharmony_ci		}
25328c2ecf20Sopenharmony_ci
25338c2ecf20Sopenharmony_ci#extract the line range in the file after the patch is applied
25348c2ecf20Sopenharmony_ci		if (!$in_commit_log &&
25358c2ecf20Sopenharmony_ci		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
25368c2ecf20Sopenharmony_ci			my $context = $4;
25378c2ecf20Sopenharmony_ci			$is_patch = 1;
25388c2ecf20Sopenharmony_ci			$first_line = $linenr + 1;
25398c2ecf20Sopenharmony_ci			$realline=$1-1;
25408c2ecf20Sopenharmony_ci			if (defined $2) {
25418c2ecf20Sopenharmony_ci				$realcnt=$3+1;
25428c2ecf20Sopenharmony_ci			} else {
25438c2ecf20Sopenharmony_ci				$realcnt=1+1;
25448c2ecf20Sopenharmony_ci			}
25458c2ecf20Sopenharmony_ci			annotate_reset();
25468c2ecf20Sopenharmony_ci			$prev_values = 'E';
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_ci			%suppress_ifbraces = ();
25498c2ecf20Sopenharmony_ci			%suppress_whiletrailers = ();
25508c2ecf20Sopenharmony_ci			%suppress_export = ();
25518c2ecf20Sopenharmony_ci			$suppress_statement = 0;
25528c2ecf20Sopenharmony_ci			if ($context =~ /\b(\w+)\s*\(/) {
25538c2ecf20Sopenharmony_ci				$context_function = $1;
25548c2ecf20Sopenharmony_ci			} else {
25558c2ecf20Sopenharmony_ci				undef $context_function;
25568c2ecf20Sopenharmony_ci			}
25578c2ecf20Sopenharmony_ci			next;
25588c2ecf20Sopenharmony_ci
25598c2ecf20Sopenharmony_ci# track the line number as we move through the hunk, note that
25608c2ecf20Sopenharmony_ci# new versions of GNU diff omit the leading space on completely
25618c2ecf20Sopenharmony_ci# blank context lines so we need to count that too.
25628c2ecf20Sopenharmony_ci		} elsif ($line =~ /^( |\+|$)/) {
25638c2ecf20Sopenharmony_ci			$realline++;
25648c2ecf20Sopenharmony_ci			$realcnt-- if ($realcnt != 0);
25658c2ecf20Sopenharmony_ci
25668c2ecf20Sopenharmony_ci			# Measure the line length and indent.
25678c2ecf20Sopenharmony_ci			($length, $indent) = line_stats($rawline);
25688c2ecf20Sopenharmony_ci
25698c2ecf20Sopenharmony_ci			# Track the previous line.
25708c2ecf20Sopenharmony_ci			($prevline, $stashline) = ($stashline, $line);
25718c2ecf20Sopenharmony_ci			($previndent, $stashindent) = ($stashindent, $indent);
25728c2ecf20Sopenharmony_ci			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
25738c2ecf20Sopenharmony_ci
25748c2ecf20Sopenharmony_ci			#warn "line<$line>\n";
25758c2ecf20Sopenharmony_ci
25768c2ecf20Sopenharmony_ci		} elsif ($realcnt == 1) {
25778c2ecf20Sopenharmony_ci			$realcnt--;
25788c2ecf20Sopenharmony_ci		}
25798c2ecf20Sopenharmony_ci
25808c2ecf20Sopenharmony_ci		my $hunk_line = ($realcnt != 0);
25818c2ecf20Sopenharmony_ci
25828c2ecf20Sopenharmony_ci		$here = "#$linenr: " if (!$file);
25838c2ecf20Sopenharmony_ci		$here = "#$realline: " if ($file);
25848c2ecf20Sopenharmony_ci
25858c2ecf20Sopenharmony_ci		my $found_file = 0;
25868c2ecf20Sopenharmony_ci		# extract the filename as it passes
25878c2ecf20Sopenharmony_ci		if ($line =~ /^diff --git.*?(\S+)$/) {
25888c2ecf20Sopenharmony_ci			$realfile = $1;
25898c2ecf20Sopenharmony_ci			$realfile =~ s@^([^/]*)/@@ if (!$file);
25908c2ecf20Sopenharmony_ci			$in_commit_log = 0;
25918c2ecf20Sopenharmony_ci			$found_file = 1;
25928c2ecf20Sopenharmony_ci		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
25938c2ecf20Sopenharmony_ci			$realfile = $1;
25948c2ecf20Sopenharmony_ci			$realfile =~ s@^([^/]*)/@@ if (!$file);
25958c2ecf20Sopenharmony_ci			$in_commit_log = 0;
25968c2ecf20Sopenharmony_ci
25978c2ecf20Sopenharmony_ci			$p1_prefix = $1;
25988c2ecf20Sopenharmony_ci			if (!$file && $tree && $p1_prefix ne '' &&
25998c2ecf20Sopenharmony_ci			    -e "$root/$p1_prefix") {
26008c2ecf20Sopenharmony_ci				WARN("PATCH_PREFIX",
26018c2ecf20Sopenharmony_ci				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
26028c2ecf20Sopenharmony_ci			}
26038c2ecf20Sopenharmony_ci
26048c2ecf20Sopenharmony_ci			if ($realfile =~ m@^include/asm/@) {
26058c2ecf20Sopenharmony_ci				ERROR("MODIFIED_INCLUDE_ASM",
26068c2ecf20Sopenharmony_ci				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
26078c2ecf20Sopenharmony_ci			}
26088c2ecf20Sopenharmony_ci			$found_file = 1;
26098c2ecf20Sopenharmony_ci		}
26108c2ecf20Sopenharmony_ci
26118c2ecf20Sopenharmony_ci#make up the handle for any error we report on this line
26128c2ecf20Sopenharmony_ci		if ($showfile) {
26138c2ecf20Sopenharmony_ci			$prefix = "$realfile:$realline: "
26148c2ecf20Sopenharmony_ci		} elsif ($emacs) {
26158c2ecf20Sopenharmony_ci			if ($file) {
26168c2ecf20Sopenharmony_ci				$prefix = "$filename:$realline: ";
26178c2ecf20Sopenharmony_ci			} else {
26188c2ecf20Sopenharmony_ci				$prefix = "$filename:$linenr: ";
26198c2ecf20Sopenharmony_ci			}
26208c2ecf20Sopenharmony_ci		}
26218c2ecf20Sopenharmony_ci
26228c2ecf20Sopenharmony_ci		if ($found_file) {
26238c2ecf20Sopenharmony_ci			if (is_maintained_obsolete($realfile)) {
26248c2ecf20Sopenharmony_ci				WARN("OBSOLETE",
26258c2ecf20Sopenharmony_ci				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
26268c2ecf20Sopenharmony_ci			}
26278c2ecf20Sopenharmony_ci			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
26288c2ecf20Sopenharmony_ci				$check = 1;
26298c2ecf20Sopenharmony_ci			} else {
26308c2ecf20Sopenharmony_ci				$check = $check_orig;
26318c2ecf20Sopenharmony_ci			}
26328c2ecf20Sopenharmony_ci			$checklicenseline = 1;
26338c2ecf20Sopenharmony_ci
26348c2ecf20Sopenharmony_ci			if ($realfile !~ /^MAINTAINERS/) {
26358c2ecf20Sopenharmony_ci				my $last_binding_patch = $is_binding_patch;
26368c2ecf20Sopenharmony_ci
26378c2ecf20Sopenharmony_ci				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
26388c2ecf20Sopenharmony_ci
26398c2ecf20Sopenharmony_ci				if (($last_binding_patch != -1) &&
26408c2ecf20Sopenharmony_ci				    ($last_binding_patch ^ $is_binding_patch)) {
26418c2ecf20Sopenharmony_ci					WARN("DT_SPLIT_BINDING_PATCH",
26428c2ecf20Sopenharmony_ci					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
26438c2ecf20Sopenharmony_ci				}
26448c2ecf20Sopenharmony_ci			}
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_ci			next;
26478c2ecf20Sopenharmony_ci		}
26488c2ecf20Sopenharmony_ci
26498c2ecf20Sopenharmony_ci		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
26508c2ecf20Sopenharmony_ci
26518c2ecf20Sopenharmony_ci		my $hereline = "$here\n$rawline\n";
26528c2ecf20Sopenharmony_ci		my $herecurr = "$here\n$rawline\n";
26538c2ecf20Sopenharmony_ci		my $hereprev = "$here\n$prevrawline\n$rawline\n";
26548c2ecf20Sopenharmony_ci
26558c2ecf20Sopenharmony_ci		$cnt_lines++ if ($realcnt != 0);
26568c2ecf20Sopenharmony_ci
26578c2ecf20Sopenharmony_ci# Verify the existence of a commit log if appropriate
26588c2ecf20Sopenharmony_ci# 2 is used because a $signature is counted in $commit_log_lines
26598c2ecf20Sopenharmony_ci		if ($in_commit_log) {
26608c2ecf20Sopenharmony_ci			if ($line !~ /^\s*$/) {
26618c2ecf20Sopenharmony_ci				$commit_log_lines++;	#could be a $signature
26628c2ecf20Sopenharmony_ci			}
26638c2ecf20Sopenharmony_ci		} elsif ($has_commit_log && $commit_log_lines < 2) {
26648c2ecf20Sopenharmony_ci			WARN("COMMIT_MESSAGE",
26658c2ecf20Sopenharmony_ci			     "Missing commit description - Add an appropriate one\n");
26668c2ecf20Sopenharmony_ci			$commit_log_lines = 2;	#warn only once
26678c2ecf20Sopenharmony_ci		}
26688c2ecf20Sopenharmony_ci
26698c2ecf20Sopenharmony_ci# Check if the commit log has what seems like a diff which can confuse patch
26708c2ecf20Sopenharmony_ci		if ($in_commit_log && !$commit_log_has_diff &&
26718c2ecf20Sopenharmony_ci		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
26728c2ecf20Sopenharmony_ci		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
26738c2ecf20Sopenharmony_ci		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
26748c2ecf20Sopenharmony_ci		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
26758c2ecf20Sopenharmony_ci			ERROR("DIFF_IN_COMMIT_MSG",
26768c2ecf20Sopenharmony_ci			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
26778c2ecf20Sopenharmony_ci			$commit_log_has_diff = 1;
26788c2ecf20Sopenharmony_ci		}
26798c2ecf20Sopenharmony_ci
26808c2ecf20Sopenharmony_ci# Check for incorrect file permissions
26818c2ecf20Sopenharmony_ci		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
26828c2ecf20Sopenharmony_ci			my $permhere = $here . "FILE: $realfile\n";
26838c2ecf20Sopenharmony_ci			if ($realfile !~ m@scripts/@ &&
26848c2ecf20Sopenharmony_ci			    $realfile !~ /\.(py|pl|awk|sh)$/) {
26858c2ecf20Sopenharmony_ci				ERROR("EXECUTE_PERMISSIONS",
26868c2ecf20Sopenharmony_ci				      "do not set execute permissions for source files\n" . $permhere);
26878c2ecf20Sopenharmony_ci			}
26888c2ecf20Sopenharmony_ci		}
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci# Check the patch for a From:
26918c2ecf20Sopenharmony_ci		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
26928c2ecf20Sopenharmony_ci			$author = $1;
26938c2ecf20Sopenharmony_ci			my $curline = $linenr;
26948c2ecf20Sopenharmony_ci			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
26958c2ecf20Sopenharmony_ci				$author .= $1;
26968c2ecf20Sopenharmony_ci			}
26978c2ecf20Sopenharmony_ci			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
26988c2ecf20Sopenharmony_ci			$author =~ s/"//g;
26998c2ecf20Sopenharmony_ci			$author = reformat_email($author);
27008c2ecf20Sopenharmony_ci		}
27018c2ecf20Sopenharmony_ci
27028c2ecf20Sopenharmony_ci# Check the patch for a signoff:
27038c2ecf20Sopenharmony_ci		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
27048c2ecf20Sopenharmony_ci			$signoff++;
27058c2ecf20Sopenharmony_ci			$in_commit_log = 0;
27068c2ecf20Sopenharmony_ci			if ($author ne ''  && $authorsignoff != 1) {
27078c2ecf20Sopenharmony_ci				if (same_email_addresses($1, $author, 1)) {
27088c2ecf20Sopenharmony_ci					$authorsignoff = 1;
27098c2ecf20Sopenharmony_ci				} else {
27108c2ecf20Sopenharmony_ci					my $ctx = $1;
27118c2ecf20Sopenharmony_ci					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
27128c2ecf20Sopenharmony_ci					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
27138c2ecf20Sopenharmony_ci
27148c2ecf20Sopenharmony_ci					if ($email_address eq $author_address && $email_name eq $author_name) {
27158c2ecf20Sopenharmony_ci						$author_sob = $ctx;
27168c2ecf20Sopenharmony_ci						$authorsignoff = 2;
27178c2ecf20Sopenharmony_ci					} elsif ($email_address eq $author_address) {
27188c2ecf20Sopenharmony_ci						$author_sob = $ctx;
27198c2ecf20Sopenharmony_ci						$authorsignoff = 3;
27208c2ecf20Sopenharmony_ci					} elsif ($email_name eq $author_name) {
27218c2ecf20Sopenharmony_ci						$author_sob = $ctx;
27228c2ecf20Sopenharmony_ci						$authorsignoff = 4;
27238c2ecf20Sopenharmony_ci
27248c2ecf20Sopenharmony_ci						my $address1 = $email_address;
27258c2ecf20Sopenharmony_ci						my $address2 = $author_address;
27268c2ecf20Sopenharmony_ci
27278c2ecf20Sopenharmony_ci						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
27288c2ecf20Sopenharmony_ci							$address1 = "$1$2";
27298c2ecf20Sopenharmony_ci						}
27308c2ecf20Sopenharmony_ci						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
27318c2ecf20Sopenharmony_ci							$address2 = "$1$2";
27328c2ecf20Sopenharmony_ci						}
27338c2ecf20Sopenharmony_ci						if ($address1 eq $address2) {
27348c2ecf20Sopenharmony_ci							$authorsignoff = 5;
27358c2ecf20Sopenharmony_ci						}
27368c2ecf20Sopenharmony_ci					}
27378c2ecf20Sopenharmony_ci				}
27388c2ecf20Sopenharmony_ci			}
27398c2ecf20Sopenharmony_ci		}
27408c2ecf20Sopenharmony_ci
27418c2ecf20Sopenharmony_ci# Check for patch separator
27428c2ecf20Sopenharmony_ci		if ($line =~ /^---$/) {
27438c2ecf20Sopenharmony_ci			$has_patch_separator = 1;
27448c2ecf20Sopenharmony_ci			$in_commit_log = 0;
27458c2ecf20Sopenharmony_ci		}
27468c2ecf20Sopenharmony_ci
27478c2ecf20Sopenharmony_ci# Check if MAINTAINERS is being updated.  If so, there's probably no need to
27488c2ecf20Sopenharmony_ci# emit the "does MAINTAINERS need updating?" message on file add/move/delete
27498c2ecf20Sopenharmony_ci		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
27508c2ecf20Sopenharmony_ci			$reported_maintainer_file = 1;
27518c2ecf20Sopenharmony_ci		}
27528c2ecf20Sopenharmony_ci
27538c2ecf20Sopenharmony_ci# Check signature styles
27548c2ecf20Sopenharmony_ci		if (!$in_header_lines &&
27558c2ecf20Sopenharmony_ci		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
27568c2ecf20Sopenharmony_ci			my $space_before = $1;
27578c2ecf20Sopenharmony_ci			my $sign_off = $2;
27588c2ecf20Sopenharmony_ci			my $space_after = $3;
27598c2ecf20Sopenharmony_ci			my $email = $4;
27608c2ecf20Sopenharmony_ci			my $ucfirst_sign_off = ucfirst(lc($sign_off));
27618c2ecf20Sopenharmony_ci
27628c2ecf20Sopenharmony_ci			if ($sign_off !~ /$signature_tags/) {
27638c2ecf20Sopenharmony_ci				WARN("BAD_SIGN_OFF",
27648c2ecf20Sopenharmony_ci				     "Non-standard signature: $sign_off\n" . $herecurr);
27658c2ecf20Sopenharmony_ci			}
27668c2ecf20Sopenharmony_ci			if (defined $space_before && $space_before ne "") {
27678c2ecf20Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
27688c2ecf20Sopenharmony_ci					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
27698c2ecf20Sopenharmony_ci				    $fix) {
27708c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =
27718c2ecf20Sopenharmony_ci					    "$ucfirst_sign_off $email";
27728c2ecf20Sopenharmony_ci				}
27738c2ecf20Sopenharmony_ci			}
27748c2ecf20Sopenharmony_ci			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
27758c2ecf20Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
27768c2ecf20Sopenharmony_ci					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
27778c2ecf20Sopenharmony_ci				    $fix) {
27788c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =
27798c2ecf20Sopenharmony_ci					    "$ucfirst_sign_off $email";
27808c2ecf20Sopenharmony_ci				}
27818c2ecf20Sopenharmony_ci
27828c2ecf20Sopenharmony_ci			}
27838c2ecf20Sopenharmony_ci			if (!defined $space_after || $space_after ne " ") {
27848c2ecf20Sopenharmony_ci				if (WARN("BAD_SIGN_OFF",
27858c2ecf20Sopenharmony_ci					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
27868c2ecf20Sopenharmony_ci				    $fix) {
27878c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =
27888c2ecf20Sopenharmony_ci					    "$ucfirst_sign_off $email";
27898c2ecf20Sopenharmony_ci				}
27908c2ecf20Sopenharmony_ci			}
27918c2ecf20Sopenharmony_ci
27928c2ecf20Sopenharmony_ci			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
27938c2ecf20Sopenharmony_ci			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
27948c2ecf20Sopenharmony_ci			if ($suggested_email eq "") {
27958c2ecf20Sopenharmony_ci				ERROR("BAD_SIGN_OFF",
27968c2ecf20Sopenharmony_ci				      "Unrecognized email address: '$email'\n" . $herecurr);
27978c2ecf20Sopenharmony_ci			} else {
27988c2ecf20Sopenharmony_ci				my $dequoted = $suggested_email;
27998c2ecf20Sopenharmony_ci				$dequoted =~ s/^"//;
28008c2ecf20Sopenharmony_ci				$dequoted =~ s/" </ </;
28018c2ecf20Sopenharmony_ci				# Don't force email to have quotes
28028c2ecf20Sopenharmony_ci				# Allow just an angle bracketed address
28038c2ecf20Sopenharmony_ci				if (!same_email_addresses($email, $suggested_email, 0)) {
28048c2ecf20Sopenharmony_ci					WARN("BAD_SIGN_OFF",
28058c2ecf20Sopenharmony_ci					     "email address '$email' might be better as '$suggested_email'\n" . $herecurr);
28068c2ecf20Sopenharmony_ci				}
28078c2ecf20Sopenharmony_ci			}
28088c2ecf20Sopenharmony_ci
28098c2ecf20Sopenharmony_ci# Check for duplicate signatures
28108c2ecf20Sopenharmony_ci			my $sig_nospace = $line;
28118c2ecf20Sopenharmony_ci			$sig_nospace =~ s/\s//g;
28128c2ecf20Sopenharmony_ci			$sig_nospace = lc($sig_nospace);
28138c2ecf20Sopenharmony_ci			if (defined $signatures{$sig_nospace}) {
28148c2ecf20Sopenharmony_ci				WARN("BAD_SIGN_OFF",
28158c2ecf20Sopenharmony_ci				     "Duplicate signature\n" . $herecurr);
28168c2ecf20Sopenharmony_ci			} else {
28178c2ecf20Sopenharmony_ci				$signatures{$sig_nospace} = 1;
28188c2ecf20Sopenharmony_ci			}
28198c2ecf20Sopenharmony_ci
28208c2ecf20Sopenharmony_ci# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
28218c2ecf20Sopenharmony_ci			if ($sign_off =~ /^co-developed-by:$/i) {
28228c2ecf20Sopenharmony_ci				if ($email eq $author) {
28238c2ecf20Sopenharmony_ci					WARN("BAD_SIGN_OFF",
28248c2ecf20Sopenharmony_ci					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
28258c2ecf20Sopenharmony_ci				}
28268c2ecf20Sopenharmony_ci				if (!defined $lines[$linenr]) {
28278c2ecf20Sopenharmony_ci					WARN("BAD_SIGN_OFF",
28288c2ecf20Sopenharmony_ci                                             "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
28298c2ecf20Sopenharmony_ci				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
28308c2ecf20Sopenharmony_ci					WARN("BAD_SIGN_OFF",
28318c2ecf20Sopenharmony_ci					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
28328c2ecf20Sopenharmony_ci				} elsif ($1 ne $email) {
28338c2ecf20Sopenharmony_ci					WARN("BAD_SIGN_OFF",
28348c2ecf20Sopenharmony_ci					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
28358c2ecf20Sopenharmony_ci				}
28368c2ecf20Sopenharmony_ci			}
28378c2ecf20Sopenharmony_ci		}
28388c2ecf20Sopenharmony_ci
28398c2ecf20Sopenharmony_ci# Check email subject for common tools that don't need to be mentioned
28408c2ecf20Sopenharmony_ci		if ($in_header_lines &&
28418c2ecf20Sopenharmony_ci		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
28428c2ecf20Sopenharmony_ci			WARN("EMAIL_SUBJECT",
28438c2ecf20Sopenharmony_ci			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
28448c2ecf20Sopenharmony_ci		}
28458c2ecf20Sopenharmony_ci
28468c2ecf20Sopenharmony_ci# Check for Gerrit Change-Ids not in any patch context
28478c2ecf20Sopenharmony_ci		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
28488c2ecf20Sopenharmony_ci			ERROR("GERRIT_CHANGE_ID",
28498c2ecf20Sopenharmony_ci			      "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
28508c2ecf20Sopenharmony_ci		}
28518c2ecf20Sopenharmony_ci
28528c2ecf20Sopenharmony_ci# Check if the commit log is in a possible stack dump
28538c2ecf20Sopenharmony_ci		if ($in_commit_log && !$commit_log_possible_stack_dump &&
28548c2ecf20Sopenharmony_ci		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
28558c2ecf20Sopenharmony_ci		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
28568c2ecf20Sopenharmony_ci					# timestamp
28578c2ecf20Sopenharmony_ci		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
28588c2ecf20Sopenharmony_ci		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
28598c2ecf20Sopenharmony_ci		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
28608c2ecf20Sopenharmony_ci					# stack dump address styles
28618c2ecf20Sopenharmony_ci			$commit_log_possible_stack_dump = 1;
28628c2ecf20Sopenharmony_ci		}
28638c2ecf20Sopenharmony_ci
28648c2ecf20Sopenharmony_ci# Check for line lengths > 75 in commit log, warn once
28658c2ecf20Sopenharmony_ci		if ($in_commit_log && !$commit_log_long_line &&
28668c2ecf20Sopenharmony_ci		    length($line) > 75 &&
28678c2ecf20Sopenharmony_ci		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
28688c2ecf20Sopenharmony_ci					# file delta changes
28698c2ecf20Sopenharmony_ci		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
28708c2ecf20Sopenharmony_ci					# filename then :
28718c2ecf20Sopenharmony_ci		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
28728c2ecf20Sopenharmony_ci					# A Fixes: or Link: line
28738c2ecf20Sopenharmony_ci		      $commit_log_possible_stack_dump)) {
28748c2ecf20Sopenharmony_ci			WARN("COMMIT_LOG_LONG_LINE",
28758c2ecf20Sopenharmony_ci			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
28768c2ecf20Sopenharmony_ci			$commit_log_long_line = 1;
28778c2ecf20Sopenharmony_ci		}
28788c2ecf20Sopenharmony_ci
28798c2ecf20Sopenharmony_ci# Reset possible stack dump if a blank line is found
28808c2ecf20Sopenharmony_ci		if ($in_commit_log && $commit_log_possible_stack_dump &&
28818c2ecf20Sopenharmony_ci		    $line =~ /^\s*$/) {
28828c2ecf20Sopenharmony_ci			$commit_log_possible_stack_dump = 0;
28838c2ecf20Sopenharmony_ci		}
28848c2ecf20Sopenharmony_ci
28858c2ecf20Sopenharmony_ci# Check for git id commit length and improperly formed commit descriptions
28868c2ecf20Sopenharmony_ci		if ($in_commit_log && !$commit_log_possible_stack_dump &&
28878c2ecf20Sopenharmony_ci		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
28888c2ecf20Sopenharmony_ci		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
28898c2ecf20Sopenharmony_ci		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
28908c2ecf20Sopenharmony_ci		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
28918c2ecf20Sopenharmony_ci		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
28928c2ecf20Sopenharmony_ci		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
28938c2ecf20Sopenharmony_ci			my $init_char = "c";
28948c2ecf20Sopenharmony_ci			my $orig_commit = "";
28958c2ecf20Sopenharmony_ci			my $short = 1;
28968c2ecf20Sopenharmony_ci			my $long = 0;
28978c2ecf20Sopenharmony_ci			my $case = 1;
28988c2ecf20Sopenharmony_ci			my $space = 1;
28998c2ecf20Sopenharmony_ci			my $hasdesc = 0;
29008c2ecf20Sopenharmony_ci			my $hasparens = 0;
29018c2ecf20Sopenharmony_ci			my $id = '0123456789ab';
29028c2ecf20Sopenharmony_ci			my $orig_desc = "commit description";
29038c2ecf20Sopenharmony_ci			my $description = "";
29048c2ecf20Sopenharmony_ci
29058c2ecf20Sopenharmony_ci			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
29068c2ecf20Sopenharmony_ci				$init_char = $1;
29078c2ecf20Sopenharmony_ci				$orig_commit = lc($2);
29088c2ecf20Sopenharmony_ci			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
29098c2ecf20Sopenharmony_ci				$orig_commit = lc($1);
29108c2ecf20Sopenharmony_ci			}
29118c2ecf20Sopenharmony_ci
29128c2ecf20Sopenharmony_ci			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
29138c2ecf20Sopenharmony_ci			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
29148c2ecf20Sopenharmony_ci			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
29158c2ecf20Sopenharmony_ci			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
29168c2ecf20Sopenharmony_ci			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
29178c2ecf20Sopenharmony_ci				$orig_desc = $1;
29188c2ecf20Sopenharmony_ci				$hasparens = 1;
29198c2ecf20Sopenharmony_ci			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
29208c2ecf20Sopenharmony_ci				 defined $rawlines[$linenr] &&
29218c2ecf20Sopenharmony_ci				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
29228c2ecf20Sopenharmony_ci				$orig_desc = $1;
29238c2ecf20Sopenharmony_ci				$hasparens = 1;
29248c2ecf20Sopenharmony_ci			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
29258c2ecf20Sopenharmony_ci				 defined $rawlines[$linenr] &&
29268c2ecf20Sopenharmony_ci				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
29278c2ecf20Sopenharmony_ci				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
29288c2ecf20Sopenharmony_ci				$orig_desc = $1;
29298c2ecf20Sopenharmony_ci				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
29308c2ecf20Sopenharmony_ci				$orig_desc .= " " . $1;
29318c2ecf20Sopenharmony_ci				$hasparens = 1;
29328c2ecf20Sopenharmony_ci			}
29338c2ecf20Sopenharmony_ci
29348c2ecf20Sopenharmony_ci			($id, $description) = git_commit_info($orig_commit,
29358c2ecf20Sopenharmony_ci							      $id, $orig_desc);
29368c2ecf20Sopenharmony_ci
29378c2ecf20Sopenharmony_ci			if (defined($id) &&
29388c2ecf20Sopenharmony_ci			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
29398c2ecf20Sopenharmony_ci				ERROR("GIT_COMMIT_ID",
29408c2ecf20Sopenharmony_ci				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
29418c2ecf20Sopenharmony_ci			}
29428c2ecf20Sopenharmony_ci		}
29438c2ecf20Sopenharmony_ci
29448c2ecf20Sopenharmony_ci# Check for added, moved or deleted files
29458c2ecf20Sopenharmony_ci		if (!$reported_maintainer_file && !$in_commit_log &&
29468c2ecf20Sopenharmony_ci		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
29478c2ecf20Sopenharmony_ci		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
29488c2ecf20Sopenharmony_ci		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
29498c2ecf20Sopenharmony_ci		      (defined($1) || defined($2))))) {
29508c2ecf20Sopenharmony_ci			$is_patch = 1;
29518c2ecf20Sopenharmony_ci			$reported_maintainer_file = 1;
29528c2ecf20Sopenharmony_ci			WARN("FILE_PATH_CHANGES",
29538c2ecf20Sopenharmony_ci			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
29548c2ecf20Sopenharmony_ci		}
29558c2ecf20Sopenharmony_ci
29568c2ecf20Sopenharmony_ci# Check for adding new DT bindings not in schema format
29578c2ecf20Sopenharmony_ci		if (!$in_commit_log &&
29588c2ecf20Sopenharmony_ci		    ($line =~ /^new file mode\s*\d+\s*$/) &&
29598c2ecf20Sopenharmony_ci		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
29608c2ecf20Sopenharmony_ci			WARN("DT_SCHEMA_BINDING_PATCH",
29618c2ecf20Sopenharmony_ci			     "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
29628c2ecf20Sopenharmony_ci		}
29638c2ecf20Sopenharmony_ci
29648c2ecf20Sopenharmony_ci# Check for wrappage within a valid hunk of the file
29658c2ecf20Sopenharmony_ci		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
29668c2ecf20Sopenharmony_ci			ERROR("CORRUPTED_PATCH",
29678c2ecf20Sopenharmony_ci			      "patch seems to be corrupt (line wrapped?)\n" .
29688c2ecf20Sopenharmony_ci				$herecurr) if (!$emitted_corrupt++);
29698c2ecf20Sopenharmony_ci		}
29708c2ecf20Sopenharmony_ci
29718c2ecf20Sopenharmony_ci# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
29728c2ecf20Sopenharmony_ci		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
29738c2ecf20Sopenharmony_ci		    $rawline !~ m/^$UTF8*$/) {
29748c2ecf20Sopenharmony_ci			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
29758c2ecf20Sopenharmony_ci
29768c2ecf20Sopenharmony_ci			my $blank = copy_spacing($rawline);
29778c2ecf20Sopenharmony_ci			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
29788c2ecf20Sopenharmony_ci			my $hereptr = "$hereline$ptr\n";
29798c2ecf20Sopenharmony_ci
29808c2ecf20Sopenharmony_ci			CHK("INVALID_UTF8",
29818c2ecf20Sopenharmony_ci			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
29828c2ecf20Sopenharmony_ci		}
29838c2ecf20Sopenharmony_ci
29848c2ecf20Sopenharmony_ci# Check if it's the start of a commit log
29858c2ecf20Sopenharmony_ci# (not a header line and we haven't seen the patch filename)
29868c2ecf20Sopenharmony_ci		if ($in_header_lines && $realfile =~ /^$/ &&
29878c2ecf20Sopenharmony_ci		    !($rawline =~ /^\s+(?:\S|$)/ ||
29888c2ecf20Sopenharmony_ci		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
29898c2ecf20Sopenharmony_ci			$in_header_lines = 0;
29908c2ecf20Sopenharmony_ci			$in_commit_log = 1;
29918c2ecf20Sopenharmony_ci			$has_commit_log = 1;
29928c2ecf20Sopenharmony_ci		}
29938c2ecf20Sopenharmony_ci
29948c2ecf20Sopenharmony_ci# Check if there is UTF-8 in a commit log when a mail header has explicitly
29958c2ecf20Sopenharmony_ci# declined it, i.e defined some charset where it is missing.
29968c2ecf20Sopenharmony_ci		if ($in_header_lines &&
29978c2ecf20Sopenharmony_ci		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
29988c2ecf20Sopenharmony_ci		    $1 !~ /utf-8/i) {
29998c2ecf20Sopenharmony_ci			$non_utf8_charset = 1;
30008c2ecf20Sopenharmony_ci		}
30018c2ecf20Sopenharmony_ci
30028c2ecf20Sopenharmony_ci		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
30038c2ecf20Sopenharmony_ci		    $rawline =~ /$NON_ASCII_UTF8/) {
30048c2ecf20Sopenharmony_ci			WARN("UTF8_BEFORE_PATCH",
30058c2ecf20Sopenharmony_ci			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
30068c2ecf20Sopenharmony_ci		}
30078c2ecf20Sopenharmony_ci
30088c2ecf20Sopenharmony_ci# Check for absolute kernel paths in commit message
30098c2ecf20Sopenharmony_ci		if ($tree && $in_commit_log) {
30108c2ecf20Sopenharmony_ci			while ($line =~ m{(?:^|\s)(/\S*)}g) {
30118c2ecf20Sopenharmony_ci				my $file = $1;
30128c2ecf20Sopenharmony_ci
30138c2ecf20Sopenharmony_ci				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
30148c2ecf20Sopenharmony_ci				    check_absolute_file($1, $herecurr)) {
30158c2ecf20Sopenharmony_ci					#
30168c2ecf20Sopenharmony_ci				} else {
30178c2ecf20Sopenharmony_ci					check_absolute_file($file, $herecurr);
30188c2ecf20Sopenharmony_ci				}
30198c2ecf20Sopenharmony_ci			}
30208c2ecf20Sopenharmony_ci		}
30218c2ecf20Sopenharmony_ci
30228c2ecf20Sopenharmony_ci# Check for various typo / spelling mistakes
30238c2ecf20Sopenharmony_ci		if (defined($misspellings) &&
30248c2ecf20Sopenharmony_ci		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
30258c2ecf20Sopenharmony_ci			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
30268c2ecf20Sopenharmony_ci				my $typo = $1;
30278c2ecf20Sopenharmony_ci				my $typo_fix = $spelling_fix{lc($typo)};
30288c2ecf20Sopenharmony_ci				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
30298c2ecf20Sopenharmony_ci				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
30308c2ecf20Sopenharmony_ci				my $msg_level = \&WARN;
30318c2ecf20Sopenharmony_ci				$msg_level = \&CHK if ($file);
30328c2ecf20Sopenharmony_ci				if (&{$msg_level}("TYPO_SPELLING",
30338c2ecf20Sopenharmony_ci						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
30348c2ecf20Sopenharmony_ci				    $fix) {
30358c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
30368c2ecf20Sopenharmony_ci				}
30378c2ecf20Sopenharmony_ci			}
30388c2ecf20Sopenharmony_ci		}
30398c2ecf20Sopenharmony_ci
30408c2ecf20Sopenharmony_ci# check for invalid commit id
30418c2ecf20Sopenharmony_ci		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
30428c2ecf20Sopenharmony_ci			my $id;
30438c2ecf20Sopenharmony_ci			my $description;
30448c2ecf20Sopenharmony_ci			($id, $description) = git_commit_info($2, undef, undef);
30458c2ecf20Sopenharmony_ci			if (!defined($id)) {
30468c2ecf20Sopenharmony_ci				WARN("UNKNOWN_COMMIT_ID",
30478c2ecf20Sopenharmony_ci				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
30488c2ecf20Sopenharmony_ci			}
30498c2ecf20Sopenharmony_ci		}
30508c2ecf20Sopenharmony_ci
30518c2ecf20Sopenharmony_ci# check for repeated words separated by a single space
30528c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+/ || $in_commit_log) {
30538c2ecf20Sopenharmony_ci			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
30548c2ecf20Sopenharmony_ci
30558c2ecf20Sopenharmony_ci				my $first = $1;
30568c2ecf20Sopenharmony_ci				my $second = $2;
30578c2ecf20Sopenharmony_ci
30588c2ecf20Sopenharmony_ci				if ($first =~ /(?:struct|union|enum)/) {
30598c2ecf20Sopenharmony_ci					pos($rawline) += length($first) + length($second) + 1;
30608c2ecf20Sopenharmony_ci					next;
30618c2ecf20Sopenharmony_ci				}
30628c2ecf20Sopenharmony_ci
30638c2ecf20Sopenharmony_ci				next if ($first ne $second);
30648c2ecf20Sopenharmony_ci				next if ($first eq 'long');
30658c2ecf20Sopenharmony_ci
30668c2ecf20Sopenharmony_ci				if (WARN("REPEATED_WORD",
30678c2ecf20Sopenharmony_ci					 "Possible repeated word: '$first'\n" . $herecurr) &&
30688c2ecf20Sopenharmony_ci				    $fix) {
30698c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
30708c2ecf20Sopenharmony_ci				}
30718c2ecf20Sopenharmony_ci			}
30728c2ecf20Sopenharmony_ci
30738c2ecf20Sopenharmony_ci			# if it's a repeated word on consecutive lines in a comment block
30748c2ecf20Sopenharmony_ci			if ($prevline =~ /$;+\s*$/ &&
30758c2ecf20Sopenharmony_ci			    $prevrawline =~ /($word_pattern)\s*$/) {
30768c2ecf20Sopenharmony_ci				my $last_word = $1;
30778c2ecf20Sopenharmony_ci				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
30788c2ecf20Sopenharmony_ci					if (WARN("REPEATED_WORD",
30798c2ecf20Sopenharmony_ci						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
30808c2ecf20Sopenharmony_ci					    $fix) {
30818c2ecf20Sopenharmony_ci						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
30828c2ecf20Sopenharmony_ci					}
30838c2ecf20Sopenharmony_ci				}
30848c2ecf20Sopenharmony_ci			}
30858c2ecf20Sopenharmony_ci		}
30868c2ecf20Sopenharmony_ci
30878c2ecf20Sopenharmony_ci# ignore non-hunk lines and lines being removed
30888c2ecf20Sopenharmony_ci		next if (!$hunk_line || $line =~ /^-/);
30898c2ecf20Sopenharmony_ci
30908c2ecf20Sopenharmony_ci#trailing whitespace
30918c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*\015/) {
30928c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
30938c2ecf20Sopenharmony_ci			if (ERROR("DOS_LINE_ENDINGS",
30948c2ecf20Sopenharmony_ci				  "DOS line endings\n" . $herevet) &&
30958c2ecf20Sopenharmony_ci			    $fix) {
30968c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
30978c2ecf20Sopenharmony_ci			}
30988c2ecf20Sopenharmony_ci		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
30998c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
31008c2ecf20Sopenharmony_ci			if (ERROR("TRAILING_WHITESPACE",
31018c2ecf20Sopenharmony_ci				  "trailing whitespace\n" . $herevet) &&
31028c2ecf20Sopenharmony_ci			    $fix) {
31038c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+$//;
31048c2ecf20Sopenharmony_ci			}
31058c2ecf20Sopenharmony_ci
31068c2ecf20Sopenharmony_ci			$rpt_cleaners = 1;
31078c2ecf20Sopenharmony_ci		}
31088c2ecf20Sopenharmony_ci
31098c2ecf20Sopenharmony_ci# Check for FSF mailing addresses.
31108c2ecf20Sopenharmony_ci		if ($rawline =~ /\bwrite to the Free/i ||
31118c2ecf20Sopenharmony_ci		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
31128c2ecf20Sopenharmony_ci		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
31138c2ecf20Sopenharmony_ci		    $rawline =~ /\b51\s+Franklin\s+St/i) {
31148c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
31158c2ecf20Sopenharmony_ci			my $msg_level = \&ERROR;
31168c2ecf20Sopenharmony_ci			$msg_level = \&CHK if ($file);
31178c2ecf20Sopenharmony_ci			&{$msg_level}("FSF_MAILING_ADDRESS",
31188c2ecf20Sopenharmony_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)
31198c2ecf20Sopenharmony_ci		}
31208c2ecf20Sopenharmony_ci
31218c2ecf20Sopenharmony_ci# check for Kconfig help text having a real description
31228c2ecf20Sopenharmony_ci# Only applies when adding the entry originally, after that we do not have
31238c2ecf20Sopenharmony_ci# sufficient context to determine whether it is indeed long enough.
31248c2ecf20Sopenharmony_ci		if ($realfile =~ /Kconfig/ &&
31258c2ecf20Sopenharmony_ci		    # 'choice' is usually the last thing on the line (though
31268c2ecf20Sopenharmony_ci		    # Kconfig supports named choices), so use a word boundary
31278c2ecf20Sopenharmony_ci		    # (\b) rather than a whitespace character (\s)
31288c2ecf20Sopenharmony_ci		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
31298c2ecf20Sopenharmony_ci			my $length = 0;
31308c2ecf20Sopenharmony_ci			my $cnt = $realcnt;
31318c2ecf20Sopenharmony_ci			my $ln = $linenr + 1;
31328c2ecf20Sopenharmony_ci			my $f;
31338c2ecf20Sopenharmony_ci			my $is_start = 0;
31348c2ecf20Sopenharmony_ci			my $is_end = 0;
31358c2ecf20Sopenharmony_ci			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
31368c2ecf20Sopenharmony_ci				$f = $lines[$ln - 1];
31378c2ecf20Sopenharmony_ci				$cnt-- if ($lines[$ln - 1] !~ /^-/);
31388c2ecf20Sopenharmony_ci				$is_end = $lines[$ln - 1] =~ /^\+/;
31398c2ecf20Sopenharmony_ci
31408c2ecf20Sopenharmony_ci				next if ($f =~ /^-/);
31418c2ecf20Sopenharmony_ci				last if (!$file && $f =~ /^\@\@/);
31428c2ecf20Sopenharmony_ci
31438c2ecf20Sopenharmony_ci				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
31448c2ecf20Sopenharmony_ci					$is_start = 1;
31458c2ecf20Sopenharmony_ci				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
31468c2ecf20Sopenharmony_ci					$length = -1;
31478c2ecf20Sopenharmony_ci				}
31488c2ecf20Sopenharmony_ci
31498c2ecf20Sopenharmony_ci				$f =~ s/^.//;
31508c2ecf20Sopenharmony_ci				$f =~ s/#.*//;
31518c2ecf20Sopenharmony_ci				$f =~ s/^\s+//;
31528c2ecf20Sopenharmony_ci				next if ($f =~ /^$/);
31538c2ecf20Sopenharmony_ci
31548c2ecf20Sopenharmony_ci				# This only checks context lines in the patch
31558c2ecf20Sopenharmony_ci				# and so hopefully shouldn't trigger false
31568c2ecf20Sopenharmony_ci				# positives, even though some of these are
31578c2ecf20Sopenharmony_ci				# common words in help texts
31588c2ecf20Sopenharmony_ci				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
31598c2ecf20Sopenharmony_ci						  if|endif|menu|endmenu|source)\b/x) {
31608c2ecf20Sopenharmony_ci					$is_end = 1;
31618c2ecf20Sopenharmony_ci					last;
31628c2ecf20Sopenharmony_ci				}
31638c2ecf20Sopenharmony_ci				$length++;
31648c2ecf20Sopenharmony_ci			}
31658c2ecf20Sopenharmony_ci			if ($is_start && $is_end && $length < $min_conf_desc_length) {
31668c2ecf20Sopenharmony_ci				WARN("CONFIG_DESCRIPTION",
31678c2ecf20Sopenharmony_ci				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
31688c2ecf20Sopenharmony_ci			}
31698c2ecf20Sopenharmony_ci			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
31708c2ecf20Sopenharmony_ci		}
31718c2ecf20Sopenharmony_ci
31728c2ecf20Sopenharmony_ci# check MAINTAINERS entries
31738c2ecf20Sopenharmony_ci		if ($realfile =~ /^MAINTAINERS$/) {
31748c2ecf20Sopenharmony_ci# check MAINTAINERS entries for the right form
31758c2ecf20Sopenharmony_ci			if ($rawline =~ /^\+[A-Z]:/ &&
31768c2ecf20Sopenharmony_ci			    $rawline !~ /^\+[A-Z]:\t\S/) {
31778c2ecf20Sopenharmony_ci				if (WARN("MAINTAINERS_STYLE",
31788c2ecf20Sopenharmony_ci					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
31798c2ecf20Sopenharmony_ci				    $fix) {
31808c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
31818c2ecf20Sopenharmony_ci				}
31828c2ecf20Sopenharmony_ci			}
31838c2ecf20Sopenharmony_ci# check MAINTAINERS entries for the right ordering too
31848c2ecf20Sopenharmony_ci			my $preferred_order = 'MRLSWQBCPTFXNK';
31858c2ecf20Sopenharmony_ci			if ($rawline =~ /^\+[A-Z]:/ &&
31868c2ecf20Sopenharmony_ci			    $prevrawline =~ /^[\+ ][A-Z]:/) {
31878c2ecf20Sopenharmony_ci				$rawline =~ /^\+([A-Z]):\s*(.*)/;
31888c2ecf20Sopenharmony_ci				my $cur = $1;
31898c2ecf20Sopenharmony_ci				my $curval = $2;
31908c2ecf20Sopenharmony_ci				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
31918c2ecf20Sopenharmony_ci				my $prev = $1;
31928c2ecf20Sopenharmony_ci				my $prevval = $2;
31938c2ecf20Sopenharmony_ci				my $curindex = index($preferred_order, $cur);
31948c2ecf20Sopenharmony_ci				my $previndex = index($preferred_order, $prev);
31958c2ecf20Sopenharmony_ci				if ($curindex < 0) {
31968c2ecf20Sopenharmony_ci					WARN("MAINTAINERS_STYLE",
31978c2ecf20Sopenharmony_ci					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
31988c2ecf20Sopenharmony_ci				} else {
31998c2ecf20Sopenharmony_ci					if ($previndex >= 0 && $curindex < $previndex) {
32008c2ecf20Sopenharmony_ci						WARN("MAINTAINERS_STYLE",
32018c2ecf20Sopenharmony_ci						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
32028c2ecf20Sopenharmony_ci					} elsif ((($prev eq 'F' && $cur eq 'F') ||
32038c2ecf20Sopenharmony_ci						  ($prev eq 'X' && $cur eq 'X')) &&
32048c2ecf20Sopenharmony_ci						 ($prevval cmp $curval) > 0) {
32058c2ecf20Sopenharmony_ci						WARN("MAINTAINERS_STYLE",
32068c2ecf20Sopenharmony_ci						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
32078c2ecf20Sopenharmony_ci					}
32088c2ecf20Sopenharmony_ci				}
32098c2ecf20Sopenharmony_ci			}
32108c2ecf20Sopenharmony_ci		}
32118c2ecf20Sopenharmony_ci
32128c2ecf20Sopenharmony_ci# discourage the use of boolean for type definition attributes of Kconfig options
32138c2ecf20Sopenharmony_ci		if ($realfile =~ /Kconfig/ &&
32148c2ecf20Sopenharmony_ci		    $line =~ /^\+\s*\bboolean\b/) {
32158c2ecf20Sopenharmony_ci			WARN("CONFIG_TYPE_BOOLEAN",
32168c2ecf20Sopenharmony_ci			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
32178c2ecf20Sopenharmony_ci		}
32188c2ecf20Sopenharmony_ci
32198c2ecf20Sopenharmony_ci		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
32208c2ecf20Sopenharmony_ci		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
32218c2ecf20Sopenharmony_ci			my $flag = $1;
32228c2ecf20Sopenharmony_ci			my $replacement = {
32238c2ecf20Sopenharmony_ci				'EXTRA_AFLAGS' =>   'asflags-y',
32248c2ecf20Sopenharmony_ci				'EXTRA_CFLAGS' =>   'ccflags-y',
32258c2ecf20Sopenharmony_ci				'EXTRA_CPPFLAGS' => 'cppflags-y',
32268c2ecf20Sopenharmony_ci				'EXTRA_LDFLAGS' =>  'ldflags-y',
32278c2ecf20Sopenharmony_ci			};
32288c2ecf20Sopenharmony_ci
32298c2ecf20Sopenharmony_ci			WARN("DEPRECATED_VARIABLE",
32308c2ecf20Sopenharmony_ci			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
32318c2ecf20Sopenharmony_ci		}
32328c2ecf20Sopenharmony_ci
32338c2ecf20Sopenharmony_ci# check for DT compatible documentation
32348c2ecf20Sopenharmony_ci		if (defined $root &&
32358c2ecf20Sopenharmony_ci			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
32368c2ecf20Sopenharmony_ci			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
32378c2ecf20Sopenharmony_ci
32388c2ecf20Sopenharmony_ci			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
32398c2ecf20Sopenharmony_ci
32408c2ecf20Sopenharmony_ci			my $dt_path = $root . "/Documentation/devicetree/bindings/";
32418c2ecf20Sopenharmony_ci			my $vp_file = $dt_path . "vendor-prefixes.yaml";
32428c2ecf20Sopenharmony_ci
32438c2ecf20Sopenharmony_ci			foreach my $compat (@compats) {
32448c2ecf20Sopenharmony_ci				my $compat2 = $compat;
32458c2ecf20Sopenharmony_ci				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
32468c2ecf20Sopenharmony_ci				my $compat3 = $compat;
32478c2ecf20Sopenharmony_ci				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
32488c2ecf20Sopenharmony_ci				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
32498c2ecf20Sopenharmony_ci				if ( $? >> 8 ) {
32508c2ecf20Sopenharmony_ci					WARN("UNDOCUMENTED_DT_STRING",
32518c2ecf20Sopenharmony_ci					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
32528c2ecf20Sopenharmony_ci				}
32538c2ecf20Sopenharmony_ci
32548c2ecf20Sopenharmony_ci				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
32558c2ecf20Sopenharmony_ci				my $vendor = $1;
32568c2ecf20Sopenharmony_ci				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
32578c2ecf20Sopenharmony_ci				if ( $? >> 8 ) {
32588c2ecf20Sopenharmony_ci					WARN("UNDOCUMENTED_DT_STRING",
32598c2ecf20Sopenharmony_ci					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
32608c2ecf20Sopenharmony_ci				}
32618c2ecf20Sopenharmony_ci			}
32628c2ecf20Sopenharmony_ci		}
32638c2ecf20Sopenharmony_ci
32648c2ecf20Sopenharmony_ci# check for using SPDX license tag at beginning of files
32658c2ecf20Sopenharmony_ci		if ($realline == $checklicenseline) {
32668c2ecf20Sopenharmony_ci			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
32678c2ecf20Sopenharmony_ci				$checklicenseline = 2;
32688c2ecf20Sopenharmony_ci			} elsif ($rawline =~ /^\+/) {
32698c2ecf20Sopenharmony_ci				my $comment = "";
32708c2ecf20Sopenharmony_ci				if ($realfile =~ /\.(h|s|S)$/) {
32718c2ecf20Sopenharmony_ci					$comment = '/*';
32728c2ecf20Sopenharmony_ci				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
32738c2ecf20Sopenharmony_ci					$comment = '//';
32748c2ecf20Sopenharmony_ci				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
32758c2ecf20Sopenharmony_ci					$comment = '#';
32768c2ecf20Sopenharmony_ci				} elsif ($realfile =~ /\.rst$/) {
32778c2ecf20Sopenharmony_ci					$comment = '..';
32788c2ecf20Sopenharmony_ci				}
32798c2ecf20Sopenharmony_ci
32808c2ecf20Sopenharmony_ci# check SPDX comment style for .[chsS] files
32818c2ecf20Sopenharmony_ci				if ($realfile =~ /\.[chsS]$/ &&
32828c2ecf20Sopenharmony_ci				    $rawline =~ /SPDX-License-Identifier:/ &&
32838c2ecf20Sopenharmony_ci				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
32848c2ecf20Sopenharmony_ci					WARN("SPDX_LICENSE_TAG",
32858c2ecf20Sopenharmony_ci					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
32868c2ecf20Sopenharmony_ci				}
32878c2ecf20Sopenharmony_ci
32888c2ecf20Sopenharmony_ci				if ($comment !~ /^$/ &&
32898c2ecf20Sopenharmony_ci				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
32908c2ecf20Sopenharmony_ci					WARN("SPDX_LICENSE_TAG",
32918c2ecf20Sopenharmony_ci					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
32928c2ecf20Sopenharmony_ci				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
32938c2ecf20Sopenharmony_ci					my $spdx_license = $1;
32948c2ecf20Sopenharmony_ci					if (!is_SPDX_License_valid($spdx_license)) {
32958c2ecf20Sopenharmony_ci						WARN("SPDX_LICENSE_TAG",
32968c2ecf20Sopenharmony_ci						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
32978c2ecf20Sopenharmony_ci					}
32988c2ecf20Sopenharmony_ci					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
32998c2ecf20Sopenharmony_ci					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
33008c2ecf20Sopenharmony_ci						my $msg_level = \&WARN;
33018c2ecf20Sopenharmony_ci						$msg_level = \&CHK if ($file);
33028c2ecf20Sopenharmony_ci						if (&{$msg_level}("SPDX_LICENSE_TAG",
33038c2ecf20Sopenharmony_ci
33048c2ecf20Sopenharmony_ci								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
33058c2ecf20Sopenharmony_ci						    $fix) {
33068c2ecf20Sopenharmony_ci							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
33078c2ecf20Sopenharmony_ci						}
33088c2ecf20Sopenharmony_ci					}
33098c2ecf20Sopenharmony_ci				}
33108c2ecf20Sopenharmony_ci			}
33118c2ecf20Sopenharmony_ci		}
33128c2ecf20Sopenharmony_ci
33138c2ecf20Sopenharmony_ci# check for embedded filenames
33148c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+.*\Q$realfile\E/) {
33158c2ecf20Sopenharmony_ci			WARN("EMBEDDED_FILENAME",
33168c2ecf20Sopenharmony_ci			     "It's generally not useful to have the filename in the file\n" . $herecurr);
33178c2ecf20Sopenharmony_ci		}
33188c2ecf20Sopenharmony_ci
33198c2ecf20Sopenharmony_ci# check we are in a valid source file if not then ignore this hunk
33208c2ecf20Sopenharmony_ci		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
33218c2ecf20Sopenharmony_ci
33228c2ecf20Sopenharmony_ci# check for using SPDX-License-Identifier on the wrong line number
33238c2ecf20Sopenharmony_ci		if ($realline != $checklicenseline &&
33248c2ecf20Sopenharmony_ci		    $rawline =~ /\bSPDX-License-Identifier:/ &&
33258c2ecf20Sopenharmony_ci		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
33268c2ecf20Sopenharmony_ci			WARN("SPDX_LICENSE_TAG",
33278c2ecf20Sopenharmony_ci			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
33288c2ecf20Sopenharmony_ci		}
33298c2ecf20Sopenharmony_ci
33308c2ecf20Sopenharmony_ci# line length limit (with some exclusions)
33318c2ecf20Sopenharmony_ci#
33328c2ecf20Sopenharmony_ci# There are a few types of lines that may extend beyond $max_line_length:
33338c2ecf20Sopenharmony_ci#	logging functions like pr_info that end in a string
33348c2ecf20Sopenharmony_ci#	lines with a single string
33358c2ecf20Sopenharmony_ci#	#defines that are a single string
33368c2ecf20Sopenharmony_ci#	lines with an RFC3986 like URL
33378c2ecf20Sopenharmony_ci#
33388c2ecf20Sopenharmony_ci# There are 3 different line length message types:
33398c2ecf20Sopenharmony_ci# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
33408c2ecf20Sopenharmony_ci# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
33418c2ecf20Sopenharmony_ci# LONG_LINE		all other lines longer than $max_line_length
33428c2ecf20Sopenharmony_ci#
33438c2ecf20Sopenharmony_ci# if LONG_LINE is ignored, the other 2 types are also ignored
33448c2ecf20Sopenharmony_ci#
33458c2ecf20Sopenharmony_ci
33468c2ecf20Sopenharmony_ci		if ($line =~ /^\+/ && $length > $max_line_length) {
33478c2ecf20Sopenharmony_ci			my $msg_type = "LONG_LINE";
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci			# Check the allowed long line types first
33508c2ecf20Sopenharmony_ci
33518c2ecf20Sopenharmony_ci			# logging functions that end in a string that starts
33528c2ecf20Sopenharmony_ci			# before $max_line_length
33538c2ecf20Sopenharmony_ci			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
33548c2ecf20Sopenharmony_ci			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
33558c2ecf20Sopenharmony_ci				$msg_type = "";
33568c2ecf20Sopenharmony_ci
33578c2ecf20Sopenharmony_ci			# lines with only strings (w/ possible termination)
33588c2ecf20Sopenharmony_ci			# #defines with only strings
33598c2ecf20Sopenharmony_ci			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
33608c2ecf20Sopenharmony_ci				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
33618c2ecf20Sopenharmony_ci				$msg_type = "";
33628c2ecf20Sopenharmony_ci
33638c2ecf20Sopenharmony_ci			# More special cases
33648c2ecf20Sopenharmony_ci			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
33658c2ecf20Sopenharmony_ci				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
33668c2ecf20Sopenharmony_ci				$msg_type = "";
33678c2ecf20Sopenharmony_ci
33688c2ecf20Sopenharmony_ci			# URL ($rawline is used in case the URL is in a comment)
33698c2ecf20Sopenharmony_ci			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
33708c2ecf20Sopenharmony_ci				$msg_type = "";
33718c2ecf20Sopenharmony_ci
33728c2ecf20Sopenharmony_ci			# Otherwise set the alternate message types
33738c2ecf20Sopenharmony_ci
33748c2ecf20Sopenharmony_ci			# a comment starts before $max_line_length
33758c2ecf20Sopenharmony_ci			} elsif ($line =~ /($;[\s$;]*)$/ &&
33768c2ecf20Sopenharmony_ci				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
33778c2ecf20Sopenharmony_ci				$msg_type = "LONG_LINE_COMMENT"
33788c2ecf20Sopenharmony_ci
33798c2ecf20Sopenharmony_ci			# a quoted string starts before $max_line_length
33808c2ecf20Sopenharmony_ci			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
33818c2ecf20Sopenharmony_ci				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
33828c2ecf20Sopenharmony_ci				$msg_type = "LONG_LINE_STRING"
33838c2ecf20Sopenharmony_ci			}
33848c2ecf20Sopenharmony_ci
33858c2ecf20Sopenharmony_ci			if ($msg_type ne "" &&
33868c2ecf20Sopenharmony_ci			    (show_type("LONG_LINE") || show_type($msg_type))) {
33878c2ecf20Sopenharmony_ci				my $msg_level = \&WARN;
33888c2ecf20Sopenharmony_ci				$msg_level = \&CHK if ($file);
33898c2ecf20Sopenharmony_ci				&{$msg_level}($msg_type,
33908c2ecf20Sopenharmony_ci					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
33918c2ecf20Sopenharmony_ci			}
33928c2ecf20Sopenharmony_ci		}
33938c2ecf20Sopenharmony_ci
33948c2ecf20Sopenharmony_ci# check for adding lines without a newline.
33958c2ecf20Sopenharmony_ci		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
33968c2ecf20Sopenharmony_ci			WARN("MISSING_EOF_NEWLINE",
33978c2ecf20Sopenharmony_ci			     "adding a line without newline at end of file\n" . $herecurr);
33988c2ecf20Sopenharmony_ci		}
33998c2ecf20Sopenharmony_ci
34008c2ecf20Sopenharmony_ci# check we are in a valid source file C or perl if not then ignore this hunk
34018c2ecf20Sopenharmony_ci		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
34028c2ecf20Sopenharmony_ci
34038c2ecf20Sopenharmony_ci# at the beginning of a line any tabs must come first and anything
34048c2ecf20Sopenharmony_ci# more than $tabsize must use tabs.
34058c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+\s* \t\s*\S/ ||
34068c2ecf20Sopenharmony_ci		    $rawline =~ /^\+\s*        \s*/) {
34078c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34088c2ecf20Sopenharmony_ci			$rpt_cleaners = 1;
34098c2ecf20Sopenharmony_ci			if (ERROR("CODE_INDENT",
34108c2ecf20Sopenharmony_ci				  "code indent should use tabs where possible\n" . $herevet) &&
34118c2ecf20Sopenharmony_ci			    $fix) {
34128c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
34138c2ecf20Sopenharmony_ci			}
34148c2ecf20Sopenharmony_ci		}
34158c2ecf20Sopenharmony_ci
34168c2ecf20Sopenharmony_ci# check for space before tabs.
34178c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
34188c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34198c2ecf20Sopenharmony_ci			if (WARN("SPACE_BEFORE_TAB",
34208c2ecf20Sopenharmony_ci				"please, no space before tabs\n" . $herevet) &&
34218c2ecf20Sopenharmony_ci			    $fix) {
34228c2ecf20Sopenharmony_ci				while ($fixed[$fixlinenr] =~
34238c2ecf20Sopenharmony_ci					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
34248c2ecf20Sopenharmony_ci				while ($fixed[$fixlinenr] =~
34258c2ecf20Sopenharmony_ci					   s/(^\+.*) +\t/$1\t/) {}
34268c2ecf20Sopenharmony_ci			}
34278c2ecf20Sopenharmony_ci		}
34288c2ecf20Sopenharmony_ci
34298c2ecf20Sopenharmony_ci# check for assignments on the start of a line
34308c2ecf20Sopenharmony_ci		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
34318c2ecf20Sopenharmony_ci			CHK("ASSIGNMENT_CONTINUATIONS",
34328c2ecf20Sopenharmony_ci			    "Assignment operator '$1' should be on the previous line\n" . $hereprev);
34338c2ecf20Sopenharmony_ci		}
34348c2ecf20Sopenharmony_ci
34358c2ecf20Sopenharmony_ci# check for && or || at the start of a line
34368c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
34378c2ecf20Sopenharmony_ci			CHK("LOGICAL_CONTINUATIONS",
34388c2ecf20Sopenharmony_ci			    "Logical continuations should be on the previous line\n" . $hereprev);
34398c2ecf20Sopenharmony_ci		}
34408c2ecf20Sopenharmony_ci
34418c2ecf20Sopenharmony_ci# check indentation starts on a tab stop
34428c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
34438c2ecf20Sopenharmony_ci		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
34448c2ecf20Sopenharmony_ci			my $indent = length($1);
34458c2ecf20Sopenharmony_ci			if ($indent % $tabsize) {
34468c2ecf20Sopenharmony_ci				if (WARN("TABSTOP",
34478c2ecf20Sopenharmony_ci					 "Statements should start on a tabstop\n" . $herecurr) &&
34488c2ecf20Sopenharmony_ci				    $fix) {
34498c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
34508c2ecf20Sopenharmony_ci				}
34518c2ecf20Sopenharmony_ci			}
34528c2ecf20Sopenharmony_ci		}
34538c2ecf20Sopenharmony_ci
34548c2ecf20Sopenharmony_ci# check multi-line statement indentation matches previous line
34558c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
34568c2ecf20Sopenharmony_ci		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
34578c2ecf20Sopenharmony_ci			$prevline =~ /^\+(\t*)(.*)$/;
34588c2ecf20Sopenharmony_ci			my $oldindent = $1;
34598c2ecf20Sopenharmony_ci			my $rest = $2;
34608c2ecf20Sopenharmony_ci
34618c2ecf20Sopenharmony_ci			my $pos = pos_last_openparen($rest);
34628c2ecf20Sopenharmony_ci			if ($pos >= 0) {
34638c2ecf20Sopenharmony_ci				$line =~ /^(\+| )([ \t]*)/;
34648c2ecf20Sopenharmony_ci				my $newindent = $2;
34658c2ecf20Sopenharmony_ci
34668c2ecf20Sopenharmony_ci				my $goodtabindent = $oldindent .
34678c2ecf20Sopenharmony_ci					"\t" x ($pos / $tabsize) .
34688c2ecf20Sopenharmony_ci					" "  x ($pos % $tabsize);
34698c2ecf20Sopenharmony_ci				my $goodspaceindent = $oldindent . " "  x $pos;
34708c2ecf20Sopenharmony_ci
34718c2ecf20Sopenharmony_ci				if ($newindent ne $goodtabindent &&
34728c2ecf20Sopenharmony_ci				    $newindent ne $goodspaceindent) {
34738c2ecf20Sopenharmony_ci
34748c2ecf20Sopenharmony_ci					if (CHK("PARENTHESIS_ALIGNMENT",
34758c2ecf20Sopenharmony_ci						"Alignment should match open parenthesis\n" . $hereprev) &&
34768c2ecf20Sopenharmony_ci					    $fix && $line =~ /^\+/) {
34778c2ecf20Sopenharmony_ci						$fixed[$fixlinenr] =~
34788c2ecf20Sopenharmony_ci						    s/^\+[ \t]*/\+$goodtabindent/;
34798c2ecf20Sopenharmony_ci					}
34808c2ecf20Sopenharmony_ci				}
34818c2ecf20Sopenharmony_ci			}
34828c2ecf20Sopenharmony_ci		}
34838c2ecf20Sopenharmony_ci
34848c2ecf20Sopenharmony_ci# check for space after cast like "(int) foo" or "(struct foo) bar"
34858c2ecf20Sopenharmony_ci# avoid checking a few false positives:
34868c2ecf20Sopenharmony_ci#   "sizeof(<type>)" or "__alignof__(<type>)"
34878c2ecf20Sopenharmony_ci#   function pointer declarations like "(*foo)(int) = bar;"
34888c2ecf20Sopenharmony_ci#   structure definitions like "(struct foo) { 0 };"
34898c2ecf20Sopenharmony_ci#   multiline macros that define functions
34908c2ecf20Sopenharmony_ci#   known attributes or the __attribute__ keyword
34918c2ecf20Sopenharmony_ci		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
34928c2ecf20Sopenharmony_ci		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
34938c2ecf20Sopenharmony_ci			if (CHK("SPACING",
34948c2ecf20Sopenharmony_ci				"No space is necessary after a cast\n" . $herecurr) &&
34958c2ecf20Sopenharmony_ci			    $fix) {
34968c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
34978c2ecf20Sopenharmony_ci				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
34988c2ecf20Sopenharmony_ci			}
34998c2ecf20Sopenharmony_ci		}
35008c2ecf20Sopenharmony_ci
35018c2ecf20Sopenharmony_ci# Block comment styles
35028c2ecf20Sopenharmony_ci# Networking with an initial /*
35038c2ecf20Sopenharmony_ci		if ($realfile =~ m@^(drivers/net/|net/)@ &&
35048c2ecf20Sopenharmony_ci		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
35058c2ecf20Sopenharmony_ci		    $rawline =~ /^\+[ \t]*\*/ &&
35068c2ecf20Sopenharmony_ci		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
35078c2ecf20Sopenharmony_ci			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
35088c2ecf20Sopenharmony_ci			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
35098c2ecf20Sopenharmony_ci		}
35108c2ecf20Sopenharmony_ci
35118c2ecf20Sopenharmony_ci# Block comments use * on subsequent lines
35128c2ecf20Sopenharmony_ci		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
35138c2ecf20Sopenharmony_ci		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
35148c2ecf20Sopenharmony_ci		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
35158c2ecf20Sopenharmony_ci		    $rawline =~ /^\+/ &&			#line is new
35168c2ecf20Sopenharmony_ci		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
35178c2ecf20Sopenharmony_ci			WARN("BLOCK_COMMENT_STYLE",
35188c2ecf20Sopenharmony_ci			     "Block comments use * on subsequent lines\n" . $hereprev);
35198c2ecf20Sopenharmony_ci		}
35208c2ecf20Sopenharmony_ci
35218c2ecf20Sopenharmony_ci# Block comments use */ on trailing lines
35228c2ecf20Sopenharmony_ci		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
35238c2ecf20Sopenharmony_ci		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
35248c2ecf20Sopenharmony_ci		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
35258c2ecf20Sopenharmony_ci		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
35268c2ecf20Sopenharmony_ci			WARN("BLOCK_COMMENT_STYLE",
35278c2ecf20Sopenharmony_ci			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
35288c2ecf20Sopenharmony_ci		}
35298c2ecf20Sopenharmony_ci
35308c2ecf20Sopenharmony_ci# Block comment * alignment
35318c2ecf20Sopenharmony_ci		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
35328c2ecf20Sopenharmony_ci		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
35338c2ecf20Sopenharmony_ci		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
35348c2ecf20Sopenharmony_ci		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
35358c2ecf20Sopenharmony_ci		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
35368c2ecf20Sopenharmony_ci		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
35378c2ecf20Sopenharmony_ci			my $oldindent;
35388c2ecf20Sopenharmony_ci			$prevrawline =~ m@^\+([ \t]*/?)\*@;
35398c2ecf20Sopenharmony_ci			if (defined($1)) {
35408c2ecf20Sopenharmony_ci				$oldindent = expand_tabs($1);
35418c2ecf20Sopenharmony_ci			} else {
35428c2ecf20Sopenharmony_ci				$prevrawline =~ m@^\+(.*/?)\*@;
35438c2ecf20Sopenharmony_ci				$oldindent = expand_tabs($1);
35448c2ecf20Sopenharmony_ci			}
35458c2ecf20Sopenharmony_ci			$rawline =~ m@^\+([ \t]*)\*@;
35468c2ecf20Sopenharmony_ci			my $newindent = $1;
35478c2ecf20Sopenharmony_ci			$newindent = expand_tabs($newindent);
35488c2ecf20Sopenharmony_ci			if (length($oldindent) ne length($newindent)) {
35498c2ecf20Sopenharmony_ci				WARN("BLOCK_COMMENT_STYLE",
35508c2ecf20Sopenharmony_ci				     "Block comments should align the * on each line\n" . $hereprev);
35518c2ecf20Sopenharmony_ci			}
35528c2ecf20Sopenharmony_ci		}
35538c2ecf20Sopenharmony_ci
35548c2ecf20Sopenharmony_ci# check for missing blank lines after struct/union declarations
35558c2ecf20Sopenharmony_ci# with exceptions for various attributes and macros
35568c2ecf20Sopenharmony_ci		if ($prevline =~ /^[\+ ]};?\s*$/ &&
35578c2ecf20Sopenharmony_ci		    $line =~ /^\+/ &&
35588c2ecf20Sopenharmony_ci		    !($line =~ /^\+\s*$/ ||
35598c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
35608c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*MODULE_/i ||
35618c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
35628c2ecf20Sopenharmony_ci		      $line =~ /^\+[a-z_]*init/ ||
35638c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
35648c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*DECLARE/ ||
35658c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
35668c2ecf20Sopenharmony_ci		      $line =~ /^\+\s*__setup/)) {
35678c2ecf20Sopenharmony_ci			if (CHK("LINE_SPACING",
35688c2ecf20Sopenharmony_ci				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
35698c2ecf20Sopenharmony_ci			    $fix) {
35708c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, "\+");
35718c2ecf20Sopenharmony_ci			}
35728c2ecf20Sopenharmony_ci		}
35738c2ecf20Sopenharmony_ci
35748c2ecf20Sopenharmony_ci# check for multiple consecutive blank lines
35758c2ecf20Sopenharmony_ci		if ($prevline =~ /^[\+ ]\s*$/ &&
35768c2ecf20Sopenharmony_ci		    $line =~ /^\+\s*$/ &&
35778c2ecf20Sopenharmony_ci		    $last_blank_line != ($linenr - 1)) {
35788c2ecf20Sopenharmony_ci			if (CHK("LINE_SPACING",
35798c2ecf20Sopenharmony_ci				"Please don't use multiple blank lines\n" . $hereprev) &&
35808c2ecf20Sopenharmony_ci			    $fix) {
35818c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
35828c2ecf20Sopenharmony_ci			}
35838c2ecf20Sopenharmony_ci
35848c2ecf20Sopenharmony_ci			$last_blank_line = $linenr;
35858c2ecf20Sopenharmony_ci		}
35868c2ecf20Sopenharmony_ci
35878c2ecf20Sopenharmony_ci# check for missing blank lines after declarations
35888c2ecf20Sopenharmony_ci		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
35898c2ecf20Sopenharmony_ci			# actual declarations
35908c2ecf20Sopenharmony_ci		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
35918c2ecf20Sopenharmony_ci			# function pointer declarations
35928c2ecf20Sopenharmony_ci		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
35938c2ecf20Sopenharmony_ci			# foo bar; where foo is some local typedef or #define
35948c2ecf20Sopenharmony_ci		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
35958c2ecf20Sopenharmony_ci			# known declaration macros
35968c2ecf20Sopenharmony_ci		     $prevline =~ /^\+\s+$declaration_macros/) &&
35978c2ecf20Sopenharmony_ci			# for "else if" which can look like "$Ident $Ident"
35988c2ecf20Sopenharmony_ci		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
35998c2ecf20Sopenharmony_ci			# other possible extensions of declaration lines
36008c2ecf20Sopenharmony_ci		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
36018c2ecf20Sopenharmony_ci			# not starting a section or a macro "\" extended line
36028c2ecf20Sopenharmony_ci		      $prevline =~ /(?:\{\s*|\\)$/) &&
36038c2ecf20Sopenharmony_ci			# looks like a declaration
36048c2ecf20Sopenharmony_ci		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
36058c2ecf20Sopenharmony_ci			# function pointer declarations
36068c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
36078c2ecf20Sopenharmony_ci			# foo bar; where foo is some local typedef or #define
36088c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
36098c2ecf20Sopenharmony_ci			# known declaration macros
36108c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+$declaration_macros/ ||
36118c2ecf20Sopenharmony_ci			# start of struct or union or enum
36128c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
36138c2ecf20Sopenharmony_ci			# start or end of block or continuation of declaration
36148c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
36158c2ecf20Sopenharmony_ci			# bitfield continuation
36168c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
36178c2ecf20Sopenharmony_ci			# other possible extensions of declaration lines
36188c2ecf20Sopenharmony_ci		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
36198c2ecf20Sopenharmony_ci			# indentation of previous and current line are the same
36208c2ecf20Sopenharmony_ci		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
36218c2ecf20Sopenharmony_ci			if (WARN("LINE_SPACING",
36228c2ecf20Sopenharmony_ci				 "Missing a blank line after declarations\n" . $hereprev) &&
36238c2ecf20Sopenharmony_ci			    $fix) {
36248c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, "\+");
36258c2ecf20Sopenharmony_ci			}
36268c2ecf20Sopenharmony_ci		}
36278c2ecf20Sopenharmony_ci
36288c2ecf20Sopenharmony_ci# check for spaces at the beginning of a line.
36298c2ecf20Sopenharmony_ci# Exceptions:
36308c2ecf20Sopenharmony_ci#  1) within comments
36318c2ecf20Sopenharmony_ci#  2) indented preprocessor commands
36328c2ecf20Sopenharmony_ci#  3) hanging labels
36338c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
36348c2ecf20Sopenharmony_ci			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
36358c2ecf20Sopenharmony_ci			if (WARN("LEADING_SPACE",
36368c2ecf20Sopenharmony_ci				 "please, no spaces at the start of a line\n" . $herevet) &&
36378c2ecf20Sopenharmony_ci			    $fix) {
36388c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
36398c2ecf20Sopenharmony_ci			}
36408c2ecf20Sopenharmony_ci		}
36418c2ecf20Sopenharmony_ci
36428c2ecf20Sopenharmony_ci# check we are in a valid C source file if not then ignore this hunk
36438c2ecf20Sopenharmony_ci		next if ($realfile !~ /\.(h|c)$/);
36448c2ecf20Sopenharmony_ci
36458c2ecf20Sopenharmony_ci# check for unusual line ending [ or (
36468c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*([\[\(])\s*$/) {
36478c2ecf20Sopenharmony_ci			CHK("OPEN_ENDED_LINE",
36488c2ecf20Sopenharmony_ci			    "Lines should not end with a '$1'\n" . $herecurr);
36498c2ecf20Sopenharmony_ci		}
36508c2ecf20Sopenharmony_ci
36518c2ecf20Sopenharmony_ci# check if this appears to be the start function declaration, save the name
36528c2ecf20Sopenharmony_ci		if ($sline =~ /^\+\{\s*$/ &&
36538c2ecf20Sopenharmony_ci		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
36548c2ecf20Sopenharmony_ci			$context_function = $1;
36558c2ecf20Sopenharmony_ci		}
36568c2ecf20Sopenharmony_ci
36578c2ecf20Sopenharmony_ci# check if this appears to be the end of function declaration
36588c2ecf20Sopenharmony_ci		if ($sline =~ /^\+\}\s*$/) {
36598c2ecf20Sopenharmony_ci			undef $context_function;
36608c2ecf20Sopenharmony_ci		}
36618c2ecf20Sopenharmony_ci
36628c2ecf20Sopenharmony_ci# check indentation of any line with a bare else
36638c2ecf20Sopenharmony_ci# (but not if it is a multiple line "if (foo) return bar; else return baz;")
36648c2ecf20Sopenharmony_ci# if the previous line is a break or return and is indented 1 tab more...
36658c2ecf20Sopenharmony_ci		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
36668c2ecf20Sopenharmony_ci			my $tabs = length($1) + 1;
36678c2ecf20Sopenharmony_ci			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
36688c2ecf20Sopenharmony_ci			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
36698c2ecf20Sopenharmony_ci			     defined $lines[$linenr] &&
36708c2ecf20Sopenharmony_ci			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
36718c2ecf20Sopenharmony_ci				WARN("UNNECESSARY_ELSE",
36728c2ecf20Sopenharmony_ci				     "else is not generally useful after a break or return\n" . $hereprev);
36738c2ecf20Sopenharmony_ci			}
36748c2ecf20Sopenharmony_ci		}
36758c2ecf20Sopenharmony_ci
36768c2ecf20Sopenharmony_ci# check indentation of a line with a break;
36778c2ecf20Sopenharmony_ci# if the previous line is a goto or return and is indented the same # of tabs
36788c2ecf20Sopenharmony_ci		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
36798c2ecf20Sopenharmony_ci			my $tabs = $1;
36808c2ecf20Sopenharmony_ci			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
36818c2ecf20Sopenharmony_ci				WARN("UNNECESSARY_BREAK",
36828c2ecf20Sopenharmony_ci				     "break is not useful after a goto or return\n" . $hereprev);
36838c2ecf20Sopenharmony_ci			}
36848c2ecf20Sopenharmony_ci		}
36858c2ecf20Sopenharmony_ci
36868c2ecf20Sopenharmony_ci# check for RCS/CVS revision markers
36878c2ecf20Sopenharmony_ci		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
36888c2ecf20Sopenharmony_ci			WARN("CVS_KEYWORD",
36898c2ecf20Sopenharmony_ci			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
36908c2ecf20Sopenharmony_ci		}
36918c2ecf20Sopenharmony_ci
36928c2ecf20Sopenharmony_ci# check for old HOTPLUG __dev<foo> section markings
36938c2ecf20Sopenharmony_ci		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
36948c2ecf20Sopenharmony_ci			WARN("HOTPLUG_SECTION",
36958c2ecf20Sopenharmony_ci			     "Using $1 is unnecessary\n" . $herecurr);
36968c2ecf20Sopenharmony_ci		}
36978c2ecf20Sopenharmony_ci
36988c2ecf20Sopenharmony_ci# Check for potential 'bare' types
36998c2ecf20Sopenharmony_ci		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
37008c2ecf20Sopenharmony_ci		    $realline_next);
37018c2ecf20Sopenharmony_ci#print "LINE<$line>\n";
37028c2ecf20Sopenharmony_ci		if ($linenr > $suppress_statement &&
37038c2ecf20Sopenharmony_ci		    $realcnt && $sline =~ /.\s*\S/) {
37048c2ecf20Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
37058c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
37068c2ecf20Sopenharmony_ci			$stat =~ s/\n./\n /g;
37078c2ecf20Sopenharmony_ci			$cond =~ s/\n./\n /g;
37088c2ecf20Sopenharmony_ci
37098c2ecf20Sopenharmony_ci#print "linenr<$linenr> <$stat>\n";
37108c2ecf20Sopenharmony_ci			# If this statement has no statement boundaries within
37118c2ecf20Sopenharmony_ci			# it there is no point in retrying a statement scan
37128c2ecf20Sopenharmony_ci			# until we hit end of it.
37138c2ecf20Sopenharmony_ci			my $frag = $stat; $frag =~ s/;+\s*$//;
37148c2ecf20Sopenharmony_ci			if ($frag !~ /(?:{|;)/) {
37158c2ecf20Sopenharmony_ci#print "skip<$line_nr_next>\n";
37168c2ecf20Sopenharmony_ci				$suppress_statement = $line_nr_next;
37178c2ecf20Sopenharmony_ci			}
37188c2ecf20Sopenharmony_ci
37198c2ecf20Sopenharmony_ci			# Find the real next line.
37208c2ecf20Sopenharmony_ci			$realline_next = $line_nr_next;
37218c2ecf20Sopenharmony_ci			if (defined $realline_next &&
37228c2ecf20Sopenharmony_ci			    (!defined $lines[$realline_next - 1] ||
37238c2ecf20Sopenharmony_ci			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
37248c2ecf20Sopenharmony_ci				$realline_next++;
37258c2ecf20Sopenharmony_ci			}
37268c2ecf20Sopenharmony_ci
37278c2ecf20Sopenharmony_ci			my $s = $stat;
37288c2ecf20Sopenharmony_ci			$s =~ s/{.*$//s;
37298c2ecf20Sopenharmony_ci
37308c2ecf20Sopenharmony_ci			# Ignore goto labels.
37318c2ecf20Sopenharmony_ci			if ($s =~ /$Ident:\*$/s) {
37328c2ecf20Sopenharmony_ci
37338c2ecf20Sopenharmony_ci			# Ignore functions being called
37348c2ecf20Sopenharmony_ci			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
37358c2ecf20Sopenharmony_ci
37368c2ecf20Sopenharmony_ci			} elsif ($s =~ /^.\s*else\b/s) {
37378c2ecf20Sopenharmony_ci
37388c2ecf20Sopenharmony_ci			# declarations always start with types
37398c2ecf20Sopenharmony_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) {
37408c2ecf20Sopenharmony_ci				my $type = $1;
37418c2ecf20Sopenharmony_ci				$type =~ s/\s+/ /g;
37428c2ecf20Sopenharmony_ci				possible($type, "A:" . $s);
37438c2ecf20Sopenharmony_ci
37448c2ecf20Sopenharmony_ci			# definitions in global scope can only start with types
37458c2ecf20Sopenharmony_ci			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
37468c2ecf20Sopenharmony_ci				possible($1, "B:" . $s);
37478c2ecf20Sopenharmony_ci			}
37488c2ecf20Sopenharmony_ci
37498c2ecf20Sopenharmony_ci			# any (foo ... *) is a pointer cast, and foo is a type
37508c2ecf20Sopenharmony_ci			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
37518c2ecf20Sopenharmony_ci				possible($1, "C:" . $s);
37528c2ecf20Sopenharmony_ci			}
37538c2ecf20Sopenharmony_ci
37548c2ecf20Sopenharmony_ci			# Check for any sort of function declaration.
37558c2ecf20Sopenharmony_ci			# int foo(something bar, other baz);
37568c2ecf20Sopenharmony_ci			# void (*store_gdt)(x86_descr_ptr *);
37578c2ecf20Sopenharmony_ci			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
37588c2ecf20Sopenharmony_ci				my ($name_len) = length($1);
37598c2ecf20Sopenharmony_ci
37608c2ecf20Sopenharmony_ci				my $ctx = $s;
37618c2ecf20Sopenharmony_ci				substr($ctx, 0, $name_len + 1, '');
37628c2ecf20Sopenharmony_ci				$ctx =~ s/\)[^\)]*$//;
37638c2ecf20Sopenharmony_ci
37648c2ecf20Sopenharmony_ci				for my $arg (split(/\s*,\s*/, $ctx)) {
37658c2ecf20Sopenharmony_ci					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
37668c2ecf20Sopenharmony_ci
37678c2ecf20Sopenharmony_ci						possible($1, "D:" . $s);
37688c2ecf20Sopenharmony_ci					}
37698c2ecf20Sopenharmony_ci				}
37708c2ecf20Sopenharmony_ci			}
37718c2ecf20Sopenharmony_ci
37728c2ecf20Sopenharmony_ci		}
37738c2ecf20Sopenharmony_ci
37748c2ecf20Sopenharmony_ci#
37758c2ecf20Sopenharmony_ci# Checks which may be anchored in the context.
37768c2ecf20Sopenharmony_ci#
37778c2ecf20Sopenharmony_ci
37788c2ecf20Sopenharmony_ci# Check for switch () and associated case and default
37798c2ecf20Sopenharmony_ci# statements should be at the same indent.
37808c2ecf20Sopenharmony_ci		if ($line=~/\bswitch\s*\(.*\)/) {
37818c2ecf20Sopenharmony_ci			my $err = '';
37828c2ecf20Sopenharmony_ci			my $sep = '';
37838c2ecf20Sopenharmony_ci			my @ctx = ctx_block_outer($linenr, $realcnt);
37848c2ecf20Sopenharmony_ci			shift(@ctx);
37858c2ecf20Sopenharmony_ci			for my $ctx (@ctx) {
37868c2ecf20Sopenharmony_ci				my ($clen, $cindent) = line_stats($ctx);
37878c2ecf20Sopenharmony_ci				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
37888c2ecf20Sopenharmony_ci							$indent != $cindent) {
37898c2ecf20Sopenharmony_ci					$err .= "$sep$ctx\n";
37908c2ecf20Sopenharmony_ci					$sep = '';
37918c2ecf20Sopenharmony_ci				} else {
37928c2ecf20Sopenharmony_ci					$sep = "[...]\n";
37938c2ecf20Sopenharmony_ci				}
37948c2ecf20Sopenharmony_ci			}
37958c2ecf20Sopenharmony_ci			if ($err ne '') {
37968c2ecf20Sopenharmony_ci				ERROR("SWITCH_CASE_INDENT_LEVEL",
37978c2ecf20Sopenharmony_ci				      "switch and case should be at the same indent\n$hereline$err");
37988c2ecf20Sopenharmony_ci			}
37998c2ecf20Sopenharmony_ci		}
38008c2ecf20Sopenharmony_ci
38018c2ecf20Sopenharmony_ci# if/while/etc brace do not go on next line, unless defining a do while loop,
38028c2ecf20Sopenharmony_ci# or if that brace on the next line is for something else
38038c2ecf20Sopenharmony_ci		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
38048c2ecf20Sopenharmony_ci			my $pre_ctx = "$1$2";
38058c2ecf20Sopenharmony_ci
38068c2ecf20Sopenharmony_ci			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
38078c2ecf20Sopenharmony_ci
38088c2ecf20Sopenharmony_ci			if ($line =~ /^\+\t{6,}/) {
38098c2ecf20Sopenharmony_ci				WARN("DEEP_INDENTATION",
38108c2ecf20Sopenharmony_ci				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
38118c2ecf20Sopenharmony_ci			}
38128c2ecf20Sopenharmony_ci
38138c2ecf20Sopenharmony_ci			my $ctx_cnt = $realcnt - $#ctx - 1;
38148c2ecf20Sopenharmony_ci			my $ctx = join("\n", @ctx);
38158c2ecf20Sopenharmony_ci
38168c2ecf20Sopenharmony_ci			my $ctx_ln = $linenr;
38178c2ecf20Sopenharmony_ci			my $ctx_skip = $realcnt;
38188c2ecf20Sopenharmony_ci
38198c2ecf20Sopenharmony_ci			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
38208c2ecf20Sopenharmony_ci					defined $lines[$ctx_ln - 1] &&
38218c2ecf20Sopenharmony_ci					$lines[$ctx_ln - 1] =~ /^-/)) {
38228c2ecf20Sopenharmony_ci				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
38238c2ecf20Sopenharmony_ci				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
38248c2ecf20Sopenharmony_ci				$ctx_ln++;
38258c2ecf20Sopenharmony_ci			}
38268c2ecf20Sopenharmony_ci
38278c2ecf20Sopenharmony_ci			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
38288c2ecf20Sopenharmony_ci			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
38298c2ecf20Sopenharmony_ci
38308c2ecf20Sopenharmony_ci			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
38318c2ecf20Sopenharmony_ci				ERROR("OPEN_BRACE",
38328c2ecf20Sopenharmony_ci				      "that open brace { should be on the previous line\n" .
38338c2ecf20Sopenharmony_ci					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
38348c2ecf20Sopenharmony_ci			}
38358c2ecf20Sopenharmony_ci			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
38368c2ecf20Sopenharmony_ci			    $ctx =~ /\)\s*\;\s*$/ &&
38378c2ecf20Sopenharmony_ci			    defined $lines[$ctx_ln - 1])
38388c2ecf20Sopenharmony_ci			{
38398c2ecf20Sopenharmony_ci				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
38408c2ecf20Sopenharmony_ci				if ($nindent > $indent) {
38418c2ecf20Sopenharmony_ci					WARN("TRAILING_SEMICOLON",
38428c2ecf20Sopenharmony_ci					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
38438c2ecf20Sopenharmony_ci						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
38448c2ecf20Sopenharmony_ci				}
38458c2ecf20Sopenharmony_ci			}
38468c2ecf20Sopenharmony_ci		}
38478c2ecf20Sopenharmony_ci
38488c2ecf20Sopenharmony_ci# Check relative indent for conditionals and blocks.
38498c2ecf20Sopenharmony_ci		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
38508c2ecf20Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
38518c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0)
38528c2ecf20Sopenharmony_ci					if (!defined $stat);
38538c2ecf20Sopenharmony_ci			my ($s, $c) = ($stat, $cond);
38548c2ecf20Sopenharmony_ci
38558c2ecf20Sopenharmony_ci			substr($s, 0, length($c), '');
38568c2ecf20Sopenharmony_ci
38578c2ecf20Sopenharmony_ci			# remove inline comments
38588c2ecf20Sopenharmony_ci			$s =~ s/$;/ /g;
38598c2ecf20Sopenharmony_ci			$c =~ s/$;/ /g;
38608c2ecf20Sopenharmony_ci
38618c2ecf20Sopenharmony_ci			# Find out how long the conditional actually is.
38628c2ecf20Sopenharmony_ci			my @newlines = ($c =~ /\n/gs);
38638c2ecf20Sopenharmony_ci			my $cond_lines = 1 + $#newlines;
38648c2ecf20Sopenharmony_ci
38658c2ecf20Sopenharmony_ci			# Make sure we remove the line prefixes as we have
38668c2ecf20Sopenharmony_ci			# none on the first line, and are going to readd them
38678c2ecf20Sopenharmony_ci			# where necessary.
38688c2ecf20Sopenharmony_ci			$s =~ s/\n./\n/gs;
38698c2ecf20Sopenharmony_ci			while ($s =~ /\n\s+\\\n/) {
38708c2ecf20Sopenharmony_ci				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
38718c2ecf20Sopenharmony_ci			}
38728c2ecf20Sopenharmony_ci
38738c2ecf20Sopenharmony_ci			# We want to check the first line inside the block
38748c2ecf20Sopenharmony_ci			# starting at the end of the conditional, so remove:
38758c2ecf20Sopenharmony_ci			#  1) any blank line termination
38768c2ecf20Sopenharmony_ci			#  2) any opening brace { on end of the line
38778c2ecf20Sopenharmony_ci			#  3) any do (...) {
38788c2ecf20Sopenharmony_ci			my $continuation = 0;
38798c2ecf20Sopenharmony_ci			my $check = 0;
38808c2ecf20Sopenharmony_ci			$s =~ s/^.*\bdo\b//;
38818c2ecf20Sopenharmony_ci			$s =~ s/^\s*{//;
38828c2ecf20Sopenharmony_ci			if ($s =~ s/^\s*\\//) {
38838c2ecf20Sopenharmony_ci				$continuation = 1;
38848c2ecf20Sopenharmony_ci			}
38858c2ecf20Sopenharmony_ci			if ($s =~ s/^\s*?\n//) {
38868c2ecf20Sopenharmony_ci				$check = 1;
38878c2ecf20Sopenharmony_ci				$cond_lines++;
38888c2ecf20Sopenharmony_ci			}
38898c2ecf20Sopenharmony_ci
38908c2ecf20Sopenharmony_ci			# Also ignore a loop construct at the end of a
38918c2ecf20Sopenharmony_ci			# preprocessor statement.
38928c2ecf20Sopenharmony_ci			if (($prevline =~ /^.\s*#\s*define\s/ ||
38938c2ecf20Sopenharmony_ci			    $prevline =~ /\\\s*$/) && $continuation == 0) {
38948c2ecf20Sopenharmony_ci				$check = 0;
38958c2ecf20Sopenharmony_ci			}
38968c2ecf20Sopenharmony_ci
38978c2ecf20Sopenharmony_ci			my $cond_ptr = -1;
38988c2ecf20Sopenharmony_ci			$continuation = 0;
38998c2ecf20Sopenharmony_ci			while ($cond_ptr != $cond_lines) {
39008c2ecf20Sopenharmony_ci				$cond_ptr = $cond_lines;
39018c2ecf20Sopenharmony_ci
39028c2ecf20Sopenharmony_ci				# If we see an #else/#elif then the code
39038c2ecf20Sopenharmony_ci				# is not linear.
39048c2ecf20Sopenharmony_ci				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
39058c2ecf20Sopenharmony_ci					$check = 0;
39068c2ecf20Sopenharmony_ci				}
39078c2ecf20Sopenharmony_ci
39088c2ecf20Sopenharmony_ci				# Ignore:
39098c2ecf20Sopenharmony_ci				#  1) blank lines, they should be at 0,
39108c2ecf20Sopenharmony_ci				#  2) preprocessor lines, and
39118c2ecf20Sopenharmony_ci				#  3) labels.
39128c2ecf20Sopenharmony_ci				if ($continuation ||
39138c2ecf20Sopenharmony_ci				    $s =~ /^\s*?\n/ ||
39148c2ecf20Sopenharmony_ci				    $s =~ /^\s*#\s*?/ ||
39158c2ecf20Sopenharmony_ci				    $s =~ /^\s*$Ident\s*:/) {
39168c2ecf20Sopenharmony_ci					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
39178c2ecf20Sopenharmony_ci					if ($s =~ s/^.*?\n//) {
39188c2ecf20Sopenharmony_ci						$cond_lines++;
39198c2ecf20Sopenharmony_ci					}
39208c2ecf20Sopenharmony_ci				}
39218c2ecf20Sopenharmony_ci			}
39228c2ecf20Sopenharmony_ci
39238c2ecf20Sopenharmony_ci			my (undef, $sindent) = line_stats("+" . $s);
39248c2ecf20Sopenharmony_ci			my $stat_real = raw_line($linenr, $cond_lines);
39258c2ecf20Sopenharmony_ci
39268c2ecf20Sopenharmony_ci			# Check if either of these lines are modified, else
39278c2ecf20Sopenharmony_ci			# this is not this patch's fault.
39288c2ecf20Sopenharmony_ci			if (!defined($stat_real) ||
39298c2ecf20Sopenharmony_ci			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
39308c2ecf20Sopenharmony_ci				$check = 0;
39318c2ecf20Sopenharmony_ci			}
39328c2ecf20Sopenharmony_ci			if (defined($stat_real) && $cond_lines > 1) {
39338c2ecf20Sopenharmony_ci				$stat_real = "[...]\n$stat_real";
39348c2ecf20Sopenharmony_ci			}
39358c2ecf20Sopenharmony_ci
39368c2ecf20Sopenharmony_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";
39378c2ecf20Sopenharmony_ci
39388c2ecf20Sopenharmony_ci			if ($check && $s ne '' &&
39398c2ecf20Sopenharmony_ci			    (($sindent % $tabsize) != 0 ||
39408c2ecf20Sopenharmony_ci			     ($sindent < $indent) ||
39418c2ecf20Sopenharmony_ci			     ($sindent == $indent &&
39428c2ecf20Sopenharmony_ci			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
39438c2ecf20Sopenharmony_ci			     ($sindent > $indent + $tabsize))) {
39448c2ecf20Sopenharmony_ci				WARN("SUSPECT_CODE_INDENT",
39458c2ecf20Sopenharmony_ci				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
39468c2ecf20Sopenharmony_ci			}
39478c2ecf20Sopenharmony_ci		}
39488c2ecf20Sopenharmony_ci
39498c2ecf20Sopenharmony_ci		# Track the 'values' across context and added lines.
39508c2ecf20Sopenharmony_ci		my $opline = $line; $opline =~ s/^./ /;
39518c2ecf20Sopenharmony_ci		my ($curr_values, $curr_vars) =
39528c2ecf20Sopenharmony_ci				annotate_values($opline . "\n", $prev_values);
39538c2ecf20Sopenharmony_ci		$curr_values = $prev_values . $curr_values;
39548c2ecf20Sopenharmony_ci		if ($dbg_values) {
39558c2ecf20Sopenharmony_ci			my $outline = $opline; $outline =~ s/\t/ /g;
39568c2ecf20Sopenharmony_ci			print "$linenr > .$outline\n";
39578c2ecf20Sopenharmony_ci			print "$linenr > $curr_values\n";
39588c2ecf20Sopenharmony_ci			print "$linenr >  $curr_vars\n";
39598c2ecf20Sopenharmony_ci		}
39608c2ecf20Sopenharmony_ci		$prev_values = substr($curr_values, -1);
39618c2ecf20Sopenharmony_ci
39628c2ecf20Sopenharmony_ci#ignore lines not being added
39638c2ecf20Sopenharmony_ci		next if ($line =~ /^[^\+]/);
39648c2ecf20Sopenharmony_ci
39658c2ecf20Sopenharmony_ci# check for self assignments used to avoid compiler warnings
39668c2ecf20Sopenharmony_ci# e.g.:	int foo = foo, *bar = NULL;
39678c2ecf20Sopenharmony_ci#	struct foo bar = *(&(bar));
39688c2ecf20Sopenharmony_ci		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
39698c2ecf20Sopenharmony_ci			my $var = $1;
39708c2ecf20Sopenharmony_ci			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
39718c2ecf20Sopenharmony_ci				WARN("SELF_ASSIGNMENT",
39728c2ecf20Sopenharmony_ci				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
39738c2ecf20Sopenharmony_ci			}
39748c2ecf20Sopenharmony_ci		}
39758c2ecf20Sopenharmony_ci
39768c2ecf20Sopenharmony_ci# check for dereferences that span multiple lines
39778c2ecf20Sopenharmony_ci		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
39788c2ecf20Sopenharmony_ci		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
39798c2ecf20Sopenharmony_ci			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
39808c2ecf20Sopenharmony_ci			my $ref = $1;
39818c2ecf20Sopenharmony_ci			$line =~ /^.\s*($Lval)/;
39828c2ecf20Sopenharmony_ci			$ref .= $1;
39838c2ecf20Sopenharmony_ci			$ref =~ s/\s//g;
39848c2ecf20Sopenharmony_ci			WARN("MULTILINE_DEREFERENCE",
39858c2ecf20Sopenharmony_ci			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
39868c2ecf20Sopenharmony_ci		}
39878c2ecf20Sopenharmony_ci
39888c2ecf20Sopenharmony_ci# check for declarations of signed or unsigned without int
39898c2ecf20Sopenharmony_ci		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
39908c2ecf20Sopenharmony_ci			my $type = $1;
39918c2ecf20Sopenharmony_ci			my $var = $2;
39928c2ecf20Sopenharmony_ci			$var = "" if (!defined $var);
39938c2ecf20Sopenharmony_ci			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
39948c2ecf20Sopenharmony_ci				my $sign = $1;
39958c2ecf20Sopenharmony_ci				my $pointer = $2;
39968c2ecf20Sopenharmony_ci
39978c2ecf20Sopenharmony_ci				$pointer = "" if (!defined $pointer);
39988c2ecf20Sopenharmony_ci
39998c2ecf20Sopenharmony_ci				if (WARN("UNSPECIFIED_INT",
40008c2ecf20Sopenharmony_ci					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
40018c2ecf20Sopenharmony_ci				    $fix) {
40028c2ecf20Sopenharmony_ci					my $decl = trim($sign) . " int ";
40038c2ecf20Sopenharmony_ci					my $comp_pointer = $pointer;
40048c2ecf20Sopenharmony_ci					$comp_pointer =~ s/\s//g;
40058c2ecf20Sopenharmony_ci					$decl .= $comp_pointer;
40068c2ecf20Sopenharmony_ci					$decl = rtrim($decl) if ($var eq "");
40078c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
40088c2ecf20Sopenharmony_ci				}
40098c2ecf20Sopenharmony_ci			}
40108c2ecf20Sopenharmony_ci		}
40118c2ecf20Sopenharmony_ci
40128c2ecf20Sopenharmony_ci# TEST: allow direct testing of the type matcher.
40138c2ecf20Sopenharmony_ci		if ($dbg_type) {
40148c2ecf20Sopenharmony_ci			if ($line =~ /^.\s*$Declare\s*$/) {
40158c2ecf20Sopenharmony_ci				ERROR("TEST_TYPE",
40168c2ecf20Sopenharmony_ci				      "TEST: is type\n" . $herecurr);
40178c2ecf20Sopenharmony_ci			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
40188c2ecf20Sopenharmony_ci				ERROR("TEST_NOT_TYPE",
40198c2ecf20Sopenharmony_ci				      "TEST: is not type ($1 is)\n". $herecurr);
40208c2ecf20Sopenharmony_ci			}
40218c2ecf20Sopenharmony_ci			next;
40228c2ecf20Sopenharmony_ci		}
40238c2ecf20Sopenharmony_ci# TEST: allow direct testing of the attribute matcher.
40248c2ecf20Sopenharmony_ci		if ($dbg_attr) {
40258c2ecf20Sopenharmony_ci			if ($line =~ /^.\s*$Modifier\s*$/) {
40268c2ecf20Sopenharmony_ci				ERROR("TEST_ATTR",
40278c2ecf20Sopenharmony_ci				      "TEST: is attr\n" . $herecurr);
40288c2ecf20Sopenharmony_ci			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
40298c2ecf20Sopenharmony_ci				ERROR("TEST_NOT_ATTR",
40308c2ecf20Sopenharmony_ci				      "TEST: is not attr ($1 is)\n". $herecurr);
40318c2ecf20Sopenharmony_ci			}
40328c2ecf20Sopenharmony_ci			next;
40338c2ecf20Sopenharmony_ci		}
40348c2ecf20Sopenharmony_ci
40358c2ecf20Sopenharmony_ci# check for initialisation to aggregates open brace on the next line
40368c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*{/ &&
40378c2ecf20Sopenharmony_ci		    $prevline =~ /(?:^|[^=])=\s*$/) {
40388c2ecf20Sopenharmony_ci			if (ERROR("OPEN_BRACE",
40398c2ecf20Sopenharmony_ci				  "that open brace { should be on the previous line\n" . $hereprev) &&
40408c2ecf20Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
40418c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
40428c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
40438c2ecf20Sopenharmony_ci				my $fixedline = $prevrawline;
40448c2ecf20Sopenharmony_ci				$fixedline =~ s/\s*=\s*$/ = {/;
40458c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
40468c2ecf20Sopenharmony_ci				$fixedline = $line;
40478c2ecf20Sopenharmony_ci				$fixedline =~ s/^(.\s*)\{\s*/$1/;
40488c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
40498c2ecf20Sopenharmony_ci			}
40508c2ecf20Sopenharmony_ci		}
40518c2ecf20Sopenharmony_ci
40528c2ecf20Sopenharmony_ci#
40538c2ecf20Sopenharmony_ci# Checks which are anchored on the added line.
40548c2ecf20Sopenharmony_ci#
40558c2ecf20Sopenharmony_ci
40568c2ecf20Sopenharmony_ci# check for malformed paths in #include statements (uses RAW line)
40578c2ecf20Sopenharmony_ci		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
40588c2ecf20Sopenharmony_ci			my $path = $1;
40598c2ecf20Sopenharmony_ci			if ($path =~ m{//}) {
40608c2ecf20Sopenharmony_ci				ERROR("MALFORMED_INCLUDE",
40618c2ecf20Sopenharmony_ci				      "malformed #include filename\n" . $herecurr);
40628c2ecf20Sopenharmony_ci			}
40638c2ecf20Sopenharmony_ci			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
40648c2ecf20Sopenharmony_ci				ERROR("UAPI_INCLUDE",
40658c2ecf20Sopenharmony_ci				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
40668c2ecf20Sopenharmony_ci			}
40678c2ecf20Sopenharmony_ci		}
40688c2ecf20Sopenharmony_ci
40698c2ecf20Sopenharmony_ci# no C99 // comments
40708c2ecf20Sopenharmony_ci		if ($line =~ m{//}) {
40718c2ecf20Sopenharmony_ci			if (ERROR("C99_COMMENTS",
40728c2ecf20Sopenharmony_ci				  "do not use C99 // comments\n" . $herecurr) &&
40738c2ecf20Sopenharmony_ci			    $fix) {
40748c2ecf20Sopenharmony_ci				my $line = $fixed[$fixlinenr];
40758c2ecf20Sopenharmony_ci				if ($line =~ /\/\/(.*)$/) {
40768c2ecf20Sopenharmony_ci					my $comment = trim($1);
40778c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
40788c2ecf20Sopenharmony_ci				}
40798c2ecf20Sopenharmony_ci			}
40808c2ecf20Sopenharmony_ci		}
40818c2ecf20Sopenharmony_ci		# Remove C99 comments.
40828c2ecf20Sopenharmony_ci		$line =~ s@//.*@@;
40838c2ecf20Sopenharmony_ci		$opline =~ s@//.*@@;
40848c2ecf20Sopenharmony_ci
40858c2ecf20Sopenharmony_ci# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
40868c2ecf20Sopenharmony_ci# the whole statement.
40878c2ecf20Sopenharmony_ci#print "APW <$lines[$realline_next - 1]>\n";
40888c2ecf20Sopenharmony_ci		if (defined $realline_next &&
40898c2ecf20Sopenharmony_ci		    exists $lines[$realline_next - 1] &&
40908c2ecf20Sopenharmony_ci		    !defined $suppress_export{$realline_next} &&
40918c2ecf20Sopenharmony_ci		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
40928c2ecf20Sopenharmony_ci		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
40938c2ecf20Sopenharmony_ci			# Handle definitions which produce identifiers with
40948c2ecf20Sopenharmony_ci			# a prefix:
40958c2ecf20Sopenharmony_ci			#   XXX(foo);
40968c2ecf20Sopenharmony_ci			#   EXPORT_SYMBOL(something_foo);
40978c2ecf20Sopenharmony_ci			my $name = $1;
40988c2ecf20Sopenharmony_ci			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
40998c2ecf20Sopenharmony_ci			    $name =~ /^${Ident}_$2/) {
41008c2ecf20Sopenharmony_ci#print "FOO C name<$name>\n";
41018c2ecf20Sopenharmony_ci				$suppress_export{$realline_next} = 1;
41028c2ecf20Sopenharmony_ci
41038c2ecf20Sopenharmony_ci			} elsif ($stat !~ /(?:
41048c2ecf20Sopenharmony_ci				\n.}\s*$|
41058c2ecf20Sopenharmony_ci				^.DEFINE_$Ident\(\Q$name\E\)|
41068c2ecf20Sopenharmony_ci				^.DECLARE_$Ident\(\Q$name\E\)|
41078c2ecf20Sopenharmony_ci				^.LIST_HEAD\(\Q$name\E\)|
41088c2ecf20Sopenharmony_ci				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
41098c2ecf20Sopenharmony_ci				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
41108c2ecf20Sopenharmony_ci			    )/x) {
41118c2ecf20Sopenharmony_ci#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
41128c2ecf20Sopenharmony_ci				$suppress_export{$realline_next} = 2;
41138c2ecf20Sopenharmony_ci			} else {
41148c2ecf20Sopenharmony_ci				$suppress_export{$realline_next} = 1;
41158c2ecf20Sopenharmony_ci			}
41168c2ecf20Sopenharmony_ci		}
41178c2ecf20Sopenharmony_ci		if (!defined $suppress_export{$linenr} &&
41188c2ecf20Sopenharmony_ci		    $prevline =~ /^.\s*$/ &&
41198c2ecf20Sopenharmony_ci		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
41208c2ecf20Sopenharmony_ci		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
41218c2ecf20Sopenharmony_ci#print "FOO B <$lines[$linenr - 1]>\n";
41228c2ecf20Sopenharmony_ci			$suppress_export{$linenr} = 2;
41238c2ecf20Sopenharmony_ci		}
41248c2ecf20Sopenharmony_ci		if (defined $suppress_export{$linenr} &&
41258c2ecf20Sopenharmony_ci		    $suppress_export{$linenr} == 2) {
41268c2ecf20Sopenharmony_ci			WARN("EXPORT_SYMBOL",
41278c2ecf20Sopenharmony_ci			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
41288c2ecf20Sopenharmony_ci		}
41298c2ecf20Sopenharmony_ci
41308c2ecf20Sopenharmony_ci# check for global initialisers.
41318c2ecf20Sopenharmony_ci		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
41328c2ecf20Sopenharmony_ci			if (ERROR("GLOBAL_INITIALISERS",
41338c2ecf20Sopenharmony_ci				  "do not initialise globals to $1\n" . $herecurr) &&
41348c2ecf20Sopenharmony_ci			    $fix) {
41358c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
41368c2ecf20Sopenharmony_ci			}
41378c2ecf20Sopenharmony_ci		}
41388c2ecf20Sopenharmony_ci# check for static initialisers.
41398c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
41408c2ecf20Sopenharmony_ci			if (ERROR("INITIALISED_STATIC",
41418c2ecf20Sopenharmony_ci				  "do not initialise statics to $1\n" .
41428c2ecf20Sopenharmony_ci				      $herecurr) &&
41438c2ecf20Sopenharmony_ci			    $fix) {
41448c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
41458c2ecf20Sopenharmony_ci			}
41468c2ecf20Sopenharmony_ci		}
41478c2ecf20Sopenharmony_ci
41488c2ecf20Sopenharmony_ci# check for misordered declarations of char/short/int/long with signed/unsigned
41498c2ecf20Sopenharmony_ci		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
41508c2ecf20Sopenharmony_ci			my $tmp = trim($1);
41518c2ecf20Sopenharmony_ci			WARN("MISORDERED_TYPE",
41528c2ecf20Sopenharmony_ci			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
41538c2ecf20Sopenharmony_ci		}
41548c2ecf20Sopenharmony_ci
41558c2ecf20Sopenharmony_ci# check for unnecessary <signed> int declarations of short/long/long long
41568c2ecf20Sopenharmony_ci		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
41578c2ecf20Sopenharmony_ci			my $type = trim($1);
41588c2ecf20Sopenharmony_ci			next if ($type !~ /\bint\b/);
41598c2ecf20Sopenharmony_ci			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
41608c2ecf20Sopenharmony_ci			my $new_type = $type;
41618c2ecf20Sopenharmony_ci			$new_type =~ s/\b\s*int\s*\b/ /;
41628c2ecf20Sopenharmony_ci			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
41638c2ecf20Sopenharmony_ci			$new_type =~ s/^const\s+//;
41648c2ecf20Sopenharmony_ci			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
41658c2ecf20Sopenharmony_ci			$new_type = "const $new_type" if ($type =~ /^const\b/);
41668c2ecf20Sopenharmony_ci			$new_type =~ s/\s+/ /g;
41678c2ecf20Sopenharmony_ci			$new_type = trim($new_type);
41688c2ecf20Sopenharmony_ci			if (WARN("UNNECESSARY_INT",
41698c2ecf20Sopenharmony_ci				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
41708c2ecf20Sopenharmony_ci			    $fix) {
41718c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
41728c2ecf20Sopenharmony_ci			}
41738c2ecf20Sopenharmony_ci		}
41748c2ecf20Sopenharmony_ci
41758c2ecf20Sopenharmony_ci# check for static const char * arrays.
41768c2ecf20Sopenharmony_ci		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
41778c2ecf20Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
41788c2ecf20Sopenharmony_ci			     "static const char * array should probably be static const char * const\n" .
41798c2ecf20Sopenharmony_ci				$herecurr);
41808c2ecf20Sopenharmony_ci		}
41818c2ecf20Sopenharmony_ci
41828c2ecf20Sopenharmony_ci# check for initialized const char arrays that should be static const
41838c2ecf20Sopenharmony_ci		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
41848c2ecf20Sopenharmony_ci			if (WARN("STATIC_CONST_CHAR_ARRAY",
41858c2ecf20Sopenharmony_ci				 "const array should probably be static const\n" . $herecurr) &&
41868c2ecf20Sopenharmony_ci			    $fix) {
41878c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
41888c2ecf20Sopenharmony_ci			}
41898c2ecf20Sopenharmony_ci		}
41908c2ecf20Sopenharmony_ci
41918c2ecf20Sopenharmony_ci# check for static char foo[] = "bar" declarations.
41928c2ecf20Sopenharmony_ci		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
41938c2ecf20Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
41948c2ecf20Sopenharmony_ci			     "static char array declaration should probably be static const char\n" .
41958c2ecf20Sopenharmony_ci				$herecurr);
41968c2ecf20Sopenharmony_ci		}
41978c2ecf20Sopenharmony_ci
41988c2ecf20Sopenharmony_ci# check for const <foo> const where <foo> is not a pointer or array type
41998c2ecf20Sopenharmony_ci		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
42008c2ecf20Sopenharmony_ci			my $found = $1;
42018c2ecf20Sopenharmony_ci			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
42028c2ecf20Sopenharmony_ci				WARN("CONST_CONST",
42038c2ecf20Sopenharmony_ci				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
42048c2ecf20Sopenharmony_ci			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
42058c2ecf20Sopenharmony_ci				WARN("CONST_CONST",
42068c2ecf20Sopenharmony_ci				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
42078c2ecf20Sopenharmony_ci			}
42088c2ecf20Sopenharmony_ci		}
42098c2ecf20Sopenharmony_ci
42108c2ecf20Sopenharmony_ci# check for non-global char *foo[] = {"bar", ...} declarations.
42118c2ecf20Sopenharmony_ci		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
42128c2ecf20Sopenharmony_ci			WARN("STATIC_CONST_CHAR_ARRAY",
42138c2ecf20Sopenharmony_ci			     "char * array declaration might be better as static const\n" .
42148c2ecf20Sopenharmony_ci				$herecurr);
42158c2ecf20Sopenharmony_ci               }
42168c2ecf20Sopenharmony_ci
42178c2ecf20Sopenharmony_ci# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
42188c2ecf20Sopenharmony_ci		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
42198c2ecf20Sopenharmony_ci			my $array = $1;
42208c2ecf20Sopenharmony_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*\))@) {
42218c2ecf20Sopenharmony_ci				my $array_div = $1;
42228c2ecf20Sopenharmony_ci				if (WARN("ARRAY_SIZE",
42238c2ecf20Sopenharmony_ci					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
42248c2ecf20Sopenharmony_ci				    $fix) {
42258c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
42268c2ecf20Sopenharmony_ci				}
42278c2ecf20Sopenharmony_ci			}
42288c2ecf20Sopenharmony_ci		}
42298c2ecf20Sopenharmony_ci
42308c2ecf20Sopenharmony_ci# check for function declarations without arguments like "int foo()"
42318c2ecf20Sopenharmony_ci		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
42328c2ecf20Sopenharmony_ci			if (ERROR("FUNCTION_WITHOUT_ARGS",
42338c2ecf20Sopenharmony_ci				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
42348c2ecf20Sopenharmony_ci			    $fix) {
42358c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
42368c2ecf20Sopenharmony_ci			}
42378c2ecf20Sopenharmony_ci		}
42388c2ecf20Sopenharmony_ci
42398c2ecf20Sopenharmony_ci# check for new typedefs, only function parameters and sparse annotations
42408c2ecf20Sopenharmony_ci# make sense.
42418c2ecf20Sopenharmony_ci		if ($line =~ /\btypedef\s/ &&
42428c2ecf20Sopenharmony_ci		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
42438c2ecf20Sopenharmony_ci		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
42448c2ecf20Sopenharmony_ci		    $line !~ /\b$typeTypedefs\b/ &&
42458c2ecf20Sopenharmony_ci		    $line !~ /\b__bitwise\b/) {
42468c2ecf20Sopenharmony_ci			WARN("NEW_TYPEDEFS",
42478c2ecf20Sopenharmony_ci			     "do not add new typedefs\n" . $herecurr);
42488c2ecf20Sopenharmony_ci		}
42498c2ecf20Sopenharmony_ci
42508c2ecf20Sopenharmony_ci# * goes on variable not on type
42518c2ecf20Sopenharmony_ci		# (char*[ const])
42528c2ecf20Sopenharmony_ci		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
42538c2ecf20Sopenharmony_ci			#print "AA<$1>\n";
42548c2ecf20Sopenharmony_ci			my ($ident, $from, $to) = ($1, $2, $2);
42558c2ecf20Sopenharmony_ci
42568c2ecf20Sopenharmony_ci			# Should start with a space.
42578c2ecf20Sopenharmony_ci			$to =~ s/^(\S)/ $1/;
42588c2ecf20Sopenharmony_ci			# Should not end with a space.
42598c2ecf20Sopenharmony_ci			$to =~ s/\s+$//;
42608c2ecf20Sopenharmony_ci			# '*'s should not have spaces between.
42618c2ecf20Sopenharmony_ci			while ($to =~ s/\*\s+\*/\*\*/) {
42628c2ecf20Sopenharmony_ci			}
42638c2ecf20Sopenharmony_ci
42648c2ecf20Sopenharmony_ci##			print "1: from<$from> to<$to> ident<$ident>\n";
42658c2ecf20Sopenharmony_ci			if ($from ne $to) {
42668c2ecf20Sopenharmony_ci				if (ERROR("POINTER_LOCATION",
42678c2ecf20Sopenharmony_ci					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
42688c2ecf20Sopenharmony_ci				    $fix) {
42698c2ecf20Sopenharmony_ci					my $sub_from = $ident;
42708c2ecf20Sopenharmony_ci					my $sub_to = $ident;
42718c2ecf20Sopenharmony_ci					$sub_to =~ s/\Q$from\E/$to/;
42728c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~
42738c2ecf20Sopenharmony_ci					    s@\Q$sub_from\E@$sub_to@;
42748c2ecf20Sopenharmony_ci				}
42758c2ecf20Sopenharmony_ci			}
42768c2ecf20Sopenharmony_ci		}
42778c2ecf20Sopenharmony_ci		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
42788c2ecf20Sopenharmony_ci			#print "BB<$1>\n";
42798c2ecf20Sopenharmony_ci			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
42808c2ecf20Sopenharmony_ci
42818c2ecf20Sopenharmony_ci			# Should start with a space.
42828c2ecf20Sopenharmony_ci			$to =~ s/^(\S)/ $1/;
42838c2ecf20Sopenharmony_ci			# Should not end with a space.
42848c2ecf20Sopenharmony_ci			$to =~ s/\s+$//;
42858c2ecf20Sopenharmony_ci			# '*'s should not have spaces between.
42868c2ecf20Sopenharmony_ci			while ($to =~ s/\*\s+\*/\*\*/) {
42878c2ecf20Sopenharmony_ci			}
42888c2ecf20Sopenharmony_ci			# Modifiers should have spaces.
42898c2ecf20Sopenharmony_ci			$to =~ s/(\b$Modifier$)/$1 /;
42908c2ecf20Sopenharmony_ci
42918c2ecf20Sopenharmony_ci##			print "2: from<$from> to<$to> ident<$ident>\n";
42928c2ecf20Sopenharmony_ci			if ($from ne $to && $ident !~ /^$Modifier$/) {
42938c2ecf20Sopenharmony_ci				if (ERROR("POINTER_LOCATION",
42948c2ecf20Sopenharmony_ci					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
42958c2ecf20Sopenharmony_ci				    $fix) {
42968c2ecf20Sopenharmony_ci
42978c2ecf20Sopenharmony_ci					my $sub_from = $match;
42988c2ecf20Sopenharmony_ci					my $sub_to = $match;
42998c2ecf20Sopenharmony_ci					$sub_to =~ s/\Q$from\E/$to/;
43008c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~
43018c2ecf20Sopenharmony_ci					    s@\Q$sub_from\E@$sub_to@;
43028c2ecf20Sopenharmony_ci				}
43038c2ecf20Sopenharmony_ci			}
43048c2ecf20Sopenharmony_ci		}
43058c2ecf20Sopenharmony_ci
43068c2ecf20Sopenharmony_ci# avoid BUG() or BUG_ON()
43078c2ecf20Sopenharmony_ci		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
43088c2ecf20Sopenharmony_ci			my $msg_level = \&WARN;
43098c2ecf20Sopenharmony_ci			$msg_level = \&CHK if ($file);
43108c2ecf20Sopenharmony_ci			&{$msg_level}("AVOID_BUG",
43118c2ecf20Sopenharmony_ci				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
43128c2ecf20Sopenharmony_ci		}
43138c2ecf20Sopenharmony_ci
43148c2ecf20Sopenharmony_ci# avoid LINUX_VERSION_CODE
43158c2ecf20Sopenharmony_ci		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
43168c2ecf20Sopenharmony_ci			WARN("LINUX_VERSION_CODE",
43178c2ecf20Sopenharmony_ci			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
43188c2ecf20Sopenharmony_ci		}
43198c2ecf20Sopenharmony_ci
43208c2ecf20Sopenharmony_ci# check for uses of printk_ratelimit
43218c2ecf20Sopenharmony_ci		if ($line =~ /\bprintk_ratelimit\s*\(/) {
43228c2ecf20Sopenharmony_ci			WARN("PRINTK_RATELIMITED",
43238c2ecf20Sopenharmony_ci			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
43248c2ecf20Sopenharmony_ci		}
43258c2ecf20Sopenharmony_ci
43268c2ecf20Sopenharmony_ci# printk should use KERN_* levels
43278c2ecf20Sopenharmony_ci		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
43288c2ecf20Sopenharmony_ci			WARN("PRINTK_WITHOUT_KERN_LEVEL",
43298c2ecf20Sopenharmony_ci			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
43308c2ecf20Sopenharmony_ci		}
43318c2ecf20Sopenharmony_ci
43328c2ecf20Sopenharmony_ci		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
43338c2ecf20Sopenharmony_ci			my $orig = $1;
43348c2ecf20Sopenharmony_ci			my $level = lc($orig);
43358c2ecf20Sopenharmony_ci			$level = "warn" if ($level eq "warning");
43368c2ecf20Sopenharmony_ci			my $level2 = $level;
43378c2ecf20Sopenharmony_ci			$level2 = "dbg" if ($level eq "debug");
43388c2ecf20Sopenharmony_ci			WARN("PREFER_PR_LEVEL",
43398c2ecf20Sopenharmony_ci			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
43408c2ecf20Sopenharmony_ci		}
43418c2ecf20Sopenharmony_ci
43428c2ecf20Sopenharmony_ci		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
43438c2ecf20Sopenharmony_ci			my $orig = $1;
43448c2ecf20Sopenharmony_ci			my $level = lc($orig);
43458c2ecf20Sopenharmony_ci			$level = "warn" if ($level eq "warning");
43468c2ecf20Sopenharmony_ci			$level = "dbg" if ($level eq "debug");
43478c2ecf20Sopenharmony_ci			WARN("PREFER_DEV_LEVEL",
43488c2ecf20Sopenharmony_ci			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
43498c2ecf20Sopenharmony_ci		}
43508c2ecf20Sopenharmony_ci
43518c2ecf20Sopenharmony_ci# trace_printk should not be used in production code.
43528c2ecf20Sopenharmony_ci		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
43538c2ecf20Sopenharmony_ci			WARN("TRACE_PRINTK",
43548c2ecf20Sopenharmony_ci			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
43558c2ecf20Sopenharmony_ci		}
43568c2ecf20Sopenharmony_ci
43578c2ecf20Sopenharmony_ci# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
43588c2ecf20Sopenharmony_ci# number of false positives, but assembly files are not checked, so at
43598c2ecf20Sopenharmony_ci# least the arch entry code will not trigger this warning.
43608c2ecf20Sopenharmony_ci		if ($line =~ /\bENOSYS\b/) {
43618c2ecf20Sopenharmony_ci			WARN("ENOSYS",
43628c2ecf20Sopenharmony_ci			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
43638c2ecf20Sopenharmony_ci		}
43648c2ecf20Sopenharmony_ci
43658c2ecf20Sopenharmony_ci# ENOTSUPP is not a standard error code and should be avoided in new patches.
43668c2ecf20Sopenharmony_ci# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
43678c2ecf20Sopenharmony_ci# Similarly to ENOSYS warning a small number of false positives is expected.
43688c2ecf20Sopenharmony_ci		if (!$file && $line =~ /\bENOTSUPP\b/) {
43698c2ecf20Sopenharmony_ci			if (WARN("ENOTSUPP",
43708c2ecf20Sopenharmony_ci				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
43718c2ecf20Sopenharmony_ci			    $fix) {
43728c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
43738c2ecf20Sopenharmony_ci			}
43748c2ecf20Sopenharmony_ci		}
43758c2ecf20Sopenharmony_ci
43768c2ecf20Sopenharmony_ci# function brace can't be on same line, except for #defines of do while,
43778c2ecf20Sopenharmony_ci# or if closed on same line
43788c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
43798c2ecf20Sopenharmony_ci		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
43808c2ecf20Sopenharmony_ci		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
43818c2ecf20Sopenharmony_ci		    $sline !~ /}/) {
43828c2ecf20Sopenharmony_ci			if (ERROR("OPEN_BRACE",
43838c2ecf20Sopenharmony_ci				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
43848c2ecf20Sopenharmony_ci			    $fix) {
43858c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
43868c2ecf20Sopenharmony_ci				my $fixed_line = $rawline;
43878c2ecf20Sopenharmony_ci				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
43888c2ecf20Sopenharmony_ci				my $line1 = $1;
43898c2ecf20Sopenharmony_ci				my $line2 = $2;
43908c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, ltrim($line1));
43918c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, "\+{");
43928c2ecf20Sopenharmony_ci				if ($line2 !~ /^\s*$/) {
43938c2ecf20Sopenharmony_ci					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
43948c2ecf20Sopenharmony_ci				}
43958c2ecf20Sopenharmony_ci			}
43968c2ecf20Sopenharmony_ci		}
43978c2ecf20Sopenharmony_ci
43988c2ecf20Sopenharmony_ci# open braces for enum, union and struct go on the same line.
43998c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*{/ &&
44008c2ecf20Sopenharmony_ci		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
44018c2ecf20Sopenharmony_ci			if (ERROR("OPEN_BRACE",
44028c2ecf20Sopenharmony_ci				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
44038c2ecf20Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
44048c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
44058c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
44068c2ecf20Sopenharmony_ci				my $fixedline = rtrim($prevrawline) . " {";
44078c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
44088c2ecf20Sopenharmony_ci				$fixedline = $rawline;
44098c2ecf20Sopenharmony_ci				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
44108c2ecf20Sopenharmony_ci				if ($fixedline !~ /^\+\s*$/) {
44118c2ecf20Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
44128c2ecf20Sopenharmony_ci				}
44138c2ecf20Sopenharmony_ci			}
44148c2ecf20Sopenharmony_ci		}
44158c2ecf20Sopenharmony_ci
44168c2ecf20Sopenharmony_ci# missing space after union, struct or enum definition
44178c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
44188c2ecf20Sopenharmony_ci			if (WARN("SPACING",
44198c2ecf20Sopenharmony_ci				 "missing space after $1 definition\n" . $herecurr) &&
44208c2ecf20Sopenharmony_ci			    $fix) {
44218c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
44228c2ecf20Sopenharmony_ci				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
44238c2ecf20Sopenharmony_ci			}
44248c2ecf20Sopenharmony_ci		}
44258c2ecf20Sopenharmony_ci
44268c2ecf20Sopenharmony_ci# Function pointer declarations
44278c2ecf20Sopenharmony_ci# check spacing between type, funcptr, and args
44288c2ecf20Sopenharmony_ci# canonical declaration is "type (*funcptr)(args...)"
44298c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
44308c2ecf20Sopenharmony_ci			my $declare = $1;
44318c2ecf20Sopenharmony_ci			my $pre_pointer_space = $2;
44328c2ecf20Sopenharmony_ci			my $post_pointer_space = $3;
44338c2ecf20Sopenharmony_ci			my $funcname = $4;
44348c2ecf20Sopenharmony_ci			my $post_funcname_space = $5;
44358c2ecf20Sopenharmony_ci			my $pre_args_space = $6;
44368c2ecf20Sopenharmony_ci
44378c2ecf20Sopenharmony_ci# the $Declare variable will capture all spaces after the type
44388c2ecf20Sopenharmony_ci# so check it for a missing trailing missing space but pointer return types
44398c2ecf20Sopenharmony_ci# don't need a space so don't warn for those.
44408c2ecf20Sopenharmony_ci			my $post_declare_space = "";
44418c2ecf20Sopenharmony_ci			if ($declare =~ /(\s+)$/) {
44428c2ecf20Sopenharmony_ci				$post_declare_space = $1;
44438c2ecf20Sopenharmony_ci				$declare = rtrim($declare);
44448c2ecf20Sopenharmony_ci			}
44458c2ecf20Sopenharmony_ci			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
44468c2ecf20Sopenharmony_ci				WARN("SPACING",
44478c2ecf20Sopenharmony_ci				     "missing space after return type\n" . $herecurr);
44488c2ecf20Sopenharmony_ci				$post_declare_space = " ";
44498c2ecf20Sopenharmony_ci			}
44508c2ecf20Sopenharmony_ci
44518c2ecf20Sopenharmony_ci# unnecessary space "type  (*funcptr)(args...)"
44528c2ecf20Sopenharmony_ci# This test is not currently implemented because these declarations are
44538c2ecf20Sopenharmony_ci# equivalent to
44548c2ecf20Sopenharmony_ci#	int  foo(int bar, ...)
44558c2ecf20Sopenharmony_ci# and this is form shouldn't/doesn't generate a checkpatch warning.
44568c2ecf20Sopenharmony_ci#
44578c2ecf20Sopenharmony_ci#			elsif ($declare =~ /\s{2,}$/) {
44588c2ecf20Sopenharmony_ci#				WARN("SPACING",
44598c2ecf20Sopenharmony_ci#				     "Multiple spaces after return type\n" . $herecurr);
44608c2ecf20Sopenharmony_ci#			}
44618c2ecf20Sopenharmony_ci
44628c2ecf20Sopenharmony_ci# unnecessary space "type ( *funcptr)(args...)"
44638c2ecf20Sopenharmony_ci			if (defined $pre_pointer_space &&
44648c2ecf20Sopenharmony_ci			    $pre_pointer_space =~ /^\s/) {
44658c2ecf20Sopenharmony_ci				WARN("SPACING",
44668c2ecf20Sopenharmony_ci				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
44678c2ecf20Sopenharmony_ci			}
44688c2ecf20Sopenharmony_ci
44698c2ecf20Sopenharmony_ci# unnecessary space "type (* funcptr)(args...)"
44708c2ecf20Sopenharmony_ci			if (defined $post_pointer_space &&
44718c2ecf20Sopenharmony_ci			    $post_pointer_space =~ /^\s/) {
44728c2ecf20Sopenharmony_ci				WARN("SPACING",
44738c2ecf20Sopenharmony_ci				     "Unnecessary space before function pointer name\n" . $herecurr);
44748c2ecf20Sopenharmony_ci			}
44758c2ecf20Sopenharmony_ci
44768c2ecf20Sopenharmony_ci# unnecessary space "type (*funcptr )(args...)"
44778c2ecf20Sopenharmony_ci			if (defined $post_funcname_space &&
44788c2ecf20Sopenharmony_ci			    $post_funcname_space =~ /^\s/) {
44798c2ecf20Sopenharmony_ci				WARN("SPACING",
44808c2ecf20Sopenharmony_ci				     "Unnecessary space after function pointer name\n" . $herecurr);
44818c2ecf20Sopenharmony_ci			}
44828c2ecf20Sopenharmony_ci
44838c2ecf20Sopenharmony_ci# unnecessary space "type (*funcptr) (args...)"
44848c2ecf20Sopenharmony_ci			if (defined $pre_args_space &&
44858c2ecf20Sopenharmony_ci			    $pre_args_space =~ /^\s/) {
44868c2ecf20Sopenharmony_ci				WARN("SPACING",
44878c2ecf20Sopenharmony_ci				     "Unnecessary space before function pointer arguments\n" . $herecurr);
44888c2ecf20Sopenharmony_ci			}
44898c2ecf20Sopenharmony_ci
44908c2ecf20Sopenharmony_ci			if (show_type("SPACING") && $fix) {
44918c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
44928c2ecf20Sopenharmony_ci				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
44938c2ecf20Sopenharmony_ci			}
44948c2ecf20Sopenharmony_ci		}
44958c2ecf20Sopenharmony_ci
44968c2ecf20Sopenharmony_ci# check for spacing round square brackets; allowed:
44978c2ecf20Sopenharmony_ci#  1. with a type on the left -- int [] a;
44988c2ecf20Sopenharmony_ci#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
44998c2ecf20Sopenharmony_ci#  3. inside a curly brace -- = { [0...10] = 5 }
45008c2ecf20Sopenharmony_ci		while ($line =~ /(.*?\s)\[/g) {
45018c2ecf20Sopenharmony_ci			my ($where, $prefix) = ($-[1], $1);
45028c2ecf20Sopenharmony_ci			if ($prefix !~ /$Type\s+$/ &&
45038c2ecf20Sopenharmony_ci			    ($where != 0 || $prefix !~ /^.\s+$/) &&
45048c2ecf20Sopenharmony_ci			    $prefix !~ /[{,:]\s+$/) {
45058c2ecf20Sopenharmony_ci				if (ERROR("BRACKET_SPACE",
45068c2ecf20Sopenharmony_ci					  "space prohibited before open square bracket '['\n" . $herecurr) &&
45078c2ecf20Sopenharmony_ci				    $fix) {
45088c2ecf20Sopenharmony_ci				    $fixed[$fixlinenr] =~
45098c2ecf20Sopenharmony_ci					s/^(\+.*?)\s+\[/$1\[/;
45108c2ecf20Sopenharmony_ci				}
45118c2ecf20Sopenharmony_ci			}
45128c2ecf20Sopenharmony_ci		}
45138c2ecf20Sopenharmony_ci
45148c2ecf20Sopenharmony_ci# check for spaces between functions and their parentheses.
45158c2ecf20Sopenharmony_ci		while ($line =~ /($Ident)\s+\(/g) {
45168c2ecf20Sopenharmony_ci			my $name = $1;
45178c2ecf20Sopenharmony_ci			my $ctx_before = substr($line, 0, $-[1]);
45188c2ecf20Sopenharmony_ci			my $ctx = "$ctx_before$name";
45198c2ecf20Sopenharmony_ci
45208c2ecf20Sopenharmony_ci			# Ignore those directives where spaces _are_ permitted.
45218c2ecf20Sopenharmony_ci			if ($name =~ /^(?:
45228c2ecf20Sopenharmony_ci				if|for|while|switch|return|case|
45238c2ecf20Sopenharmony_ci				volatile|__volatile__|
45248c2ecf20Sopenharmony_ci				__attribute__|format|__extension__|
45258c2ecf20Sopenharmony_ci				asm|__asm__)$/x)
45268c2ecf20Sopenharmony_ci			{
45278c2ecf20Sopenharmony_ci			# cpp #define statements have non-optional spaces, ie
45288c2ecf20Sopenharmony_ci			# if there is a space between the name and the open
45298c2ecf20Sopenharmony_ci			# parenthesis it is simply not a parameter group.
45308c2ecf20Sopenharmony_ci			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
45318c2ecf20Sopenharmony_ci
45328c2ecf20Sopenharmony_ci			# cpp #elif statement condition may start with a (
45338c2ecf20Sopenharmony_ci			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
45348c2ecf20Sopenharmony_ci
45358c2ecf20Sopenharmony_ci			# If this whole things ends with a type its most
45368c2ecf20Sopenharmony_ci			# likely a typedef for a function.
45378c2ecf20Sopenharmony_ci			} elsif ($ctx =~ /$Type$/) {
45388c2ecf20Sopenharmony_ci
45398c2ecf20Sopenharmony_ci			} else {
45408c2ecf20Sopenharmony_ci				if (WARN("SPACING",
45418c2ecf20Sopenharmony_ci					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
45428c2ecf20Sopenharmony_ci					     $fix) {
45438c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~
45448c2ecf20Sopenharmony_ci					    s/\b$name\s+\(/$name\(/;
45458c2ecf20Sopenharmony_ci				}
45468c2ecf20Sopenharmony_ci			}
45478c2ecf20Sopenharmony_ci		}
45488c2ecf20Sopenharmony_ci
45498c2ecf20Sopenharmony_ci# Check operator spacing.
45508c2ecf20Sopenharmony_ci		if (!($line=~/\#\s*include/)) {
45518c2ecf20Sopenharmony_ci			my $fixed_line = "";
45528c2ecf20Sopenharmony_ci			my $line_fixed = 0;
45538c2ecf20Sopenharmony_ci
45548c2ecf20Sopenharmony_ci			my $ops = qr{
45558c2ecf20Sopenharmony_ci				<<=|>>=|<=|>=|==|!=|
45568c2ecf20Sopenharmony_ci				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
45578c2ecf20Sopenharmony_ci				=>|->|<<|>>|<|>|=|!|~|
45588c2ecf20Sopenharmony_ci				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
45598c2ecf20Sopenharmony_ci				\?:|\?|:
45608c2ecf20Sopenharmony_ci			}x;
45618c2ecf20Sopenharmony_ci			my @elements = split(/($ops|;)/, $opline);
45628c2ecf20Sopenharmony_ci
45638c2ecf20Sopenharmony_ci##			print("element count: <" . $#elements . ">\n");
45648c2ecf20Sopenharmony_ci##			foreach my $el (@elements) {
45658c2ecf20Sopenharmony_ci##				print("el: <$el>\n");
45668c2ecf20Sopenharmony_ci##			}
45678c2ecf20Sopenharmony_ci
45688c2ecf20Sopenharmony_ci			my @fix_elements = ();
45698c2ecf20Sopenharmony_ci			my $off = 0;
45708c2ecf20Sopenharmony_ci
45718c2ecf20Sopenharmony_ci			foreach my $el (@elements) {
45728c2ecf20Sopenharmony_ci				push(@fix_elements, substr($rawline, $off, length($el)));
45738c2ecf20Sopenharmony_ci				$off += length($el);
45748c2ecf20Sopenharmony_ci			}
45758c2ecf20Sopenharmony_ci
45768c2ecf20Sopenharmony_ci			$off = 0;
45778c2ecf20Sopenharmony_ci
45788c2ecf20Sopenharmony_ci			my $blank = copy_spacing($opline);
45798c2ecf20Sopenharmony_ci			my $last_after = -1;
45808c2ecf20Sopenharmony_ci
45818c2ecf20Sopenharmony_ci			for (my $n = 0; $n < $#elements; $n += 2) {
45828c2ecf20Sopenharmony_ci
45838c2ecf20Sopenharmony_ci				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
45848c2ecf20Sopenharmony_ci
45858c2ecf20Sopenharmony_ci##				print("n: <$n> good: <$good>\n");
45868c2ecf20Sopenharmony_ci
45878c2ecf20Sopenharmony_ci				$off += length($elements[$n]);
45888c2ecf20Sopenharmony_ci
45898c2ecf20Sopenharmony_ci				# Pick up the preceding and succeeding characters.
45908c2ecf20Sopenharmony_ci				my $ca = substr($opline, 0, $off);
45918c2ecf20Sopenharmony_ci				my $cc = '';
45928c2ecf20Sopenharmony_ci				if (length($opline) >= ($off + length($elements[$n + 1]))) {
45938c2ecf20Sopenharmony_ci					$cc = substr($opline, $off + length($elements[$n + 1]));
45948c2ecf20Sopenharmony_ci				}
45958c2ecf20Sopenharmony_ci				my $cb = "$ca$;$cc";
45968c2ecf20Sopenharmony_ci
45978c2ecf20Sopenharmony_ci				my $a = '';
45988c2ecf20Sopenharmony_ci				$a = 'V' if ($elements[$n] ne '');
45998c2ecf20Sopenharmony_ci				$a = 'W' if ($elements[$n] =~ /\s$/);
46008c2ecf20Sopenharmony_ci				$a = 'C' if ($elements[$n] =~ /$;$/);
46018c2ecf20Sopenharmony_ci				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
46028c2ecf20Sopenharmony_ci				$a = 'O' if ($elements[$n] eq '');
46038c2ecf20Sopenharmony_ci				$a = 'E' if ($ca =~ /^\s*$/);
46048c2ecf20Sopenharmony_ci
46058c2ecf20Sopenharmony_ci				my $op = $elements[$n + 1];
46068c2ecf20Sopenharmony_ci
46078c2ecf20Sopenharmony_ci				my $c = '';
46088c2ecf20Sopenharmony_ci				if (defined $elements[$n + 2]) {
46098c2ecf20Sopenharmony_ci					$c = 'V' if ($elements[$n + 2] ne '');
46108c2ecf20Sopenharmony_ci					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
46118c2ecf20Sopenharmony_ci					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
46128c2ecf20Sopenharmony_ci					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
46138c2ecf20Sopenharmony_ci					$c = 'O' if ($elements[$n + 2] eq '');
46148c2ecf20Sopenharmony_ci					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
46158c2ecf20Sopenharmony_ci				} else {
46168c2ecf20Sopenharmony_ci					$c = 'E';
46178c2ecf20Sopenharmony_ci				}
46188c2ecf20Sopenharmony_ci
46198c2ecf20Sopenharmony_ci				my $ctx = "${a}x${c}";
46208c2ecf20Sopenharmony_ci
46218c2ecf20Sopenharmony_ci				my $at = "(ctx:$ctx)";
46228c2ecf20Sopenharmony_ci
46238c2ecf20Sopenharmony_ci				my $ptr = substr($blank, 0, $off) . "^";
46248c2ecf20Sopenharmony_ci				my $hereptr = "$hereline$ptr\n";
46258c2ecf20Sopenharmony_ci
46268c2ecf20Sopenharmony_ci				# Pull out the value of this operator.
46278c2ecf20Sopenharmony_ci				my $op_type = substr($curr_values, $off + 1, 1);
46288c2ecf20Sopenharmony_ci
46298c2ecf20Sopenharmony_ci				# Get the full operator variant.
46308c2ecf20Sopenharmony_ci				my $opv = $op . substr($curr_vars, $off, 1);
46318c2ecf20Sopenharmony_ci
46328c2ecf20Sopenharmony_ci				# Ignore operators passed as parameters.
46338c2ecf20Sopenharmony_ci				if ($op_type ne 'V' &&
46348c2ecf20Sopenharmony_ci				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
46358c2ecf20Sopenharmony_ci
46368c2ecf20Sopenharmony_ci#				# Ignore comments
46378c2ecf20Sopenharmony_ci#				} elsif ($op =~ /^$;+$/) {
46388c2ecf20Sopenharmony_ci
46398c2ecf20Sopenharmony_ci				# ; should have either the end of line or a space or \ after it
46408c2ecf20Sopenharmony_ci				} elsif ($op eq ';') {
46418c2ecf20Sopenharmony_ci					if ($ctx !~ /.x[WEBC]/ &&
46428c2ecf20Sopenharmony_ci					    $cc !~ /^\\/ && $cc !~ /^;/) {
46438c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
46448c2ecf20Sopenharmony_ci							  "space required after that '$op' $at\n" . $hereptr)) {
46458c2ecf20Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
46468c2ecf20Sopenharmony_ci							$line_fixed = 1;
46478c2ecf20Sopenharmony_ci						}
46488c2ecf20Sopenharmony_ci					}
46498c2ecf20Sopenharmony_ci
46508c2ecf20Sopenharmony_ci				# // is a comment
46518c2ecf20Sopenharmony_ci				} elsif ($op eq '//') {
46528c2ecf20Sopenharmony_ci
46538c2ecf20Sopenharmony_ci				#   :   when part of a bitfield
46548c2ecf20Sopenharmony_ci				} elsif ($opv eq ':B') {
46558c2ecf20Sopenharmony_ci					# skip the bitfield test for now
46568c2ecf20Sopenharmony_ci
46578c2ecf20Sopenharmony_ci				# No spaces for:
46588c2ecf20Sopenharmony_ci				#   ->
46598c2ecf20Sopenharmony_ci				} elsif ($op eq '->') {
46608c2ecf20Sopenharmony_ci					if ($ctx =~ /Wx.|.xW/) {
46618c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
46628c2ecf20Sopenharmony_ci							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
46638c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
46648c2ecf20Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
46658c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
46668c2ecf20Sopenharmony_ci							}
46678c2ecf20Sopenharmony_ci							$line_fixed = 1;
46688c2ecf20Sopenharmony_ci						}
46698c2ecf20Sopenharmony_ci					}
46708c2ecf20Sopenharmony_ci
46718c2ecf20Sopenharmony_ci				# , must not have a space before and must have a space on the right.
46728c2ecf20Sopenharmony_ci				} elsif ($op eq ',') {
46738c2ecf20Sopenharmony_ci					my $rtrim_before = 0;
46748c2ecf20Sopenharmony_ci					my $space_after = 0;
46758c2ecf20Sopenharmony_ci					if ($ctx =~ /Wx./) {
46768c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
46778c2ecf20Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
46788c2ecf20Sopenharmony_ci							$line_fixed = 1;
46798c2ecf20Sopenharmony_ci							$rtrim_before = 1;
46808c2ecf20Sopenharmony_ci						}
46818c2ecf20Sopenharmony_ci					}
46828c2ecf20Sopenharmony_ci					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
46838c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
46848c2ecf20Sopenharmony_ci							  "space required after that '$op' $at\n" . $hereptr)) {
46858c2ecf20Sopenharmony_ci							$line_fixed = 1;
46868c2ecf20Sopenharmony_ci							$last_after = $n;
46878c2ecf20Sopenharmony_ci							$space_after = 1;
46888c2ecf20Sopenharmony_ci						}
46898c2ecf20Sopenharmony_ci					}
46908c2ecf20Sopenharmony_ci					if ($rtrim_before || $space_after) {
46918c2ecf20Sopenharmony_ci						if ($rtrim_before) {
46928c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
46938c2ecf20Sopenharmony_ci						} else {
46948c2ecf20Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
46958c2ecf20Sopenharmony_ci						}
46968c2ecf20Sopenharmony_ci						if ($space_after) {
46978c2ecf20Sopenharmony_ci							$good .= " ";
46988c2ecf20Sopenharmony_ci						}
46998c2ecf20Sopenharmony_ci					}
47008c2ecf20Sopenharmony_ci
47018c2ecf20Sopenharmony_ci				# '*' as part of a type definition -- reported already.
47028c2ecf20Sopenharmony_ci				} elsif ($opv eq '*_') {
47038c2ecf20Sopenharmony_ci					#warn "'*' is part of type\n";
47048c2ecf20Sopenharmony_ci
47058c2ecf20Sopenharmony_ci				# unary operators should have a space before and
47068c2ecf20Sopenharmony_ci				# none after.  May be left adjacent to another
47078c2ecf20Sopenharmony_ci				# unary operator, or a cast
47088c2ecf20Sopenharmony_ci				} elsif ($op eq '!' || $op eq '~' ||
47098c2ecf20Sopenharmony_ci					 $opv eq '*U' || $opv eq '-U' ||
47108c2ecf20Sopenharmony_ci					 $opv eq '&U' || $opv eq '&&U') {
47118c2ecf20Sopenharmony_ci					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
47128c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47138c2ecf20Sopenharmony_ci							  "space required before that '$op' $at\n" . $hereptr)) {
47148c2ecf20Sopenharmony_ci							if ($n != $last_after + 2) {
47158c2ecf20Sopenharmony_ci								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
47168c2ecf20Sopenharmony_ci								$line_fixed = 1;
47178c2ecf20Sopenharmony_ci							}
47188c2ecf20Sopenharmony_ci						}
47198c2ecf20Sopenharmony_ci					}
47208c2ecf20Sopenharmony_ci					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
47218c2ecf20Sopenharmony_ci						# A unary '*' may be const
47228c2ecf20Sopenharmony_ci
47238c2ecf20Sopenharmony_ci					} elsif ($ctx =~ /.xW/) {
47248c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47258c2ecf20Sopenharmony_ci							  "space prohibited after that '$op' $at\n" . $hereptr)) {
47268c2ecf20Sopenharmony_ci							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
47278c2ecf20Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
47288c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
47298c2ecf20Sopenharmony_ci							}
47308c2ecf20Sopenharmony_ci							$line_fixed = 1;
47318c2ecf20Sopenharmony_ci						}
47328c2ecf20Sopenharmony_ci					}
47338c2ecf20Sopenharmony_ci
47348c2ecf20Sopenharmony_ci				# unary ++ and unary -- are allowed no space on one side.
47358c2ecf20Sopenharmony_ci				} elsif ($op eq '++' or $op eq '--') {
47368c2ecf20Sopenharmony_ci					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
47378c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47388c2ecf20Sopenharmony_ci							  "space required one side of that '$op' $at\n" . $hereptr)) {
47398c2ecf20Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
47408c2ecf20Sopenharmony_ci							$line_fixed = 1;
47418c2ecf20Sopenharmony_ci						}
47428c2ecf20Sopenharmony_ci					}
47438c2ecf20Sopenharmony_ci					if ($ctx =~ /Wx[BE]/ ||
47448c2ecf20Sopenharmony_ci					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
47458c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47468c2ecf20Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
47478c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
47488c2ecf20Sopenharmony_ci							$line_fixed = 1;
47498c2ecf20Sopenharmony_ci						}
47508c2ecf20Sopenharmony_ci					}
47518c2ecf20Sopenharmony_ci					if ($ctx =~ /ExW/) {
47528c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47538c2ecf20Sopenharmony_ci							  "space prohibited after that '$op' $at\n" . $hereptr)) {
47548c2ecf20Sopenharmony_ci							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
47558c2ecf20Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
47568c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
47578c2ecf20Sopenharmony_ci							}
47588c2ecf20Sopenharmony_ci							$line_fixed = 1;
47598c2ecf20Sopenharmony_ci						}
47608c2ecf20Sopenharmony_ci					}
47618c2ecf20Sopenharmony_ci
47628c2ecf20Sopenharmony_ci				# << and >> may either have or not have spaces both sides
47638c2ecf20Sopenharmony_ci				} elsif ($op eq '<<' or $op eq '>>' or
47648c2ecf20Sopenharmony_ci					 $op eq '&' or $op eq '^' or $op eq '|' or
47658c2ecf20Sopenharmony_ci					 $op eq '+' or $op eq '-' or
47668c2ecf20Sopenharmony_ci					 $op eq '*' or $op eq '/' or
47678c2ecf20Sopenharmony_ci					 $op eq '%')
47688c2ecf20Sopenharmony_ci				{
47698c2ecf20Sopenharmony_ci					if ($check) {
47708c2ecf20Sopenharmony_ci						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
47718c2ecf20Sopenharmony_ci							if (CHK("SPACING",
47728c2ecf20Sopenharmony_ci								"spaces preferred around that '$op' $at\n" . $hereptr)) {
47738c2ecf20Sopenharmony_ci								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
47748c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
47758c2ecf20Sopenharmony_ci								$line_fixed = 1;
47768c2ecf20Sopenharmony_ci							}
47778c2ecf20Sopenharmony_ci						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
47788c2ecf20Sopenharmony_ci							if (CHK("SPACING",
47798c2ecf20Sopenharmony_ci								"space preferred before that '$op' $at\n" . $hereptr)) {
47808c2ecf20Sopenharmony_ci								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
47818c2ecf20Sopenharmony_ci								$line_fixed = 1;
47828c2ecf20Sopenharmony_ci							}
47838c2ecf20Sopenharmony_ci						}
47848c2ecf20Sopenharmony_ci					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
47858c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
47868c2ecf20Sopenharmony_ci							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
47878c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
47888c2ecf20Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
47898c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
47908c2ecf20Sopenharmony_ci							}
47918c2ecf20Sopenharmony_ci							$line_fixed = 1;
47928c2ecf20Sopenharmony_ci						}
47938c2ecf20Sopenharmony_ci					}
47948c2ecf20Sopenharmony_ci
47958c2ecf20Sopenharmony_ci				# A colon needs no spaces before when it is
47968c2ecf20Sopenharmony_ci				# terminating a case value or a label.
47978c2ecf20Sopenharmony_ci				} elsif ($opv eq ':C' || $opv eq ':L') {
47988c2ecf20Sopenharmony_ci					if ($ctx =~ /Wx./) {
47998c2ecf20Sopenharmony_ci						if (ERROR("SPACING",
48008c2ecf20Sopenharmony_ci							  "space prohibited before that '$op' $at\n" . $hereptr)) {
48018c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
48028c2ecf20Sopenharmony_ci							$line_fixed = 1;
48038c2ecf20Sopenharmony_ci						}
48048c2ecf20Sopenharmony_ci					}
48058c2ecf20Sopenharmony_ci
48068c2ecf20Sopenharmony_ci				# All the others need spaces both sides.
48078c2ecf20Sopenharmony_ci				} elsif ($ctx !~ /[EWC]x[CWE]/) {
48088c2ecf20Sopenharmony_ci					my $ok = 0;
48098c2ecf20Sopenharmony_ci
48108c2ecf20Sopenharmony_ci					# Ignore email addresses <foo@bar>
48118c2ecf20Sopenharmony_ci					if (($op eq '<' &&
48128c2ecf20Sopenharmony_ci					     $cc =~ /^\S+\@\S+>/) ||
48138c2ecf20Sopenharmony_ci					    ($op eq '>' &&
48148c2ecf20Sopenharmony_ci					     $ca =~ /<\S+\@\S+$/))
48158c2ecf20Sopenharmony_ci					{
48168c2ecf20Sopenharmony_ci						$ok = 1;
48178c2ecf20Sopenharmony_ci					}
48188c2ecf20Sopenharmony_ci
48198c2ecf20Sopenharmony_ci					# for asm volatile statements
48208c2ecf20Sopenharmony_ci					# ignore a colon with another
48218c2ecf20Sopenharmony_ci					# colon immediately before or after
48228c2ecf20Sopenharmony_ci					if (($op eq ':') &&
48238c2ecf20Sopenharmony_ci					    ($ca =~ /:$/ || $cc =~ /^:/)) {
48248c2ecf20Sopenharmony_ci						$ok = 1;
48258c2ecf20Sopenharmony_ci					}
48268c2ecf20Sopenharmony_ci
48278c2ecf20Sopenharmony_ci					# messages are ERROR, but ?: are CHK
48288c2ecf20Sopenharmony_ci					if ($ok == 0) {
48298c2ecf20Sopenharmony_ci						my $msg_level = \&ERROR;
48308c2ecf20Sopenharmony_ci						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
48318c2ecf20Sopenharmony_ci
48328c2ecf20Sopenharmony_ci						if (&{$msg_level}("SPACING",
48338c2ecf20Sopenharmony_ci								  "spaces required around that '$op' $at\n" . $hereptr)) {
48348c2ecf20Sopenharmony_ci							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
48358c2ecf20Sopenharmony_ci							if (defined $fix_elements[$n + 2]) {
48368c2ecf20Sopenharmony_ci								$fix_elements[$n + 2] =~ s/^\s+//;
48378c2ecf20Sopenharmony_ci							}
48388c2ecf20Sopenharmony_ci							$line_fixed = 1;
48398c2ecf20Sopenharmony_ci						}
48408c2ecf20Sopenharmony_ci					}
48418c2ecf20Sopenharmony_ci				}
48428c2ecf20Sopenharmony_ci				$off += length($elements[$n + 1]);
48438c2ecf20Sopenharmony_ci
48448c2ecf20Sopenharmony_ci##				print("n: <$n> GOOD: <$good>\n");
48458c2ecf20Sopenharmony_ci
48468c2ecf20Sopenharmony_ci				$fixed_line = $fixed_line . $good;
48478c2ecf20Sopenharmony_ci			}
48488c2ecf20Sopenharmony_ci
48498c2ecf20Sopenharmony_ci			if (($#elements % 2) == 0) {
48508c2ecf20Sopenharmony_ci				$fixed_line = $fixed_line . $fix_elements[$#elements];
48518c2ecf20Sopenharmony_ci			}
48528c2ecf20Sopenharmony_ci
48538c2ecf20Sopenharmony_ci			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
48548c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] = $fixed_line;
48558c2ecf20Sopenharmony_ci			}
48568c2ecf20Sopenharmony_ci
48578c2ecf20Sopenharmony_ci
48588c2ecf20Sopenharmony_ci		}
48598c2ecf20Sopenharmony_ci
48608c2ecf20Sopenharmony_ci# check for whitespace before a non-naked semicolon
48618c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*\S\s+;\s*$/) {
48628c2ecf20Sopenharmony_ci			if (WARN("SPACING",
48638c2ecf20Sopenharmony_ci				 "space prohibited before semicolon\n" . $herecurr) &&
48648c2ecf20Sopenharmony_ci			    $fix) {
48658c2ecf20Sopenharmony_ci				1 while $fixed[$fixlinenr] =~
48668c2ecf20Sopenharmony_ci				    s/^(\+.*\S)\s+;/$1;/;
48678c2ecf20Sopenharmony_ci			}
48688c2ecf20Sopenharmony_ci		}
48698c2ecf20Sopenharmony_ci
48708c2ecf20Sopenharmony_ci# check for multiple assignments
48718c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
48728c2ecf20Sopenharmony_ci			CHK("MULTIPLE_ASSIGNMENTS",
48738c2ecf20Sopenharmony_ci			    "multiple assignments should be avoided\n" . $herecurr);
48748c2ecf20Sopenharmony_ci		}
48758c2ecf20Sopenharmony_ci
48768c2ecf20Sopenharmony_ci## # check for multiple declarations, allowing for a function declaration
48778c2ecf20Sopenharmony_ci## # continuation.
48788c2ecf20Sopenharmony_ci## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
48798c2ecf20Sopenharmony_ci## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
48808c2ecf20Sopenharmony_ci##
48818c2ecf20Sopenharmony_ci## 			# Remove any bracketed sections to ensure we do not
48828c2ecf20Sopenharmony_ci## 			# falsly report the parameters of functions.
48838c2ecf20Sopenharmony_ci## 			my $ln = $line;
48848c2ecf20Sopenharmony_ci## 			while ($ln =~ s/\([^\(\)]*\)//g) {
48858c2ecf20Sopenharmony_ci## 			}
48868c2ecf20Sopenharmony_ci## 			if ($ln =~ /,/) {
48878c2ecf20Sopenharmony_ci## 				WARN("MULTIPLE_DECLARATION",
48888c2ecf20Sopenharmony_ci##				     "declaring multiple variables together should be avoided\n" . $herecurr);
48898c2ecf20Sopenharmony_ci## 			}
48908c2ecf20Sopenharmony_ci## 		}
48918c2ecf20Sopenharmony_ci
48928c2ecf20Sopenharmony_ci#need space before brace following if, while, etc
48938c2ecf20Sopenharmony_ci		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
48948c2ecf20Sopenharmony_ci		    $line =~ /\b(?:else|do)\{/) {
48958c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
48968c2ecf20Sopenharmony_ci				  "space required before the open brace '{'\n" . $herecurr) &&
48978c2ecf20Sopenharmony_ci			    $fix) {
48988c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
48998c2ecf20Sopenharmony_ci			}
49008c2ecf20Sopenharmony_ci		}
49018c2ecf20Sopenharmony_ci
49028c2ecf20Sopenharmony_ci## # check for blank lines before declarations
49038c2ecf20Sopenharmony_ci##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
49048c2ecf20Sopenharmony_ci##		    $prevrawline =~ /^.\s*$/) {
49058c2ecf20Sopenharmony_ci##			WARN("SPACING",
49068c2ecf20Sopenharmony_ci##			     "No blank lines before declarations\n" . $hereprev);
49078c2ecf20Sopenharmony_ci##		}
49088c2ecf20Sopenharmony_ci##
49098c2ecf20Sopenharmony_ci
49108c2ecf20Sopenharmony_ci# closing brace should have a space following it when it has anything
49118c2ecf20Sopenharmony_ci# on the line
49128c2ecf20Sopenharmony_ci		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
49138c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
49148c2ecf20Sopenharmony_ci				  "space required after that close brace '}'\n" . $herecurr) &&
49158c2ecf20Sopenharmony_ci			    $fix) {
49168c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
49178c2ecf20Sopenharmony_ci				    s/}((?!(?:,|;|\)))\S)/} $1/;
49188c2ecf20Sopenharmony_ci			}
49198c2ecf20Sopenharmony_ci		}
49208c2ecf20Sopenharmony_ci
49218c2ecf20Sopenharmony_ci# check spacing on square brackets
49228c2ecf20Sopenharmony_ci		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
49238c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
49248c2ecf20Sopenharmony_ci				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
49258c2ecf20Sopenharmony_ci			    $fix) {
49268c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
49278c2ecf20Sopenharmony_ci				    s/\[\s+/\[/;
49288c2ecf20Sopenharmony_ci			}
49298c2ecf20Sopenharmony_ci		}
49308c2ecf20Sopenharmony_ci		if ($line =~ /\s\]/) {
49318c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
49328c2ecf20Sopenharmony_ci				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
49338c2ecf20Sopenharmony_ci			    $fix) {
49348c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
49358c2ecf20Sopenharmony_ci				    s/\s+\]/\]/;
49368c2ecf20Sopenharmony_ci			}
49378c2ecf20Sopenharmony_ci		}
49388c2ecf20Sopenharmony_ci
49398c2ecf20Sopenharmony_ci# check spacing on parentheses
49408c2ecf20Sopenharmony_ci		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
49418c2ecf20Sopenharmony_ci		    $line !~ /for\s*\(\s+;/) {
49428c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
49438c2ecf20Sopenharmony_ci				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
49448c2ecf20Sopenharmony_ci			    $fix) {
49458c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
49468c2ecf20Sopenharmony_ci				    s/\(\s+/\(/;
49478c2ecf20Sopenharmony_ci			}
49488c2ecf20Sopenharmony_ci		}
49498c2ecf20Sopenharmony_ci		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
49508c2ecf20Sopenharmony_ci		    $line !~ /for\s*\(.*;\s+\)/ &&
49518c2ecf20Sopenharmony_ci		    $line !~ /:\s+\)/) {
49528c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
49538c2ecf20Sopenharmony_ci				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
49548c2ecf20Sopenharmony_ci			    $fix) {
49558c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
49568c2ecf20Sopenharmony_ci				    s/\s+\)/\)/;
49578c2ecf20Sopenharmony_ci			}
49588c2ecf20Sopenharmony_ci		}
49598c2ecf20Sopenharmony_ci
49608c2ecf20Sopenharmony_ci# check unnecessary parentheses around addressof/dereference single $Lvals
49618c2ecf20Sopenharmony_ci# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
49628c2ecf20Sopenharmony_ci
49638c2ecf20Sopenharmony_ci		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
49648c2ecf20Sopenharmony_ci			my $var = $1;
49658c2ecf20Sopenharmony_ci			if (CHK("UNNECESSARY_PARENTHESES",
49668c2ecf20Sopenharmony_ci				"Unnecessary parentheses around $var\n" . $herecurr) &&
49678c2ecf20Sopenharmony_ci			    $fix) {
49688c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
49698c2ecf20Sopenharmony_ci			}
49708c2ecf20Sopenharmony_ci		}
49718c2ecf20Sopenharmony_ci
49728c2ecf20Sopenharmony_ci# check for unnecessary parentheses around function pointer uses
49738c2ecf20Sopenharmony_ci# ie: (foo->bar)(); should be foo->bar();
49748c2ecf20Sopenharmony_ci# but not "if (foo->bar) (" to avoid some false positives
49758c2ecf20Sopenharmony_ci		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
49768c2ecf20Sopenharmony_ci			my $var = $2;
49778c2ecf20Sopenharmony_ci			if (CHK("UNNECESSARY_PARENTHESES",
49788c2ecf20Sopenharmony_ci				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
49798c2ecf20Sopenharmony_ci			    $fix) {
49808c2ecf20Sopenharmony_ci				my $var2 = deparenthesize($var);
49818c2ecf20Sopenharmony_ci				$var2 =~ s/\s//g;
49828c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
49838c2ecf20Sopenharmony_ci			}
49848c2ecf20Sopenharmony_ci		}
49858c2ecf20Sopenharmony_ci
49868c2ecf20Sopenharmony_ci# check for unnecessary parentheses around comparisons in if uses
49878c2ecf20Sopenharmony_ci# when !drivers/staging or command-line uses --strict
49888c2ecf20Sopenharmony_ci		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
49898c2ecf20Sopenharmony_ci		    $perl_version_ok && defined($stat) &&
49908c2ecf20Sopenharmony_ci		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
49918c2ecf20Sopenharmony_ci			my $if_stat = $1;
49928c2ecf20Sopenharmony_ci			my $test = substr($2, 1, -1);
49938c2ecf20Sopenharmony_ci			my $herectx;
49948c2ecf20Sopenharmony_ci			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
49958c2ecf20Sopenharmony_ci				my $match = $1;
49968c2ecf20Sopenharmony_ci				# avoid parentheses around potential macro args
49978c2ecf20Sopenharmony_ci				next if ($match =~ /^\s*\w+\s*$/);
49988c2ecf20Sopenharmony_ci				if (!defined($herectx)) {
49998c2ecf20Sopenharmony_ci					$herectx = $here . "\n";
50008c2ecf20Sopenharmony_ci					my $cnt = statement_rawlines($if_stat);
50018c2ecf20Sopenharmony_ci					for (my $n = 0; $n < $cnt; $n++) {
50028c2ecf20Sopenharmony_ci						my $rl = raw_line($linenr, $n);
50038c2ecf20Sopenharmony_ci						$herectx .=  $rl . "\n";
50048c2ecf20Sopenharmony_ci						last if $rl =~ /^[ \+].*\{/;
50058c2ecf20Sopenharmony_ci					}
50068c2ecf20Sopenharmony_ci				}
50078c2ecf20Sopenharmony_ci				CHK("UNNECESSARY_PARENTHESES",
50088c2ecf20Sopenharmony_ci				    "Unnecessary parentheses around '$match'\n" . $herectx);
50098c2ecf20Sopenharmony_ci			}
50108c2ecf20Sopenharmony_ci		}
50118c2ecf20Sopenharmony_ci
50128c2ecf20Sopenharmony_ci#goto labels aren't indented, allow a single space however
50138c2ecf20Sopenharmony_ci		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
50148c2ecf20Sopenharmony_ci		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
50158c2ecf20Sopenharmony_ci			if (WARN("INDENTED_LABEL",
50168c2ecf20Sopenharmony_ci				 "labels should not be indented\n" . $herecurr) &&
50178c2ecf20Sopenharmony_ci			    $fix) {
50188c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
50198c2ecf20Sopenharmony_ci				    s/^(.)\s+/$1/;
50208c2ecf20Sopenharmony_ci			}
50218c2ecf20Sopenharmony_ci		}
50228c2ecf20Sopenharmony_ci
50238c2ecf20Sopenharmony_ci# check if a statement with a comma should be two statements like:
50248c2ecf20Sopenharmony_ci#	foo = bar(),	/* comma should be semicolon */
50258c2ecf20Sopenharmony_ci#	bar = baz();
50268c2ecf20Sopenharmony_ci		if (defined($stat) &&
50278c2ecf20Sopenharmony_ci		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
50288c2ecf20Sopenharmony_ci			my $cnt = statement_rawlines($stat);
50298c2ecf20Sopenharmony_ci			my $herectx = get_stat_here($linenr, $cnt, $here);
50308c2ecf20Sopenharmony_ci			WARN("SUSPECT_COMMA_SEMICOLON",
50318c2ecf20Sopenharmony_ci			     "Possible comma where semicolon could be used\n" . $herectx);
50328c2ecf20Sopenharmony_ci		}
50338c2ecf20Sopenharmony_ci
50348c2ecf20Sopenharmony_ci# return is not a function
50358c2ecf20Sopenharmony_ci		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
50368c2ecf20Sopenharmony_ci			my $spacing = $1;
50378c2ecf20Sopenharmony_ci			if ($perl_version_ok &&
50388c2ecf20Sopenharmony_ci			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
50398c2ecf20Sopenharmony_ci				my $value = $1;
50408c2ecf20Sopenharmony_ci				$value = deparenthesize($value);
50418c2ecf20Sopenharmony_ci				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
50428c2ecf20Sopenharmony_ci					ERROR("RETURN_PARENTHESES",
50438c2ecf20Sopenharmony_ci					      "return is not a function, parentheses are not required\n" . $herecurr);
50448c2ecf20Sopenharmony_ci				}
50458c2ecf20Sopenharmony_ci			} elsif ($spacing !~ /\s+/) {
50468c2ecf20Sopenharmony_ci				ERROR("SPACING",
50478c2ecf20Sopenharmony_ci				      "space required before the open parenthesis '('\n" . $herecurr);
50488c2ecf20Sopenharmony_ci			}
50498c2ecf20Sopenharmony_ci		}
50508c2ecf20Sopenharmony_ci
50518c2ecf20Sopenharmony_ci# unnecessary return in a void function
50528c2ecf20Sopenharmony_ci# at end-of-function, with the previous line a single leading tab, then return;
50538c2ecf20Sopenharmony_ci# and the line before that not a goto label target like "out:"
50548c2ecf20Sopenharmony_ci		if ($sline =~ /^[ \+]}\s*$/ &&
50558c2ecf20Sopenharmony_ci		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
50568c2ecf20Sopenharmony_ci		    $linenr >= 3 &&
50578c2ecf20Sopenharmony_ci		    $lines[$linenr - 3] =~ /^[ +]/ &&
50588c2ecf20Sopenharmony_ci		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
50598c2ecf20Sopenharmony_ci			WARN("RETURN_VOID",
50608c2ecf20Sopenharmony_ci			     "void function return statements are not generally useful\n" . $hereprev);
50618c2ecf20Sopenharmony_ci               }
50628c2ecf20Sopenharmony_ci
50638c2ecf20Sopenharmony_ci# if statements using unnecessary parentheses - ie: if ((foo == bar))
50648c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
50658c2ecf20Sopenharmony_ci		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
50668c2ecf20Sopenharmony_ci			my $openparens = $1;
50678c2ecf20Sopenharmony_ci			my $count = $openparens =~ tr@\(@\(@;
50688c2ecf20Sopenharmony_ci			my $msg = "";
50698c2ecf20Sopenharmony_ci			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
50708c2ecf20Sopenharmony_ci				my $comp = $4;	#Not $1 because of $LvalOrFunc
50718c2ecf20Sopenharmony_ci				$msg = " - maybe == should be = ?" if ($comp eq "==");
50728c2ecf20Sopenharmony_ci				WARN("UNNECESSARY_PARENTHESES",
50738c2ecf20Sopenharmony_ci				     "Unnecessary parentheses$msg\n" . $herecurr);
50748c2ecf20Sopenharmony_ci			}
50758c2ecf20Sopenharmony_ci		}
50768c2ecf20Sopenharmony_ci
50778c2ecf20Sopenharmony_ci# comparisons with a constant or upper case identifier on the left
50788c2ecf20Sopenharmony_ci#	avoid cases like "foo + BAR < baz"
50798c2ecf20Sopenharmony_ci#	only fix matches surrounded by parentheses to avoid incorrect
50808c2ecf20Sopenharmony_ci#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
50818c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
50828c2ecf20Sopenharmony_ci		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
50838c2ecf20Sopenharmony_ci			my $lead = $1;
50848c2ecf20Sopenharmony_ci			my $const = $2;
50858c2ecf20Sopenharmony_ci			my $comp = $3;
50868c2ecf20Sopenharmony_ci			my $to = $4;
50878c2ecf20Sopenharmony_ci			my $newcomp = $comp;
50888c2ecf20Sopenharmony_ci			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
50898c2ecf20Sopenharmony_ci			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
50908c2ecf20Sopenharmony_ci			    WARN("CONSTANT_COMPARISON",
50918c2ecf20Sopenharmony_ci				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
50928c2ecf20Sopenharmony_ci			    $fix) {
50938c2ecf20Sopenharmony_ci				if ($comp eq "<") {
50948c2ecf20Sopenharmony_ci					$newcomp = ">";
50958c2ecf20Sopenharmony_ci				} elsif ($comp eq "<=") {
50968c2ecf20Sopenharmony_ci					$newcomp = ">=";
50978c2ecf20Sopenharmony_ci				} elsif ($comp eq ">") {
50988c2ecf20Sopenharmony_ci					$newcomp = "<";
50998c2ecf20Sopenharmony_ci				} elsif ($comp eq ">=") {
51008c2ecf20Sopenharmony_ci					$newcomp = "<=";
51018c2ecf20Sopenharmony_ci				}
51028c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
51038c2ecf20Sopenharmony_ci			}
51048c2ecf20Sopenharmony_ci		}
51058c2ecf20Sopenharmony_ci
51068c2ecf20Sopenharmony_ci# Return of what appears to be an errno should normally be negative
51078c2ecf20Sopenharmony_ci		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
51088c2ecf20Sopenharmony_ci			my $name = $1;
51098c2ecf20Sopenharmony_ci			if ($name ne 'EOF' && $name ne 'ERROR') {
51108c2ecf20Sopenharmony_ci				WARN("USE_NEGATIVE_ERRNO",
51118c2ecf20Sopenharmony_ci				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
51128c2ecf20Sopenharmony_ci			}
51138c2ecf20Sopenharmony_ci		}
51148c2ecf20Sopenharmony_ci
51158c2ecf20Sopenharmony_ci# Need a space before open parenthesis after if, while etc
51168c2ecf20Sopenharmony_ci		if ($line =~ /\b(if|while|for|switch)\(/) {
51178c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
51188c2ecf20Sopenharmony_ci				  "space required before the open parenthesis '('\n" . $herecurr) &&
51198c2ecf20Sopenharmony_ci			    $fix) {
51208c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
51218c2ecf20Sopenharmony_ci				    s/\b(if|while|for|switch)\(/$1 \(/;
51228c2ecf20Sopenharmony_ci			}
51238c2ecf20Sopenharmony_ci		}
51248c2ecf20Sopenharmony_ci
51258c2ecf20Sopenharmony_ci# Check for illegal assignment in if conditional -- and check for trailing
51268c2ecf20Sopenharmony_ci# statements after the conditional.
51278c2ecf20Sopenharmony_ci		if ($line =~ /do\s*(?!{)/) {
51288c2ecf20Sopenharmony_ci			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
51298c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0)
51308c2ecf20Sopenharmony_ci					if (!defined $stat);
51318c2ecf20Sopenharmony_ci			my ($stat_next) = ctx_statement_block($line_nr_next,
51328c2ecf20Sopenharmony_ci						$remain_next, $off_next);
51338c2ecf20Sopenharmony_ci			$stat_next =~ s/\n./\n /g;
51348c2ecf20Sopenharmony_ci			##print "stat<$stat> stat_next<$stat_next>\n";
51358c2ecf20Sopenharmony_ci
51368c2ecf20Sopenharmony_ci			if ($stat_next =~ /^\s*while\b/) {
51378c2ecf20Sopenharmony_ci				# If the statement carries leading newlines,
51388c2ecf20Sopenharmony_ci				# then count those as offsets.
51398c2ecf20Sopenharmony_ci				my ($whitespace) =
51408c2ecf20Sopenharmony_ci					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
51418c2ecf20Sopenharmony_ci				my $offset =
51428c2ecf20Sopenharmony_ci					statement_rawlines($whitespace) - 1;
51438c2ecf20Sopenharmony_ci
51448c2ecf20Sopenharmony_ci				$suppress_whiletrailers{$line_nr_next +
51458c2ecf20Sopenharmony_ci								$offset} = 1;
51468c2ecf20Sopenharmony_ci			}
51478c2ecf20Sopenharmony_ci		}
51488c2ecf20Sopenharmony_ci		if (!defined $suppress_whiletrailers{$linenr} &&
51498c2ecf20Sopenharmony_ci		    defined($stat) && defined($cond) &&
51508c2ecf20Sopenharmony_ci		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
51518c2ecf20Sopenharmony_ci			my ($s, $c) = ($stat, $cond);
51528c2ecf20Sopenharmony_ci
51538c2ecf20Sopenharmony_ci			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
51548c2ecf20Sopenharmony_ci				if (ERROR("ASSIGN_IN_IF",
51558c2ecf20Sopenharmony_ci					  "do not use assignment in if condition\n" . $herecurr) &&
51568c2ecf20Sopenharmony_ci				    $fix && $perl_version_ok) {
51578c2ecf20Sopenharmony_ci					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
51588c2ecf20Sopenharmony_ci						my $space = $1;
51598c2ecf20Sopenharmony_ci						my $not = $2;
51608c2ecf20Sopenharmony_ci						my $statement = $3;
51618c2ecf20Sopenharmony_ci						my $assigned = $4;
51628c2ecf20Sopenharmony_ci						my $test = $8;
51638c2ecf20Sopenharmony_ci						my $against = $9;
51648c2ecf20Sopenharmony_ci						my $brace = $15;
51658c2ecf20Sopenharmony_ci						fix_delete_line($fixlinenr, $rawline);
51668c2ecf20Sopenharmony_ci						fix_insert_line($fixlinenr, "$space$statement;");
51678c2ecf20Sopenharmony_ci						my $newline = "${space}if (";
51688c2ecf20Sopenharmony_ci						$newline .= '!' if defined($not);
51698c2ecf20Sopenharmony_ci						$newline .= '(' if (defined $not && defined($test) && defined($against));
51708c2ecf20Sopenharmony_ci						$newline .= "$assigned";
51718c2ecf20Sopenharmony_ci						$newline .= " $test $against" if (defined($test) && defined($against));
51728c2ecf20Sopenharmony_ci						$newline .= ')' if (defined $not && defined($test) && defined($against));
51738c2ecf20Sopenharmony_ci						$newline .= ')';
51748c2ecf20Sopenharmony_ci						$newline .= " {" if (defined($brace));
51758c2ecf20Sopenharmony_ci						fix_insert_line($fixlinenr + 1, $newline);
51768c2ecf20Sopenharmony_ci					}
51778c2ecf20Sopenharmony_ci				}
51788c2ecf20Sopenharmony_ci			}
51798c2ecf20Sopenharmony_ci
51808c2ecf20Sopenharmony_ci			# Find out what is on the end of the line after the
51818c2ecf20Sopenharmony_ci			# conditional.
51828c2ecf20Sopenharmony_ci			substr($s, 0, length($c), '');
51838c2ecf20Sopenharmony_ci			$s =~ s/\n.*//g;
51848c2ecf20Sopenharmony_ci			$s =~ s/$;//g;	# Remove any comments
51858c2ecf20Sopenharmony_ci			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
51868c2ecf20Sopenharmony_ci			    $c !~ /}\s*while\s*/)
51878c2ecf20Sopenharmony_ci			{
51888c2ecf20Sopenharmony_ci				# Find out how long the conditional actually is.
51898c2ecf20Sopenharmony_ci				my @newlines = ($c =~ /\n/gs);
51908c2ecf20Sopenharmony_ci				my $cond_lines = 1 + $#newlines;
51918c2ecf20Sopenharmony_ci				my $stat_real = '';
51928c2ecf20Sopenharmony_ci
51938c2ecf20Sopenharmony_ci				$stat_real = raw_line($linenr, $cond_lines)
51948c2ecf20Sopenharmony_ci							. "\n" if ($cond_lines);
51958c2ecf20Sopenharmony_ci				if (defined($stat_real) && $cond_lines > 1) {
51968c2ecf20Sopenharmony_ci					$stat_real = "[...]\n$stat_real";
51978c2ecf20Sopenharmony_ci				}
51988c2ecf20Sopenharmony_ci
51998c2ecf20Sopenharmony_ci				ERROR("TRAILING_STATEMENTS",
52008c2ecf20Sopenharmony_ci				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
52018c2ecf20Sopenharmony_ci			}
52028c2ecf20Sopenharmony_ci		}
52038c2ecf20Sopenharmony_ci
52048c2ecf20Sopenharmony_ci# Check for bitwise tests written as boolean
52058c2ecf20Sopenharmony_ci		if ($line =~ /
52068c2ecf20Sopenharmony_ci			(?:
52078c2ecf20Sopenharmony_ci				(?:\[|\(|\&\&|\|\|)
52088c2ecf20Sopenharmony_ci				\s*0[xX][0-9]+\s*
52098c2ecf20Sopenharmony_ci				(?:\&\&|\|\|)
52108c2ecf20Sopenharmony_ci			|
52118c2ecf20Sopenharmony_ci				(?:\&\&|\|\|)
52128c2ecf20Sopenharmony_ci				\s*0[xX][0-9]+\s*
52138c2ecf20Sopenharmony_ci				(?:\&\&|\|\||\)|\])
52148c2ecf20Sopenharmony_ci			)/x)
52158c2ecf20Sopenharmony_ci		{
52168c2ecf20Sopenharmony_ci			WARN("HEXADECIMAL_BOOLEAN_TEST",
52178c2ecf20Sopenharmony_ci			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
52188c2ecf20Sopenharmony_ci		}
52198c2ecf20Sopenharmony_ci
52208c2ecf20Sopenharmony_ci# if and else should not have general statements after it
52218c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
52228c2ecf20Sopenharmony_ci			my $s = $1;
52238c2ecf20Sopenharmony_ci			$s =~ s/$;//g;	# Remove any comments
52248c2ecf20Sopenharmony_ci			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
52258c2ecf20Sopenharmony_ci				ERROR("TRAILING_STATEMENTS",
52268c2ecf20Sopenharmony_ci				      "trailing statements should be on next line\n" . $herecurr);
52278c2ecf20Sopenharmony_ci			}
52288c2ecf20Sopenharmony_ci		}
52298c2ecf20Sopenharmony_ci# if should not continue a brace
52308c2ecf20Sopenharmony_ci		if ($line =~ /}\s*if\b/) {
52318c2ecf20Sopenharmony_ci			ERROR("TRAILING_STATEMENTS",
52328c2ecf20Sopenharmony_ci			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
52338c2ecf20Sopenharmony_ci				$herecurr);
52348c2ecf20Sopenharmony_ci		}
52358c2ecf20Sopenharmony_ci# case and default should not have general statements after them
52368c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
52378c2ecf20Sopenharmony_ci		    $line !~ /\G(?:
52388c2ecf20Sopenharmony_ci			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
52398c2ecf20Sopenharmony_ci			\s*return\s+
52408c2ecf20Sopenharmony_ci		    )/xg)
52418c2ecf20Sopenharmony_ci		{
52428c2ecf20Sopenharmony_ci			ERROR("TRAILING_STATEMENTS",
52438c2ecf20Sopenharmony_ci			      "trailing statements should be on next line\n" . $herecurr);
52448c2ecf20Sopenharmony_ci		}
52458c2ecf20Sopenharmony_ci
52468c2ecf20Sopenharmony_ci		# Check for }<nl>else {, these must be at the same
52478c2ecf20Sopenharmony_ci		# indent level to be relevant to each other.
52488c2ecf20Sopenharmony_ci		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
52498c2ecf20Sopenharmony_ci		    $previndent == $indent) {
52508c2ecf20Sopenharmony_ci			if (ERROR("ELSE_AFTER_BRACE",
52518c2ecf20Sopenharmony_ci				  "else should follow close brace '}'\n" . $hereprev) &&
52528c2ecf20Sopenharmony_ci			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
52538c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
52548c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
52558c2ecf20Sopenharmony_ci				my $fixedline = $prevrawline;
52568c2ecf20Sopenharmony_ci				$fixedline =~ s/}\s*$//;
52578c2ecf20Sopenharmony_ci				if ($fixedline !~ /^\+\s*$/) {
52588c2ecf20Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
52598c2ecf20Sopenharmony_ci				}
52608c2ecf20Sopenharmony_ci				$fixedline = $rawline;
52618c2ecf20Sopenharmony_ci				$fixedline =~ s/^(.\s*)else/$1} else/;
52628c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr, $fixedline);
52638c2ecf20Sopenharmony_ci			}
52648c2ecf20Sopenharmony_ci		}
52658c2ecf20Sopenharmony_ci
52668c2ecf20Sopenharmony_ci		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
52678c2ecf20Sopenharmony_ci		    $previndent == $indent) {
52688c2ecf20Sopenharmony_ci			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
52698c2ecf20Sopenharmony_ci
52708c2ecf20Sopenharmony_ci			# Find out what is on the end of the line after the
52718c2ecf20Sopenharmony_ci			# conditional.
52728c2ecf20Sopenharmony_ci			substr($s, 0, length($c), '');
52738c2ecf20Sopenharmony_ci			$s =~ s/\n.*//g;
52748c2ecf20Sopenharmony_ci
52758c2ecf20Sopenharmony_ci			if ($s =~ /^\s*;/) {
52768c2ecf20Sopenharmony_ci				if (ERROR("WHILE_AFTER_BRACE",
52778c2ecf20Sopenharmony_ci					  "while should follow close brace '}'\n" . $hereprev) &&
52788c2ecf20Sopenharmony_ci				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
52798c2ecf20Sopenharmony_ci					fix_delete_line($fixlinenr - 1, $prevrawline);
52808c2ecf20Sopenharmony_ci					fix_delete_line($fixlinenr, $rawline);
52818c2ecf20Sopenharmony_ci					my $fixedline = $prevrawline;
52828c2ecf20Sopenharmony_ci					my $trailing = $rawline;
52838c2ecf20Sopenharmony_ci					$trailing =~ s/^\+//;
52848c2ecf20Sopenharmony_ci					$trailing = trim($trailing);
52858c2ecf20Sopenharmony_ci					$fixedline =~ s/}\s*$/} $trailing/;
52868c2ecf20Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
52878c2ecf20Sopenharmony_ci				}
52888c2ecf20Sopenharmony_ci			}
52898c2ecf20Sopenharmony_ci		}
52908c2ecf20Sopenharmony_ci
52918c2ecf20Sopenharmony_ci#Specific variable tests
52928c2ecf20Sopenharmony_ci		while ($line =~ m{($Constant|$Lval)}g) {
52938c2ecf20Sopenharmony_ci			my $var = $1;
52948c2ecf20Sopenharmony_ci
52958c2ecf20Sopenharmony_ci#CamelCase
52968c2ecf20Sopenharmony_ci			if ($var !~ /^$Constant$/ &&
52978c2ecf20Sopenharmony_ci			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
52988c2ecf20Sopenharmony_ci#Ignore Page<foo> variants
52998c2ecf20Sopenharmony_ci			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
53008c2ecf20Sopenharmony_ci#Ignore SI style variants like nS, mV and dB
53018c2ecf20Sopenharmony_ci#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
53028c2ecf20Sopenharmony_ci			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
53038c2ecf20Sopenharmony_ci#Ignore some three character SI units explicitly, like MiB and KHz
53048c2ecf20Sopenharmony_ci			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
53058c2ecf20Sopenharmony_ci				while ($var =~ m{($Ident)}g) {
53068c2ecf20Sopenharmony_ci					my $word = $1;
53078c2ecf20Sopenharmony_ci					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
53088c2ecf20Sopenharmony_ci					if ($check) {
53098c2ecf20Sopenharmony_ci						seed_camelcase_includes();
53108c2ecf20Sopenharmony_ci						if (!$file && !$camelcase_file_seeded) {
53118c2ecf20Sopenharmony_ci							seed_camelcase_file($realfile);
53128c2ecf20Sopenharmony_ci							$camelcase_file_seeded = 1;
53138c2ecf20Sopenharmony_ci						}
53148c2ecf20Sopenharmony_ci					}
53158c2ecf20Sopenharmony_ci					if (!defined $camelcase{$word}) {
53168c2ecf20Sopenharmony_ci						$camelcase{$word} = 1;
53178c2ecf20Sopenharmony_ci						CHK("CAMELCASE",
53188c2ecf20Sopenharmony_ci						    "Avoid CamelCase: <$word>\n" . $herecurr);
53198c2ecf20Sopenharmony_ci					}
53208c2ecf20Sopenharmony_ci				}
53218c2ecf20Sopenharmony_ci			}
53228c2ecf20Sopenharmony_ci		}
53238c2ecf20Sopenharmony_ci
53248c2ecf20Sopenharmony_ci#no spaces allowed after \ in define
53258c2ecf20Sopenharmony_ci		if ($line =~ /\#\s*define.*\\\s+$/) {
53268c2ecf20Sopenharmony_ci			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
53278c2ecf20Sopenharmony_ci				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
53288c2ecf20Sopenharmony_ci			    $fix) {
53298c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+$//;
53308c2ecf20Sopenharmony_ci			}
53318c2ecf20Sopenharmony_ci		}
53328c2ecf20Sopenharmony_ci
53338c2ecf20Sopenharmony_ci# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
53348c2ecf20Sopenharmony_ci# itself <asm/foo.h> (uses RAW line)
53358c2ecf20Sopenharmony_ci		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
53368c2ecf20Sopenharmony_ci			my $file = "$1.h";
53378c2ecf20Sopenharmony_ci			my $checkfile = "include/linux/$file";
53388c2ecf20Sopenharmony_ci			if (-f "$root/$checkfile" &&
53398c2ecf20Sopenharmony_ci			    $realfile ne $checkfile &&
53408c2ecf20Sopenharmony_ci			    $1 !~ /$allowed_asm_includes/)
53418c2ecf20Sopenharmony_ci			{
53428c2ecf20Sopenharmony_ci				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
53438c2ecf20Sopenharmony_ci				if ($asminclude > 0) {
53448c2ecf20Sopenharmony_ci					if ($realfile =~ m{^arch/}) {
53458c2ecf20Sopenharmony_ci						CHK("ARCH_INCLUDE_LINUX",
53468c2ecf20Sopenharmony_ci						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
53478c2ecf20Sopenharmony_ci					} else {
53488c2ecf20Sopenharmony_ci						WARN("INCLUDE_LINUX",
53498c2ecf20Sopenharmony_ci						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
53508c2ecf20Sopenharmony_ci					}
53518c2ecf20Sopenharmony_ci				}
53528c2ecf20Sopenharmony_ci			}
53538c2ecf20Sopenharmony_ci		}
53548c2ecf20Sopenharmony_ci
53558c2ecf20Sopenharmony_ci# multi-statement macros should be enclosed in a do while loop, grab the
53568c2ecf20Sopenharmony_ci# first statement and ensure its the whole macro if its not enclosed
53578c2ecf20Sopenharmony_ci# in a known good container
53588c2ecf20Sopenharmony_ci		if ($realfile !~ m@/vmlinux.lds.h$@ &&
53598c2ecf20Sopenharmony_ci		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
53608c2ecf20Sopenharmony_ci			my $ln = $linenr;
53618c2ecf20Sopenharmony_ci			my $cnt = $realcnt;
53628c2ecf20Sopenharmony_ci			my ($off, $dstat, $dcond, $rest);
53638c2ecf20Sopenharmony_ci			my $ctx = '';
53648c2ecf20Sopenharmony_ci			my $has_flow_statement = 0;
53658c2ecf20Sopenharmony_ci			my $has_arg_concat = 0;
53668c2ecf20Sopenharmony_ci			($dstat, $dcond, $ln, $cnt, $off) =
53678c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
53688c2ecf20Sopenharmony_ci			$ctx = $dstat;
53698c2ecf20Sopenharmony_ci			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
53708c2ecf20Sopenharmony_ci			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
53718c2ecf20Sopenharmony_ci
53728c2ecf20Sopenharmony_ci			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
53738c2ecf20Sopenharmony_ci			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
53748c2ecf20Sopenharmony_ci
53758c2ecf20Sopenharmony_ci			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
53768c2ecf20Sopenharmony_ci			my $define_args = $1;
53778c2ecf20Sopenharmony_ci			my $define_stmt = $dstat;
53788c2ecf20Sopenharmony_ci			my @def_args = ();
53798c2ecf20Sopenharmony_ci
53808c2ecf20Sopenharmony_ci			if (defined $define_args && $define_args ne "") {
53818c2ecf20Sopenharmony_ci				$define_args = substr($define_args, 1, length($define_args) - 2);
53828c2ecf20Sopenharmony_ci				$define_args =~ s/\s*//g;
53838c2ecf20Sopenharmony_ci				$define_args =~ s/\\\+?//g;
53848c2ecf20Sopenharmony_ci				@def_args = split(",", $define_args);
53858c2ecf20Sopenharmony_ci			}
53868c2ecf20Sopenharmony_ci
53878c2ecf20Sopenharmony_ci			$dstat =~ s/$;//g;
53888c2ecf20Sopenharmony_ci			$dstat =~ s/\\\n.//g;
53898c2ecf20Sopenharmony_ci			$dstat =~ s/^\s*//s;
53908c2ecf20Sopenharmony_ci			$dstat =~ s/\s*$//s;
53918c2ecf20Sopenharmony_ci
53928c2ecf20Sopenharmony_ci			# Flatten any parentheses and braces
53938c2ecf20Sopenharmony_ci			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
53948c2ecf20Sopenharmony_ci			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
53958c2ecf20Sopenharmony_ci			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
53968c2ecf20Sopenharmony_ci			{
53978c2ecf20Sopenharmony_ci			}
53988c2ecf20Sopenharmony_ci
53998c2ecf20Sopenharmony_ci			# Flatten any obvious string concatenation.
54008c2ecf20Sopenharmony_ci			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
54018c2ecf20Sopenharmony_ci			       $dstat =~ s/$Ident\s*($String)/$1/)
54028c2ecf20Sopenharmony_ci			{
54038c2ecf20Sopenharmony_ci			}
54048c2ecf20Sopenharmony_ci
54058c2ecf20Sopenharmony_ci			# Make asm volatile uses seem like a generic function
54068c2ecf20Sopenharmony_ci			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
54078c2ecf20Sopenharmony_ci
54088c2ecf20Sopenharmony_ci			my $exceptions = qr{
54098c2ecf20Sopenharmony_ci				$Declare|
54108c2ecf20Sopenharmony_ci				module_param_named|
54118c2ecf20Sopenharmony_ci				MODULE_PARM_DESC|
54128c2ecf20Sopenharmony_ci				DECLARE_PER_CPU|
54138c2ecf20Sopenharmony_ci				DEFINE_PER_CPU|
54148c2ecf20Sopenharmony_ci				__typeof__\(|
54158c2ecf20Sopenharmony_ci				union|
54168c2ecf20Sopenharmony_ci				struct|
54178c2ecf20Sopenharmony_ci				\.$Ident\s*=\s*|
54188c2ecf20Sopenharmony_ci				^\"|\"$|
54198c2ecf20Sopenharmony_ci				^\[
54208c2ecf20Sopenharmony_ci			}x;
54218c2ecf20Sopenharmony_ci			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
54228c2ecf20Sopenharmony_ci
54238c2ecf20Sopenharmony_ci			$ctx =~ s/\n*$//;
54248c2ecf20Sopenharmony_ci			my $stmt_cnt = statement_rawlines($ctx);
54258c2ecf20Sopenharmony_ci			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
54268c2ecf20Sopenharmony_ci
54278c2ecf20Sopenharmony_ci			if ($dstat ne '' &&
54288c2ecf20Sopenharmony_ci			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
54298c2ecf20Sopenharmony_ci			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
54308c2ecf20Sopenharmony_ci			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
54318c2ecf20Sopenharmony_ci			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
54328c2ecf20Sopenharmony_ci			    $dstat !~ /$exceptions/ &&
54338c2ecf20Sopenharmony_ci			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
54348c2ecf20Sopenharmony_ci			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
54358c2ecf20Sopenharmony_ci			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
54368c2ecf20Sopenharmony_ci			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
54378c2ecf20Sopenharmony_ci			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
54388c2ecf20Sopenharmony_ci			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
54398c2ecf20Sopenharmony_ci			    $dstat !~ /^do\s*{/ &&					# do {...
54408c2ecf20Sopenharmony_ci			    $dstat !~ /^\(\{/ &&						# ({...
54418c2ecf20Sopenharmony_ci			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
54428c2ecf20Sopenharmony_ci			{
54438c2ecf20Sopenharmony_ci				if ($dstat =~ /^\s*if\b/) {
54448c2ecf20Sopenharmony_ci					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
54458c2ecf20Sopenharmony_ci					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
54468c2ecf20Sopenharmony_ci				} elsif ($dstat =~ /;/) {
54478c2ecf20Sopenharmony_ci					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
54488c2ecf20Sopenharmony_ci					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
54498c2ecf20Sopenharmony_ci				} else {
54508c2ecf20Sopenharmony_ci					ERROR("COMPLEX_MACRO",
54518c2ecf20Sopenharmony_ci					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
54528c2ecf20Sopenharmony_ci				}
54538c2ecf20Sopenharmony_ci
54548c2ecf20Sopenharmony_ci			}
54558c2ecf20Sopenharmony_ci
54568c2ecf20Sopenharmony_ci			# Make $define_stmt single line, comment-free, etc
54578c2ecf20Sopenharmony_ci			my @stmt_array = split('\n', $define_stmt);
54588c2ecf20Sopenharmony_ci			my $first = 1;
54598c2ecf20Sopenharmony_ci			$define_stmt = "";
54608c2ecf20Sopenharmony_ci			foreach my $l (@stmt_array) {
54618c2ecf20Sopenharmony_ci				$l =~ s/\\$//;
54628c2ecf20Sopenharmony_ci				if ($first) {
54638c2ecf20Sopenharmony_ci					$define_stmt = $l;
54648c2ecf20Sopenharmony_ci					$first = 0;
54658c2ecf20Sopenharmony_ci				} elsif ($l =~ /^[\+ ]/) {
54668c2ecf20Sopenharmony_ci					$define_stmt .= substr($l, 1);
54678c2ecf20Sopenharmony_ci				}
54688c2ecf20Sopenharmony_ci			}
54698c2ecf20Sopenharmony_ci			$define_stmt =~ s/$;//g;
54708c2ecf20Sopenharmony_ci			$define_stmt =~ s/\s+/ /g;
54718c2ecf20Sopenharmony_ci			$define_stmt = trim($define_stmt);
54728c2ecf20Sopenharmony_ci
54738c2ecf20Sopenharmony_ci# check if any macro arguments are reused (ignore '...' and 'type')
54748c2ecf20Sopenharmony_ci			foreach my $arg (@def_args) {
54758c2ecf20Sopenharmony_ci			        next if ($arg =~ /\.\.\./);
54768c2ecf20Sopenharmony_ci			        next if ($arg =~ /^type$/i);
54778c2ecf20Sopenharmony_ci				my $tmp_stmt = $define_stmt;
54788c2ecf20Sopenharmony_ci				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
54798c2ecf20Sopenharmony_ci				$tmp_stmt =~ s/\#+\s*$arg\b//g;
54808c2ecf20Sopenharmony_ci				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
54818c2ecf20Sopenharmony_ci				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
54828c2ecf20Sopenharmony_ci				if ($use_cnt > 1) {
54838c2ecf20Sopenharmony_ci					CHK("MACRO_ARG_REUSE",
54848c2ecf20Sopenharmony_ci					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
54858c2ecf20Sopenharmony_ci				    }
54868c2ecf20Sopenharmony_ci# check if any macro arguments may have other precedence issues
54878c2ecf20Sopenharmony_ci				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
54888c2ecf20Sopenharmony_ci				    ((defined($1) && $1 ne ',') ||
54898c2ecf20Sopenharmony_ci				     (defined($2) && $2 ne ','))) {
54908c2ecf20Sopenharmony_ci					CHK("MACRO_ARG_PRECEDENCE",
54918c2ecf20Sopenharmony_ci					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
54928c2ecf20Sopenharmony_ci				}
54938c2ecf20Sopenharmony_ci			}
54948c2ecf20Sopenharmony_ci
54958c2ecf20Sopenharmony_ci# check for macros with flow control, but without ## concatenation
54968c2ecf20Sopenharmony_ci# ## concatenation is commonly a macro that defines a function so ignore those
54978c2ecf20Sopenharmony_ci			if ($has_flow_statement && !$has_arg_concat) {
54988c2ecf20Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
54998c2ecf20Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
55008c2ecf20Sopenharmony_ci
55018c2ecf20Sopenharmony_ci				WARN("MACRO_WITH_FLOW_CONTROL",
55028c2ecf20Sopenharmony_ci				     "Macros with flow control statements should be avoided\n" . "$herectx");
55038c2ecf20Sopenharmony_ci			}
55048c2ecf20Sopenharmony_ci
55058c2ecf20Sopenharmony_ci# check for line continuations outside of #defines, preprocessor #, and asm
55068c2ecf20Sopenharmony_ci
55078c2ecf20Sopenharmony_ci		} else {
55088c2ecf20Sopenharmony_ci			if ($prevline !~ /^..*\\$/ &&
55098c2ecf20Sopenharmony_ci			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
55108c2ecf20Sopenharmony_ci			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
55118c2ecf20Sopenharmony_ci			    $line =~ /^\+.*\\$/) {
55128c2ecf20Sopenharmony_ci				WARN("LINE_CONTINUATIONS",
55138c2ecf20Sopenharmony_ci				     "Avoid unnecessary line continuations\n" . $herecurr);
55148c2ecf20Sopenharmony_ci			}
55158c2ecf20Sopenharmony_ci		}
55168c2ecf20Sopenharmony_ci
55178c2ecf20Sopenharmony_ci# do {} while (0) macro tests:
55188c2ecf20Sopenharmony_ci# single-statement macros do not need to be enclosed in do while (0) loop,
55198c2ecf20Sopenharmony_ci# macro should not end with a semicolon
55208c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
55218c2ecf20Sopenharmony_ci		    $realfile !~ m@/vmlinux.lds.h$@ &&
55228c2ecf20Sopenharmony_ci		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
55238c2ecf20Sopenharmony_ci			my $ln = $linenr;
55248c2ecf20Sopenharmony_ci			my $cnt = $realcnt;
55258c2ecf20Sopenharmony_ci			my ($off, $dstat, $dcond, $rest);
55268c2ecf20Sopenharmony_ci			my $ctx = '';
55278c2ecf20Sopenharmony_ci			($dstat, $dcond, $ln, $cnt, $off) =
55288c2ecf20Sopenharmony_ci				ctx_statement_block($linenr, $realcnt, 0);
55298c2ecf20Sopenharmony_ci			$ctx = $dstat;
55308c2ecf20Sopenharmony_ci
55318c2ecf20Sopenharmony_ci			$dstat =~ s/\\\n.//g;
55328c2ecf20Sopenharmony_ci			$dstat =~ s/$;/ /g;
55338c2ecf20Sopenharmony_ci
55348c2ecf20Sopenharmony_ci			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
55358c2ecf20Sopenharmony_ci				my $stmts = $2;
55368c2ecf20Sopenharmony_ci				my $semis = $3;
55378c2ecf20Sopenharmony_ci
55388c2ecf20Sopenharmony_ci				$ctx =~ s/\n*$//;
55398c2ecf20Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
55408c2ecf20Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
55418c2ecf20Sopenharmony_ci
55428c2ecf20Sopenharmony_ci				if (($stmts =~ tr/;/;/) == 1 &&
55438c2ecf20Sopenharmony_ci				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
55448c2ecf20Sopenharmony_ci					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
55458c2ecf20Sopenharmony_ci					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
55468c2ecf20Sopenharmony_ci				}
55478c2ecf20Sopenharmony_ci				if (defined $semis && $semis ne "") {
55488c2ecf20Sopenharmony_ci					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
55498c2ecf20Sopenharmony_ci					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
55508c2ecf20Sopenharmony_ci				}
55518c2ecf20Sopenharmony_ci			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
55528c2ecf20Sopenharmony_ci				$ctx =~ s/\n*$//;
55538c2ecf20Sopenharmony_ci				my $cnt = statement_rawlines($ctx);
55548c2ecf20Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
55558c2ecf20Sopenharmony_ci
55568c2ecf20Sopenharmony_ci				WARN("TRAILING_SEMICOLON",
55578c2ecf20Sopenharmony_ci				     "macros should not use a trailing semicolon\n" . "$herectx");
55588c2ecf20Sopenharmony_ci			}
55598c2ecf20Sopenharmony_ci		}
55608c2ecf20Sopenharmony_ci
55618c2ecf20Sopenharmony_ci# check for redundant bracing round if etc
55628c2ecf20Sopenharmony_ci		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
55638c2ecf20Sopenharmony_ci			my ($level, $endln, @chunks) =
55648c2ecf20Sopenharmony_ci				ctx_statement_full($linenr, $realcnt, 1);
55658c2ecf20Sopenharmony_ci			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
55668c2ecf20Sopenharmony_ci			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
55678c2ecf20Sopenharmony_ci			if ($#chunks > 0 && $level == 0) {
55688c2ecf20Sopenharmony_ci				my @allowed = ();
55698c2ecf20Sopenharmony_ci				my $allow = 0;
55708c2ecf20Sopenharmony_ci				my $seen = 0;
55718c2ecf20Sopenharmony_ci				my $herectx = $here . "\n";
55728c2ecf20Sopenharmony_ci				my $ln = $linenr - 1;
55738c2ecf20Sopenharmony_ci				for my $chunk (@chunks) {
55748c2ecf20Sopenharmony_ci					my ($cond, $block) = @{$chunk};
55758c2ecf20Sopenharmony_ci
55768c2ecf20Sopenharmony_ci					# If the condition carries leading newlines, then count those as offsets.
55778c2ecf20Sopenharmony_ci					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
55788c2ecf20Sopenharmony_ci					my $offset = statement_rawlines($whitespace) - 1;
55798c2ecf20Sopenharmony_ci
55808c2ecf20Sopenharmony_ci					$allowed[$allow] = 0;
55818c2ecf20Sopenharmony_ci					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
55828c2ecf20Sopenharmony_ci
55838c2ecf20Sopenharmony_ci					# We have looked at and allowed this specific line.
55848c2ecf20Sopenharmony_ci					$suppress_ifbraces{$ln + $offset} = 1;
55858c2ecf20Sopenharmony_ci
55868c2ecf20Sopenharmony_ci					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
55878c2ecf20Sopenharmony_ci					$ln += statement_rawlines($block) - 1;
55888c2ecf20Sopenharmony_ci
55898c2ecf20Sopenharmony_ci					substr($block, 0, length($cond), '');
55908c2ecf20Sopenharmony_ci
55918c2ecf20Sopenharmony_ci					$seen++ if ($block =~ /^\s*{/);
55928c2ecf20Sopenharmony_ci
55938c2ecf20Sopenharmony_ci					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
55948c2ecf20Sopenharmony_ci					if (statement_lines($cond) > 1) {
55958c2ecf20Sopenharmony_ci						#print "APW: ALLOWED: cond<$cond>\n";
55968c2ecf20Sopenharmony_ci						$allowed[$allow] = 1;
55978c2ecf20Sopenharmony_ci					}
55988c2ecf20Sopenharmony_ci					if ($block =~/\b(?:if|for|while)\b/) {
55998c2ecf20Sopenharmony_ci						#print "APW: ALLOWED: block<$block>\n";
56008c2ecf20Sopenharmony_ci						$allowed[$allow] = 1;
56018c2ecf20Sopenharmony_ci					}
56028c2ecf20Sopenharmony_ci					if (statement_block_size($block) > 1) {
56038c2ecf20Sopenharmony_ci						#print "APW: ALLOWED: lines block<$block>\n";
56048c2ecf20Sopenharmony_ci						$allowed[$allow] = 1;
56058c2ecf20Sopenharmony_ci					}
56068c2ecf20Sopenharmony_ci					$allow++;
56078c2ecf20Sopenharmony_ci				}
56088c2ecf20Sopenharmony_ci				if ($seen) {
56098c2ecf20Sopenharmony_ci					my $sum_allowed = 0;
56108c2ecf20Sopenharmony_ci					foreach (@allowed) {
56118c2ecf20Sopenharmony_ci						$sum_allowed += $_;
56128c2ecf20Sopenharmony_ci					}
56138c2ecf20Sopenharmony_ci					if ($sum_allowed == 0) {
56148c2ecf20Sopenharmony_ci						WARN("BRACES",
56158c2ecf20Sopenharmony_ci						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
56168c2ecf20Sopenharmony_ci					} elsif ($sum_allowed != $allow &&
56178c2ecf20Sopenharmony_ci						 $seen != $allow) {
56188c2ecf20Sopenharmony_ci						CHK("BRACES",
56198c2ecf20Sopenharmony_ci						    "braces {} should be used on all arms of this statement\n" . $herectx);
56208c2ecf20Sopenharmony_ci					}
56218c2ecf20Sopenharmony_ci				}
56228c2ecf20Sopenharmony_ci			}
56238c2ecf20Sopenharmony_ci		}
56248c2ecf20Sopenharmony_ci		if (!defined $suppress_ifbraces{$linenr - 1} &&
56258c2ecf20Sopenharmony_ci					$line =~ /\b(if|while|for|else)\b/) {
56268c2ecf20Sopenharmony_ci			my $allowed = 0;
56278c2ecf20Sopenharmony_ci
56288c2ecf20Sopenharmony_ci			# Check the pre-context.
56298c2ecf20Sopenharmony_ci			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
56308c2ecf20Sopenharmony_ci				#print "APW: ALLOWED: pre<$1>\n";
56318c2ecf20Sopenharmony_ci				$allowed = 1;
56328c2ecf20Sopenharmony_ci			}
56338c2ecf20Sopenharmony_ci
56348c2ecf20Sopenharmony_ci			my ($level, $endln, @chunks) =
56358c2ecf20Sopenharmony_ci				ctx_statement_full($linenr, $realcnt, $-[0]);
56368c2ecf20Sopenharmony_ci
56378c2ecf20Sopenharmony_ci			# Check the condition.
56388c2ecf20Sopenharmony_ci			my ($cond, $block) = @{$chunks[0]};
56398c2ecf20Sopenharmony_ci			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
56408c2ecf20Sopenharmony_ci			if (defined $cond) {
56418c2ecf20Sopenharmony_ci				substr($block, 0, length($cond), '');
56428c2ecf20Sopenharmony_ci			}
56438c2ecf20Sopenharmony_ci			if (statement_lines($cond) > 1) {
56448c2ecf20Sopenharmony_ci				#print "APW: ALLOWED: cond<$cond>\n";
56458c2ecf20Sopenharmony_ci				$allowed = 1;
56468c2ecf20Sopenharmony_ci			}
56478c2ecf20Sopenharmony_ci			if ($block =~/\b(?:if|for|while)\b/) {
56488c2ecf20Sopenharmony_ci				#print "APW: ALLOWED: block<$block>\n";
56498c2ecf20Sopenharmony_ci				$allowed = 1;
56508c2ecf20Sopenharmony_ci			}
56518c2ecf20Sopenharmony_ci			if (statement_block_size($block) > 1) {
56528c2ecf20Sopenharmony_ci				#print "APW: ALLOWED: lines block<$block>\n";
56538c2ecf20Sopenharmony_ci				$allowed = 1;
56548c2ecf20Sopenharmony_ci			}
56558c2ecf20Sopenharmony_ci			# Check the post-context.
56568c2ecf20Sopenharmony_ci			if (defined $chunks[1]) {
56578c2ecf20Sopenharmony_ci				my ($cond, $block) = @{$chunks[1]};
56588c2ecf20Sopenharmony_ci				if (defined $cond) {
56598c2ecf20Sopenharmony_ci					substr($block, 0, length($cond), '');
56608c2ecf20Sopenharmony_ci				}
56618c2ecf20Sopenharmony_ci				if ($block =~ /^\s*\{/) {
56628c2ecf20Sopenharmony_ci					#print "APW: ALLOWED: chunk-1 block<$block>\n";
56638c2ecf20Sopenharmony_ci					$allowed = 1;
56648c2ecf20Sopenharmony_ci				}
56658c2ecf20Sopenharmony_ci			}
56668c2ecf20Sopenharmony_ci			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
56678c2ecf20Sopenharmony_ci				my $cnt = statement_rawlines($block);
56688c2ecf20Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
56698c2ecf20Sopenharmony_ci
56708c2ecf20Sopenharmony_ci				WARN("BRACES",
56718c2ecf20Sopenharmony_ci				     "braces {} are not necessary for single statement blocks\n" . $herectx);
56728c2ecf20Sopenharmony_ci			}
56738c2ecf20Sopenharmony_ci		}
56748c2ecf20Sopenharmony_ci
56758c2ecf20Sopenharmony_ci# check for single line unbalanced braces
56768c2ecf20Sopenharmony_ci		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
56778c2ecf20Sopenharmony_ci		    $sline =~ /^.\s*else\s*\{\s*$/) {
56788c2ecf20Sopenharmony_ci			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
56798c2ecf20Sopenharmony_ci		}
56808c2ecf20Sopenharmony_ci
56818c2ecf20Sopenharmony_ci# check for unnecessary blank lines around braces
56828c2ecf20Sopenharmony_ci		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
56838c2ecf20Sopenharmony_ci			if (CHK("BRACES",
56848c2ecf20Sopenharmony_ci				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
56858c2ecf20Sopenharmony_ci			    $fix && $prevrawline =~ /^\+/) {
56868c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
56878c2ecf20Sopenharmony_ci			}
56888c2ecf20Sopenharmony_ci		}
56898c2ecf20Sopenharmony_ci		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
56908c2ecf20Sopenharmony_ci			if (CHK("BRACES",
56918c2ecf20Sopenharmony_ci				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
56928c2ecf20Sopenharmony_ci			    $fix) {
56938c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
56948c2ecf20Sopenharmony_ci			}
56958c2ecf20Sopenharmony_ci		}
56968c2ecf20Sopenharmony_ci
56978c2ecf20Sopenharmony_ci# no volatiles please
56988c2ecf20Sopenharmony_ci		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
56998c2ecf20Sopenharmony_ci		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
57008c2ecf20Sopenharmony_ci			WARN("VOLATILE",
57018c2ecf20Sopenharmony_ci			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
57028c2ecf20Sopenharmony_ci		}
57038c2ecf20Sopenharmony_ci
57048c2ecf20Sopenharmony_ci# Check for user-visible strings broken across lines, which breaks the ability
57058c2ecf20Sopenharmony_ci# to grep for the string.  Make exceptions when the previous string ends in a
57068c2ecf20Sopenharmony_ci# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
57078c2ecf20Sopenharmony_ci# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
57088c2ecf20Sopenharmony_ci		if ($line =~ /^\+\s*$String/ &&
57098c2ecf20Sopenharmony_ci		    $prevline =~ /"\s*$/ &&
57108c2ecf20Sopenharmony_ci		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
57118c2ecf20Sopenharmony_ci			if (WARN("SPLIT_STRING",
57128c2ecf20Sopenharmony_ci				 "quoted string split across lines\n" . $hereprev) &&
57138c2ecf20Sopenharmony_ci				     $fix &&
57148c2ecf20Sopenharmony_ci				     $prevrawline =~ /^\+.*"\s*$/ &&
57158c2ecf20Sopenharmony_ci				     $last_coalesced_string_linenr != $linenr - 1) {
57168c2ecf20Sopenharmony_ci				my $extracted_string = get_quoted_string($line, $rawline);
57178c2ecf20Sopenharmony_ci				my $comma_close = "";
57188c2ecf20Sopenharmony_ci				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
57198c2ecf20Sopenharmony_ci					$comma_close = $1;
57208c2ecf20Sopenharmony_ci				}
57218c2ecf20Sopenharmony_ci
57228c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr - 1, $prevrawline);
57238c2ecf20Sopenharmony_ci				fix_delete_line($fixlinenr, $rawline);
57248c2ecf20Sopenharmony_ci				my $fixedline = $prevrawline;
57258c2ecf20Sopenharmony_ci				$fixedline =~ s/"\s*$//;
57268c2ecf20Sopenharmony_ci				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
57278c2ecf20Sopenharmony_ci				fix_insert_line($fixlinenr - 1, $fixedline);
57288c2ecf20Sopenharmony_ci				$fixedline = $rawline;
57298c2ecf20Sopenharmony_ci				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
57308c2ecf20Sopenharmony_ci				if ($fixedline !~ /\+\s*$/) {
57318c2ecf20Sopenharmony_ci					fix_insert_line($fixlinenr, $fixedline);
57328c2ecf20Sopenharmony_ci				}
57338c2ecf20Sopenharmony_ci				$last_coalesced_string_linenr = $linenr;
57348c2ecf20Sopenharmony_ci			}
57358c2ecf20Sopenharmony_ci		}
57368c2ecf20Sopenharmony_ci
57378c2ecf20Sopenharmony_ci# check for missing a space in a string concatenation
57388c2ecf20Sopenharmony_ci		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
57398c2ecf20Sopenharmony_ci			WARN('MISSING_SPACE',
57408c2ecf20Sopenharmony_ci			     "break quoted strings at a space character\n" . $hereprev);
57418c2ecf20Sopenharmony_ci		}
57428c2ecf20Sopenharmony_ci
57438c2ecf20Sopenharmony_ci# check for an embedded function name in a string when the function is known
57448c2ecf20Sopenharmony_ci# This does not work very well for -f --file checking as it depends on patch
57458c2ecf20Sopenharmony_ci# context providing the function name or a single line form for in-file
57468c2ecf20Sopenharmony_ci# function declarations
57478c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*$String/ &&
57488c2ecf20Sopenharmony_ci		    defined($context_function) &&
57498c2ecf20Sopenharmony_ci		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
57508c2ecf20Sopenharmony_ci		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
57518c2ecf20Sopenharmony_ci			WARN("EMBEDDED_FUNCTION_NAME",
57528c2ecf20Sopenharmony_ci			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
57538c2ecf20Sopenharmony_ci		}
57548c2ecf20Sopenharmony_ci
57558c2ecf20Sopenharmony_ci# check for spaces before a quoted newline
57568c2ecf20Sopenharmony_ci		if ($rawline =~ /^.*\".*\s\\n/) {
57578c2ecf20Sopenharmony_ci			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
57588c2ecf20Sopenharmony_ci				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
57598c2ecf20Sopenharmony_ci			    $fix) {
57608c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
57618c2ecf20Sopenharmony_ci			}
57628c2ecf20Sopenharmony_ci
57638c2ecf20Sopenharmony_ci		}
57648c2ecf20Sopenharmony_ci
57658c2ecf20Sopenharmony_ci# concatenated string without spaces between elements
57668c2ecf20Sopenharmony_ci		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
57678c2ecf20Sopenharmony_ci			if (CHK("CONCATENATED_STRING",
57688c2ecf20Sopenharmony_ci				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
57698c2ecf20Sopenharmony_ci			    $fix) {
57708c2ecf20Sopenharmony_ci				while ($line =~ /($String)/g) {
57718c2ecf20Sopenharmony_ci					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
57728c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
57738c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
57748c2ecf20Sopenharmony_ci				}
57758c2ecf20Sopenharmony_ci			}
57768c2ecf20Sopenharmony_ci		}
57778c2ecf20Sopenharmony_ci
57788c2ecf20Sopenharmony_ci# uncoalesced string fragments
57798c2ecf20Sopenharmony_ci		if ($line =~ /$String\s*"/) {
57808c2ecf20Sopenharmony_ci			if (WARN("STRING_FRAGMENTS",
57818c2ecf20Sopenharmony_ci				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
57828c2ecf20Sopenharmony_ci			    $fix) {
57838c2ecf20Sopenharmony_ci				while ($line =~ /($String)(?=\s*")/g) {
57848c2ecf20Sopenharmony_ci					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
57858c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
57868c2ecf20Sopenharmony_ci				}
57878c2ecf20Sopenharmony_ci			}
57888c2ecf20Sopenharmony_ci		}
57898c2ecf20Sopenharmony_ci
57908c2ecf20Sopenharmony_ci# check for non-standard and hex prefixed decimal printf formats
57918c2ecf20Sopenharmony_ci		my $show_L = 1;	#don't show the same defect twice
57928c2ecf20Sopenharmony_ci		my $show_Z = 1;
57938c2ecf20Sopenharmony_ci		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
57948c2ecf20Sopenharmony_ci			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
57958c2ecf20Sopenharmony_ci			$string =~ s/%%/__/g;
57968c2ecf20Sopenharmony_ci			# check for %L
57978c2ecf20Sopenharmony_ci			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
57988c2ecf20Sopenharmony_ci				WARN("PRINTF_L",
57998c2ecf20Sopenharmony_ci				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
58008c2ecf20Sopenharmony_ci				$show_L = 0;
58018c2ecf20Sopenharmony_ci			}
58028c2ecf20Sopenharmony_ci			# check for %Z
58038c2ecf20Sopenharmony_ci			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
58048c2ecf20Sopenharmony_ci				WARN("PRINTF_Z",
58058c2ecf20Sopenharmony_ci				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
58068c2ecf20Sopenharmony_ci				$show_Z = 0;
58078c2ecf20Sopenharmony_ci			}
58088c2ecf20Sopenharmony_ci			# check for 0x<decimal>
58098c2ecf20Sopenharmony_ci			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
58108c2ecf20Sopenharmony_ci				ERROR("PRINTF_0XDECIMAL",
58118c2ecf20Sopenharmony_ci				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
58128c2ecf20Sopenharmony_ci			}
58138c2ecf20Sopenharmony_ci		}
58148c2ecf20Sopenharmony_ci
58158c2ecf20Sopenharmony_ci# check for line continuations in quoted strings with odd counts of "
58168c2ecf20Sopenharmony_ci		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
58178c2ecf20Sopenharmony_ci			WARN("LINE_CONTINUATIONS",
58188c2ecf20Sopenharmony_ci			     "Avoid line continuations in quoted strings\n" . $herecurr);
58198c2ecf20Sopenharmony_ci		}
58208c2ecf20Sopenharmony_ci
58218c2ecf20Sopenharmony_ci# warn about #if 0
58228c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
58238c2ecf20Sopenharmony_ci			WARN("IF_0",
58248c2ecf20Sopenharmony_ci			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
58258c2ecf20Sopenharmony_ci		}
58268c2ecf20Sopenharmony_ci
58278c2ecf20Sopenharmony_ci# warn about #if 1
58288c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
58298c2ecf20Sopenharmony_ci			WARN("IF_1",
58308c2ecf20Sopenharmony_ci			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
58318c2ecf20Sopenharmony_ci		}
58328c2ecf20Sopenharmony_ci
58338c2ecf20Sopenharmony_ci# check for needless "if (<foo>) fn(<foo>)" uses
58348c2ecf20Sopenharmony_ci		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
58358c2ecf20Sopenharmony_ci			my $tested = quotemeta($1);
58368c2ecf20Sopenharmony_ci			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
58378c2ecf20Sopenharmony_ci			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
58388c2ecf20Sopenharmony_ci				my $func = $1;
58398c2ecf20Sopenharmony_ci				if (WARN('NEEDLESS_IF',
58408c2ecf20Sopenharmony_ci					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
58418c2ecf20Sopenharmony_ci				    $fix) {
58428c2ecf20Sopenharmony_ci					my $do_fix = 1;
58438c2ecf20Sopenharmony_ci					my $leading_tabs = "";
58448c2ecf20Sopenharmony_ci					my $new_leading_tabs = "";
58458c2ecf20Sopenharmony_ci					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
58468c2ecf20Sopenharmony_ci						$leading_tabs = $1;
58478c2ecf20Sopenharmony_ci					} else {
58488c2ecf20Sopenharmony_ci						$do_fix = 0;
58498c2ecf20Sopenharmony_ci					}
58508c2ecf20Sopenharmony_ci					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
58518c2ecf20Sopenharmony_ci						$new_leading_tabs = $1;
58528c2ecf20Sopenharmony_ci						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
58538c2ecf20Sopenharmony_ci							$do_fix = 0;
58548c2ecf20Sopenharmony_ci						}
58558c2ecf20Sopenharmony_ci					} else {
58568c2ecf20Sopenharmony_ci						$do_fix = 0;
58578c2ecf20Sopenharmony_ci					}
58588c2ecf20Sopenharmony_ci					if ($do_fix) {
58598c2ecf20Sopenharmony_ci						fix_delete_line($fixlinenr - 1, $prevrawline);
58608c2ecf20Sopenharmony_ci						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
58618c2ecf20Sopenharmony_ci					}
58628c2ecf20Sopenharmony_ci				}
58638c2ecf20Sopenharmony_ci			}
58648c2ecf20Sopenharmony_ci		}
58658c2ecf20Sopenharmony_ci
58668c2ecf20Sopenharmony_ci# check for unnecessary "Out of Memory" messages
58678c2ecf20Sopenharmony_ci		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
58688c2ecf20Sopenharmony_ci		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
58698c2ecf20Sopenharmony_ci		    (defined $1 || defined $3) &&
58708c2ecf20Sopenharmony_ci		    $linenr > 3) {
58718c2ecf20Sopenharmony_ci			my $testval = $2;
58728c2ecf20Sopenharmony_ci			my $testline = $lines[$linenr - 3];
58738c2ecf20Sopenharmony_ci
58748c2ecf20Sopenharmony_ci			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
58758c2ecf20Sopenharmony_ci#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
58768c2ecf20Sopenharmony_ci
58778c2ecf20Sopenharmony_ci			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
58788c2ecf20Sopenharmony_ci			    $s !~ /\b__GFP_NOWARN\b/ ) {
58798c2ecf20Sopenharmony_ci				WARN("OOM_MESSAGE",
58808c2ecf20Sopenharmony_ci				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
58818c2ecf20Sopenharmony_ci			}
58828c2ecf20Sopenharmony_ci		}
58838c2ecf20Sopenharmony_ci
58848c2ecf20Sopenharmony_ci# check for logging functions with KERN_<LEVEL>
58858c2ecf20Sopenharmony_ci		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
58868c2ecf20Sopenharmony_ci		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
58878c2ecf20Sopenharmony_ci			my $level = $1;
58888c2ecf20Sopenharmony_ci			if (WARN("UNNECESSARY_KERN_LEVEL",
58898c2ecf20Sopenharmony_ci				 "Possible unnecessary $level\n" . $herecurr) &&
58908c2ecf20Sopenharmony_ci			    $fix) {
58918c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
58928c2ecf20Sopenharmony_ci			}
58938c2ecf20Sopenharmony_ci		}
58948c2ecf20Sopenharmony_ci
58958c2ecf20Sopenharmony_ci# check for logging continuations
58968c2ecf20Sopenharmony_ci		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
58978c2ecf20Sopenharmony_ci			WARN("LOGGING_CONTINUATION",
58988c2ecf20Sopenharmony_ci			     "Avoid logging continuation uses where feasible\n" . $herecurr);
58998c2ecf20Sopenharmony_ci		}
59008c2ecf20Sopenharmony_ci
59018c2ecf20Sopenharmony_ci# check for mask then right shift without a parentheses
59028c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
59038c2ecf20Sopenharmony_ci		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
59048c2ecf20Sopenharmony_ci		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
59058c2ecf20Sopenharmony_ci			WARN("MASK_THEN_SHIFT",
59068c2ecf20Sopenharmony_ci			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
59078c2ecf20Sopenharmony_ci		}
59088c2ecf20Sopenharmony_ci
59098c2ecf20Sopenharmony_ci# check for pointer comparisons to NULL
59108c2ecf20Sopenharmony_ci		if ($perl_version_ok) {
59118c2ecf20Sopenharmony_ci			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
59128c2ecf20Sopenharmony_ci				my $val = $1;
59138c2ecf20Sopenharmony_ci				my $equal = "!";
59148c2ecf20Sopenharmony_ci				$equal = "" if ($4 eq "!=");
59158c2ecf20Sopenharmony_ci				if (CHK("COMPARISON_TO_NULL",
59168c2ecf20Sopenharmony_ci					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
59178c2ecf20Sopenharmony_ci					    $fix) {
59188c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
59198c2ecf20Sopenharmony_ci				}
59208c2ecf20Sopenharmony_ci			}
59218c2ecf20Sopenharmony_ci		}
59228c2ecf20Sopenharmony_ci
59238c2ecf20Sopenharmony_ci# check for bad placement of section $InitAttribute (e.g.: __initdata)
59248c2ecf20Sopenharmony_ci		if ($line =~ /(\b$InitAttribute\b)/) {
59258c2ecf20Sopenharmony_ci			my $attr = $1;
59268c2ecf20Sopenharmony_ci			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
59278c2ecf20Sopenharmony_ci				my $ptr = $1;
59288c2ecf20Sopenharmony_ci				my $var = $2;
59298c2ecf20Sopenharmony_ci				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
59308c2ecf20Sopenharmony_ci				      ERROR("MISPLACED_INIT",
59318c2ecf20Sopenharmony_ci					    "$attr should be placed after $var\n" . $herecurr)) ||
59328c2ecf20Sopenharmony_ci				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
59338c2ecf20Sopenharmony_ci				      WARN("MISPLACED_INIT",
59348c2ecf20Sopenharmony_ci					   "$attr should be placed after $var\n" . $herecurr))) &&
59358c2ecf20Sopenharmony_ci				    $fix) {
59368c2ecf20Sopenharmony_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;
59378c2ecf20Sopenharmony_ci				}
59388c2ecf20Sopenharmony_ci			}
59398c2ecf20Sopenharmony_ci		}
59408c2ecf20Sopenharmony_ci
59418c2ecf20Sopenharmony_ci# check for $InitAttributeData (ie: __initdata) with const
59428c2ecf20Sopenharmony_ci		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
59438c2ecf20Sopenharmony_ci			my $attr = $1;
59448c2ecf20Sopenharmony_ci			$attr =~ /($InitAttributePrefix)(.*)/;
59458c2ecf20Sopenharmony_ci			my $attr_prefix = $1;
59468c2ecf20Sopenharmony_ci			my $attr_type = $2;
59478c2ecf20Sopenharmony_ci			if (ERROR("INIT_ATTRIBUTE",
59488c2ecf20Sopenharmony_ci				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
59498c2ecf20Sopenharmony_ci			    $fix) {
59508c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
59518c2ecf20Sopenharmony_ci				    s/$InitAttributeData/${attr_prefix}initconst/;
59528c2ecf20Sopenharmony_ci			}
59538c2ecf20Sopenharmony_ci		}
59548c2ecf20Sopenharmony_ci
59558c2ecf20Sopenharmony_ci# check for $InitAttributeConst (ie: __initconst) without const
59568c2ecf20Sopenharmony_ci		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
59578c2ecf20Sopenharmony_ci			my $attr = $1;
59588c2ecf20Sopenharmony_ci			if (ERROR("INIT_ATTRIBUTE",
59598c2ecf20Sopenharmony_ci				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
59608c2ecf20Sopenharmony_ci			    $fix) {
59618c2ecf20Sopenharmony_ci				my $lead = $fixed[$fixlinenr] =~
59628c2ecf20Sopenharmony_ci				    /(^\+\s*(?:static\s+))/;
59638c2ecf20Sopenharmony_ci				$lead = rtrim($1);
59648c2ecf20Sopenharmony_ci				$lead = "$lead " if ($lead !~ /^\+$/);
59658c2ecf20Sopenharmony_ci				$lead = "${lead}const ";
59668c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
59678c2ecf20Sopenharmony_ci			}
59688c2ecf20Sopenharmony_ci		}
59698c2ecf20Sopenharmony_ci
59708c2ecf20Sopenharmony_ci# check for __read_mostly with const non-pointer (should just be const)
59718c2ecf20Sopenharmony_ci		if ($line =~ /\b__read_mostly\b/ &&
59728c2ecf20Sopenharmony_ci		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
59738c2ecf20Sopenharmony_ci			if (ERROR("CONST_READ_MOSTLY",
59748c2ecf20Sopenharmony_ci				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
59758c2ecf20Sopenharmony_ci			    $fix) {
59768c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
59778c2ecf20Sopenharmony_ci			}
59788c2ecf20Sopenharmony_ci		}
59798c2ecf20Sopenharmony_ci
59808c2ecf20Sopenharmony_ci# don't use __constant_<foo> functions outside of include/uapi/
59818c2ecf20Sopenharmony_ci		if ($realfile !~ m@^include/uapi/@ &&
59828c2ecf20Sopenharmony_ci		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
59838c2ecf20Sopenharmony_ci			my $constant_func = $1;
59848c2ecf20Sopenharmony_ci			my $func = $constant_func;
59858c2ecf20Sopenharmony_ci			$func =~ s/^__constant_//;
59868c2ecf20Sopenharmony_ci			if (WARN("CONSTANT_CONVERSION",
59878c2ecf20Sopenharmony_ci				 "$constant_func should be $func\n" . $herecurr) &&
59888c2ecf20Sopenharmony_ci			    $fix) {
59898c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
59908c2ecf20Sopenharmony_ci			}
59918c2ecf20Sopenharmony_ci		}
59928c2ecf20Sopenharmony_ci
59938c2ecf20Sopenharmony_ci# prefer usleep_range over udelay
59948c2ecf20Sopenharmony_ci		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
59958c2ecf20Sopenharmony_ci			my $delay = $1;
59968c2ecf20Sopenharmony_ci			# ignore udelay's < 10, however
59978c2ecf20Sopenharmony_ci			if (! ($delay < 10) ) {
59988c2ecf20Sopenharmony_ci				CHK("USLEEP_RANGE",
59998c2ecf20Sopenharmony_ci				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
60008c2ecf20Sopenharmony_ci			}
60018c2ecf20Sopenharmony_ci			if ($delay > 2000) {
60028c2ecf20Sopenharmony_ci				WARN("LONG_UDELAY",
60038c2ecf20Sopenharmony_ci				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
60048c2ecf20Sopenharmony_ci			}
60058c2ecf20Sopenharmony_ci		}
60068c2ecf20Sopenharmony_ci
60078c2ecf20Sopenharmony_ci# warn about unexpectedly long msleep's
60088c2ecf20Sopenharmony_ci		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
60098c2ecf20Sopenharmony_ci			if ($1 < 20) {
60108c2ecf20Sopenharmony_ci				WARN("MSLEEP",
60118c2ecf20Sopenharmony_ci				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
60128c2ecf20Sopenharmony_ci			}
60138c2ecf20Sopenharmony_ci		}
60148c2ecf20Sopenharmony_ci
60158c2ecf20Sopenharmony_ci# check for comparisons of jiffies
60168c2ecf20Sopenharmony_ci		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
60178c2ecf20Sopenharmony_ci			WARN("JIFFIES_COMPARISON",
60188c2ecf20Sopenharmony_ci			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
60198c2ecf20Sopenharmony_ci		}
60208c2ecf20Sopenharmony_ci
60218c2ecf20Sopenharmony_ci# check for comparisons of get_jiffies_64()
60228c2ecf20Sopenharmony_ci		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
60238c2ecf20Sopenharmony_ci			WARN("JIFFIES_COMPARISON",
60248c2ecf20Sopenharmony_ci			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
60258c2ecf20Sopenharmony_ci		}
60268c2ecf20Sopenharmony_ci
60278c2ecf20Sopenharmony_ci# warn about #ifdefs in C files
60288c2ecf20Sopenharmony_ci#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
60298c2ecf20Sopenharmony_ci#			print "#ifdef in C files should be avoided\n";
60308c2ecf20Sopenharmony_ci#			print "$herecurr";
60318c2ecf20Sopenharmony_ci#			$clean = 0;
60328c2ecf20Sopenharmony_ci#		}
60338c2ecf20Sopenharmony_ci
60348c2ecf20Sopenharmony_ci# warn about spacing in #ifdefs
60358c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
60368c2ecf20Sopenharmony_ci			if (ERROR("SPACING",
60378c2ecf20Sopenharmony_ci				  "exactly one space required after that #$1\n" . $herecurr) &&
60388c2ecf20Sopenharmony_ci			    $fix) {
60398c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~
60408c2ecf20Sopenharmony_ci				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
60418c2ecf20Sopenharmony_ci			}
60428c2ecf20Sopenharmony_ci
60438c2ecf20Sopenharmony_ci		}
60448c2ecf20Sopenharmony_ci
60458c2ecf20Sopenharmony_ci# check for spinlock_t definitions without a comment.
60468c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
60478c2ecf20Sopenharmony_ci		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
60488c2ecf20Sopenharmony_ci			my $which = $1;
60498c2ecf20Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
60508c2ecf20Sopenharmony_ci				CHK("UNCOMMENTED_DEFINITION",
60518c2ecf20Sopenharmony_ci				    "$1 definition without comment\n" . $herecurr);
60528c2ecf20Sopenharmony_ci			}
60538c2ecf20Sopenharmony_ci		}
60548c2ecf20Sopenharmony_ci# check for memory barriers without a comment.
60558c2ecf20Sopenharmony_ci
60568c2ecf20Sopenharmony_ci		my $barriers = qr{
60578c2ecf20Sopenharmony_ci			mb|
60588c2ecf20Sopenharmony_ci			rmb|
60598c2ecf20Sopenharmony_ci			wmb
60608c2ecf20Sopenharmony_ci		}x;
60618c2ecf20Sopenharmony_ci		my $barrier_stems = qr{
60628c2ecf20Sopenharmony_ci			mb__before_atomic|
60638c2ecf20Sopenharmony_ci			mb__after_atomic|
60648c2ecf20Sopenharmony_ci			store_release|
60658c2ecf20Sopenharmony_ci			load_acquire|
60668c2ecf20Sopenharmony_ci			store_mb|
60678c2ecf20Sopenharmony_ci			(?:$barriers)
60688c2ecf20Sopenharmony_ci		}x;
60698c2ecf20Sopenharmony_ci		my $all_barriers = qr{
60708c2ecf20Sopenharmony_ci			(?:$barriers)|
60718c2ecf20Sopenharmony_ci			smp_(?:$barrier_stems)|
60728c2ecf20Sopenharmony_ci			virt_(?:$barrier_stems)
60738c2ecf20Sopenharmony_ci		}x;
60748c2ecf20Sopenharmony_ci
60758c2ecf20Sopenharmony_ci		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
60768c2ecf20Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
60778c2ecf20Sopenharmony_ci				WARN("MEMORY_BARRIER",
60788c2ecf20Sopenharmony_ci				     "memory barrier without comment\n" . $herecurr);
60798c2ecf20Sopenharmony_ci			}
60808c2ecf20Sopenharmony_ci		}
60818c2ecf20Sopenharmony_ci
60828c2ecf20Sopenharmony_ci		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
60838c2ecf20Sopenharmony_ci
60848c2ecf20Sopenharmony_ci		if ($realfile !~ m@^include/asm-generic/@ &&
60858c2ecf20Sopenharmony_ci		    $realfile !~ m@/barrier\.h$@ &&
60868c2ecf20Sopenharmony_ci		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
60878c2ecf20Sopenharmony_ci		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
60888c2ecf20Sopenharmony_ci			WARN("MEMORY_BARRIER",
60898c2ecf20Sopenharmony_ci			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
60908c2ecf20Sopenharmony_ci		}
60918c2ecf20Sopenharmony_ci
60928c2ecf20Sopenharmony_ci# check for waitqueue_active without a comment.
60938c2ecf20Sopenharmony_ci		if ($line =~ /\bwaitqueue_active\s*\(/) {
60948c2ecf20Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
60958c2ecf20Sopenharmony_ci				WARN("WAITQUEUE_ACTIVE",
60968c2ecf20Sopenharmony_ci				     "waitqueue_active without comment\n" . $herecurr);
60978c2ecf20Sopenharmony_ci			}
60988c2ecf20Sopenharmony_ci		}
60998c2ecf20Sopenharmony_ci
61008c2ecf20Sopenharmony_ci# check for data_race without a comment.
61018c2ecf20Sopenharmony_ci		if ($line =~ /\bdata_race\s*\(/) {
61028c2ecf20Sopenharmony_ci			if (!ctx_has_comment($first_line, $linenr)) {
61038c2ecf20Sopenharmony_ci				WARN("DATA_RACE",
61048c2ecf20Sopenharmony_ci				     "data_race without comment\n" . $herecurr);
61058c2ecf20Sopenharmony_ci			}
61068c2ecf20Sopenharmony_ci		}
61078c2ecf20Sopenharmony_ci
61088c2ecf20Sopenharmony_ci# check of hardware specific defines
61098c2ecf20Sopenharmony_ci		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
61108c2ecf20Sopenharmony_ci			CHK("ARCH_DEFINES",
61118c2ecf20Sopenharmony_ci			    "architecture specific defines should be avoided\n" .  $herecurr);
61128c2ecf20Sopenharmony_ci		}
61138c2ecf20Sopenharmony_ci
61148c2ecf20Sopenharmony_ci# check that the storage class is not after a type
61158c2ecf20Sopenharmony_ci		if ($line =~ /\b($Type)\s+($Storage)\b/) {
61168c2ecf20Sopenharmony_ci			WARN("STORAGE_CLASS",
61178c2ecf20Sopenharmony_ci			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
61188c2ecf20Sopenharmony_ci		}
61198c2ecf20Sopenharmony_ci# Check that the storage class is at the beginning of a declaration
61208c2ecf20Sopenharmony_ci		if ($line =~ /\b$Storage\b/ &&
61218c2ecf20Sopenharmony_ci		    $line !~ /^.\s*$Storage/ &&
61228c2ecf20Sopenharmony_ci		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
61238c2ecf20Sopenharmony_ci		    $1 !~ /[\,\)]\s*$/) {
61248c2ecf20Sopenharmony_ci			WARN("STORAGE_CLASS",
61258c2ecf20Sopenharmony_ci			     "storage class should be at the beginning of the declaration\n" . $herecurr);
61268c2ecf20Sopenharmony_ci		}
61278c2ecf20Sopenharmony_ci
61288c2ecf20Sopenharmony_ci# check the location of the inline attribute, that it is between
61298c2ecf20Sopenharmony_ci# storage class and type.
61308c2ecf20Sopenharmony_ci		if ($line =~ /\b$Type\s+$Inline\b/ ||
61318c2ecf20Sopenharmony_ci		    $line =~ /\b$Inline\s+$Storage\b/) {
61328c2ecf20Sopenharmony_ci			ERROR("INLINE_LOCATION",
61338c2ecf20Sopenharmony_ci			      "inline keyword should sit between storage class and type\n" . $herecurr);
61348c2ecf20Sopenharmony_ci		}
61358c2ecf20Sopenharmony_ci
61368c2ecf20Sopenharmony_ci# Check for __inline__ and __inline, prefer inline
61378c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61388c2ecf20Sopenharmony_ci		    $line =~ /\b(__inline__|__inline)\b/) {
61398c2ecf20Sopenharmony_ci			if (WARN("INLINE",
61408c2ecf20Sopenharmony_ci				 "plain inline is preferred over $1\n" . $herecurr) &&
61418c2ecf20Sopenharmony_ci			    $fix) {
61428c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
61438c2ecf20Sopenharmony_ci
61448c2ecf20Sopenharmony_ci			}
61458c2ecf20Sopenharmony_ci		}
61468c2ecf20Sopenharmony_ci
61478c2ecf20Sopenharmony_ci# Check for __attribute__ packed, prefer __packed
61488c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61498c2ecf20Sopenharmony_ci		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
61508c2ecf20Sopenharmony_ci			WARN("PREFER_PACKED",
61518c2ecf20Sopenharmony_ci			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
61528c2ecf20Sopenharmony_ci		}
61538c2ecf20Sopenharmony_ci
61548c2ecf20Sopenharmony_ci# Check for __attribute__ aligned, prefer __aligned
61558c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61568c2ecf20Sopenharmony_ci		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
61578c2ecf20Sopenharmony_ci			WARN("PREFER_ALIGNED",
61588c2ecf20Sopenharmony_ci			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
61598c2ecf20Sopenharmony_ci		}
61608c2ecf20Sopenharmony_ci
61618c2ecf20Sopenharmony_ci# Check for __attribute__ section, prefer __section
61628c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61638c2ecf20Sopenharmony_ci		    $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
61648c2ecf20Sopenharmony_ci			my $old = substr($rawline, $-[1], $+[1] - $-[1]);
61658c2ecf20Sopenharmony_ci			my $new = substr($old, 1, -1);
61668c2ecf20Sopenharmony_ci			if (WARN("PREFER_SECTION",
61678c2ecf20Sopenharmony_ci				 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
61688c2ecf20Sopenharmony_ci			    $fix) {
61698c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
61708c2ecf20Sopenharmony_ci			}
61718c2ecf20Sopenharmony_ci		}
61728c2ecf20Sopenharmony_ci
61738c2ecf20Sopenharmony_ci# Check for __attribute__ format(printf, prefer __printf
61748c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61758c2ecf20Sopenharmony_ci		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
61768c2ecf20Sopenharmony_ci			if (WARN("PREFER_PRINTF",
61778c2ecf20Sopenharmony_ci				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
61788c2ecf20Sopenharmony_ci			    $fix) {
61798c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
61808c2ecf20Sopenharmony_ci
61818c2ecf20Sopenharmony_ci			}
61828c2ecf20Sopenharmony_ci		}
61838c2ecf20Sopenharmony_ci
61848c2ecf20Sopenharmony_ci# Check for __attribute__ format(scanf, prefer __scanf
61858c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
61868c2ecf20Sopenharmony_ci		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
61878c2ecf20Sopenharmony_ci			if (WARN("PREFER_SCANF",
61888c2ecf20Sopenharmony_ci				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
61898c2ecf20Sopenharmony_ci			    $fix) {
61908c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
61918c2ecf20Sopenharmony_ci			}
61928c2ecf20Sopenharmony_ci		}
61938c2ecf20Sopenharmony_ci
61948c2ecf20Sopenharmony_ci# Check for __attribute__ weak, or __weak declarations (may have link issues)
61958c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
61968c2ecf20Sopenharmony_ci		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
61978c2ecf20Sopenharmony_ci		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
61988c2ecf20Sopenharmony_ci		     $line =~ /\b__weak\b/)) {
61998c2ecf20Sopenharmony_ci			ERROR("WEAK_DECLARATION",
62008c2ecf20Sopenharmony_ci			      "Using weak declarations can have unintended link defects\n" . $herecurr);
62018c2ecf20Sopenharmony_ci		}
62028c2ecf20Sopenharmony_ci
62038c2ecf20Sopenharmony_ci# check for c99 types like uint8_t used outside of uapi/ and tools/
62048c2ecf20Sopenharmony_ci		if ($realfile !~ m@\binclude/uapi/@ &&
62058c2ecf20Sopenharmony_ci		    $realfile !~ m@\btools/@ &&
62068c2ecf20Sopenharmony_ci		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
62078c2ecf20Sopenharmony_ci			my $type = $1;
62088c2ecf20Sopenharmony_ci			if ($type =~ /\b($typeC99Typedefs)\b/) {
62098c2ecf20Sopenharmony_ci				$type = $1;
62108c2ecf20Sopenharmony_ci				my $kernel_type = 'u';
62118c2ecf20Sopenharmony_ci				$kernel_type = 's' if ($type =~ /^_*[si]/);
62128c2ecf20Sopenharmony_ci				$type =~ /(\d+)/;
62138c2ecf20Sopenharmony_ci				$kernel_type .= $1;
62148c2ecf20Sopenharmony_ci				if (CHK("PREFER_KERNEL_TYPES",
62158c2ecf20Sopenharmony_ci					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
62168c2ecf20Sopenharmony_ci				    $fix) {
62178c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
62188c2ecf20Sopenharmony_ci				}
62198c2ecf20Sopenharmony_ci			}
62208c2ecf20Sopenharmony_ci		}
62218c2ecf20Sopenharmony_ci
62228c2ecf20Sopenharmony_ci# check for cast of C90 native int or longer types constants
62238c2ecf20Sopenharmony_ci		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
62248c2ecf20Sopenharmony_ci			my $cast = $1;
62258c2ecf20Sopenharmony_ci			my $const = $2;
62268c2ecf20Sopenharmony_ci			if (WARN("TYPECAST_INT_CONSTANT",
62278c2ecf20Sopenharmony_ci				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
62288c2ecf20Sopenharmony_ci			    $fix) {
62298c2ecf20Sopenharmony_ci				my $suffix = "";
62308c2ecf20Sopenharmony_ci				my $newconst = $const;
62318c2ecf20Sopenharmony_ci				$newconst =~ s/${Int_type}$//;
62328c2ecf20Sopenharmony_ci				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
62338c2ecf20Sopenharmony_ci				if ($cast =~ /\blong\s+long\b/) {
62348c2ecf20Sopenharmony_ci					$suffix .= 'LL';
62358c2ecf20Sopenharmony_ci				} elsif ($cast =~ /\blong\b/) {
62368c2ecf20Sopenharmony_ci					$suffix .= 'L';
62378c2ecf20Sopenharmony_ci				}
62388c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
62398c2ecf20Sopenharmony_ci			}
62408c2ecf20Sopenharmony_ci		}
62418c2ecf20Sopenharmony_ci
62428c2ecf20Sopenharmony_ci# check for sizeof(&)
62438c2ecf20Sopenharmony_ci		if ($line =~ /\bsizeof\s*\(\s*\&/) {
62448c2ecf20Sopenharmony_ci			WARN("SIZEOF_ADDRESS",
62458c2ecf20Sopenharmony_ci			     "sizeof(& should be avoided\n" . $herecurr);
62468c2ecf20Sopenharmony_ci		}
62478c2ecf20Sopenharmony_ci
62488c2ecf20Sopenharmony_ci# check for sizeof without parenthesis
62498c2ecf20Sopenharmony_ci		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
62508c2ecf20Sopenharmony_ci			if (WARN("SIZEOF_PARENTHESIS",
62518c2ecf20Sopenharmony_ci				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
62528c2ecf20Sopenharmony_ci			    $fix) {
62538c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
62548c2ecf20Sopenharmony_ci			}
62558c2ecf20Sopenharmony_ci		}
62568c2ecf20Sopenharmony_ci
62578c2ecf20Sopenharmony_ci# check for struct spinlock declarations
62588c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
62598c2ecf20Sopenharmony_ci			WARN("USE_SPINLOCK_T",
62608c2ecf20Sopenharmony_ci			     "struct spinlock should be spinlock_t\n" . $herecurr);
62618c2ecf20Sopenharmony_ci		}
62628c2ecf20Sopenharmony_ci
62638c2ecf20Sopenharmony_ci# check for seq_printf uses that could be seq_puts
62648c2ecf20Sopenharmony_ci		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
62658c2ecf20Sopenharmony_ci			my $fmt = get_quoted_string($line, $rawline);
62668c2ecf20Sopenharmony_ci			$fmt =~ s/%%//g;
62678c2ecf20Sopenharmony_ci			if ($fmt !~ /%/) {
62688c2ecf20Sopenharmony_ci				if (WARN("PREFER_SEQ_PUTS",
62698c2ecf20Sopenharmony_ci					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
62708c2ecf20Sopenharmony_ci				    $fix) {
62718c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
62728c2ecf20Sopenharmony_ci				}
62738c2ecf20Sopenharmony_ci			}
62748c2ecf20Sopenharmony_ci		}
62758c2ecf20Sopenharmony_ci
62768c2ecf20Sopenharmony_ci# check for vsprintf extension %p<foo> misuses
62778c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
62788c2ecf20Sopenharmony_ci		    defined $stat &&
62798c2ecf20Sopenharmony_ci		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
62808c2ecf20Sopenharmony_ci		    $1 !~ /^_*volatile_*$/) {
62818c2ecf20Sopenharmony_ci			my $stat_real;
62828c2ecf20Sopenharmony_ci
62838c2ecf20Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
62848c2ecf20Sopenharmony_ci			$lc = $lc + $linenr;
62858c2ecf20Sopenharmony_ci		        for (my $count = $linenr; $count <= $lc; $count++) {
62868c2ecf20Sopenharmony_ci				my $specifier;
62878c2ecf20Sopenharmony_ci				my $extension;
62888c2ecf20Sopenharmony_ci				my $qualifier;
62898c2ecf20Sopenharmony_ci				my $bad_specifier = "";
62908c2ecf20Sopenharmony_ci				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
62918c2ecf20Sopenharmony_ci				$fmt =~ s/%%//g;
62928c2ecf20Sopenharmony_ci
62938c2ecf20Sopenharmony_ci				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
62948c2ecf20Sopenharmony_ci					$specifier = $1;
62958c2ecf20Sopenharmony_ci					$extension = $2;
62968c2ecf20Sopenharmony_ci					$qualifier = $3;
62978c2ecf20Sopenharmony_ci					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
62988c2ecf20Sopenharmony_ci					    ($extension eq "f" &&
62998c2ecf20Sopenharmony_ci					     defined $qualifier && $qualifier !~ /^w/)) {
63008c2ecf20Sopenharmony_ci						$bad_specifier = $specifier;
63018c2ecf20Sopenharmony_ci						last;
63028c2ecf20Sopenharmony_ci					}
63038c2ecf20Sopenharmony_ci					if ($extension eq "x" && !defined($stat_real)) {
63048c2ecf20Sopenharmony_ci						if (!defined($stat_real)) {
63058c2ecf20Sopenharmony_ci							$stat_real = get_stat_real($linenr, $lc);
63068c2ecf20Sopenharmony_ci						}
63078c2ecf20Sopenharmony_ci						WARN("VSPRINTF_SPECIFIER_PX",
63088c2ecf20Sopenharmony_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");
63098c2ecf20Sopenharmony_ci					}
63108c2ecf20Sopenharmony_ci				}
63118c2ecf20Sopenharmony_ci				if ($bad_specifier ne "") {
63128c2ecf20Sopenharmony_ci					my $stat_real = get_stat_real($linenr, $lc);
63138c2ecf20Sopenharmony_ci					my $ext_type = "Invalid";
63148c2ecf20Sopenharmony_ci					my $use = "";
63158c2ecf20Sopenharmony_ci					if ($bad_specifier =~ /p[Ff]/) {
63168c2ecf20Sopenharmony_ci						$use = " - use %pS instead";
63178c2ecf20Sopenharmony_ci						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
63188c2ecf20Sopenharmony_ci					}
63198c2ecf20Sopenharmony_ci
63208c2ecf20Sopenharmony_ci					WARN("VSPRINTF_POINTER_EXTENSION",
63218c2ecf20Sopenharmony_ci					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
63228c2ecf20Sopenharmony_ci				}
63238c2ecf20Sopenharmony_ci			}
63248c2ecf20Sopenharmony_ci		}
63258c2ecf20Sopenharmony_ci
63268c2ecf20Sopenharmony_ci# Check for misused memsets
63278c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
63288c2ecf20Sopenharmony_ci		    defined $stat &&
63298c2ecf20Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
63308c2ecf20Sopenharmony_ci
63318c2ecf20Sopenharmony_ci			my $ms_addr = $2;
63328c2ecf20Sopenharmony_ci			my $ms_val = $7;
63338c2ecf20Sopenharmony_ci			my $ms_size = $12;
63348c2ecf20Sopenharmony_ci
63358c2ecf20Sopenharmony_ci			if ($ms_size =~ /^(0x|)0$/i) {
63368c2ecf20Sopenharmony_ci				ERROR("MEMSET",
63378c2ecf20Sopenharmony_ci				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
63388c2ecf20Sopenharmony_ci			} elsif ($ms_size =~ /^(0x|)1$/i) {
63398c2ecf20Sopenharmony_ci				WARN("MEMSET",
63408c2ecf20Sopenharmony_ci				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
63418c2ecf20Sopenharmony_ci			}
63428c2ecf20Sopenharmony_ci		}
63438c2ecf20Sopenharmony_ci
63448c2ecf20Sopenharmony_ci# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
63458c2ecf20Sopenharmony_ci#		if ($perl_version_ok &&
63468c2ecf20Sopenharmony_ci#		    defined $stat &&
63478c2ecf20Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
63488c2ecf20Sopenharmony_ci#			if (WARN("PREFER_ETHER_ADDR_COPY",
63498c2ecf20Sopenharmony_ci#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
63508c2ecf20Sopenharmony_ci#			    $fix) {
63518c2ecf20Sopenharmony_ci#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
63528c2ecf20Sopenharmony_ci#			}
63538c2ecf20Sopenharmony_ci#		}
63548c2ecf20Sopenharmony_ci
63558c2ecf20Sopenharmony_ci# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
63568c2ecf20Sopenharmony_ci#		if ($perl_version_ok &&
63578c2ecf20Sopenharmony_ci#		    defined $stat &&
63588c2ecf20Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
63598c2ecf20Sopenharmony_ci#			WARN("PREFER_ETHER_ADDR_EQUAL",
63608c2ecf20Sopenharmony_ci#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
63618c2ecf20Sopenharmony_ci#		}
63628c2ecf20Sopenharmony_ci
63638c2ecf20Sopenharmony_ci# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
63648c2ecf20Sopenharmony_ci# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
63658c2ecf20Sopenharmony_ci#		if ($perl_version_ok &&
63668c2ecf20Sopenharmony_ci#		    defined $stat &&
63678c2ecf20Sopenharmony_ci#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
63688c2ecf20Sopenharmony_ci#
63698c2ecf20Sopenharmony_ci#			my $ms_val = $7;
63708c2ecf20Sopenharmony_ci#
63718c2ecf20Sopenharmony_ci#			if ($ms_val =~ /^(?:0x|)0+$/i) {
63728c2ecf20Sopenharmony_ci#				if (WARN("PREFER_ETH_ZERO_ADDR",
63738c2ecf20Sopenharmony_ci#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
63748c2ecf20Sopenharmony_ci#				    $fix) {
63758c2ecf20Sopenharmony_ci#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
63768c2ecf20Sopenharmony_ci#				}
63778c2ecf20Sopenharmony_ci#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
63788c2ecf20Sopenharmony_ci#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
63798c2ecf20Sopenharmony_ci#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
63808c2ecf20Sopenharmony_ci#				    $fix) {
63818c2ecf20Sopenharmony_ci#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
63828c2ecf20Sopenharmony_ci#				}
63838c2ecf20Sopenharmony_ci#			}
63848c2ecf20Sopenharmony_ci#		}
63858c2ecf20Sopenharmony_ci
63868c2ecf20Sopenharmony_ci# typecasts on min/max could be min_t/max_t
63878c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
63888c2ecf20Sopenharmony_ci		    defined $stat &&
63898c2ecf20Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
63908c2ecf20Sopenharmony_ci			if (defined $2 || defined $7) {
63918c2ecf20Sopenharmony_ci				my $call = $1;
63928c2ecf20Sopenharmony_ci				my $cast1 = deparenthesize($2);
63938c2ecf20Sopenharmony_ci				my $arg1 = $3;
63948c2ecf20Sopenharmony_ci				my $cast2 = deparenthesize($7);
63958c2ecf20Sopenharmony_ci				my $arg2 = $8;
63968c2ecf20Sopenharmony_ci				my $cast;
63978c2ecf20Sopenharmony_ci
63988c2ecf20Sopenharmony_ci				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
63998c2ecf20Sopenharmony_ci					$cast = "$cast1 or $cast2";
64008c2ecf20Sopenharmony_ci				} elsif ($cast1 ne "") {
64018c2ecf20Sopenharmony_ci					$cast = $cast1;
64028c2ecf20Sopenharmony_ci				} else {
64038c2ecf20Sopenharmony_ci					$cast = $cast2;
64048c2ecf20Sopenharmony_ci				}
64058c2ecf20Sopenharmony_ci				WARN("MINMAX",
64068c2ecf20Sopenharmony_ci				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
64078c2ecf20Sopenharmony_ci			}
64088c2ecf20Sopenharmony_ci		}
64098c2ecf20Sopenharmony_ci
64108c2ecf20Sopenharmony_ci# check usleep_range arguments
64118c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
64128c2ecf20Sopenharmony_ci		    defined $stat &&
64138c2ecf20Sopenharmony_ci		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
64148c2ecf20Sopenharmony_ci			my $min = $1;
64158c2ecf20Sopenharmony_ci			my $max = $7;
64168c2ecf20Sopenharmony_ci			if ($min eq $max) {
64178c2ecf20Sopenharmony_ci				WARN("USLEEP_RANGE",
64188c2ecf20Sopenharmony_ci				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
64198c2ecf20Sopenharmony_ci			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
64208c2ecf20Sopenharmony_ci				 $min > $max) {
64218c2ecf20Sopenharmony_ci				WARN("USLEEP_RANGE",
64228c2ecf20Sopenharmony_ci				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
64238c2ecf20Sopenharmony_ci			}
64248c2ecf20Sopenharmony_ci		}
64258c2ecf20Sopenharmony_ci
64268c2ecf20Sopenharmony_ci# check for naked sscanf
64278c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
64288c2ecf20Sopenharmony_ci		    defined $stat &&
64298c2ecf20Sopenharmony_ci		    $line =~ /\bsscanf\b/ &&
64308c2ecf20Sopenharmony_ci		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
64318c2ecf20Sopenharmony_ci		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
64328c2ecf20Sopenharmony_ci		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
64338c2ecf20Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
64348c2ecf20Sopenharmony_ci			$lc = $lc + $linenr;
64358c2ecf20Sopenharmony_ci			my $stat_real = get_stat_real($linenr, $lc);
64368c2ecf20Sopenharmony_ci			WARN("NAKED_SSCANF",
64378c2ecf20Sopenharmony_ci			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
64388c2ecf20Sopenharmony_ci		}
64398c2ecf20Sopenharmony_ci
64408c2ecf20Sopenharmony_ci# check for simple sscanf that should be kstrto<foo>
64418c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
64428c2ecf20Sopenharmony_ci		    defined $stat &&
64438c2ecf20Sopenharmony_ci		    $line =~ /\bsscanf\b/) {
64448c2ecf20Sopenharmony_ci			my $lc = $stat =~ tr@\n@@;
64458c2ecf20Sopenharmony_ci			$lc = $lc + $linenr;
64468c2ecf20Sopenharmony_ci			my $stat_real = get_stat_real($linenr, $lc);
64478c2ecf20Sopenharmony_ci			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
64488c2ecf20Sopenharmony_ci				my $format = $6;
64498c2ecf20Sopenharmony_ci				my $count = $format =~ tr@%@%@;
64508c2ecf20Sopenharmony_ci				if ($count == 1 &&
64518c2ecf20Sopenharmony_ci				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
64528c2ecf20Sopenharmony_ci					WARN("SSCANF_TO_KSTRTO",
64538c2ecf20Sopenharmony_ci					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
64548c2ecf20Sopenharmony_ci				}
64558c2ecf20Sopenharmony_ci			}
64568c2ecf20Sopenharmony_ci		}
64578c2ecf20Sopenharmony_ci
64588c2ecf20Sopenharmony_ci# check for new externs in .h files.
64598c2ecf20Sopenharmony_ci		if ($realfile =~ /\.h$/ &&
64608c2ecf20Sopenharmony_ci		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
64618c2ecf20Sopenharmony_ci			if (CHK("AVOID_EXTERNS",
64628c2ecf20Sopenharmony_ci				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
64638c2ecf20Sopenharmony_ci			    $fix) {
64648c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
64658c2ecf20Sopenharmony_ci			}
64668c2ecf20Sopenharmony_ci		}
64678c2ecf20Sopenharmony_ci
64688c2ecf20Sopenharmony_ci# check for new externs in .c files.
64698c2ecf20Sopenharmony_ci		if ($realfile =~ /\.c$/ && defined $stat &&
64708c2ecf20Sopenharmony_ci		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
64718c2ecf20Sopenharmony_ci		{
64728c2ecf20Sopenharmony_ci			my $function_name = $1;
64738c2ecf20Sopenharmony_ci			my $paren_space = $2;
64748c2ecf20Sopenharmony_ci
64758c2ecf20Sopenharmony_ci			my $s = $stat;
64768c2ecf20Sopenharmony_ci			if (defined $cond) {
64778c2ecf20Sopenharmony_ci				substr($s, 0, length($cond), '');
64788c2ecf20Sopenharmony_ci			}
64798c2ecf20Sopenharmony_ci			if ($s =~ /^\s*;/)
64808c2ecf20Sopenharmony_ci			{
64818c2ecf20Sopenharmony_ci				WARN("AVOID_EXTERNS",
64828c2ecf20Sopenharmony_ci				     "externs should be avoided in .c files\n" .  $herecurr);
64838c2ecf20Sopenharmony_ci			}
64848c2ecf20Sopenharmony_ci
64858c2ecf20Sopenharmony_ci			if ($paren_space =~ /\n/) {
64868c2ecf20Sopenharmony_ci				WARN("FUNCTION_ARGUMENTS",
64878c2ecf20Sopenharmony_ci				     "arguments for function declarations should follow identifier\n" . $herecurr);
64888c2ecf20Sopenharmony_ci			}
64898c2ecf20Sopenharmony_ci
64908c2ecf20Sopenharmony_ci		} elsif ($realfile =~ /\.c$/ && defined $stat &&
64918c2ecf20Sopenharmony_ci		    $stat =~ /^.\s*extern\s+/)
64928c2ecf20Sopenharmony_ci		{
64938c2ecf20Sopenharmony_ci			WARN("AVOID_EXTERNS",
64948c2ecf20Sopenharmony_ci			     "externs should be avoided in .c files\n" .  $herecurr);
64958c2ecf20Sopenharmony_ci		}
64968c2ecf20Sopenharmony_ci
64978c2ecf20Sopenharmony_ci# check for function declarations that have arguments without identifier names
64988c2ecf20Sopenharmony_ci		if (defined $stat &&
64998c2ecf20Sopenharmony_ci		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
65008c2ecf20Sopenharmony_ci		    $1 ne "void") {
65018c2ecf20Sopenharmony_ci			my $args = trim($1);
65028c2ecf20Sopenharmony_ci			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
65038c2ecf20Sopenharmony_ci				my $arg = trim($1);
65048c2ecf20Sopenharmony_ci				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
65058c2ecf20Sopenharmony_ci					WARN("FUNCTION_ARGUMENTS",
65068c2ecf20Sopenharmony_ci					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
65078c2ecf20Sopenharmony_ci				}
65088c2ecf20Sopenharmony_ci			}
65098c2ecf20Sopenharmony_ci		}
65108c2ecf20Sopenharmony_ci
65118c2ecf20Sopenharmony_ci# check for function definitions
65128c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
65138c2ecf20Sopenharmony_ci		    defined $stat &&
65148c2ecf20Sopenharmony_ci		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
65158c2ecf20Sopenharmony_ci			$context_function = $1;
65168c2ecf20Sopenharmony_ci
65178c2ecf20Sopenharmony_ci# check for multiline function definition with misplaced open brace
65188c2ecf20Sopenharmony_ci			my $ok = 0;
65198c2ecf20Sopenharmony_ci			my $cnt = statement_rawlines($stat);
65208c2ecf20Sopenharmony_ci			my $herectx = $here . "\n";
65218c2ecf20Sopenharmony_ci			for (my $n = 0; $n < $cnt; $n++) {
65228c2ecf20Sopenharmony_ci				my $rl = raw_line($linenr, $n);
65238c2ecf20Sopenharmony_ci				$herectx .=  $rl . "\n";
65248c2ecf20Sopenharmony_ci				$ok = 1 if ($rl =~ /^[ \+]\{/);
65258c2ecf20Sopenharmony_ci				$ok = 1 if ($rl =~ /\{/ && $n == 0);
65268c2ecf20Sopenharmony_ci				last if $rl =~ /^[ \+].*\{/;
65278c2ecf20Sopenharmony_ci			}
65288c2ecf20Sopenharmony_ci			if (!$ok) {
65298c2ecf20Sopenharmony_ci				ERROR("OPEN_BRACE",
65308c2ecf20Sopenharmony_ci				      "open brace '{' following function definitions go on the next line\n" . $herectx);
65318c2ecf20Sopenharmony_ci			}
65328c2ecf20Sopenharmony_ci		}
65338c2ecf20Sopenharmony_ci
65348c2ecf20Sopenharmony_ci# checks for new __setup's
65358c2ecf20Sopenharmony_ci		if ($rawline =~ /\b__setup\("([^"]*)"/) {
65368c2ecf20Sopenharmony_ci			my $name = $1;
65378c2ecf20Sopenharmony_ci
65388c2ecf20Sopenharmony_ci			if (!grep(/$name/, @setup_docs)) {
65398c2ecf20Sopenharmony_ci				CHK("UNDOCUMENTED_SETUP",
65408c2ecf20Sopenharmony_ci				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
65418c2ecf20Sopenharmony_ci			}
65428c2ecf20Sopenharmony_ci		}
65438c2ecf20Sopenharmony_ci
65448c2ecf20Sopenharmony_ci# check for pointless casting of alloc functions
65458c2ecf20Sopenharmony_ci		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
65468c2ecf20Sopenharmony_ci			WARN("UNNECESSARY_CASTS",
65478c2ecf20Sopenharmony_ci			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
65488c2ecf20Sopenharmony_ci		}
65498c2ecf20Sopenharmony_ci
65508c2ecf20Sopenharmony_ci# alloc style
65518c2ecf20Sopenharmony_ci# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
65528c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
65538c2ecf20Sopenharmony_ci		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
65548c2ecf20Sopenharmony_ci			CHK("ALLOC_SIZEOF_STRUCT",
65558c2ecf20Sopenharmony_ci			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
65568c2ecf20Sopenharmony_ci		}
65578c2ecf20Sopenharmony_ci
65588c2ecf20Sopenharmony_ci# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
65598c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
65608c2ecf20Sopenharmony_ci		    defined $stat &&
65618c2ecf20Sopenharmony_ci		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
65628c2ecf20Sopenharmony_ci			my $oldfunc = $3;
65638c2ecf20Sopenharmony_ci			my $a1 = $4;
65648c2ecf20Sopenharmony_ci			my $a2 = $10;
65658c2ecf20Sopenharmony_ci			my $newfunc = "kmalloc_array";
65668c2ecf20Sopenharmony_ci			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
65678c2ecf20Sopenharmony_ci			my $r1 = $a1;
65688c2ecf20Sopenharmony_ci			my $r2 = $a2;
65698c2ecf20Sopenharmony_ci			if ($a1 =~ /^sizeof\s*\S/) {
65708c2ecf20Sopenharmony_ci				$r1 = $a2;
65718c2ecf20Sopenharmony_ci				$r2 = $a1;
65728c2ecf20Sopenharmony_ci			}
65738c2ecf20Sopenharmony_ci			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
65748c2ecf20Sopenharmony_ci			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
65758c2ecf20Sopenharmony_ci				my $cnt = statement_rawlines($stat);
65768c2ecf20Sopenharmony_ci				my $herectx = get_stat_here($linenr, $cnt, $here);
65778c2ecf20Sopenharmony_ci
65788c2ecf20Sopenharmony_ci				if (WARN("ALLOC_WITH_MULTIPLY",
65798c2ecf20Sopenharmony_ci					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
65808c2ecf20Sopenharmony_ci				    $cnt == 1 &&
65818c2ecf20Sopenharmony_ci				    $fix) {
65828c2ecf20Sopenharmony_ci					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
65838c2ecf20Sopenharmony_ci				}
65848c2ecf20Sopenharmony_ci			}
65858c2ecf20Sopenharmony_ci		}
65868c2ecf20Sopenharmony_ci
65878c2ecf20Sopenharmony_ci# check for krealloc arg reuse
65888c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
65898c2ecf20Sopenharmony_ci		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
65908c2ecf20Sopenharmony_ci		    $1 eq $3) {
65918c2ecf20Sopenharmony_ci			WARN("KREALLOC_ARG_REUSE",
65928c2ecf20Sopenharmony_ci			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
65938c2ecf20Sopenharmony_ci		}
65948c2ecf20Sopenharmony_ci
65958c2ecf20Sopenharmony_ci# check for alloc argument mismatch
65968c2ecf20Sopenharmony_ci		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
65978c2ecf20Sopenharmony_ci			WARN("ALLOC_ARRAY_ARGS",
65988c2ecf20Sopenharmony_ci			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
65998c2ecf20Sopenharmony_ci		}
66008c2ecf20Sopenharmony_ci
66018c2ecf20Sopenharmony_ci# check for multiple semicolons
66028c2ecf20Sopenharmony_ci		if ($line =~ /;\s*;\s*$/) {
66038c2ecf20Sopenharmony_ci			if (WARN("ONE_SEMICOLON",
66048c2ecf20Sopenharmony_ci				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
66058c2ecf20Sopenharmony_ci			    $fix) {
66068c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
66078c2ecf20Sopenharmony_ci			}
66088c2ecf20Sopenharmony_ci		}
66098c2ecf20Sopenharmony_ci
66108c2ecf20Sopenharmony_ci# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
66118c2ecf20Sopenharmony_ci		if ($realfile !~ m@^include/uapi/@ &&
66128c2ecf20Sopenharmony_ci		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
66138c2ecf20Sopenharmony_ci			my $ull = "";
66148c2ecf20Sopenharmony_ci			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
66158c2ecf20Sopenharmony_ci			if (CHK("BIT_MACRO",
66168c2ecf20Sopenharmony_ci				"Prefer using the BIT$ull macro\n" . $herecurr) &&
66178c2ecf20Sopenharmony_ci			    $fix) {
66188c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
66198c2ecf20Sopenharmony_ci			}
66208c2ecf20Sopenharmony_ci		}
66218c2ecf20Sopenharmony_ci
66228c2ecf20Sopenharmony_ci# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
66238c2ecf20Sopenharmony_ci		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
66248c2ecf20Sopenharmony_ci			WARN("IS_ENABLED_CONFIG",
66258c2ecf20Sopenharmony_ci			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
66268c2ecf20Sopenharmony_ci		}
66278c2ecf20Sopenharmony_ci
66288c2ecf20Sopenharmony_ci# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
66298c2ecf20Sopenharmony_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*$/) {
66308c2ecf20Sopenharmony_ci			my $config = $1;
66318c2ecf20Sopenharmony_ci			if (WARN("PREFER_IS_ENABLED",
66328c2ecf20Sopenharmony_ci				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
66338c2ecf20Sopenharmony_ci			    $fix) {
66348c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
66358c2ecf20Sopenharmony_ci			}
66368c2ecf20Sopenharmony_ci		}
66378c2ecf20Sopenharmony_ci
66388c2ecf20Sopenharmony_ci# check for /* fallthrough */ like comment, prefer fallthrough;
66398c2ecf20Sopenharmony_ci		my @fallthroughs = (
66408c2ecf20Sopenharmony_ci			'fallthrough',
66418c2ecf20Sopenharmony_ci			'@fallthrough@',
66428c2ecf20Sopenharmony_ci			'lint -fallthrough[ \t]*',
66438c2ecf20Sopenharmony_ci			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
66448c2ecf20Sopenharmony_ci			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
66458c2ecf20Sopenharmony_ci			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
66468c2ecf20Sopenharmony_ci			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
66478c2ecf20Sopenharmony_ci		    );
66488c2ecf20Sopenharmony_ci		if ($raw_comment ne '') {
66498c2ecf20Sopenharmony_ci			foreach my $ft (@fallthroughs) {
66508c2ecf20Sopenharmony_ci				if ($raw_comment =~ /$ft/) {
66518c2ecf20Sopenharmony_ci					my $msg_level = \&WARN;
66528c2ecf20Sopenharmony_ci					$msg_level = \&CHK if ($file);
66538c2ecf20Sopenharmony_ci					&{$msg_level}("PREFER_FALLTHROUGH",
66548c2ecf20Sopenharmony_ci						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
66558c2ecf20Sopenharmony_ci					last;
66568c2ecf20Sopenharmony_ci				}
66578c2ecf20Sopenharmony_ci			}
66588c2ecf20Sopenharmony_ci		}
66598c2ecf20Sopenharmony_ci
66608c2ecf20Sopenharmony_ci# check for switch/default statements without a break;
66618c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
66628c2ecf20Sopenharmony_ci		    defined $stat &&
66638c2ecf20Sopenharmony_ci		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
66648c2ecf20Sopenharmony_ci			my $cnt = statement_rawlines($stat);
66658c2ecf20Sopenharmony_ci			my $herectx = get_stat_here($linenr, $cnt, $here);
66668c2ecf20Sopenharmony_ci
66678c2ecf20Sopenharmony_ci			WARN("DEFAULT_NO_BREAK",
66688c2ecf20Sopenharmony_ci			     "switch default: should use break\n" . $herectx);
66698c2ecf20Sopenharmony_ci		}
66708c2ecf20Sopenharmony_ci
66718c2ecf20Sopenharmony_ci# check for gcc specific __FUNCTION__
66728c2ecf20Sopenharmony_ci		if ($line =~ /\b__FUNCTION__\b/) {
66738c2ecf20Sopenharmony_ci			if (WARN("USE_FUNC",
66748c2ecf20Sopenharmony_ci				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
66758c2ecf20Sopenharmony_ci			    $fix) {
66768c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
66778c2ecf20Sopenharmony_ci			}
66788c2ecf20Sopenharmony_ci		}
66798c2ecf20Sopenharmony_ci
66808c2ecf20Sopenharmony_ci# check for uses of __DATE__, __TIME__, __TIMESTAMP__
66818c2ecf20Sopenharmony_ci		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
66828c2ecf20Sopenharmony_ci			ERROR("DATE_TIME",
66838c2ecf20Sopenharmony_ci			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
66848c2ecf20Sopenharmony_ci		}
66858c2ecf20Sopenharmony_ci
66868c2ecf20Sopenharmony_ci# check for use of yield()
66878c2ecf20Sopenharmony_ci		if ($line =~ /\byield\s*\(\s*\)/) {
66888c2ecf20Sopenharmony_ci			WARN("YIELD",
66898c2ecf20Sopenharmony_ci			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
66908c2ecf20Sopenharmony_ci		}
66918c2ecf20Sopenharmony_ci
66928c2ecf20Sopenharmony_ci# check for comparisons against true and false
66938c2ecf20Sopenharmony_ci		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
66948c2ecf20Sopenharmony_ci			my $lead = $1;
66958c2ecf20Sopenharmony_ci			my $arg = $2;
66968c2ecf20Sopenharmony_ci			my $test = $3;
66978c2ecf20Sopenharmony_ci			my $otype = $4;
66988c2ecf20Sopenharmony_ci			my $trail = $5;
66998c2ecf20Sopenharmony_ci			my $op = "!";
67008c2ecf20Sopenharmony_ci
67018c2ecf20Sopenharmony_ci			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
67028c2ecf20Sopenharmony_ci
67038c2ecf20Sopenharmony_ci			my $type = lc($otype);
67048c2ecf20Sopenharmony_ci			if ($type =~ /^(?:true|false)$/) {
67058c2ecf20Sopenharmony_ci				if (("$test" eq "==" && "$type" eq "true") ||
67068c2ecf20Sopenharmony_ci				    ("$test" eq "!=" && "$type" eq "false")) {
67078c2ecf20Sopenharmony_ci					$op = "";
67088c2ecf20Sopenharmony_ci				}
67098c2ecf20Sopenharmony_ci
67108c2ecf20Sopenharmony_ci				CHK("BOOL_COMPARISON",
67118c2ecf20Sopenharmony_ci				    "Using comparison to $otype is error prone\n" . $herecurr);
67128c2ecf20Sopenharmony_ci
67138c2ecf20Sopenharmony_ci## maybe suggesting a correct construct would better
67148c2ecf20Sopenharmony_ci##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
67158c2ecf20Sopenharmony_ci
67168c2ecf20Sopenharmony_ci			}
67178c2ecf20Sopenharmony_ci		}
67188c2ecf20Sopenharmony_ci
67198c2ecf20Sopenharmony_ci# check for semaphores initialized locked
67208c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
67218c2ecf20Sopenharmony_ci			WARN("CONSIDER_COMPLETION",
67228c2ecf20Sopenharmony_ci			     "consider using a completion\n" . $herecurr);
67238c2ecf20Sopenharmony_ci		}
67248c2ecf20Sopenharmony_ci
67258c2ecf20Sopenharmony_ci# recommend kstrto* over simple_strto* and strict_strto*
67268c2ecf20Sopenharmony_ci		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
67278c2ecf20Sopenharmony_ci			WARN("CONSIDER_KSTRTO",
67288c2ecf20Sopenharmony_ci			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
67298c2ecf20Sopenharmony_ci		}
67308c2ecf20Sopenharmony_ci
67318c2ecf20Sopenharmony_ci# check for __initcall(), use device_initcall() explicitly or more appropriate function please
67328c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*__initcall\s*\(/) {
67338c2ecf20Sopenharmony_ci			WARN("USE_DEVICE_INITCALL",
67348c2ecf20Sopenharmony_ci			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
67358c2ecf20Sopenharmony_ci		}
67368c2ecf20Sopenharmony_ci
67378c2ecf20Sopenharmony_ci# check for spin_is_locked(), suggest lockdep instead
67388c2ecf20Sopenharmony_ci		if ($line =~ /\bspin_is_locked\(/) {
67398c2ecf20Sopenharmony_ci			WARN("USE_LOCKDEP",
67408c2ecf20Sopenharmony_ci			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
67418c2ecf20Sopenharmony_ci		}
67428c2ecf20Sopenharmony_ci
67438c2ecf20Sopenharmony_ci# check for deprecated apis
67448c2ecf20Sopenharmony_ci		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
67458c2ecf20Sopenharmony_ci			my $deprecated_api = $1;
67468c2ecf20Sopenharmony_ci			my $new_api = $deprecated_apis{$deprecated_api};
67478c2ecf20Sopenharmony_ci			WARN("DEPRECATED_API",
67488c2ecf20Sopenharmony_ci			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
67498c2ecf20Sopenharmony_ci		}
67508c2ecf20Sopenharmony_ci
67518c2ecf20Sopenharmony_ci# check for various structs that are normally const (ops, kgdb, device_tree)
67528c2ecf20Sopenharmony_ci# and avoid what seem like struct definitions 'struct foo {'
67538c2ecf20Sopenharmony_ci		if (defined($const_structs) &&
67548c2ecf20Sopenharmony_ci		    $line !~ /\bconst\b/ &&
67558c2ecf20Sopenharmony_ci		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
67568c2ecf20Sopenharmony_ci			WARN("CONST_STRUCT",
67578c2ecf20Sopenharmony_ci			     "struct $1 should normally be const\n" . $herecurr);
67588c2ecf20Sopenharmony_ci		}
67598c2ecf20Sopenharmony_ci
67608c2ecf20Sopenharmony_ci# use of NR_CPUS is usually wrong
67618c2ecf20Sopenharmony_ci# ignore definitions of NR_CPUS and usage to define arrays as likely right
67628c2ecf20Sopenharmony_ci		if ($line =~ /\bNR_CPUS\b/ &&
67638c2ecf20Sopenharmony_ci		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
67648c2ecf20Sopenharmony_ci		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
67658c2ecf20Sopenharmony_ci		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
67668c2ecf20Sopenharmony_ci		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
67678c2ecf20Sopenharmony_ci		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
67688c2ecf20Sopenharmony_ci		{
67698c2ecf20Sopenharmony_ci			WARN("NR_CPUS",
67708c2ecf20Sopenharmony_ci			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
67718c2ecf20Sopenharmony_ci		}
67728c2ecf20Sopenharmony_ci
67738c2ecf20Sopenharmony_ci# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
67748c2ecf20Sopenharmony_ci		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
67758c2ecf20Sopenharmony_ci			ERROR("DEFINE_ARCH_HAS",
67768c2ecf20Sopenharmony_ci			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
67778c2ecf20Sopenharmony_ci		}
67788c2ecf20Sopenharmony_ci
67798c2ecf20Sopenharmony_ci# likely/unlikely comparisons similar to "(likely(foo) > 0)"
67808c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
67818c2ecf20Sopenharmony_ci		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
67828c2ecf20Sopenharmony_ci			WARN("LIKELY_MISUSE",
67838c2ecf20Sopenharmony_ci			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
67848c2ecf20Sopenharmony_ci		}
67858c2ecf20Sopenharmony_ci
67868c2ecf20Sopenharmony_ci# nested likely/unlikely calls
67878c2ecf20Sopenharmony_ci		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
67888c2ecf20Sopenharmony_ci			WARN("LIKELY_MISUSE",
67898c2ecf20Sopenharmony_ci			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
67908c2ecf20Sopenharmony_ci		}
67918c2ecf20Sopenharmony_ci
67928c2ecf20Sopenharmony_ci# whine mightly about in_atomic
67938c2ecf20Sopenharmony_ci		if ($line =~ /\bin_atomic\s*\(/) {
67948c2ecf20Sopenharmony_ci			if ($realfile =~ m@^drivers/@) {
67958c2ecf20Sopenharmony_ci				ERROR("IN_ATOMIC",
67968c2ecf20Sopenharmony_ci				      "do not use in_atomic in drivers\n" . $herecurr);
67978c2ecf20Sopenharmony_ci			} elsif ($realfile !~ m@^kernel/@) {
67988c2ecf20Sopenharmony_ci				WARN("IN_ATOMIC",
67998c2ecf20Sopenharmony_ci				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
68008c2ecf20Sopenharmony_ci			}
68018c2ecf20Sopenharmony_ci		}
68028c2ecf20Sopenharmony_ci
68038c2ecf20Sopenharmony_ci# check for mutex_trylock_recursive usage
68048c2ecf20Sopenharmony_ci		if ($line =~ /mutex_trylock_recursive/) {
68058c2ecf20Sopenharmony_ci			ERROR("LOCKING",
68068c2ecf20Sopenharmony_ci			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
68078c2ecf20Sopenharmony_ci		}
68088c2ecf20Sopenharmony_ci
68098c2ecf20Sopenharmony_ci# check for lockdep_set_novalidate_class
68108c2ecf20Sopenharmony_ci		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
68118c2ecf20Sopenharmony_ci		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
68128c2ecf20Sopenharmony_ci			if ($realfile !~ m@^kernel/lockdep@ &&
68138c2ecf20Sopenharmony_ci			    $realfile !~ m@^include/linux/lockdep@ &&
68148c2ecf20Sopenharmony_ci			    $realfile !~ m@^drivers/base/core@) {
68158c2ecf20Sopenharmony_ci				ERROR("LOCKDEP",
68168c2ecf20Sopenharmony_ci				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
68178c2ecf20Sopenharmony_ci			}
68188c2ecf20Sopenharmony_ci		}
68198c2ecf20Sopenharmony_ci
68208c2ecf20Sopenharmony_ci		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
68218c2ecf20Sopenharmony_ci		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
68228c2ecf20Sopenharmony_ci			WARN("EXPORTED_WORLD_WRITABLE",
68238c2ecf20Sopenharmony_ci			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
68248c2ecf20Sopenharmony_ci		}
68258c2ecf20Sopenharmony_ci
68268c2ecf20Sopenharmony_ci# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
68278c2ecf20Sopenharmony_ci# and whether or not function naming is typical and if
68288c2ecf20Sopenharmony_ci# DEVICE_ATTR permissions uses are unusual too
68298c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
68308c2ecf20Sopenharmony_ci		    defined $stat &&
68318c2ecf20Sopenharmony_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*\)/) {
68328c2ecf20Sopenharmony_ci			my $var = $1;
68338c2ecf20Sopenharmony_ci			my $perms = $2;
68348c2ecf20Sopenharmony_ci			my $show = $3;
68358c2ecf20Sopenharmony_ci			my $store = $4;
68368c2ecf20Sopenharmony_ci			my $octal_perms = perms_to_octal($perms);
68378c2ecf20Sopenharmony_ci			if ($show =~ /^${var}_show$/ &&
68388c2ecf20Sopenharmony_ci			    $store =~ /^${var}_store$/ &&
68398c2ecf20Sopenharmony_ci			    $octal_perms eq "0644") {
68408c2ecf20Sopenharmony_ci				if (WARN("DEVICE_ATTR_RW",
68418c2ecf20Sopenharmony_ci					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
68428c2ecf20Sopenharmony_ci				    $fix) {
68438c2ecf20Sopenharmony_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})/;
68448c2ecf20Sopenharmony_ci				}
68458c2ecf20Sopenharmony_ci			} elsif ($show =~ /^${var}_show$/ &&
68468c2ecf20Sopenharmony_ci				 $store =~ /^NULL$/ &&
68478c2ecf20Sopenharmony_ci				 $octal_perms eq "0444") {
68488c2ecf20Sopenharmony_ci				if (WARN("DEVICE_ATTR_RO",
68498c2ecf20Sopenharmony_ci					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
68508c2ecf20Sopenharmony_ci				    $fix) {
68518c2ecf20Sopenharmony_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})/;
68528c2ecf20Sopenharmony_ci				}
68538c2ecf20Sopenharmony_ci			} elsif ($show =~ /^NULL$/ &&
68548c2ecf20Sopenharmony_ci				 $store =~ /^${var}_store$/ &&
68558c2ecf20Sopenharmony_ci				 $octal_perms eq "0200") {
68568c2ecf20Sopenharmony_ci				if (WARN("DEVICE_ATTR_WO",
68578c2ecf20Sopenharmony_ci					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
68588c2ecf20Sopenharmony_ci				    $fix) {
68598c2ecf20Sopenharmony_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})/;
68608c2ecf20Sopenharmony_ci				}
68618c2ecf20Sopenharmony_ci			} elsif ($octal_perms eq "0644" ||
68628c2ecf20Sopenharmony_ci				 $octal_perms eq "0444" ||
68638c2ecf20Sopenharmony_ci				 $octal_perms eq "0200") {
68648c2ecf20Sopenharmony_ci				my $newshow = "$show";
68658c2ecf20Sopenharmony_ci				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
68668c2ecf20Sopenharmony_ci				my $newstore = $store;
68678c2ecf20Sopenharmony_ci				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
68688c2ecf20Sopenharmony_ci				my $rename = "";
68698c2ecf20Sopenharmony_ci				if ($show ne $newshow) {
68708c2ecf20Sopenharmony_ci					$rename .= " '$show' to '$newshow'";
68718c2ecf20Sopenharmony_ci				}
68728c2ecf20Sopenharmony_ci				if ($store ne $newstore) {
68738c2ecf20Sopenharmony_ci					$rename .= " '$store' to '$newstore'";
68748c2ecf20Sopenharmony_ci				}
68758c2ecf20Sopenharmony_ci				WARN("DEVICE_ATTR_FUNCTIONS",
68768c2ecf20Sopenharmony_ci				     "Consider renaming function(s)$rename\n" . $herecurr);
68778c2ecf20Sopenharmony_ci			} else {
68788c2ecf20Sopenharmony_ci				WARN("DEVICE_ATTR_PERMS",
68798c2ecf20Sopenharmony_ci				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
68808c2ecf20Sopenharmony_ci			}
68818c2ecf20Sopenharmony_ci		}
68828c2ecf20Sopenharmony_ci
68838c2ecf20Sopenharmony_ci# Mode permission misuses where it seems decimal should be octal
68848c2ecf20Sopenharmony_ci# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
68858c2ecf20Sopenharmony_ci# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
68868c2ecf20Sopenharmony_ci#   specific definition of not visible in sysfs.
68878c2ecf20Sopenharmony_ci# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
68888c2ecf20Sopenharmony_ci#   use the default permissions
68898c2ecf20Sopenharmony_ci		if ($perl_version_ok &&
68908c2ecf20Sopenharmony_ci		    defined $stat &&
68918c2ecf20Sopenharmony_ci		    $line =~ /$mode_perms_search/) {
68928c2ecf20Sopenharmony_ci			foreach my $entry (@mode_permission_funcs) {
68938c2ecf20Sopenharmony_ci				my $func = $entry->[0];
68948c2ecf20Sopenharmony_ci				my $arg_pos = $entry->[1];
68958c2ecf20Sopenharmony_ci
68968c2ecf20Sopenharmony_ci				my $lc = $stat =~ tr@\n@@;
68978c2ecf20Sopenharmony_ci				$lc = $lc + $linenr;
68988c2ecf20Sopenharmony_ci				my $stat_real = get_stat_real($linenr, $lc);
68998c2ecf20Sopenharmony_ci
69008c2ecf20Sopenharmony_ci				my $skip_args = "";
69018c2ecf20Sopenharmony_ci				if ($arg_pos > 1) {
69028c2ecf20Sopenharmony_ci					$arg_pos--;
69038c2ecf20Sopenharmony_ci					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
69048c2ecf20Sopenharmony_ci				}
69058c2ecf20Sopenharmony_ci				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
69068c2ecf20Sopenharmony_ci				if ($stat =~ /$test/) {
69078c2ecf20Sopenharmony_ci					my $val = $1;
69088c2ecf20Sopenharmony_ci					$val = $6 if ($skip_args ne "");
69098c2ecf20Sopenharmony_ci					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
69108c2ecf20Sopenharmony_ci					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
69118c2ecf20Sopenharmony_ci					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
69128c2ecf20Sopenharmony_ci						ERROR("NON_OCTAL_PERMISSIONS",
69138c2ecf20Sopenharmony_ci						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
69148c2ecf20Sopenharmony_ci					}
69158c2ecf20Sopenharmony_ci					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
69168c2ecf20Sopenharmony_ci						ERROR("EXPORTED_WORLD_WRITABLE",
69178c2ecf20Sopenharmony_ci						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
69188c2ecf20Sopenharmony_ci					}
69198c2ecf20Sopenharmony_ci				}
69208c2ecf20Sopenharmony_ci			}
69218c2ecf20Sopenharmony_ci		}
69228c2ecf20Sopenharmony_ci
69238c2ecf20Sopenharmony_ci# check for uses of S_<PERMS> that could be octal for readability
69248c2ecf20Sopenharmony_ci		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
69258c2ecf20Sopenharmony_ci			my $oval = $1;
69268c2ecf20Sopenharmony_ci			my $octal = perms_to_octal($oval);
69278c2ecf20Sopenharmony_ci			if (WARN("SYMBOLIC_PERMS",
69288c2ecf20Sopenharmony_ci				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
69298c2ecf20Sopenharmony_ci			    $fix) {
69308c2ecf20Sopenharmony_ci				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
69318c2ecf20Sopenharmony_ci			}
69328c2ecf20Sopenharmony_ci		}
69338c2ecf20Sopenharmony_ci
69348c2ecf20Sopenharmony_ci# validate content of MODULE_LICENSE against list from include/linux/module.h
69358c2ecf20Sopenharmony_ci		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
69368c2ecf20Sopenharmony_ci			my $extracted_string = get_quoted_string($line, $rawline);
69378c2ecf20Sopenharmony_ci			my $valid_licenses = qr{
69388c2ecf20Sopenharmony_ci						GPL|
69398c2ecf20Sopenharmony_ci						GPL\ v2|
69408c2ecf20Sopenharmony_ci						GPL\ and\ additional\ rights|
69418c2ecf20Sopenharmony_ci						Dual\ BSD/GPL|
69428c2ecf20Sopenharmony_ci						Dual\ MIT/GPL|
69438c2ecf20Sopenharmony_ci						Dual\ MPL/GPL|
69448c2ecf20Sopenharmony_ci						Proprietary
69458c2ecf20Sopenharmony_ci					}x;
69468c2ecf20Sopenharmony_ci			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
69478c2ecf20Sopenharmony_ci				WARN("MODULE_LICENSE",
69488c2ecf20Sopenharmony_ci				     "unknown module license " . $extracted_string . "\n" . $herecurr);
69498c2ecf20Sopenharmony_ci			}
69508c2ecf20Sopenharmony_ci		}
69518c2ecf20Sopenharmony_ci
69528c2ecf20Sopenharmony_ci# check for sysctl duplicate constants
69538c2ecf20Sopenharmony_ci		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
69548c2ecf20Sopenharmony_ci			WARN("DUPLICATED_SYSCTL_CONST",
69558c2ecf20Sopenharmony_ci				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
69568c2ecf20Sopenharmony_ci		}
69578c2ecf20Sopenharmony_ci	}
69588c2ecf20Sopenharmony_ci
69598c2ecf20Sopenharmony_ci	# If we have no input at all, then there is nothing to report on
69608c2ecf20Sopenharmony_ci	# so just keep quiet.
69618c2ecf20Sopenharmony_ci	if ($#rawlines == -1) {
69628c2ecf20Sopenharmony_ci		exit(0);
69638c2ecf20Sopenharmony_ci	}
69648c2ecf20Sopenharmony_ci
69658c2ecf20Sopenharmony_ci	# In mailback mode only produce a report in the negative, for
69668c2ecf20Sopenharmony_ci	# things that appear to be patches.
69678c2ecf20Sopenharmony_ci	if ($mailback && ($clean == 1 || !$is_patch)) {
69688c2ecf20Sopenharmony_ci		exit(0);
69698c2ecf20Sopenharmony_ci	}
69708c2ecf20Sopenharmony_ci
69718c2ecf20Sopenharmony_ci	# This is not a patch, and we are are in 'no-patch' mode so
69728c2ecf20Sopenharmony_ci	# just keep quiet.
69738c2ecf20Sopenharmony_ci	if (!$chk_patch && !$is_patch) {
69748c2ecf20Sopenharmony_ci		exit(0);
69758c2ecf20Sopenharmony_ci	}
69768c2ecf20Sopenharmony_ci
69778c2ecf20Sopenharmony_ci	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
69788c2ecf20Sopenharmony_ci		ERROR("NOT_UNIFIED_DIFF",
69798c2ecf20Sopenharmony_ci		      "Does not appear to be a unified-diff format patch\n");
69808c2ecf20Sopenharmony_ci	}
69818c2ecf20Sopenharmony_ci	if ($is_patch && $has_commit_log && $chk_signoff) {
69828c2ecf20Sopenharmony_ci		if ($signoff == 0) {
69838c2ecf20Sopenharmony_ci			ERROR("MISSING_SIGN_OFF",
69848c2ecf20Sopenharmony_ci			      "Missing Signed-off-by: line(s)\n");
69858c2ecf20Sopenharmony_ci		} elsif ($authorsignoff != 1) {
69868c2ecf20Sopenharmony_ci			# authorsignoff values:
69878c2ecf20Sopenharmony_ci			# 0 -> missing sign off
69888c2ecf20Sopenharmony_ci			# 1 -> sign off identical
69898c2ecf20Sopenharmony_ci			# 2 -> names and addresses match, comments mismatch
69908c2ecf20Sopenharmony_ci			# 3 -> addresses match, names different
69918c2ecf20Sopenharmony_ci			# 4 -> names match, addresses different
69928c2ecf20Sopenharmony_ci			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
69938c2ecf20Sopenharmony_ci
69948c2ecf20Sopenharmony_ci			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
69958c2ecf20Sopenharmony_ci
69968c2ecf20Sopenharmony_ci			if ($authorsignoff == 0) {
69978c2ecf20Sopenharmony_ci				ERROR("NO_AUTHOR_SIGN_OFF",
69988c2ecf20Sopenharmony_ci				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
69998c2ecf20Sopenharmony_ci			} elsif ($authorsignoff == 2) {
70008c2ecf20Sopenharmony_ci				CHK("FROM_SIGN_OFF_MISMATCH",
70018c2ecf20Sopenharmony_ci				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
70028c2ecf20Sopenharmony_ci			} elsif ($authorsignoff == 3) {
70038c2ecf20Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
70048c2ecf20Sopenharmony_ci				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
70058c2ecf20Sopenharmony_ci			} elsif ($authorsignoff == 4) {
70068c2ecf20Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
70078c2ecf20Sopenharmony_ci				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
70088c2ecf20Sopenharmony_ci			} elsif ($authorsignoff == 5) {
70098c2ecf20Sopenharmony_ci				WARN("FROM_SIGN_OFF_MISMATCH",
70108c2ecf20Sopenharmony_ci				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
70118c2ecf20Sopenharmony_ci			}
70128c2ecf20Sopenharmony_ci		}
70138c2ecf20Sopenharmony_ci	}
70148c2ecf20Sopenharmony_ci
70158c2ecf20Sopenharmony_ci	print report_dump();
70168c2ecf20Sopenharmony_ci	if ($summary && !($clean == 1 && $quiet == 1)) {
70178c2ecf20Sopenharmony_ci		print "$filename " if ($summary_file);
70188c2ecf20Sopenharmony_ci		print "total: $cnt_error errors, $cnt_warn warnings, " .
70198c2ecf20Sopenharmony_ci			(($check)? "$cnt_chk checks, " : "") .
70208c2ecf20Sopenharmony_ci			"$cnt_lines lines checked\n";
70218c2ecf20Sopenharmony_ci	}
70228c2ecf20Sopenharmony_ci
70238c2ecf20Sopenharmony_ci	if ($quiet == 0) {
70248c2ecf20Sopenharmony_ci		# If there were any defects found and not already fixing them
70258c2ecf20Sopenharmony_ci		if (!$clean and !$fix) {
70268c2ecf20Sopenharmony_ci			print << "EOM"
70278c2ecf20Sopenharmony_ci
70288c2ecf20Sopenharmony_ciNOTE: For some of the reported defects, checkpatch may be able to
70298c2ecf20Sopenharmony_ci      mechanically convert to the typical style using --fix or --fix-inplace.
70308c2ecf20Sopenharmony_ciEOM
70318c2ecf20Sopenharmony_ci		}
70328c2ecf20Sopenharmony_ci		# If there were whitespace errors which cleanpatch can fix
70338c2ecf20Sopenharmony_ci		# then suggest that.
70348c2ecf20Sopenharmony_ci		if ($rpt_cleaners) {
70358c2ecf20Sopenharmony_ci			$rpt_cleaners = 0;
70368c2ecf20Sopenharmony_ci			print << "EOM"
70378c2ecf20Sopenharmony_ci
70388c2ecf20Sopenharmony_ciNOTE: Whitespace errors detected.
70398c2ecf20Sopenharmony_ci      You may wish to use scripts/cleanpatch or scripts/cleanfile
70408c2ecf20Sopenharmony_ciEOM
70418c2ecf20Sopenharmony_ci		}
70428c2ecf20Sopenharmony_ci	}
70438c2ecf20Sopenharmony_ci
70448c2ecf20Sopenharmony_ci	if ($clean == 0 && $fix &&
70458c2ecf20Sopenharmony_ci	    ("@rawlines" ne "@fixed" ||
70468c2ecf20Sopenharmony_ci	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
70478c2ecf20Sopenharmony_ci		my $newfile = $filename;
70488c2ecf20Sopenharmony_ci		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
70498c2ecf20Sopenharmony_ci		my $linecount = 0;
70508c2ecf20Sopenharmony_ci		my $f;
70518c2ecf20Sopenharmony_ci
70528c2ecf20Sopenharmony_ci		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
70538c2ecf20Sopenharmony_ci
70548c2ecf20Sopenharmony_ci		open($f, '>', $newfile)
70558c2ecf20Sopenharmony_ci		    or die "$P: Can't open $newfile for write\n";
70568c2ecf20Sopenharmony_ci		foreach my $fixed_line (@fixed) {
70578c2ecf20Sopenharmony_ci			$linecount++;
70588c2ecf20Sopenharmony_ci			if ($file) {
70598c2ecf20Sopenharmony_ci				if ($linecount > 3) {
70608c2ecf20Sopenharmony_ci					$fixed_line =~ s/^\+//;
70618c2ecf20Sopenharmony_ci					print $f $fixed_line . "\n";
70628c2ecf20Sopenharmony_ci				}
70638c2ecf20Sopenharmony_ci			} else {
70648c2ecf20Sopenharmony_ci				print $f $fixed_line . "\n";
70658c2ecf20Sopenharmony_ci			}
70668c2ecf20Sopenharmony_ci		}
70678c2ecf20Sopenharmony_ci		close($f);
70688c2ecf20Sopenharmony_ci
70698c2ecf20Sopenharmony_ci		if (!$quiet) {
70708c2ecf20Sopenharmony_ci			print << "EOM";
70718c2ecf20Sopenharmony_ci
70728c2ecf20Sopenharmony_ciWrote EXPERIMENTAL --fix correction(s) to '$newfile'
70738c2ecf20Sopenharmony_ci
70748c2ecf20Sopenharmony_ciDo _NOT_ trust the results written to this file.
70758c2ecf20Sopenharmony_ciDo _NOT_ submit these changes without inspecting them for correctness.
70768c2ecf20Sopenharmony_ci
70778c2ecf20Sopenharmony_ciThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
70788c2ecf20Sopenharmony_ciNo warranties, expressed or implied...
70798c2ecf20Sopenharmony_ciEOM
70808c2ecf20Sopenharmony_ci		}
70818c2ecf20Sopenharmony_ci	}
70828c2ecf20Sopenharmony_ci
70838c2ecf20Sopenharmony_ci	if ($quiet == 0) {
70848c2ecf20Sopenharmony_ci		print "\n";
70858c2ecf20Sopenharmony_ci		if ($clean == 1) {
70868c2ecf20Sopenharmony_ci			print "$vname has no obvious style problems and is ready for submission.\n";
70878c2ecf20Sopenharmony_ci		} else {
70888c2ecf20Sopenharmony_ci			print "$vname has style problems, please review.\n";
70898c2ecf20Sopenharmony_ci		}
70908c2ecf20Sopenharmony_ci	}
70918c2ecf20Sopenharmony_ci	return $clean;
70928c2ecf20Sopenharmony_ci}
7093