xref: /aosp_15_r20/tools/repohooks/tools/checkpatch.pl (revision d68f33bc6fb0cc2476107c2af0573a2f5a63dfc1)
1*d68f33bcSAndroid Build Coastguard Worker#!/usr/bin/env perl
2*d68f33bcSAndroid Build Coastguard Worker# SPDX-License-Identifier: GPL-2.0
3*d68f33bcSAndroid Build Coastguard Worker#
4*d68f33bcSAndroid Build Coastguard Worker# (c) 2001, Dave Jones. (the file handling bit)
5*d68f33bcSAndroid Build Coastguard Worker# (c) 2005, Joel Schopp <[email protected]> (the ugly bit)
6*d68f33bcSAndroid Build Coastguard Worker# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)
7*d68f33bcSAndroid Build Coastguard Worker# (c) 2008-2010 Andy Whitcroft <[email protected]>
8*d68f33bcSAndroid Build Coastguard Worker# (c) 2010-2018 Joe Perches <[email protected]>
9*d68f33bcSAndroid Build Coastguard Worker
10*d68f33bcSAndroid Build Coastguard Workeruse strict;
11*d68f33bcSAndroid Build Coastguard Workeruse warnings;
12*d68f33bcSAndroid Build Coastguard Workeruse POSIX;
13*d68f33bcSAndroid Build Coastguard Workeruse File::Basename;
14*d68f33bcSAndroid Build Coastguard Workeruse Cwd 'abs_path';
15*d68f33bcSAndroid Build Coastguard Workeruse Term::ANSIColor qw(:constants);
16*d68f33bcSAndroid Build Coastguard Workeruse Encode qw(decode encode);
17*d68f33bcSAndroid Build Coastguard Worker
18*d68f33bcSAndroid Build Coastguard Workermy $P = $0;
19*d68f33bcSAndroid Build Coastguard Workermy $D = dirname(abs_path($P));
20*d68f33bcSAndroid Build Coastguard Worker
21*d68f33bcSAndroid Build Coastguard Workermy $V = '0.32';
22*d68f33bcSAndroid Build Coastguard Worker
23*d68f33bcSAndroid Build Coastguard Workeruse Getopt::Long qw(:config no_auto_abbrev);
24*d68f33bcSAndroid Build Coastguard Worker
25*d68f33bcSAndroid Build Coastguard Workermy $quiet = 0;
26*d68f33bcSAndroid Build Coastguard Workermy $verbose = 0;
27*d68f33bcSAndroid Build Coastguard Workermy %verbose_messages = ();
28*d68f33bcSAndroid Build Coastguard Workermy %verbose_emitted = ();
29*d68f33bcSAndroid Build Coastguard Workermy $tree = 1;
30*d68f33bcSAndroid Build Coastguard Workermy $chk_signoff = 1;
31*d68f33bcSAndroid Build Coastguard Workermy $chk_patch = 1;
32*d68f33bcSAndroid Build Coastguard Workermy $tst_only;
33*d68f33bcSAndroid Build Coastguard Workermy $emacs = 0;
34*d68f33bcSAndroid Build Coastguard Workermy $terse = 0;
35*d68f33bcSAndroid Build Coastguard Workermy $showfile = 0;
36*d68f33bcSAndroid Build Coastguard Workermy $file = 0;
37*d68f33bcSAndroid Build Coastguard Workermy $git = 0;
38*d68f33bcSAndroid Build Coastguard Workermy %git_commits = ();
39*d68f33bcSAndroid Build Coastguard Workermy $check = 0;
40*d68f33bcSAndroid Build Coastguard Workermy $check_orig = 0;
41*d68f33bcSAndroid Build Coastguard Workermy $summary = 1;
42*d68f33bcSAndroid Build Coastguard Workermy $mailback = 0;
43*d68f33bcSAndroid Build Coastguard Workermy $summary_file = 0;
44*d68f33bcSAndroid Build Coastguard Workermy $show_types = 0;
45*d68f33bcSAndroid Build Coastguard Workermy $list_types = 0;
46*d68f33bcSAndroid Build Coastguard Workermy $fix = 0;
47*d68f33bcSAndroid Build Coastguard Workermy $fix_inplace = 0;
48*d68f33bcSAndroid Build Coastguard Workermy $root;
49*d68f33bcSAndroid Build Coastguard Workermy $gitroot = $ENV{'GIT_DIR'};
50*d68f33bcSAndroid Build Coastguard Worker$gitroot = ".git" if !defined($gitroot);
51*d68f33bcSAndroid Build Coastguard Workermy %debug;
52*d68f33bcSAndroid Build Coastguard Workermy %camelcase = ();
53*d68f33bcSAndroid Build Coastguard Workermy %use_type = ();
54*d68f33bcSAndroid Build Coastguard Workermy @use = ();
55*d68f33bcSAndroid Build Coastguard Workermy %ignore_type = ();
56*d68f33bcSAndroid Build Coastguard Workermy @ignore = ();
57*d68f33bcSAndroid Build Coastguard Workermy $help = 0;
58*d68f33bcSAndroid Build Coastguard Workermy $configuration_file = ".checkpatch.conf";
59*d68f33bcSAndroid Build Coastguard Workermy $max_line_length = 100;
60*d68f33bcSAndroid Build Coastguard Workermy $ignore_perl_version = 0;
61*d68f33bcSAndroid Build Coastguard Workermy $minimum_perl_version = 5.10.0;
62*d68f33bcSAndroid Build Coastguard Workermy $min_conf_desc_length = 4;
63*d68f33bcSAndroid Build Coastguard Workermy $spelling_file = "$D/spelling.txt";
64*d68f33bcSAndroid Build Coastguard Workermy $codespell = 0;
65*d68f33bcSAndroid Build Coastguard Workermy $codespellfile = "/usr/share/codespell/dictionary.txt";
66*d68f33bcSAndroid Build Coastguard Workermy $user_codespellfile = "";
67*d68f33bcSAndroid Build Coastguard Workermy $conststructsfile = "$D/const_structs.checkpatch";
68*d68f33bcSAndroid Build Coastguard Workermy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
69*d68f33bcSAndroid Build Coastguard Workermy $typedefsfile;
70*d68f33bcSAndroid Build Coastguard Workermy $color = "auto";
71*d68f33bcSAndroid Build Coastguard Workermy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
72*d68f33bcSAndroid Build Coastguard Worker# git output parsing needs US English output, so first set backtick child process LANGUAGE
73*d68f33bcSAndroid Build Coastguard Workermy $git_command ='export LANGUAGE=en_US.UTF-8; git';
74*d68f33bcSAndroid Build Coastguard Workermy $tabsize = 8;
75*d68f33bcSAndroid Build Coastguard Workermy ${CONFIG_} = "CONFIG_";
76*d68f33bcSAndroid Build Coastguard Worker
77*d68f33bcSAndroid Build Coastguard Workersub help {
78*d68f33bcSAndroid Build Coastguard Worker	my ($exitcode) = @_;
79*d68f33bcSAndroid Build Coastguard Worker
80*d68f33bcSAndroid Build Coastguard Worker	print << "EOM";
81*d68f33bcSAndroid Build Coastguard WorkerUsage: $P [OPTION]... [FILE]...
82*d68f33bcSAndroid Build Coastguard WorkerVersion: $V
83*d68f33bcSAndroid Build Coastguard Worker
84*d68f33bcSAndroid Build Coastguard WorkerOptions:
85*d68f33bcSAndroid Build Coastguard Worker  -q, --quiet                quiet
86*d68f33bcSAndroid Build Coastguard Worker  -v, --verbose              verbose mode
87*d68f33bcSAndroid Build Coastguard Worker  --no-tree                  run without a kernel tree
88*d68f33bcSAndroid Build Coastguard Worker  --no-signoff               do not check for 'Signed-off-by' line
89*d68f33bcSAndroid Build Coastguard Worker  --patch                    treat FILE as patchfile (default)
90*d68f33bcSAndroid Build Coastguard Worker  --emacs                    emacs compile window format
91*d68f33bcSAndroid Build Coastguard Worker  --terse                    one line per report
92*d68f33bcSAndroid Build Coastguard Worker  --showfile                 emit diffed file position, not input file position
93*d68f33bcSAndroid Build Coastguard Worker  -g, --git                  treat FILE as a single commit or git revision range
94*d68f33bcSAndroid Build Coastguard Worker                             single git commit with:
95*d68f33bcSAndroid Build Coastguard Worker                               <rev>
96*d68f33bcSAndroid Build Coastguard Worker                               <rev>^
97*d68f33bcSAndroid Build Coastguard Worker                               <rev>~n
98*d68f33bcSAndroid Build Coastguard Worker                             multiple git commits with:
99*d68f33bcSAndroid Build Coastguard Worker                               <rev1>..<rev2>
100*d68f33bcSAndroid Build Coastguard Worker                               <rev1>...<rev2>
101*d68f33bcSAndroid Build Coastguard Worker                               <rev>-<count>
102*d68f33bcSAndroid Build Coastguard Worker                             git merges are ignored
103*d68f33bcSAndroid Build Coastguard Worker  -f, --file                 treat FILE as regular source file
104*d68f33bcSAndroid Build Coastguard Worker  --subjective, --strict     enable more subjective tests
105*d68f33bcSAndroid Build Coastguard Worker  --list-types               list the possible message types
106*d68f33bcSAndroid Build Coastguard Worker  --types TYPE(,TYPE2...)    show only these comma separated message types
107*d68f33bcSAndroid Build Coastguard Worker  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
108*d68f33bcSAndroid Build Coastguard Worker  --show-types               show the specific message type in the output
109*d68f33bcSAndroid Build Coastguard Worker  --max-line-length=n        set the maximum line length, (default $max_line_length)
110*d68f33bcSAndroid Build Coastguard Worker                             if exceeded, warn on patches
111*d68f33bcSAndroid Build Coastguard Worker                             requires --strict for use with --file
112*d68f33bcSAndroid Build Coastguard Worker  --min-conf-desc-length=n   set the min description length, if shorter, warn
113*d68f33bcSAndroid Build Coastguard Worker  --tab-size=n               set the number of spaces for tab (default $tabsize)
114*d68f33bcSAndroid Build Coastguard Worker  --root=PATH                PATH to the kernel tree root
115*d68f33bcSAndroid Build Coastguard Worker  --no-summary               suppress the per-file summary
116*d68f33bcSAndroid Build Coastguard Worker  --mailback                 only produce a report in case of warnings/errors
117*d68f33bcSAndroid Build Coastguard Worker  --summary-file             include the filename in summary
118*d68f33bcSAndroid Build Coastguard Worker  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
119*d68f33bcSAndroid Build Coastguard Worker                             'values', 'possible', 'type', and 'attr' (default
120*d68f33bcSAndroid Build Coastguard Worker                             is all off)
121*d68f33bcSAndroid Build Coastguard Worker  --test-only=WORD           report only warnings/errors containing WORD
122*d68f33bcSAndroid Build Coastguard Worker                             literally
123*d68f33bcSAndroid Build Coastguard Worker  --fix                      EXPERIMENTAL - may create horrible results
124*d68f33bcSAndroid Build Coastguard Worker                             If correctable single-line errors exist, create
125*d68f33bcSAndroid Build Coastguard Worker                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
126*d68f33bcSAndroid Build Coastguard Worker                             with potential errors corrected to the preferred
127*d68f33bcSAndroid Build Coastguard Worker                             checkpatch style
128*d68f33bcSAndroid Build Coastguard Worker  --fix-inplace              EXPERIMENTAL - may create horrible results
129*d68f33bcSAndroid Build Coastguard Worker                             Is the same as --fix, but overwrites the input
130*d68f33bcSAndroid Build Coastguard Worker                             file.  It's your fault if there's no backup or git
131*d68f33bcSAndroid Build Coastguard Worker  --ignore-perl-version      override checking of perl version.  expect
132*d68f33bcSAndroid Build Coastguard Worker                             runtime errors.
133*d68f33bcSAndroid Build Coastguard Worker  --codespell                Use the codespell dictionary for spelling/typos
134*d68f33bcSAndroid Build Coastguard Worker                             (default:$codespellfile)
135*d68f33bcSAndroid Build Coastguard Worker  --codespellfile            Use this codespell dictionary
136*d68f33bcSAndroid Build Coastguard Worker  --typedefsfile             Read additional types from this file
137*d68f33bcSAndroid Build Coastguard Worker  --color[=WHEN]             Use colors 'always', 'never', or only when output
138*d68f33bcSAndroid Build Coastguard Worker                             is a terminal ('auto'). Default is 'auto'.
139*d68f33bcSAndroid Build Coastguard Worker  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
140*d68f33bcSAndroid Build Coastguard Worker                             ${CONFIG_})
141*d68f33bcSAndroid Build Coastguard Worker  -h, --help, --version      display this help and exit
142*d68f33bcSAndroid Build Coastguard Worker
143*d68f33bcSAndroid Build Coastguard WorkerWhen FILE is - read standard input.
144*d68f33bcSAndroid Build Coastguard WorkerEOM
145*d68f33bcSAndroid Build Coastguard Worker
146*d68f33bcSAndroid Build Coastguard Worker	exit($exitcode);
147*d68f33bcSAndroid Build Coastguard Worker}
148*d68f33bcSAndroid Build Coastguard Worker
149*d68f33bcSAndroid Build Coastguard Workersub uniq {
150*d68f33bcSAndroid Build Coastguard Worker	my %seen;
151*d68f33bcSAndroid Build Coastguard Worker	return grep { !$seen{$_}++ } @_;
152*d68f33bcSAndroid Build Coastguard Worker}
153*d68f33bcSAndroid Build Coastguard Worker
154*d68f33bcSAndroid Build Coastguard Workersub list_types {
155*d68f33bcSAndroid Build Coastguard Worker	my ($exitcode) = @_;
156*d68f33bcSAndroid Build Coastguard Worker
157*d68f33bcSAndroid Build Coastguard Worker	my $count = 0;
158*d68f33bcSAndroid Build Coastguard Worker
159*d68f33bcSAndroid Build Coastguard Worker	local $/ = undef;
160*d68f33bcSAndroid Build Coastguard Worker
161*d68f33bcSAndroid Build Coastguard Worker	open(my $script, '<', abs_path($P)) or
162*d68f33bcSAndroid Build Coastguard Worker	    die "$P: Can't read '$P' $!\n";
163*d68f33bcSAndroid Build Coastguard Worker
164*d68f33bcSAndroid Build Coastguard Worker	my $text = <$script>;
165*d68f33bcSAndroid Build Coastguard Worker	close($script);
166*d68f33bcSAndroid Build Coastguard Worker
167*d68f33bcSAndroid Build Coastguard Worker	my %types = ();
168*d68f33bcSAndroid Build Coastguard Worker	# Also catch when type or level is passed through a variable
169*d68f33bcSAndroid Build Coastguard Worker	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
170*d68f33bcSAndroid Build Coastguard Worker		if (defined($1)) {
171*d68f33bcSAndroid Build Coastguard Worker			if (exists($types{$2})) {
172*d68f33bcSAndroid Build Coastguard Worker				$types{$2} .= ",$1" if ($types{$2} ne $1);
173*d68f33bcSAndroid Build Coastguard Worker			} else {
174*d68f33bcSAndroid Build Coastguard Worker				$types{$2} = $1;
175*d68f33bcSAndroid Build Coastguard Worker			}
176*d68f33bcSAndroid Build Coastguard Worker		} else {
177*d68f33bcSAndroid Build Coastguard Worker			$types{$2} = "UNDETERMINED";
178*d68f33bcSAndroid Build Coastguard Worker		}
179*d68f33bcSAndroid Build Coastguard Worker	}
180*d68f33bcSAndroid Build Coastguard Worker
181*d68f33bcSAndroid Build Coastguard Worker	print("#\tMessage type\n\n");
182*d68f33bcSAndroid Build Coastguard Worker	if ($color) {
183*d68f33bcSAndroid Build Coastguard Worker		print(" ( Color coding: ");
184*d68f33bcSAndroid Build Coastguard Worker		print(RED . "ERROR" . RESET);
185*d68f33bcSAndroid Build Coastguard Worker		print(" | ");
186*d68f33bcSAndroid Build Coastguard Worker		print(YELLOW . "WARNING" . RESET);
187*d68f33bcSAndroid Build Coastguard Worker		print(" | ");
188*d68f33bcSAndroid Build Coastguard Worker		print(GREEN . "CHECK" . RESET);
189*d68f33bcSAndroid Build Coastguard Worker		print(" | ");
190*d68f33bcSAndroid Build Coastguard Worker		print("Multiple levels / Undetermined");
191*d68f33bcSAndroid Build Coastguard Worker		print(" )\n\n");
192*d68f33bcSAndroid Build Coastguard Worker	}
193*d68f33bcSAndroid Build Coastguard Worker
194*d68f33bcSAndroid Build Coastguard Worker	foreach my $type (sort keys %types) {
195*d68f33bcSAndroid Build Coastguard Worker		my $orig_type = $type;
196*d68f33bcSAndroid Build Coastguard Worker		if ($color) {
197*d68f33bcSAndroid Build Coastguard Worker			my $level = $types{$type};
198*d68f33bcSAndroid Build Coastguard Worker			if ($level eq "ERROR") {
199*d68f33bcSAndroid Build Coastguard Worker				$type = RED . $type . RESET;
200*d68f33bcSAndroid Build Coastguard Worker			} elsif ($level eq "WARN") {
201*d68f33bcSAndroid Build Coastguard Worker				$type = YELLOW . $type . RESET;
202*d68f33bcSAndroid Build Coastguard Worker			} elsif ($level eq "CHK") {
203*d68f33bcSAndroid Build Coastguard Worker				$type = GREEN . $type . RESET;
204*d68f33bcSAndroid Build Coastguard Worker			}
205*d68f33bcSAndroid Build Coastguard Worker		}
206*d68f33bcSAndroid Build Coastguard Worker		print(++$count . "\t" . $type . "\n");
207*d68f33bcSAndroid Build Coastguard Worker		if ($verbose && exists($verbose_messages{$orig_type})) {
208*d68f33bcSAndroid Build Coastguard Worker			my $message = $verbose_messages{$orig_type};
209*d68f33bcSAndroid Build Coastguard Worker			$message =~ s/\n/\n\t/g;
210*d68f33bcSAndroid Build Coastguard Worker			print("\t" . $message . "\n\n");
211*d68f33bcSAndroid Build Coastguard Worker		}
212*d68f33bcSAndroid Build Coastguard Worker	}
213*d68f33bcSAndroid Build Coastguard Worker
214*d68f33bcSAndroid Build Coastguard Worker	exit($exitcode);
215*d68f33bcSAndroid Build Coastguard Worker}
216*d68f33bcSAndroid Build Coastguard Worker
217*d68f33bcSAndroid Build Coastguard Workermy $conf = which_conf($configuration_file);
218*d68f33bcSAndroid Build Coastguard Workerif (-f $conf) {
219*d68f33bcSAndroid Build Coastguard Worker	my @conf_args;
220*d68f33bcSAndroid Build Coastguard Worker	open(my $conffile, '<', "$conf")
221*d68f33bcSAndroid Build Coastguard Worker	    or warn "$P: Can't find a readable $configuration_file file $!\n";
222*d68f33bcSAndroid Build Coastguard Worker
223*d68f33bcSAndroid Build Coastguard Worker	while (<$conffile>) {
224*d68f33bcSAndroid Build Coastguard Worker		my $line = $_;
225*d68f33bcSAndroid Build Coastguard Worker
226*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/\s*\n?$//g;
227*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/^\s*//g;
228*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/\s+/ /g;
229*d68f33bcSAndroid Build Coastguard Worker
230*d68f33bcSAndroid Build Coastguard Worker		next if ($line =~ m/^\s*#/);
231*d68f33bcSAndroid Build Coastguard Worker		next if ($line =~ m/^\s*$/);
232*d68f33bcSAndroid Build Coastguard Worker
233*d68f33bcSAndroid Build Coastguard Worker		my @words = split(" ", $line);
234*d68f33bcSAndroid Build Coastguard Worker		foreach my $word (@words) {
235*d68f33bcSAndroid Build Coastguard Worker			last if ($word =~ m/^#/);
236*d68f33bcSAndroid Build Coastguard Worker			push (@conf_args, $word);
237*d68f33bcSAndroid Build Coastguard Worker		}
238*d68f33bcSAndroid Build Coastguard Worker	}
239*d68f33bcSAndroid Build Coastguard Worker	close($conffile);
240*d68f33bcSAndroid Build Coastguard Worker	unshift(@ARGV, @conf_args) if @conf_args;
241*d68f33bcSAndroid Build Coastguard Worker}
242*d68f33bcSAndroid Build Coastguard Worker
243*d68f33bcSAndroid Build Coastguard Workersub load_docs {
244*d68f33bcSAndroid Build Coastguard Worker	open(my $docs, '<', "$docsfile")
245*d68f33bcSAndroid Build Coastguard Worker	    or warn "$P: Can't read the documentation file $docsfile $!\n";
246*d68f33bcSAndroid Build Coastguard Worker
247*d68f33bcSAndroid Build Coastguard Worker	my $type = '';
248*d68f33bcSAndroid Build Coastguard Worker	my $desc = '';
249*d68f33bcSAndroid Build Coastguard Worker	my $in_desc = 0;
250*d68f33bcSAndroid Build Coastguard Worker
251*d68f33bcSAndroid Build Coastguard Worker	while (<$docs>) {
252*d68f33bcSAndroid Build Coastguard Worker		chomp;
253*d68f33bcSAndroid Build Coastguard Worker		my $line = $_;
254*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/\s+$//;
255*d68f33bcSAndroid Build Coastguard Worker
256*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
257*d68f33bcSAndroid Build Coastguard Worker			if ($desc ne '') {
258*d68f33bcSAndroid Build Coastguard Worker				$verbose_messages{$type} = trim($desc);
259*d68f33bcSAndroid Build Coastguard Worker			}
260*d68f33bcSAndroid Build Coastguard Worker			$type = $1;
261*d68f33bcSAndroid Build Coastguard Worker			$desc = '';
262*d68f33bcSAndroid Build Coastguard Worker			$in_desc = 1;
263*d68f33bcSAndroid Build Coastguard Worker		} elsif ($in_desc) {
264*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^(?:\s{4,}|$)/) {
265*d68f33bcSAndroid Build Coastguard Worker				$line =~ s/^\s{4}//;
266*d68f33bcSAndroid Build Coastguard Worker				$desc .= $line;
267*d68f33bcSAndroid Build Coastguard Worker				$desc .= "\n";
268*d68f33bcSAndroid Build Coastguard Worker			} else {
269*d68f33bcSAndroid Build Coastguard Worker				$verbose_messages{$type} = trim($desc);
270*d68f33bcSAndroid Build Coastguard Worker				$type = '';
271*d68f33bcSAndroid Build Coastguard Worker				$desc = '';
272*d68f33bcSAndroid Build Coastguard Worker				$in_desc = 0;
273*d68f33bcSAndroid Build Coastguard Worker			}
274*d68f33bcSAndroid Build Coastguard Worker		}
275*d68f33bcSAndroid Build Coastguard Worker	}
276*d68f33bcSAndroid Build Coastguard Worker
277*d68f33bcSAndroid Build Coastguard Worker	if ($desc ne '') {
278*d68f33bcSAndroid Build Coastguard Worker		$verbose_messages{$type} = trim($desc);
279*d68f33bcSAndroid Build Coastguard Worker	}
280*d68f33bcSAndroid Build Coastguard Worker	close($docs);
281*d68f33bcSAndroid Build Coastguard Worker}
282*d68f33bcSAndroid Build Coastguard Worker
283*d68f33bcSAndroid Build Coastguard Worker# Perl's Getopt::Long allows options to take optional arguments after a space.
284*d68f33bcSAndroid Build Coastguard Worker# Prevent --color by itself from consuming other arguments
285*d68f33bcSAndroid Build Coastguard Workerforeach (@ARGV) {
286*d68f33bcSAndroid Build Coastguard Worker	if ($_ eq "--color" || $_ eq "-color") {
287*d68f33bcSAndroid Build Coastguard Worker		$_ = "--color=$color";
288*d68f33bcSAndroid Build Coastguard Worker	}
289*d68f33bcSAndroid Build Coastguard Worker}
290*d68f33bcSAndroid Build Coastguard Worker
291*d68f33bcSAndroid Build Coastguard WorkerGetOptions(
292*d68f33bcSAndroid Build Coastguard Worker	'q|quiet+'	=> \$quiet,
293*d68f33bcSAndroid Build Coastguard Worker	'v|verbose!'	=> \$verbose,
294*d68f33bcSAndroid Build Coastguard Worker	'tree!'		=> \$tree,
295*d68f33bcSAndroid Build Coastguard Worker	'signoff!'	=> \$chk_signoff,
296*d68f33bcSAndroid Build Coastguard Worker	'patch!'	=> \$chk_patch,
297*d68f33bcSAndroid Build Coastguard Worker	'emacs!'	=> \$emacs,
298*d68f33bcSAndroid Build Coastguard Worker	'terse!'	=> \$terse,
299*d68f33bcSAndroid Build Coastguard Worker	'showfile!'	=> \$showfile,
300*d68f33bcSAndroid Build Coastguard Worker	'f|file!'	=> \$file,
301*d68f33bcSAndroid Build Coastguard Worker	'g|git!'	=> \$git,
302*d68f33bcSAndroid Build Coastguard Worker	'subjective!'	=> \$check,
303*d68f33bcSAndroid Build Coastguard Worker	'strict!'	=> \$check,
304*d68f33bcSAndroid Build Coastguard Worker	'ignore=s'	=> \@ignore,
305*d68f33bcSAndroid Build Coastguard Worker	'types=s'	=> \@use,
306*d68f33bcSAndroid Build Coastguard Worker	'show-types!'	=> \$show_types,
307*d68f33bcSAndroid Build Coastguard Worker	'list-types!'	=> \$list_types,
308*d68f33bcSAndroid Build Coastguard Worker	'max-line-length=i' => \$max_line_length,
309*d68f33bcSAndroid Build Coastguard Worker	'min-conf-desc-length=i' => \$min_conf_desc_length,
310*d68f33bcSAndroid Build Coastguard Worker	'tab-size=i'	=> \$tabsize,
311*d68f33bcSAndroid Build Coastguard Worker	'root=s'	=> \$root,
312*d68f33bcSAndroid Build Coastguard Worker	'summary!'	=> \$summary,
313*d68f33bcSAndroid Build Coastguard Worker	'mailback!'	=> \$mailback,
314*d68f33bcSAndroid Build Coastguard Worker	'summary-file!'	=> \$summary_file,
315*d68f33bcSAndroid Build Coastguard Worker	'fix!'		=> \$fix,
316*d68f33bcSAndroid Build Coastguard Worker	'fix-inplace!'	=> \$fix_inplace,
317*d68f33bcSAndroid Build Coastguard Worker	'ignore-perl-version!' => \$ignore_perl_version,
318*d68f33bcSAndroid Build Coastguard Worker	'debug=s'	=> \%debug,
319*d68f33bcSAndroid Build Coastguard Worker	'test-only=s'	=> \$tst_only,
320*d68f33bcSAndroid Build Coastguard Worker	'codespell!'	=> \$codespell,
321*d68f33bcSAndroid Build Coastguard Worker	'codespellfile=s'	=> \$user_codespellfile,
322*d68f33bcSAndroid Build Coastguard Worker	'typedefsfile=s'	=> \$typedefsfile,
323*d68f33bcSAndroid Build Coastguard Worker	'color=s'	=> \$color,
324*d68f33bcSAndroid Build Coastguard Worker	'no-color'	=> \$color,	#keep old behaviors of -nocolor
325*d68f33bcSAndroid Build Coastguard Worker	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
326*d68f33bcSAndroid Build Coastguard Worker	'kconfig-prefix=s'	=> \${CONFIG_},
327*d68f33bcSAndroid Build Coastguard Worker	'h|help'	=> \$help,
328*d68f33bcSAndroid Build Coastguard Worker	'version'	=> \$help
329*d68f33bcSAndroid Build Coastguard Worker) or $help = 2;
330*d68f33bcSAndroid Build Coastguard Worker
331*d68f33bcSAndroid Build Coastguard Workerif ($user_codespellfile) {
332*d68f33bcSAndroid Build Coastguard Worker	# Use the user provided codespell file unconditionally
333*d68f33bcSAndroid Build Coastguard Worker	$codespellfile = $user_codespellfile;
334*d68f33bcSAndroid Build Coastguard Worker} elsif (!(-f $codespellfile)) {
335*d68f33bcSAndroid Build Coastguard Worker	# If /usr/share/codespell/dictionary.txt is not present, try to find it
336*d68f33bcSAndroid Build Coastguard Worker	# under codespell's install directory: <codespell_root>/data/dictionary.txt
337*d68f33bcSAndroid Build Coastguard Worker	if (($codespell || $help) && which("codespell") ne "" && which("python") ne "") {
338*d68f33bcSAndroid Build Coastguard Worker		my $python_codespell_dict = << "EOF";
339*d68f33bcSAndroid Build Coastguard Worker
340*d68f33bcSAndroid Build Coastguard Workerimport os.path as op
341*d68f33bcSAndroid Build Coastguard Workerimport codespell_lib
342*d68f33bcSAndroid Build Coastguard Workercodespell_dir = op.dirname(codespell_lib.__file__)
343*d68f33bcSAndroid Build Coastguard Workercodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
344*d68f33bcSAndroid Build Coastguard Workerprint(codespell_file, end='')
345*d68f33bcSAndroid Build Coastguard WorkerEOF
346*d68f33bcSAndroid Build Coastguard Worker
347*d68f33bcSAndroid Build Coastguard Worker		my $codespell_dict = `python -c "$python_codespell_dict" 2> /dev/null`;
348*d68f33bcSAndroid Build Coastguard Worker		$codespellfile = $codespell_dict if (-f $codespell_dict);
349*d68f33bcSAndroid Build Coastguard Worker	}
350*d68f33bcSAndroid Build Coastguard Worker}
351*d68f33bcSAndroid Build Coastguard Worker
352*d68f33bcSAndroid Build Coastguard Worker# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0
353*d68f33bcSAndroid Build Coastguard Worker# $help is 2 if invalid option is passed - exitcode: 1
354*d68f33bcSAndroid Build Coastguard Workerhelp($help - 1) if ($help);
355*d68f33bcSAndroid Build Coastguard Worker
356*d68f33bcSAndroid Build Coastguard Workerdie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
357*d68f33bcSAndroid Build Coastguard Workerdie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
358*d68f33bcSAndroid Build Coastguard Worker
359*d68f33bcSAndroid Build Coastguard Workerif ($color =~ /^[01]$/) {
360*d68f33bcSAndroid Build Coastguard Worker	$color = !$color;
361*d68f33bcSAndroid Build Coastguard Worker} elsif ($color =~ /^always$/i) {
362*d68f33bcSAndroid Build Coastguard Worker	$color = 1;
363*d68f33bcSAndroid Build Coastguard Worker} elsif ($color =~ /^never$/i) {
364*d68f33bcSAndroid Build Coastguard Worker	$color = 0;
365*d68f33bcSAndroid Build Coastguard Worker} elsif ($color =~ /^auto$/i) {
366*d68f33bcSAndroid Build Coastguard Worker	$color = (-t STDOUT);
367*d68f33bcSAndroid Build Coastguard Worker} else {
368*d68f33bcSAndroid Build Coastguard Worker	die "$P: Invalid color mode: $color\n";
369*d68f33bcSAndroid Build Coastguard Worker}
370*d68f33bcSAndroid Build Coastguard Worker
371*d68f33bcSAndroid Build Coastguard Workerload_docs() if ($verbose);
372*d68f33bcSAndroid Build Coastguard Workerlist_types(0) if ($list_types);
373*d68f33bcSAndroid Build Coastguard Worker
374*d68f33bcSAndroid Build Coastguard Worker$fix = 1 if ($fix_inplace);
375*d68f33bcSAndroid Build Coastguard Worker$check_orig = $check;
376*d68f33bcSAndroid Build Coastguard Worker
377*d68f33bcSAndroid Build Coastguard Workermy $exit = 0;
378*d68f33bcSAndroid Build Coastguard Worker
379*d68f33bcSAndroid Build Coastguard Workermy $perl_version_ok = 1;
380*d68f33bcSAndroid Build Coastguard Workerif ($^V && $^V lt $minimum_perl_version) {
381*d68f33bcSAndroid Build Coastguard Worker	$perl_version_ok = 0;
382*d68f33bcSAndroid Build Coastguard Worker	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
383*d68f33bcSAndroid Build Coastguard Worker	exit(1) if (!$ignore_perl_version);
384*d68f33bcSAndroid Build Coastguard Worker}
385*d68f33bcSAndroid Build Coastguard Worker
386*d68f33bcSAndroid Build Coastguard Worker#if no filenames are given, push '-' to read patch from stdin
387*d68f33bcSAndroid Build Coastguard Workerif ($#ARGV < 0) {
388*d68f33bcSAndroid Build Coastguard Worker	push(@ARGV, '-');
389*d68f33bcSAndroid Build Coastguard Worker}
390*d68f33bcSAndroid Build Coastguard Worker
391*d68f33bcSAndroid Build Coastguard Worker# skip TAB size 1 to avoid additional checks on $tabsize - 1
392*d68f33bcSAndroid Build Coastguard Workerdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
393*d68f33bcSAndroid Build Coastguard Worker
394*d68f33bcSAndroid Build Coastguard Workersub hash_save_array_words {
395*d68f33bcSAndroid Build Coastguard Worker	my ($hashRef, $arrayRef) = @_;
396*d68f33bcSAndroid Build Coastguard Worker
397*d68f33bcSAndroid Build Coastguard Worker	my @array = split(/,/, join(',', @$arrayRef));
398*d68f33bcSAndroid Build Coastguard Worker	foreach my $word (@array) {
399*d68f33bcSAndroid Build Coastguard Worker		$word =~ s/\s*\n?$//g;
400*d68f33bcSAndroid Build Coastguard Worker		$word =~ s/^\s*//g;
401*d68f33bcSAndroid Build Coastguard Worker		$word =~ s/\s+/ /g;
402*d68f33bcSAndroid Build Coastguard Worker		$word =~ tr/[a-z]/[A-Z]/;
403*d68f33bcSAndroid Build Coastguard Worker
404*d68f33bcSAndroid Build Coastguard Worker		next if ($word =~ m/^\s*#/);
405*d68f33bcSAndroid Build Coastguard Worker		next if ($word =~ m/^\s*$/);
406*d68f33bcSAndroid Build Coastguard Worker
407*d68f33bcSAndroid Build Coastguard Worker		$hashRef->{$word}++;
408*d68f33bcSAndroid Build Coastguard Worker	}
409*d68f33bcSAndroid Build Coastguard Worker}
410*d68f33bcSAndroid Build Coastguard Worker
411*d68f33bcSAndroid Build Coastguard Workersub hash_show_words {
412*d68f33bcSAndroid Build Coastguard Worker	my ($hashRef, $prefix) = @_;
413*d68f33bcSAndroid Build Coastguard Worker
414*d68f33bcSAndroid Build Coastguard Worker	if (keys %$hashRef) {
415*d68f33bcSAndroid Build Coastguard Worker		print "\nNOTE: $prefix message types:";
416*d68f33bcSAndroid Build Coastguard Worker		foreach my $word (sort keys %$hashRef) {
417*d68f33bcSAndroid Build Coastguard Worker			print " $word";
418*d68f33bcSAndroid Build Coastguard Worker		}
419*d68f33bcSAndroid Build Coastguard Worker		print "\n";
420*d68f33bcSAndroid Build Coastguard Worker	}
421*d68f33bcSAndroid Build Coastguard Worker}
422*d68f33bcSAndroid Build Coastguard Worker
423*d68f33bcSAndroid Build Coastguard Workerhash_save_array_words(\%ignore_type, \@ignore);
424*d68f33bcSAndroid Build Coastguard Workerhash_save_array_words(\%use_type, \@use);
425*d68f33bcSAndroid Build Coastguard Worker
426*d68f33bcSAndroid Build Coastguard Workermy $dbg_values = 0;
427*d68f33bcSAndroid Build Coastguard Workermy $dbg_possible = 0;
428*d68f33bcSAndroid Build Coastguard Workermy $dbg_type = 0;
429*d68f33bcSAndroid Build Coastguard Workermy $dbg_attr = 0;
430*d68f33bcSAndroid Build Coastguard Workerfor my $key (keys %debug) {
431*d68f33bcSAndroid Build Coastguard Worker	## no critic
432*d68f33bcSAndroid Build Coastguard Worker	eval "\${dbg_$key} = '$debug{$key}';";
433*d68f33bcSAndroid Build Coastguard Worker	die "$@" if ($@);
434*d68f33bcSAndroid Build Coastguard Worker}
435*d68f33bcSAndroid Build Coastguard Worker
436*d68f33bcSAndroid Build Coastguard Workermy $rpt_cleaners = 0;
437*d68f33bcSAndroid Build Coastguard Worker
438*d68f33bcSAndroid Build Coastguard Workerif ($terse) {
439*d68f33bcSAndroid Build Coastguard Worker	$emacs = 1;
440*d68f33bcSAndroid Build Coastguard Worker	$quiet++;
441*d68f33bcSAndroid Build Coastguard Worker}
442*d68f33bcSAndroid Build Coastguard Worker
443*d68f33bcSAndroid Build Coastguard Workerif ($tree) {
444*d68f33bcSAndroid Build Coastguard Worker	if (defined $root) {
445*d68f33bcSAndroid Build Coastguard Worker		if (!top_of_kernel_tree($root)) {
446*d68f33bcSAndroid Build Coastguard Worker			die "$P: $root: --root does not point at a valid tree\n";
447*d68f33bcSAndroid Build Coastguard Worker		}
448*d68f33bcSAndroid Build Coastguard Worker	} else {
449*d68f33bcSAndroid Build Coastguard Worker		if (top_of_kernel_tree('.')) {
450*d68f33bcSAndroid Build Coastguard Worker			$root = '.';
451*d68f33bcSAndroid Build Coastguard Worker		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
452*d68f33bcSAndroid Build Coastguard Worker						top_of_kernel_tree($1)) {
453*d68f33bcSAndroid Build Coastguard Worker			$root = $1;
454*d68f33bcSAndroid Build Coastguard Worker		}
455*d68f33bcSAndroid Build Coastguard Worker	}
456*d68f33bcSAndroid Build Coastguard Worker
457*d68f33bcSAndroid Build Coastguard Worker	if (!defined $root) {
458*d68f33bcSAndroid Build Coastguard Worker		print "Must be run from the top-level dir. of a kernel tree\n";
459*d68f33bcSAndroid Build Coastguard Worker		exit(2);
460*d68f33bcSAndroid Build Coastguard Worker	}
461*d68f33bcSAndroid Build Coastguard Worker}
462*d68f33bcSAndroid Build Coastguard Worker
463*d68f33bcSAndroid Build Coastguard Workermy $emitted_corrupt = 0;
464*d68f33bcSAndroid Build Coastguard Worker
465*d68f33bcSAndroid Build Coastguard Workerour $Ident	= qr{
466*d68f33bcSAndroid Build Coastguard Worker			[A-Za-z_][A-Za-z\d_]*
467*d68f33bcSAndroid Build Coastguard Worker			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
468*d68f33bcSAndroid Build Coastguard Worker		}x;
469*d68f33bcSAndroid Build Coastguard Workerour $Storage	= qr{extern|static|asmlinkage};
470*d68f33bcSAndroid Build Coastguard Workerour $Sparse	= qr{
471*d68f33bcSAndroid Build Coastguard Worker			__user|
472*d68f33bcSAndroid Build Coastguard Worker			__kernel|
473*d68f33bcSAndroid Build Coastguard Worker			__force|
474*d68f33bcSAndroid Build Coastguard Worker			__iomem|
475*d68f33bcSAndroid Build Coastguard Worker			__must_check|
476*d68f33bcSAndroid Build Coastguard Worker			__kprobes|
477*d68f33bcSAndroid Build Coastguard Worker			__ref|
478*d68f33bcSAndroid Build Coastguard Worker			__refconst|
479*d68f33bcSAndroid Build Coastguard Worker			__refdata|
480*d68f33bcSAndroid Build Coastguard Worker			__rcu|
481*d68f33bcSAndroid Build Coastguard Worker			__private
482*d68f33bcSAndroid Build Coastguard Worker		}x;
483*d68f33bcSAndroid Build Coastguard Workerour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
484*d68f33bcSAndroid Build Coastguard Workerour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
485*d68f33bcSAndroid Build Coastguard Workerour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
486*d68f33bcSAndroid Build Coastguard Workerour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
487*d68f33bcSAndroid Build Coastguard Workerour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
488*d68f33bcSAndroid Build Coastguard Worker
489*d68f33bcSAndroid Build Coastguard Worker# Notes to $Attribute:
490*d68f33bcSAndroid Build Coastguard Worker# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
491*d68f33bcSAndroid Build Coastguard Workerour $Attribute	= qr{
492*d68f33bcSAndroid Build Coastguard Worker			const|
493*d68f33bcSAndroid Build Coastguard Worker			volatile|
494*d68f33bcSAndroid Build Coastguard Worker			__percpu|
495*d68f33bcSAndroid Build Coastguard Worker			__nocast|
496*d68f33bcSAndroid Build Coastguard Worker			__safe|
497*d68f33bcSAndroid Build Coastguard Worker			__bitwise|
498*d68f33bcSAndroid Build Coastguard Worker			__packed__|
499*d68f33bcSAndroid Build Coastguard Worker			__packed2__|
500*d68f33bcSAndroid Build Coastguard Worker			__naked|
501*d68f33bcSAndroid Build Coastguard Worker			__maybe_unused|
502*d68f33bcSAndroid Build Coastguard Worker			__always_unused|
503*d68f33bcSAndroid Build Coastguard Worker			__noreturn|
504*d68f33bcSAndroid Build Coastguard Worker			__used|
505*d68f33bcSAndroid Build Coastguard Worker			__cold|
506*d68f33bcSAndroid Build Coastguard Worker			__pure|
507*d68f33bcSAndroid Build Coastguard Worker			__noclone|
508*d68f33bcSAndroid Build Coastguard Worker			__deprecated|
509*d68f33bcSAndroid Build Coastguard Worker			__read_mostly|
510*d68f33bcSAndroid Build Coastguard Worker			__ro_after_init|
511*d68f33bcSAndroid Build Coastguard Worker			__kprobes|
512*d68f33bcSAndroid Build Coastguard Worker			$InitAttribute|
513*d68f33bcSAndroid Build Coastguard Worker			____cacheline_aligned|
514*d68f33bcSAndroid Build Coastguard Worker			____cacheline_aligned_in_smp|
515*d68f33bcSAndroid Build Coastguard Worker			____cacheline_internodealigned_in_smp|
516*d68f33bcSAndroid Build Coastguard Worker			__weak|
517*d68f33bcSAndroid Build Coastguard Worker			__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
518*d68f33bcSAndroid Build Coastguard Worker		  }x;
519*d68f33bcSAndroid Build Coastguard Workerour $Modifier;
520*d68f33bcSAndroid Build Coastguard Workerour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
521*d68f33bcSAndroid Build Coastguard Workerour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
522*d68f33bcSAndroid Build Coastguard Workerour $Lval	= qr{$Ident(?:$Member)*};
523*d68f33bcSAndroid Build Coastguard Worker
524*d68f33bcSAndroid Build Coastguard Workerour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
525*d68f33bcSAndroid Build Coastguard Workerour $Binary	= qr{(?i)0b[01]+$Int_type?};
526*d68f33bcSAndroid Build Coastguard Workerour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
527*d68f33bcSAndroid Build Coastguard Workerour $Int	= qr{[0-9]+$Int_type?};
528*d68f33bcSAndroid Build Coastguard Workerour $Octal	= qr{0[0-7]+$Int_type?};
529*d68f33bcSAndroid Build Coastguard Workerour $String	= qr{(?:\b[Lu])?"[X\t]*"};
530*d68f33bcSAndroid Build Coastguard Workerour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
531*d68f33bcSAndroid Build Coastguard Workerour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
532*d68f33bcSAndroid Build Coastguard Workerour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
533*d68f33bcSAndroid Build Coastguard Workerour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
534*d68f33bcSAndroid Build Coastguard Workerour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
535*d68f33bcSAndroid Build Coastguard Workerour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
536*d68f33bcSAndroid Build Coastguard Workerour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
537*d68f33bcSAndroid Build Coastguard Workerour $Arithmetic = qr{\+|-|\*|\/|%};
538*d68f33bcSAndroid Build Coastguard Workerour $Operators	= qr{
539*d68f33bcSAndroid Build Coastguard Worker			<=|>=|==|!=|
540*d68f33bcSAndroid Build Coastguard Worker			=>|->|<<|>>|<|>|!|~|
541*d68f33bcSAndroid Build Coastguard Worker			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
542*d68f33bcSAndroid Build Coastguard Worker		  }x;
543*d68f33bcSAndroid Build Coastguard Worker
544*d68f33bcSAndroid Build Coastguard Workerour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
545*d68f33bcSAndroid Build Coastguard Worker
546*d68f33bcSAndroid Build Coastguard Workerour $BasicType;
547*d68f33bcSAndroid Build Coastguard Workerour $NonptrType;
548*d68f33bcSAndroid Build Coastguard Workerour $NonptrTypeMisordered;
549*d68f33bcSAndroid Build Coastguard Workerour $NonptrTypeWithAttr;
550*d68f33bcSAndroid Build Coastguard Workerour $Type;
551*d68f33bcSAndroid Build Coastguard Workerour $TypeMisordered;
552*d68f33bcSAndroid Build Coastguard Workerour $Declare;
553*d68f33bcSAndroid Build Coastguard Workerour $DeclareMisordered;
554*d68f33bcSAndroid Build Coastguard Worker
555*d68f33bcSAndroid Build Coastguard Workerour $NON_ASCII_UTF8	= qr{
556*d68f33bcSAndroid Build Coastguard Worker	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
557*d68f33bcSAndroid Build Coastguard Worker	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
558*d68f33bcSAndroid Build Coastguard Worker	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
559*d68f33bcSAndroid Build Coastguard Worker	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
560*d68f33bcSAndroid Build Coastguard Worker	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
561*d68f33bcSAndroid Build Coastguard Worker	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
562*d68f33bcSAndroid Build Coastguard Worker	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
563*d68f33bcSAndroid Build Coastguard Worker}x;
564*d68f33bcSAndroid Build Coastguard Worker
565*d68f33bcSAndroid Build Coastguard Workerour $UTF8	= qr{
566*d68f33bcSAndroid Build Coastguard Worker	[\x09\x0A\x0D\x20-\x7E]              # ASCII
567*d68f33bcSAndroid Build Coastguard Worker	| $NON_ASCII_UTF8
568*d68f33bcSAndroid Build Coastguard Worker}x;
569*d68f33bcSAndroid Build Coastguard Worker
570*d68f33bcSAndroid Build Coastguard Workerour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
571*d68f33bcSAndroid Build Coastguard Workerour $typeOtherOSTypedefs = qr{(?x:
572*d68f33bcSAndroid Build Coastguard Worker	u_(?:char|short|int|long) |          # bsd
573*d68f33bcSAndroid Build Coastguard Worker	u(?:nchar|short|int|long)            # sysv
574*d68f33bcSAndroid Build Coastguard Worker)};
575*d68f33bcSAndroid Build Coastguard Workerour $typeKernelTypedefs = qr{(?x:
576*d68f33bcSAndroid Build Coastguard Worker	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
577*d68f33bcSAndroid Build Coastguard Worker	atomic_t
578*d68f33bcSAndroid Build Coastguard Worker)};
579*d68f33bcSAndroid Build Coastguard Workerour $typeTypedefs = qr{(?x:
580*d68f33bcSAndroid Build Coastguard Worker	$typeC99Typedefs\b|
581*d68f33bcSAndroid Build Coastguard Worker	$typeOtherOSTypedefs\b|
582*d68f33bcSAndroid Build Coastguard Worker	$typeKernelTypedefs\b
583*d68f33bcSAndroid Build Coastguard Worker)};
584*d68f33bcSAndroid Build Coastguard Worker
585*d68f33bcSAndroid Build Coastguard Workerour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
586*d68f33bcSAndroid Build Coastguard Worker
587*d68f33bcSAndroid Build Coastguard Workerour $logFunctions = qr{(?x:
588*d68f33bcSAndroid Build Coastguard Worker	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
589*d68f33bcSAndroid Build Coastguard Worker	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
590*d68f33bcSAndroid Build Coastguard Worker	TP_printk|
591*d68f33bcSAndroid Build Coastguard Worker	WARN(?:_RATELIMIT|_ONCE|)|
592*d68f33bcSAndroid Build Coastguard Worker	panic|
593*d68f33bcSAndroid Build Coastguard Worker	MODULE_[A-Z_]+|
594*d68f33bcSAndroid Build Coastguard Worker	seq_vprintf|seq_printf|seq_puts
595*d68f33bcSAndroid Build Coastguard Worker)};
596*d68f33bcSAndroid Build Coastguard Worker
597*d68f33bcSAndroid Build Coastguard Workerour $allocFunctions = qr{(?x:
598*d68f33bcSAndroid Build Coastguard Worker	(?:(?:devm_)?
599*d68f33bcSAndroid Build Coastguard Worker		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
600*d68f33bcSAndroid Build Coastguard Worker		kstrdup(?:_const)? |
601*d68f33bcSAndroid Build Coastguard Worker		kmemdup(?:_nul)?) |
602*d68f33bcSAndroid Build Coastguard Worker	(?:\w+)?alloc_skb(?:_ip_align)? |
603*d68f33bcSAndroid Build Coastguard Worker				# dev_alloc_skb/netdev_alloc_skb, et al
604*d68f33bcSAndroid Build Coastguard Worker	dma_alloc_coherent
605*d68f33bcSAndroid Build Coastguard Worker)};
606*d68f33bcSAndroid Build Coastguard Worker
607*d68f33bcSAndroid Build Coastguard Workerour $signature_tags = qr{(?xi:
608*d68f33bcSAndroid Build Coastguard Worker	Signed-off-by:|
609*d68f33bcSAndroid Build Coastguard Worker	Co-developed-by:|
610*d68f33bcSAndroid Build Coastguard Worker	Acked-by:|
611*d68f33bcSAndroid Build Coastguard Worker	Tested-by:|
612*d68f33bcSAndroid Build Coastguard Worker	Reviewed-by:|
613*d68f33bcSAndroid Build Coastguard Worker	Reported-by:|
614*d68f33bcSAndroid Build Coastguard Worker	Suggested-by:|
615*d68f33bcSAndroid Build Coastguard Worker	To:|
616*d68f33bcSAndroid Build Coastguard Worker	Cc:
617*d68f33bcSAndroid Build Coastguard Worker)};
618*d68f33bcSAndroid Build Coastguard Worker
619*d68f33bcSAndroid Build Coastguard Workerour $tracing_logging_tags = qr{(?xi:
620*d68f33bcSAndroid Build Coastguard Worker	[=-]*> |
621*d68f33bcSAndroid Build Coastguard Worker	<[=-]* |
622*d68f33bcSAndroid Build Coastguard Worker	\[ |
623*d68f33bcSAndroid Build Coastguard Worker	\] |
624*d68f33bcSAndroid Build Coastguard Worker	start |
625*d68f33bcSAndroid Build Coastguard Worker	called |
626*d68f33bcSAndroid Build Coastguard Worker	entered |
627*d68f33bcSAndroid Build Coastguard Worker	entry |
628*d68f33bcSAndroid Build Coastguard Worker	enter |
629*d68f33bcSAndroid Build Coastguard Worker	in |
630*d68f33bcSAndroid Build Coastguard Worker	inside |
631*d68f33bcSAndroid Build Coastguard Worker	here |
632*d68f33bcSAndroid Build Coastguard Worker	begin |
633*d68f33bcSAndroid Build Coastguard Worker	exit |
634*d68f33bcSAndroid Build Coastguard Worker	end |
635*d68f33bcSAndroid Build Coastguard Worker	done |
636*d68f33bcSAndroid Build Coastguard Worker	leave |
637*d68f33bcSAndroid Build Coastguard Worker	completed |
638*d68f33bcSAndroid Build Coastguard Worker	out |
639*d68f33bcSAndroid Build Coastguard Worker	return |
640*d68f33bcSAndroid Build Coastguard Worker	[\.\!:\s]*
641*d68f33bcSAndroid Build Coastguard Worker)};
642*d68f33bcSAndroid Build Coastguard Worker
643*d68f33bcSAndroid Build Coastguard Workersub edit_distance_min {
644*d68f33bcSAndroid Build Coastguard Worker	my (@arr) = @_;
645*d68f33bcSAndroid Build Coastguard Worker	my $len = scalar @arr;
646*d68f33bcSAndroid Build Coastguard Worker	if ((scalar @arr) < 1) {
647*d68f33bcSAndroid Build Coastguard Worker		# if underflow, return
648*d68f33bcSAndroid Build Coastguard Worker		return;
649*d68f33bcSAndroid Build Coastguard Worker	}
650*d68f33bcSAndroid Build Coastguard Worker	my $min = $arr[0];
651*d68f33bcSAndroid Build Coastguard Worker	for my $i (0 .. ($len-1)) {
652*d68f33bcSAndroid Build Coastguard Worker		if ($arr[$i] < $min) {
653*d68f33bcSAndroid Build Coastguard Worker			$min = $arr[$i];
654*d68f33bcSAndroid Build Coastguard Worker		}
655*d68f33bcSAndroid Build Coastguard Worker	}
656*d68f33bcSAndroid Build Coastguard Worker	return $min;
657*d68f33bcSAndroid Build Coastguard Worker}
658*d68f33bcSAndroid Build Coastguard Worker
659*d68f33bcSAndroid Build Coastguard Workersub get_edit_distance {
660*d68f33bcSAndroid Build Coastguard Worker	my ($str1, $str2) = @_;
661*d68f33bcSAndroid Build Coastguard Worker	$str1 = lc($str1);
662*d68f33bcSAndroid Build Coastguard Worker	$str2 = lc($str2);
663*d68f33bcSAndroid Build Coastguard Worker	$str1 =~ s/-//g;
664*d68f33bcSAndroid Build Coastguard Worker	$str2 =~ s/-//g;
665*d68f33bcSAndroid Build Coastguard Worker	my $len1 = length($str1);
666*d68f33bcSAndroid Build Coastguard Worker	my $len2 = length($str2);
667*d68f33bcSAndroid Build Coastguard Worker	# two dimensional array storing minimum edit distance
668*d68f33bcSAndroid Build Coastguard Worker	my @distance;
669*d68f33bcSAndroid Build Coastguard Worker	for my $i (0 .. $len1) {
670*d68f33bcSAndroid Build Coastguard Worker		for my $j (0 .. $len2) {
671*d68f33bcSAndroid Build Coastguard Worker			if ($i == 0) {
672*d68f33bcSAndroid Build Coastguard Worker				$distance[$i][$j] = $j;
673*d68f33bcSAndroid Build Coastguard Worker			} elsif ($j == 0) {
674*d68f33bcSAndroid Build Coastguard Worker				$distance[$i][$j] = $i;
675*d68f33bcSAndroid Build Coastguard Worker			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
676*d68f33bcSAndroid Build Coastguard Worker				$distance[$i][$j] = $distance[$i - 1][$j - 1];
677*d68f33bcSAndroid Build Coastguard Worker			} else {
678*d68f33bcSAndroid Build Coastguard Worker				my $dist1 = $distance[$i][$j - 1]; #insert distance
679*d68f33bcSAndroid Build Coastguard Worker				my $dist2 = $distance[$i - 1][$j]; # remove
680*d68f33bcSAndroid Build Coastguard Worker				my $dist3 = $distance[$i - 1][$j - 1]; #replace
681*d68f33bcSAndroid Build Coastguard Worker				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
682*d68f33bcSAndroid Build Coastguard Worker			}
683*d68f33bcSAndroid Build Coastguard Worker		}
684*d68f33bcSAndroid Build Coastguard Worker	}
685*d68f33bcSAndroid Build Coastguard Worker	return $distance[$len1][$len2];
686*d68f33bcSAndroid Build Coastguard Worker}
687*d68f33bcSAndroid Build Coastguard Worker
688*d68f33bcSAndroid Build Coastguard Workersub find_standard_signature {
689*d68f33bcSAndroid Build Coastguard Worker	my ($sign_off) = @_;
690*d68f33bcSAndroid Build Coastguard Worker	my @standard_signature_tags = (
691*d68f33bcSAndroid Build Coastguard Worker		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
692*d68f33bcSAndroid Build Coastguard Worker		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
693*d68f33bcSAndroid Build Coastguard Worker	);
694*d68f33bcSAndroid Build Coastguard Worker	foreach my $signature (@standard_signature_tags) {
695*d68f33bcSAndroid Build Coastguard Worker		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
696*d68f33bcSAndroid Build Coastguard Worker	}
697*d68f33bcSAndroid Build Coastguard Worker
698*d68f33bcSAndroid Build Coastguard Worker	return "";
699*d68f33bcSAndroid Build Coastguard Worker}
700*d68f33bcSAndroid Build Coastguard Worker
701*d68f33bcSAndroid Build Coastguard Workerour @typeListMisordered = (
702*d68f33bcSAndroid Build Coastguard Worker	qr{char\s+(?:un)?signed},
703*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+(?:(?:un)?signed\s+)?short\s},
704*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+short(?:\s+(?:un)?signed)},
705*d68f33bcSAndroid Build Coastguard Worker	qr{short\s+int(?:\s+(?:un)?signed)},
706*d68f33bcSAndroid Build Coastguard Worker	qr{(?:un)?signed\s+int\s+short},
707*d68f33bcSAndroid Build Coastguard Worker	qr{short\s+(?:un)?signed},
708*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+int\s+(?:un)?signed},
709*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+long\s+(?:un)?signed},
710*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+(?:un)?signed\s+int},
711*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+(?:un)?signed\s+long},
712*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+(?:un)?signed},
713*d68f33bcSAndroid Build Coastguard Worker	qr{int\s+long\s+long\s+(?:un)?signed},
714*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+long\s+int\s+(?:un)?signed},
715*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+long\s+(?:un)?signed\s+int},
716*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+long\s+(?:un)?signed},
717*d68f33bcSAndroid Build Coastguard Worker	qr{long\s+(?:un)?signed},
718*d68f33bcSAndroid Build Coastguard Worker);
719*d68f33bcSAndroid Build Coastguard Worker
720*d68f33bcSAndroid Build Coastguard Workerour @typeList = (
721*d68f33bcSAndroid Build Coastguard Worker	qr{void},
722*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?char},
723*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?short\s+int},
724*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?short},
725*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?int},
726*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?long\s+int},
727*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
728*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?long\s+long},
729*d68f33bcSAndroid Build Coastguard Worker	qr{(?:(?:un)?signed\s+)?long},
730*d68f33bcSAndroid Build Coastguard Worker	qr{(?:un)?signed},
731*d68f33bcSAndroid Build Coastguard Worker	qr{float},
732*d68f33bcSAndroid Build Coastguard Worker	qr{double},
733*d68f33bcSAndroid Build Coastguard Worker	qr{bool},
734*d68f33bcSAndroid Build Coastguard Worker	qr{struct\s+$Ident},
735*d68f33bcSAndroid Build Coastguard Worker	qr{union\s+$Ident},
736*d68f33bcSAndroid Build Coastguard Worker	qr{enum\s+$Ident},
737*d68f33bcSAndroid Build Coastguard Worker	qr{${Ident}_t},
738*d68f33bcSAndroid Build Coastguard Worker	qr{${Ident}_handler},
739*d68f33bcSAndroid Build Coastguard Worker	qr{${Ident}_handler_fn},
740*d68f33bcSAndroid Build Coastguard Worker	@typeListMisordered,
741*d68f33bcSAndroid Build Coastguard Worker);
742*d68f33bcSAndroid Build Coastguard Worker
743*d68f33bcSAndroid Build Coastguard Workerour $C90_int_types = qr{(?x:
744*d68f33bcSAndroid Build Coastguard Worker	long\s+long\s+int\s+(?:un)?signed|
745*d68f33bcSAndroid Build Coastguard Worker	long\s+long\s+(?:un)?signed\s+int|
746*d68f33bcSAndroid Build Coastguard Worker	long\s+long\s+(?:un)?signed|
747*d68f33bcSAndroid Build Coastguard Worker	(?:(?:un)?signed\s+)?long\s+long\s+int|
748*d68f33bcSAndroid Build Coastguard Worker	(?:(?:un)?signed\s+)?long\s+long|
749*d68f33bcSAndroid Build Coastguard Worker	int\s+long\s+long\s+(?:un)?signed|
750*d68f33bcSAndroid Build Coastguard Worker	int\s+(?:(?:un)?signed\s+)?long\s+long|
751*d68f33bcSAndroid Build Coastguard Worker
752*d68f33bcSAndroid Build Coastguard Worker	long\s+int\s+(?:un)?signed|
753*d68f33bcSAndroid Build Coastguard Worker	long\s+(?:un)?signed\s+int|
754*d68f33bcSAndroid Build Coastguard Worker	long\s+(?:un)?signed|
755*d68f33bcSAndroid Build Coastguard Worker	(?:(?:un)?signed\s+)?long\s+int|
756*d68f33bcSAndroid Build Coastguard Worker	(?:(?:un)?signed\s+)?long|
757*d68f33bcSAndroid Build Coastguard Worker	int\s+long\s+(?:un)?signed|
758*d68f33bcSAndroid Build Coastguard Worker	int\s+(?:(?:un)?signed\s+)?long|
759*d68f33bcSAndroid Build Coastguard Worker
760*d68f33bcSAndroid Build Coastguard Worker	int\s+(?:un)?signed|
761*d68f33bcSAndroid Build Coastguard Worker	(?:(?:un)?signed\s+)?int
762*d68f33bcSAndroid Build Coastguard Worker)};
763*d68f33bcSAndroid Build Coastguard Worker
764*d68f33bcSAndroid Build Coastguard Workerour @typeListFile = ();
765*d68f33bcSAndroid Build Coastguard Workerour @typeListWithAttr = (
766*d68f33bcSAndroid Build Coastguard Worker	@typeList,
767*d68f33bcSAndroid Build Coastguard Worker	qr{struct\s+$InitAttribute\s+$Ident},
768*d68f33bcSAndroid Build Coastguard Worker	qr{union\s+$InitAttribute\s+$Ident},
769*d68f33bcSAndroid Build Coastguard Worker);
770*d68f33bcSAndroid Build Coastguard Worker
771*d68f33bcSAndroid Build Coastguard Workerour @modifierList = (
772*d68f33bcSAndroid Build Coastguard Worker	qr{fastcall},
773*d68f33bcSAndroid Build Coastguard Worker);
774*d68f33bcSAndroid Build Coastguard Workerour @modifierListFile = ();
775*d68f33bcSAndroid Build Coastguard Worker
776*d68f33bcSAndroid Build Coastguard Workerour @mode_permission_funcs = (
777*d68f33bcSAndroid Build Coastguard Worker	["module_param", 3],
778*d68f33bcSAndroid Build Coastguard Worker	["module_param_(?:array|named|string)", 4],
779*d68f33bcSAndroid Build Coastguard Worker	["module_param_array_named", 5],
780*d68f33bcSAndroid Build Coastguard Worker	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
781*d68f33bcSAndroid Build Coastguard Worker	["proc_create(?:_data|)", 2],
782*d68f33bcSAndroid Build Coastguard Worker	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
783*d68f33bcSAndroid Build Coastguard Worker	["IIO_DEV_ATTR_[A-Z_]+", 1],
784*d68f33bcSAndroid Build Coastguard Worker	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
785*d68f33bcSAndroid Build Coastguard Worker	["SENSOR_TEMPLATE(?:_2|)", 3],
786*d68f33bcSAndroid Build Coastguard Worker	["__ATTR", 2],
787*d68f33bcSAndroid Build Coastguard Worker);
788*d68f33bcSAndroid Build Coastguard Worker
789*d68f33bcSAndroid Build Coastguard Workermy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
790*d68f33bcSAndroid Build Coastguard Worker
791*d68f33bcSAndroid Build Coastguard Worker#Create a search pattern for all these functions to speed up a loop below
792*d68f33bcSAndroid Build Coastguard Workerour $mode_perms_search = "";
793*d68f33bcSAndroid Build Coastguard Workerforeach my $entry (@mode_permission_funcs) {
794*d68f33bcSAndroid Build Coastguard Worker	$mode_perms_search .= '|' if ($mode_perms_search ne "");
795*d68f33bcSAndroid Build Coastguard Worker	$mode_perms_search .= $entry->[0];
796*d68f33bcSAndroid Build Coastguard Worker}
797*d68f33bcSAndroid Build Coastguard Worker$mode_perms_search = "(?:${mode_perms_search})";
798*d68f33bcSAndroid Build Coastguard Worker
799*d68f33bcSAndroid Build Coastguard Workerour %deprecated_apis = (
800*d68f33bcSAndroid Build Coastguard Worker	"synchronize_rcu_bh"			=> "synchronize_rcu",
801*d68f33bcSAndroid Build Coastguard Worker	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
802*d68f33bcSAndroid Build Coastguard Worker	"call_rcu_bh"				=> "call_rcu",
803*d68f33bcSAndroid Build Coastguard Worker	"rcu_barrier_bh"			=> "rcu_barrier",
804*d68f33bcSAndroid Build Coastguard Worker	"synchronize_sched"			=> "synchronize_rcu",
805*d68f33bcSAndroid Build Coastguard Worker	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
806*d68f33bcSAndroid Build Coastguard Worker	"call_rcu_sched"			=> "call_rcu",
807*d68f33bcSAndroid Build Coastguard Worker	"rcu_barrier_sched"			=> "rcu_barrier",
808*d68f33bcSAndroid Build Coastguard Worker	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
809*d68f33bcSAndroid Build Coastguard Worker	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
810*d68f33bcSAndroid Build Coastguard Worker);
811*d68f33bcSAndroid Build Coastguard Worker
812*d68f33bcSAndroid Build Coastguard Worker#Create a search pattern for all these strings to speed up a loop below
813*d68f33bcSAndroid Build Coastguard Workerour $deprecated_apis_search = "";
814*d68f33bcSAndroid Build Coastguard Workerforeach my $entry (keys %deprecated_apis) {
815*d68f33bcSAndroid Build Coastguard Worker	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
816*d68f33bcSAndroid Build Coastguard Worker	$deprecated_apis_search .= $entry;
817*d68f33bcSAndroid Build Coastguard Worker}
818*d68f33bcSAndroid Build Coastguard Worker$deprecated_apis_search = "(?:${deprecated_apis_search})";
819*d68f33bcSAndroid Build Coastguard Worker
820*d68f33bcSAndroid Build Coastguard Workerour $mode_perms_world_writable = qr{
821*d68f33bcSAndroid Build Coastguard Worker	S_IWUGO		|
822*d68f33bcSAndroid Build Coastguard Worker	S_IWOTH		|
823*d68f33bcSAndroid Build Coastguard Worker	S_IRWXUGO	|
824*d68f33bcSAndroid Build Coastguard Worker	S_IALLUGO	|
825*d68f33bcSAndroid Build Coastguard Worker	0[0-7][0-7][2367]
826*d68f33bcSAndroid Build Coastguard Worker}x;
827*d68f33bcSAndroid Build Coastguard Worker
828*d68f33bcSAndroid Build Coastguard Workerour %mode_permission_string_types = (
829*d68f33bcSAndroid Build Coastguard Worker	"S_IRWXU" => 0700,
830*d68f33bcSAndroid Build Coastguard Worker	"S_IRUSR" => 0400,
831*d68f33bcSAndroid Build Coastguard Worker	"S_IWUSR" => 0200,
832*d68f33bcSAndroid Build Coastguard Worker	"S_IXUSR" => 0100,
833*d68f33bcSAndroid Build Coastguard Worker	"S_IRWXG" => 0070,
834*d68f33bcSAndroid Build Coastguard Worker	"S_IRGRP" => 0040,
835*d68f33bcSAndroid Build Coastguard Worker	"S_IWGRP" => 0020,
836*d68f33bcSAndroid Build Coastguard Worker	"S_IXGRP" => 0010,
837*d68f33bcSAndroid Build Coastguard Worker	"S_IRWXO" => 0007,
838*d68f33bcSAndroid Build Coastguard Worker	"S_IROTH" => 0004,
839*d68f33bcSAndroid Build Coastguard Worker	"S_IWOTH" => 0002,
840*d68f33bcSAndroid Build Coastguard Worker	"S_IXOTH" => 0001,
841*d68f33bcSAndroid Build Coastguard Worker	"S_IRWXUGO" => 0777,
842*d68f33bcSAndroid Build Coastguard Worker	"S_IRUGO" => 0444,
843*d68f33bcSAndroid Build Coastguard Worker	"S_IWUGO" => 0222,
844*d68f33bcSAndroid Build Coastguard Worker	"S_IXUGO" => 0111,
845*d68f33bcSAndroid Build Coastguard Worker);
846*d68f33bcSAndroid Build Coastguard Worker
847*d68f33bcSAndroid Build Coastguard Worker#Create a search pattern for all these strings to speed up a loop below
848*d68f33bcSAndroid Build Coastguard Workerour $mode_perms_string_search = "";
849*d68f33bcSAndroid Build Coastguard Workerforeach my $entry (keys %mode_permission_string_types) {
850*d68f33bcSAndroid Build Coastguard Worker	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
851*d68f33bcSAndroid Build Coastguard Worker	$mode_perms_string_search .= $entry;
852*d68f33bcSAndroid Build Coastguard Worker}
853*d68f33bcSAndroid Build Coastguard Workerour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
854*d68f33bcSAndroid Build Coastguard Workerour $multi_mode_perms_string_search = qr{
855*d68f33bcSAndroid Build Coastguard Worker	${single_mode_perms_string_search}
856*d68f33bcSAndroid Build Coastguard Worker	(?:\s*\|\s*${single_mode_perms_string_search})*
857*d68f33bcSAndroid Build Coastguard Worker}x;
858*d68f33bcSAndroid Build Coastguard Worker
859*d68f33bcSAndroid Build Coastguard Workersub perms_to_octal {
860*d68f33bcSAndroid Build Coastguard Worker	my ($string) = @_;
861*d68f33bcSAndroid Build Coastguard Worker
862*d68f33bcSAndroid Build Coastguard Worker	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
863*d68f33bcSAndroid Build Coastguard Worker
864*d68f33bcSAndroid Build Coastguard Worker	my $val = "";
865*d68f33bcSAndroid Build Coastguard Worker	my $oval = "";
866*d68f33bcSAndroid Build Coastguard Worker	my $to = 0;
867*d68f33bcSAndroid Build Coastguard Worker	my $curpos = 0;
868*d68f33bcSAndroid Build Coastguard Worker	my $lastpos = 0;
869*d68f33bcSAndroid Build Coastguard Worker	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
870*d68f33bcSAndroid Build Coastguard Worker		$curpos = pos($string);
871*d68f33bcSAndroid Build Coastguard Worker		my $match = $2;
872*d68f33bcSAndroid Build Coastguard Worker		my $omatch = $1;
873*d68f33bcSAndroid Build Coastguard Worker		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
874*d68f33bcSAndroid Build Coastguard Worker		$lastpos = $curpos;
875*d68f33bcSAndroid Build Coastguard Worker		$to |= $mode_permission_string_types{$match};
876*d68f33bcSAndroid Build Coastguard Worker		$val .= '\s*\|\s*' if ($val ne "");
877*d68f33bcSAndroid Build Coastguard Worker		$val .= $match;
878*d68f33bcSAndroid Build Coastguard Worker		$oval .= $omatch;
879*d68f33bcSAndroid Build Coastguard Worker	}
880*d68f33bcSAndroid Build Coastguard Worker	$oval =~ s/^\s*\|\s*//;
881*d68f33bcSAndroid Build Coastguard Worker	$oval =~ s/\s*\|\s*$//;
882*d68f33bcSAndroid Build Coastguard Worker	return sprintf("%04o", $to);
883*d68f33bcSAndroid Build Coastguard Worker}
884*d68f33bcSAndroid Build Coastguard Worker
885*d68f33bcSAndroid Build Coastguard Workerour $allowed_asm_includes = qr{(?x:
886*d68f33bcSAndroid Build Coastguard Worker	irq|
887*d68f33bcSAndroid Build Coastguard Worker	memory|
888*d68f33bcSAndroid Build Coastguard Worker	time|
889*d68f33bcSAndroid Build Coastguard Worker	reboot
890*d68f33bcSAndroid Build Coastguard Worker)};
891*d68f33bcSAndroid Build Coastguard Worker# memory.h: ARM has a custom one
892*d68f33bcSAndroid Build Coastguard Worker
893*d68f33bcSAndroid Build Coastguard Worker# Load common spelling mistakes and build regular expression list.
894*d68f33bcSAndroid Build Coastguard Workermy $misspellings;
895*d68f33bcSAndroid Build Coastguard Workermy %spelling_fix;
896*d68f33bcSAndroid Build Coastguard Worker
897*d68f33bcSAndroid Build Coastguard Workerif (open(my $spelling, '<', $spelling_file)) {
898*d68f33bcSAndroid Build Coastguard Worker	while (<$spelling>) {
899*d68f33bcSAndroid Build Coastguard Worker		my $line = $_;
900*d68f33bcSAndroid Build Coastguard Worker
901*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/\s*\n?$//g;
902*d68f33bcSAndroid Build Coastguard Worker		$line =~ s/^\s*//g;
903*d68f33bcSAndroid Build Coastguard Worker
904*d68f33bcSAndroid Build Coastguard Worker		next if ($line =~ m/^\s*#/);
905*d68f33bcSAndroid Build Coastguard Worker		next if ($line =~ m/^\s*$/);
906*d68f33bcSAndroid Build Coastguard Worker
907*d68f33bcSAndroid Build Coastguard Worker		my ($suspect, $fix) = split(/\|\|/, $line);
908*d68f33bcSAndroid Build Coastguard Worker
909*d68f33bcSAndroid Build Coastguard Worker		$spelling_fix{$suspect} = $fix;
910*d68f33bcSAndroid Build Coastguard Worker	}
911*d68f33bcSAndroid Build Coastguard Worker	close($spelling);
912*d68f33bcSAndroid Build Coastguard Worker} else {
913*d68f33bcSAndroid Build Coastguard Worker	warn "No typos will be found - file '$spelling_file': $!\n";
914*d68f33bcSAndroid Build Coastguard Worker}
915*d68f33bcSAndroid Build Coastguard Worker
916*d68f33bcSAndroid Build Coastguard Workerif ($codespell) {
917*d68f33bcSAndroid Build Coastguard Worker	if (open(my $spelling, '<', $codespellfile)) {
918*d68f33bcSAndroid Build Coastguard Worker		while (<$spelling>) {
919*d68f33bcSAndroid Build Coastguard Worker			my $line = $_;
920*d68f33bcSAndroid Build Coastguard Worker
921*d68f33bcSAndroid Build Coastguard Worker			$line =~ s/\s*\n?$//g;
922*d68f33bcSAndroid Build Coastguard Worker			$line =~ s/^\s*//g;
923*d68f33bcSAndroid Build Coastguard Worker
924*d68f33bcSAndroid Build Coastguard Worker			next if ($line =~ m/^\s*#/);
925*d68f33bcSAndroid Build Coastguard Worker			next if ($line =~ m/^\s*$/);
926*d68f33bcSAndroid Build Coastguard Worker			next if ($line =~ m/, disabled/i);
927*d68f33bcSAndroid Build Coastguard Worker
928*d68f33bcSAndroid Build Coastguard Worker			$line =~ s/,.*$//;
929*d68f33bcSAndroid Build Coastguard Worker
930*d68f33bcSAndroid Build Coastguard Worker			my ($suspect, $fix) = split(/->/, $line);
931*d68f33bcSAndroid Build Coastguard Worker
932*d68f33bcSAndroid Build Coastguard Worker			$spelling_fix{$suspect} = $fix;
933*d68f33bcSAndroid Build Coastguard Worker		}
934*d68f33bcSAndroid Build Coastguard Worker		close($spelling);
935*d68f33bcSAndroid Build Coastguard Worker	} else {
936*d68f33bcSAndroid Build Coastguard Worker		warn "No codespell typos will be found - file '$codespellfile': $!\n";
937*d68f33bcSAndroid Build Coastguard Worker	}
938*d68f33bcSAndroid Build Coastguard Worker}
939*d68f33bcSAndroid Build Coastguard Worker
940*d68f33bcSAndroid Build Coastguard Worker$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
941*d68f33bcSAndroid Build Coastguard Worker
942*d68f33bcSAndroid Build Coastguard Workersub read_words {
943*d68f33bcSAndroid Build Coastguard Worker	my ($wordsRef, $file) = @_;
944*d68f33bcSAndroid Build Coastguard Worker
945*d68f33bcSAndroid Build Coastguard Worker	if (open(my $words, '<', $file)) {
946*d68f33bcSAndroid Build Coastguard Worker		while (<$words>) {
947*d68f33bcSAndroid Build Coastguard Worker			my $line = $_;
948*d68f33bcSAndroid Build Coastguard Worker
949*d68f33bcSAndroid Build Coastguard Worker			$line =~ s/\s*\n?$//g;
950*d68f33bcSAndroid Build Coastguard Worker			$line =~ s/^\s*//g;
951*d68f33bcSAndroid Build Coastguard Worker
952*d68f33bcSAndroid Build Coastguard Worker			next if ($line =~ m/^\s*#/);
953*d68f33bcSAndroid Build Coastguard Worker			next if ($line =~ m/^\s*$/);
954*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /\s/) {
955*d68f33bcSAndroid Build Coastguard Worker				print("$file: '$line' invalid - ignored\n");
956*d68f33bcSAndroid Build Coastguard Worker				next;
957*d68f33bcSAndroid Build Coastguard Worker			}
958*d68f33bcSAndroid Build Coastguard Worker
959*d68f33bcSAndroid Build Coastguard Worker			$$wordsRef .= '|' if (defined $$wordsRef);
960*d68f33bcSAndroid Build Coastguard Worker			$$wordsRef .= $line;
961*d68f33bcSAndroid Build Coastguard Worker		}
962*d68f33bcSAndroid Build Coastguard Worker		close($file);
963*d68f33bcSAndroid Build Coastguard Worker		return 1;
964*d68f33bcSAndroid Build Coastguard Worker	}
965*d68f33bcSAndroid Build Coastguard Worker
966*d68f33bcSAndroid Build Coastguard Worker	return 0;
967*d68f33bcSAndroid Build Coastguard Worker}
968*d68f33bcSAndroid Build Coastguard Worker
969*d68f33bcSAndroid Build Coastguard Workermy $const_structs;
970*d68f33bcSAndroid Build Coastguard Workerif (show_type("CONST_STRUCT")) {
971*d68f33bcSAndroid Build Coastguard Worker	read_words(\$const_structs, $conststructsfile)
972*d68f33bcSAndroid Build Coastguard Worker	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
973*d68f33bcSAndroid Build Coastguard Worker}
974*d68f33bcSAndroid Build Coastguard Worker
975*d68f33bcSAndroid Build Coastguard Workerif (defined($typedefsfile)) {
976*d68f33bcSAndroid Build Coastguard Worker	my $typeOtherTypedefs;
977*d68f33bcSAndroid Build Coastguard Worker	read_words(\$typeOtherTypedefs, $typedefsfile)
978*d68f33bcSAndroid Build Coastguard Worker	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
979*d68f33bcSAndroid Build Coastguard Worker	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
980*d68f33bcSAndroid Build Coastguard Worker}
981*d68f33bcSAndroid Build Coastguard Worker
982*d68f33bcSAndroid Build Coastguard Workersub build_types {
983*d68f33bcSAndroid Build Coastguard Worker	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
984*d68f33bcSAndroid Build Coastguard Worker	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
985*d68f33bcSAndroid Build Coastguard Worker	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
986*d68f33bcSAndroid Build Coastguard Worker	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
987*d68f33bcSAndroid Build Coastguard Worker	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
988*d68f33bcSAndroid Build Coastguard Worker	$BasicType	= qr{
989*d68f33bcSAndroid Build Coastguard Worker				(?:$typeTypedefs\b)|
990*d68f33bcSAndroid Build Coastguard Worker				(?:${all}\b)
991*d68f33bcSAndroid Build Coastguard Worker		}x;
992*d68f33bcSAndroid Build Coastguard Worker	$NonptrType	= qr{
993*d68f33bcSAndroid Build Coastguard Worker			(?:$Modifier\s+|const\s+)*
994*d68f33bcSAndroid Build Coastguard Worker			(?:
995*d68f33bcSAndroid Build Coastguard Worker				(?:typeof|__typeof__)\s*\([^\)]*\)|
996*d68f33bcSAndroid Build Coastguard Worker				(?:$typeTypedefs\b)|
997*d68f33bcSAndroid Build Coastguard Worker				(?:${all}\b)
998*d68f33bcSAndroid Build Coastguard Worker			)
999*d68f33bcSAndroid Build Coastguard Worker			(?:\s+$Modifier|\s+const)*
1000*d68f33bcSAndroid Build Coastguard Worker		  }x;
1001*d68f33bcSAndroid Build Coastguard Worker	$NonptrTypeMisordered	= qr{
1002*d68f33bcSAndroid Build Coastguard Worker			(?:$Modifier\s+|const\s+)*
1003*d68f33bcSAndroid Build Coastguard Worker			(?:
1004*d68f33bcSAndroid Build Coastguard Worker				(?:${Misordered}\b)
1005*d68f33bcSAndroid Build Coastguard Worker			)
1006*d68f33bcSAndroid Build Coastguard Worker			(?:\s+$Modifier|\s+const)*
1007*d68f33bcSAndroid Build Coastguard Worker		  }x;
1008*d68f33bcSAndroid Build Coastguard Worker	$NonptrTypeWithAttr	= qr{
1009*d68f33bcSAndroid Build Coastguard Worker			(?:$Modifier\s+|const\s+)*
1010*d68f33bcSAndroid Build Coastguard Worker			(?:
1011*d68f33bcSAndroid Build Coastguard Worker				(?:typeof|__typeof__)\s*\([^\)]*\)|
1012*d68f33bcSAndroid Build Coastguard Worker				(?:$typeTypedefs\b)|
1013*d68f33bcSAndroid Build Coastguard Worker				(?:${allWithAttr}\b)
1014*d68f33bcSAndroid Build Coastguard Worker			)
1015*d68f33bcSAndroid Build Coastguard Worker			(?:\s+$Modifier|\s+const)*
1016*d68f33bcSAndroid Build Coastguard Worker		  }x;
1017*d68f33bcSAndroid Build Coastguard Worker	$Type	= qr{
1018*d68f33bcSAndroid Build Coastguard Worker			$NonptrType
1019*d68f33bcSAndroid Build Coastguard Worker			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
1020*d68f33bcSAndroid Build Coastguard Worker			(?:\s+$Inline|\s+$Modifier)*
1021*d68f33bcSAndroid Build Coastguard Worker		  }x;
1022*d68f33bcSAndroid Build Coastguard Worker	$TypeMisordered	= qr{
1023*d68f33bcSAndroid Build Coastguard Worker			$NonptrTypeMisordered
1024*d68f33bcSAndroid Build Coastguard Worker			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
1025*d68f33bcSAndroid Build Coastguard Worker			(?:\s+$Inline|\s+$Modifier)*
1026*d68f33bcSAndroid Build Coastguard Worker		  }x;
1027*d68f33bcSAndroid Build Coastguard Worker	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
1028*d68f33bcSAndroid Build Coastguard Worker	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
1029*d68f33bcSAndroid Build Coastguard Worker}
1030*d68f33bcSAndroid Build Coastguard Workerbuild_types();
1031*d68f33bcSAndroid Build Coastguard Worker
1032*d68f33bcSAndroid Build Coastguard Workerour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
1033*d68f33bcSAndroid Build Coastguard Worker
1034*d68f33bcSAndroid Build Coastguard Worker# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1035*d68f33bcSAndroid Build Coastguard Worker# requires at least perl version v5.10.0
1036*d68f33bcSAndroid Build Coastguard Worker# Any use must be runtime checked with $^V
1037*d68f33bcSAndroid Build Coastguard Worker
1038*d68f33bcSAndroid Build Coastguard Workerour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
1039*d68f33bcSAndroid Build Coastguard Workerour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
1040*d68f33bcSAndroid Build Coastguard Workerour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
1041*d68f33bcSAndroid Build Coastguard Worker
1042*d68f33bcSAndroid Build Coastguard Workerour $declaration_macros = qr{(?x:
1043*d68f33bcSAndroid Build Coastguard Worker	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
1044*d68f33bcSAndroid Build Coastguard Worker	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
1045*d68f33bcSAndroid Build Coastguard Worker	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
1046*d68f33bcSAndroid Build Coastguard Worker)};
1047*d68f33bcSAndroid Build Coastguard Worker
1048*d68f33bcSAndroid Build Coastguard Workerour %allow_repeated_words = (
1049*d68f33bcSAndroid Build Coastguard Worker	add => '',
1050*d68f33bcSAndroid Build Coastguard Worker	added => '',
1051*d68f33bcSAndroid Build Coastguard Worker	bad => '',
1052*d68f33bcSAndroid Build Coastguard Worker	be => '',
1053*d68f33bcSAndroid Build Coastguard Worker);
1054*d68f33bcSAndroid Build Coastguard Worker
1055*d68f33bcSAndroid Build Coastguard Workersub deparenthesize {
1056*d68f33bcSAndroid Build Coastguard Worker	my ($string) = @_;
1057*d68f33bcSAndroid Build Coastguard Worker	return "" if (!defined($string));
1058*d68f33bcSAndroid Build Coastguard Worker
1059*d68f33bcSAndroid Build Coastguard Worker	while ($string =~ /^\s*\(.*\)\s*$/) {
1060*d68f33bcSAndroid Build Coastguard Worker		$string =~ s@^\s*\(\s*@@;
1061*d68f33bcSAndroid Build Coastguard Worker		$string =~ s@\s*\)\s*$@@;
1062*d68f33bcSAndroid Build Coastguard Worker	}
1063*d68f33bcSAndroid Build Coastguard Worker
1064*d68f33bcSAndroid Build Coastguard Worker	$string =~ s@\s+@ @g;
1065*d68f33bcSAndroid Build Coastguard Worker
1066*d68f33bcSAndroid Build Coastguard Worker	return $string;
1067*d68f33bcSAndroid Build Coastguard Worker}
1068*d68f33bcSAndroid Build Coastguard Worker
1069*d68f33bcSAndroid Build Coastguard Workersub seed_camelcase_file {
1070*d68f33bcSAndroid Build Coastguard Worker	my ($file) = @_;
1071*d68f33bcSAndroid Build Coastguard Worker
1072*d68f33bcSAndroid Build Coastguard Worker	return if (!(-f $file));
1073*d68f33bcSAndroid Build Coastguard Worker
1074*d68f33bcSAndroid Build Coastguard Worker	local $/;
1075*d68f33bcSAndroid Build Coastguard Worker
1076*d68f33bcSAndroid Build Coastguard Worker	open(my $include_file, '<', "$file")
1077*d68f33bcSAndroid Build Coastguard Worker	    or warn "$P: Can't read '$file' $!\n";
1078*d68f33bcSAndroid Build Coastguard Worker	my $text = <$include_file>;
1079*d68f33bcSAndroid Build Coastguard Worker	close($include_file);
1080*d68f33bcSAndroid Build Coastguard Worker
1081*d68f33bcSAndroid Build Coastguard Worker	my @lines = split('\n', $text);
1082*d68f33bcSAndroid Build Coastguard Worker
1083*d68f33bcSAndroid Build Coastguard Worker	foreach my $line (@lines) {
1084*d68f33bcSAndroid Build Coastguard Worker		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
1085*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
1086*d68f33bcSAndroid Build Coastguard Worker			$camelcase{$1} = 1;
1087*d68f33bcSAndroid Build Coastguard Worker		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
1088*d68f33bcSAndroid Build Coastguard Worker			$camelcase{$1} = 1;
1089*d68f33bcSAndroid Build Coastguard Worker		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
1090*d68f33bcSAndroid Build Coastguard Worker			$camelcase{$1} = 1;
1091*d68f33bcSAndroid Build Coastguard Worker		}
1092*d68f33bcSAndroid Build Coastguard Worker	}
1093*d68f33bcSAndroid Build Coastguard Worker}
1094*d68f33bcSAndroid Build Coastguard Worker
1095*d68f33bcSAndroid Build Coastguard Workerour %maintained_status = ();
1096*d68f33bcSAndroid Build Coastguard Worker
1097*d68f33bcSAndroid Build Coastguard Workersub is_maintained_obsolete {
1098*d68f33bcSAndroid Build Coastguard Worker	my ($filename) = @_;
1099*d68f33bcSAndroid Build Coastguard Worker
1100*d68f33bcSAndroid Build Coastguard Worker	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
1101*d68f33bcSAndroid Build Coastguard Worker
1102*d68f33bcSAndroid Build Coastguard Worker	if (!exists($maintained_status{$filename})) {
1103*d68f33bcSAndroid Build Coastguard Worker		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1104*d68f33bcSAndroid Build Coastguard Worker	}
1105*d68f33bcSAndroid Build Coastguard Worker
1106*d68f33bcSAndroid Build Coastguard Worker	return $maintained_status{$filename} =~ /obsolete/i;
1107*d68f33bcSAndroid Build Coastguard Worker}
1108*d68f33bcSAndroid Build Coastguard Worker
1109*d68f33bcSAndroid Build Coastguard Workersub is_SPDX_License_valid {
1110*d68f33bcSAndroid Build Coastguard Worker	my ($license) = @_;
1111*d68f33bcSAndroid Build Coastguard Worker
1112*d68f33bcSAndroid Build Coastguard Worker	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
1113*d68f33bcSAndroid Build Coastguard Worker
1114*d68f33bcSAndroid Build Coastguard Worker	my $root_path = abs_path($root);
1115*d68f33bcSAndroid Build Coastguard Worker	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
1116*d68f33bcSAndroid Build Coastguard Worker	return 0 if ($status ne "");
1117*d68f33bcSAndroid Build Coastguard Worker	return 1;
1118*d68f33bcSAndroid Build Coastguard Worker}
1119*d68f33bcSAndroid Build Coastguard Worker
1120*d68f33bcSAndroid Build Coastguard Workermy $camelcase_seeded = 0;
1121*d68f33bcSAndroid Build Coastguard Workersub seed_camelcase_includes {
1122*d68f33bcSAndroid Build Coastguard Worker	return if ($camelcase_seeded);
1123*d68f33bcSAndroid Build Coastguard Worker
1124*d68f33bcSAndroid Build Coastguard Worker	my $files;
1125*d68f33bcSAndroid Build Coastguard Worker	my $camelcase_cache = "";
1126*d68f33bcSAndroid Build Coastguard Worker	my @include_files = ();
1127*d68f33bcSAndroid Build Coastguard Worker
1128*d68f33bcSAndroid Build Coastguard Worker	$camelcase_seeded = 1;
1129*d68f33bcSAndroid Build Coastguard Worker
1130*d68f33bcSAndroid Build Coastguard Worker	if (-e "$gitroot") {
1131*d68f33bcSAndroid Build Coastguard Worker		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1132*d68f33bcSAndroid Build Coastguard Worker		chomp $git_last_include_commit;
1133*d68f33bcSAndroid Build Coastguard Worker		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1134*d68f33bcSAndroid Build Coastguard Worker	} else {
1135*d68f33bcSAndroid Build Coastguard Worker		my $last_mod_date = 0;
1136*d68f33bcSAndroid Build Coastguard Worker		$files = `find $root/include -name "*.h"`;
1137*d68f33bcSAndroid Build Coastguard Worker		@include_files = split('\n', $files);
1138*d68f33bcSAndroid Build Coastguard Worker		foreach my $file (@include_files) {
1139*d68f33bcSAndroid Build Coastguard Worker			my $date = POSIX::strftime("%Y%m%d%H%M",
1140*d68f33bcSAndroid Build Coastguard Worker						   localtime((stat $file)[9]));
1141*d68f33bcSAndroid Build Coastguard Worker			$last_mod_date = $date if ($last_mod_date < $date);
1142*d68f33bcSAndroid Build Coastguard Worker		}
1143*d68f33bcSAndroid Build Coastguard Worker		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1144*d68f33bcSAndroid Build Coastguard Worker	}
1145*d68f33bcSAndroid Build Coastguard Worker
1146*d68f33bcSAndroid Build Coastguard Worker	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1147*d68f33bcSAndroid Build Coastguard Worker		open(my $camelcase_file, '<', "$camelcase_cache")
1148*d68f33bcSAndroid Build Coastguard Worker		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1149*d68f33bcSAndroid Build Coastguard Worker		while (<$camelcase_file>) {
1150*d68f33bcSAndroid Build Coastguard Worker			chomp;
1151*d68f33bcSAndroid Build Coastguard Worker			$camelcase{$_} = 1;
1152*d68f33bcSAndroid Build Coastguard Worker		}
1153*d68f33bcSAndroid Build Coastguard Worker		close($camelcase_file);
1154*d68f33bcSAndroid Build Coastguard Worker
1155*d68f33bcSAndroid Build Coastguard Worker		return;
1156*d68f33bcSAndroid Build Coastguard Worker	}
1157*d68f33bcSAndroid Build Coastguard Worker
1158*d68f33bcSAndroid Build Coastguard Worker	if (-e "$gitroot") {
1159*d68f33bcSAndroid Build Coastguard Worker		$files = `${git_command} ls-files "include/*.h"`;
1160*d68f33bcSAndroid Build Coastguard Worker		@include_files = split('\n', $files);
1161*d68f33bcSAndroid Build Coastguard Worker	}
1162*d68f33bcSAndroid Build Coastguard Worker
1163*d68f33bcSAndroid Build Coastguard Worker	foreach my $file (@include_files) {
1164*d68f33bcSAndroid Build Coastguard Worker		seed_camelcase_file($file);
1165*d68f33bcSAndroid Build Coastguard Worker	}
1166*d68f33bcSAndroid Build Coastguard Worker
1167*d68f33bcSAndroid Build Coastguard Worker	if ($camelcase_cache ne "") {
1168*d68f33bcSAndroid Build Coastguard Worker		unlink glob ".checkpatch-camelcase.*";
1169*d68f33bcSAndroid Build Coastguard Worker		open(my $camelcase_file, '>', "$camelcase_cache")
1170*d68f33bcSAndroid Build Coastguard Worker		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1171*d68f33bcSAndroid Build Coastguard Worker		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1172*d68f33bcSAndroid Build Coastguard Worker			print $camelcase_file ("$_\n");
1173*d68f33bcSAndroid Build Coastguard Worker		}
1174*d68f33bcSAndroid Build Coastguard Worker		close($camelcase_file);
1175*d68f33bcSAndroid Build Coastguard Worker	}
1176*d68f33bcSAndroid Build Coastguard Worker}
1177*d68f33bcSAndroid Build Coastguard Worker
1178*d68f33bcSAndroid Build Coastguard Workersub git_is_single_file {
1179*d68f33bcSAndroid Build Coastguard Worker	my ($filename) = @_;
1180*d68f33bcSAndroid Build Coastguard Worker
1181*d68f33bcSAndroid Build Coastguard Worker	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1182*d68f33bcSAndroid Build Coastguard Worker
1183*d68f33bcSAndroid Build Coastguard Worker	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1184*d68f33bcSAndroid Build Coastguard Worker	my $count = $output =~ tr/\n//;
1185*d68f33bcSAndroid Build Coastguard Worker	return $count eq 1 && $output =~ m{^${filename}$};
1186*d68f33bcSAndroid Build Coastguard Worker}
1187*d68f33bcSAndroid Build Coastguard Worker
1188*d68f33bcSAndroid Build Coastguard Workersub git_commit_info {
1189*d68f33bcSAndroid Build Coastguard Worker	my ($commit, $id, $desc) = @_;
1190*d68f33bcSAndroid Build Coastguard Worker
1191*d68f33bcSAndroid Build Coastguard Worker	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1192*d68f33bcSAndroid Build Coastguard Worker
1193*d68f33bcSAndroid Build Coastguard Worker	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1194*d68f33bcSAndroid Build Coastguard Worker	$output =~ s/^\s*//gm;
1195*d68f33bcSAndroid Build Coastguard Worker	my @lines = split("\n", $output);
1196*d68f33bcSAndroid Build Coastguard Worker
1197*d68f33bcSAndroid Build Coastguard Worker	return ($id, $desc) if ($#lines < 0);
1198*d68f33bcSAndroid Build Coastguard Worker
1199*d68f33bcSAndroid Build Coastguard Worker	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1200*d68f33bcSAndroid Build Coastguard Worker# Maybe one day convert this block of bash into something that returns
1201*d68f33bcSAndroid Build Coastguard Worker# all matching commit ids, but it's very slow...
1202*d68f33bcSAndroid Build Coastguard Worker#
1203*d68f33bcSAndroid Build Coastguard Worker#		echo "checking commits $1..."
1204*d68f33bcSAndroid Build Coastguard Worker#		git rev-list --remotes | grep -i "^$1" |
1205*d68f33bcSAndroid Build Coastguard Worker#		while read line ; do
1206*d68f33bcSAndroid Build Coastguard Worker#		    git log --format='%H %s' -1 $line |
1207*d68f33bcSAndroid Build Coastguard Worker#		    echo "commit $(cut -c 1-12,41-)"
1208*d68f33bcSAndroid Build Coastguard Worker#		done
1209*d68f33bcSAndroid Build Coastguard Worker	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
1210*d68f33bcSAndroid Build Coastguard Worker		 $lines[0] =~ /^fatal: bad object $commit/) {
1211*d68f33bcSAndroid Build Coastguard Worker		$id = undef;
1212*d68f33bcSAndroid Build Coastguard Worker	} else {
1213*d68f33bcSAndroid Build Coastguard Worker		$id = substr($lines[0], 0, 12);
1214*d68f33bcSAndroid Build Coastguard Worker		$desc = substr($lines[0], 41);
1215*d68f33bcSAndroid Build Coastguard Worker	}
1216*d68f33bcSAndroid Build Coastguard Worker
1217*d68f33bcSAndroid Build Coastguard Worker	return ($id, $desc);
1218*d68f33bcSAndroid Build Coastguard Worker}
1219*d68f33bcSAndroid Build Coastguard Worker
1220*d68f33bcSAndroid Build Coastguard Worker$chk_signoff = 0 if ($file);
1221*d68f33bcSAndroid Build Coastguard Worker
1222*d68f33bcSAndroid Build Coastguard Workermy @rawlines = ();
1223*d68f33bcSAndroid Build Coastguard Workermy @lines = ();
1224*d68f33bcSAndroid Build Coastguard Workermy @fixed = ();
1225*d68f33bcSAndroid Build Coastguard Workermy @fixed_inserted = ();
1226*d68f33bcSAndroid Build Coastguard Workermy @fixed_deleted = ();
1227*d68f33bcSAndroid Build Coastguard Workermy $fixlinenr = -1;
1228*d68f33bcSAndroid Build Coastguard Worker
1229*d68f33bcSAndroid Build Coastguard Worker# If input is git commits, extract all commits from the commit expressions.
1230*d68f33bcSAndroid Build Coastguard Worker# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
1231*d68f33bcSAndroid Build Coastguard Workerdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
1232*d68f33bcSAndroid Build Coastguard Worker
1233*d68f33bcSAndroid Build Coastguard Workerif ($git) {
1234*d68f33bcSAndroid Build Coastguard Worker	my @commits = ();
1235*d68f33bcSAndroid Build Coastguard Worker	foreach my $commit_expr (@ARGV) {
1236*d68f33bcSAndroid Build Coastguard Worker		my $git_range;
1237*d68f33bcSAndroid Build Coastguard Worker		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
1238*d68f33bcSAndroid Build Coastguard Worker			$git_range = "-$2 $1";
1239*d68f33bcSAndroid Build Coastguard Worker		} elsif ($commit_expr =~ m/\.\./) {
1240*d68f33bcSAndroid Build Coastguard Worker			$git_range = "$commit_expr";
1241*d68f33bcSAndroid Build Coastguard Worker		} else {
1242*d68f33bcSAndroid Build Coastguard Worker			$git_range = "-1 $commit_expr";
1243*d68f33bcSAndroid Build Coastguard Worker		}
1244*d68f33bcSAndroid Build Coastguard Worker		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
1245*d68f33bcSAndroid Build Coastguard Worker		foreach my $line (split(/\n/, $lines)) {
1246*d68f33bcSAndroid Build Coastguard Worker			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
1247*d68f33bcSAndroid Build Coastguard Worker			next if (!defined($1) || !defined($2));
1248*d68f33bcSAndroid Build Coastguard Worker			my $sha1 = $1;
1249*d68f33bcSAndroid Build Coastguard Worker			my $subject = $2;
1250*d68f33bcSAndroid Build Coastguard Worker			unshift(@commits, $sha1);
1251*d68f33bcSAndroid Build Coastguard Worker			$git_commits{$sha1} = $subject;
1252*d68f33bcSAndroid Build Coastguard Worker		}
1253*d68f33bcSAndroid Build Coastguard Worker	}
1254*d68f33bcSAndroid Build Coastguard Worker	die "$P: no git commits after extraction!\n" if (@commits == 0);
1255*d68f33bcSAndroid Build Coastguard Worker	@ARGV = @commits;
1256*d68f33bcSAndroid Build Coastguard Worker}
1257*d68f33bcSAndroid Build Coastguard Worker
1258*d68f33bcSAndroid Build Coastguard Workermy $vname;
1259*d68f33bcSAndroid Build Coastguard Worker$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
1260*d68f33bcSAndroid Build Coastguard Workerfor my $filename (@ARGV) {
1261*d68f33bcSAndroid Build Coastguard Worker	my $FILE;
1262*d68f33bcSAndroid Build Coastguard Worker	my $is_git_file = git_is_single_file($filename);
1263*d68f33bcSAndroid Build Coastguard Worker	my $oldfile = $file;
1264*d68f33bcSAndroid Build Coastguard Worker	$file = 1 if ($is_git_file);
1265*d68f33bcSAndroid Build Coastguard Worker	if ($git) {
1266*d68f33bcSAndroid Build Coastguard Worker		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
1267*d68f33bcSAndroid Build Coastguard Worker			die "$P: $filename: git format-patch failed - $!\n";
1268*d68f33bcSAndroid Build Coastguard Worker	} elsif ($file) {
1269*d68f33bcSAndroid Build Coastguard Worker		open($FILE, '-|', "diff -u /dev/null $filename") ||
1270*d68f33bcSAndroid Build Coastguard Worker			die "$P: $filename: diff failed - $!\n";
1271*d68f33bcSAndroid Build Coastguard Worker	} elsif ($filename eq '-') {
1272*d68f33bcSAndroid Build Coastguard Worker		open($FILE, '<&STDIN');
1273*d68f33bcSAndroid Build Coastguard Worker	} else {
1274*d68f33bcSAndroid Build Coastguard Worker		open($FILE, '<', "$filename") ||
1275*d68f33bcSAndroid Build Coastguard Worker			die "$P: $filename: open failed - $!\n";
1276*d68f33bcSAndroid Build Coastguard Worker	}
1277*d68f33bcSAndroid Build Coastguard Worker	if ($filename eq '-') {
1278*d68f33bcSAndroid Build Coastguard Worker		$vname = 'Your patch';
1279*d68f33bcSAndroid Build Coastguard Worker	} elsif ($git) {
1280*d68f33bcSAndroid Build Coastguard Worker		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1281*d68f33bcSAndroid Build Coastguard Worker	} else {
1282*d68f33bcSAndroid Build Coastguard Worker		$vname = $filename;
1283*d68f33bcSAndroid Build Coastguard Worker	}
1284*d68f33bcSAndroid Build Coastguard Worker	while (<$FILE>) {
1285*d68f33bcSAndroid Build Coastguard Worker		chomp;
1286*d68f33bcSAndroid Build Coastguard Worker		push(@rawlines, $_);
1287*d68f33bcSAndroid Build Coastguard Worker		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
1288*d68f33bcSAndroid Build Coastguard Worker	}
1289*d68f33bcSAndroid Build Coastguard Worker	close($FILE);
1290*d68f33bcSAndroid Build Coastguard Worker
1291*d68f33bcSAndroid Build Coastguard Worker	if ($#ARGV > 0 && $quiet == 0) {
1292*d68f33bcSAndroid Build Coastguard Worker		print '-' x length($vname) . "\n";
1293*d68f33bcSAndroid Build Coastguard Worker		print "$vname\n";
1294*d68f33bcSAndroid Build Coastguard Worker		print '-' x length($vname) . "\n";
1295*d68f33bcSAndroid Build Coastguard Worker	}
1296*d68f33bcSAndroid Build Coastguard Worker
1297*d68f33bcSAndroid Build Coastguard Worker	if (!process($filename)) {
1298*d68f33bcSAndroid Build Coastguard Worker		$exit = 1;
1299*d68f33bcSAndroid Build Coastguard Worker	}
1300*d68f33bcSAndroid Build Coastguard Worker	@rawlines = ();
1301*d68f33bcSAndroid Build Coastguard Worker	@lines = ();
1302*d68f33bcSAndroid Build Coastguard Worker	@fixed = ();
1303*d68f33bcSAndroid Build Coastguard Worker	@fixed_inserted = ();
1304*d68f33bcSAndroid Build Coastguard Worker	@fixed_deleted = ();
1305*d68f33bcSAndroid Build Coastguard Worker	$fixlinenr = -1;
1306*d68f33bcSAndroid Build Coastguard Worker	@modifierListFile = ();
1307*d68f33bcSAndroid Build Coastguard Worker	@typeListFile = ();
1308*d68f33bcSAndroid Build Coastguard Worker	build_types();
1309*d68f33bcSAndroid Build Coastguard Worker	$file = $oldfile if ($is_git_file);
1310*d68f33bcSAndroid Build Coastguard Worker}
1311*d68f33bcSAndroid Build Coastguard Worker
1312*d68f33bcSAndroid Build Coastguard Workerif (!$quiet) {
1313*d68f33bcSAndroid Build Coastguard Worker	hash_show_words(\%use_type, "Used");
1314*d68f33bcSAndroid Build Coastguard Worker	hash_show_words(\%ignore_type, "Ignored");
1315*d68f33bcSAndroid Build Coastguard Worker
1316*d68f33bcSAndroid Build Coastguard Worker	if (!$perl_version_ok) {
1317*d68f33bcSAndroid Build Coastguard Worker		print << "EOM"
1318*d68f33bcSAndroid Build Coastguard Worker
1319*d68f33bcSAndroid Build Coastguard WorkerNOTE: perl $^V is not modern enough to detect all possible issues.
1320*d68f33bcSAndroid Build Coastguard Worker      An upgrade to at least perl $minimum_perl_version is suggested.
1321*d68f33bcSAndroid Build Coastguard WorkerEOM
1322*d68f33bcSAndroid Build Coastguard Worker	}
1323*d68f33bcSAndroid Build Coastguard Worker	if ($exit) {
1324*d68f33bcSAndroid Build Coastguard Worker		print << "EOM"
1325*d68f33bcSAndroid Build Coastguard Worker
1326*d68f33bcSAndroid Build Coastguard WorkerNOTE: If any of the errors are false positives, please report
1327*d68f33bcSAndroid Build Coastguard Worker      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1328*d68f33bcSAndroid Build Coastguard WorkerEOM
1329*d68f33bcSAndroid Build Coastguard Worker	}
1330*d68f33bcSAndroid Build Coastguard Worker}
1331*d68f33bcSAndroid Build Coastguard Worker
1332*d68f33bcSAndroid Build Coastguard Workerexit($exit);
1333*d68f33bcSAndroid Build Coastguard Worker
1334*d68f33bcSAndroid Build Coastguard Workersub top_of_kernel_tree {
1335*d68f33bcSAndroid Build Coastguard Worker	my ($root) = @_;
1336*d68f33bcSAndroid Build Coastguard Worker
1337*d68f33bcSAndroid Build Coastguard Worker	my @tree_check = (
1338*d68f33bcSAndroid Build Coastguard Worker		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
1339*d68f33bcSAndroid Build Coastguard Worker		"README", "Documentation", "arch", "include", "drivers",
1340*d68f33bcSAndroid Build Coastguard Worker		"fs", "init", "ipc", "kernel", "lib", "scripts",
1341*d68f33bcSAndroid Build Coastguard Worker	);
1342*d68f33bcSAndroid Build Coastguard Worker
1343*d68f33bcSAndroid Build Coastguard Worker	foreach my $check (@tree_check) {
1344*d68f33bcSAndroid Build Coastguard Worker		if (! -e $root . '/' . $check) {
1345*d68f33bcSAndroid Build Coastguard Worker			return 0;
1346*d68f33bcSAndroid Build Coastguard Worker		}
1347*d68f33bcSAndroid Build Coastguard Worker	}
1348*d68f33bcSAndroid Build Coastguard Worker	return 1;
1349*d68f33bcSAndroid Build Coastguard Worker}
1350*d68f33bcSAndroid Build Coastguard Worker
1351*d68f33bcSAndroid Build Coastguard Workersub parse_email {
1352*d68f33bcSAndroid Build Coastguard Worker	my ($formatted_email) = @_;
1353*d68f33bcSAndroid Build Coastguard Worker
1354*d68f33bcSAndroid Build Coastguard Worker	my $name = "";
1355*d68f33bcSAndroid Build Coastguard Worker	my $quoted = "";
1356*d68f33bcSAndroid Build Coastguard Worker	my $name_comment = "";
1357*d68f33bcSAndroid Build Coastguard Worker	my $address = "";
1358*d68f33bcSAndroid Build Coastguard Worker	my $comment = "";
1359*d68f33bcSAndroid Build Coastguard Worker
1360*d68f33bcSAndroid Build Coastguard Worker	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1361*d68f33bcSAndroid Build Coastguard Worker		$name = $1;
1362*d68f33bcSAndroid Build Coastguard Worker		$address = $2;
1363*d68f33bcSAndroid Build Coastguard Worker		$comment = $3 if defined $3;
1364*d68f33bcSAndroid Build Coastguard Worker	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1365*d68f33bcSAndroid Build Coastguard Worker		$address = $1;
1366*d68f33bcSAndroid Build Coastguard Worker		$comment = $2 if defined $2;
1367*d68f33bcSAndroid Build Coastguard Worker	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1368*d68f33bcSAndroid Build Coastguard Worker		$address = $1;
1369*d68f33bcSAndroid Build Coastguard Worker		$comment = $2 if defined $2;
1370*d68f33bcSAndroid Build Coastguard Worker		$formatted_email =~ s/\Q$address\E.*$//;
1371*d68f33bcSAndroid Build Coastguard Worker		$name = $formatted_email;
1372*d68f33bcSAndroid Build Coastguard Worker		$name = trim($name);
1373*d68f33bcSAndroid Build Coastguard Worker		$name =~ s/^\"|\"$//g;
1374*d68f33bcSAndroid Build Coastguard Worker		# If there's a name left after stripping spaces and
1375*d68f33bcSAndroid Build Coastguard Worker		# leading quotes, and the address doesn't have both
1376*d68f33bcSAndroid Build Coastguard Worker		# leading and trailing angle brackets, the address
1377*d68f33bcSAndroid Build Coastguard Worker		# is invalid. ie:
1378*d68f33bcSAndroid Build Coastguard Worker		#   "joe smith [email protected]" bad
1379*d68f33bcSAndroid Build Coastguard Worker		#   "joe smith <[email protected]" bad
1380*d68f33bcSAndroid Build Coastguard Worker		if ($name ne "" && $address !~ /^<[^>]+>$/) {
1381*d68f33bcSAndroid Build Coastguard Worker			$name = "";
1382*d68f33bcSAndroid Build Coastguard Worker			$address = "";
1383*d68f33bcSAndroid Build Coastguard Worker			$comment = "";
1384*d68f33bcSAndroid Build Coastguard Worker		}
1385*d68f33bcSAndroid Build Coastguard Worker	}
1386*d68f33bcSAndroid Build Coastguard Worker
1387*d68f33bcSAndroid Build Coastguard Worker	# Extract comments from names excluding quoted parts
1388*d68f33bcSAndroid Build Coastguard Worker	# "John D. (Doe)" - Do not extract
1389*d68f33bcSAndroid Build Coastguard Worker	if ($name =~ s/\"(.+)\"//) {
1390*d68f33bcSAndroid Build Coastguard Worker		$quoted = $1;
1391*d68f33bcSAndroid Build Coastguard Worker	}
1392*d68f33bcSAndroid Build Coastguard Worker	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1393*d68f33bcSAndroid Build Coastguard Worker		$name_comment .= trim($1);
1394*d68f33bcSAndroid Build Coastguard Worker	}
1395*d68f33bcSAndroid Build Coastguard Worker	$name =~ s/^[ \"]+|[ \"]+$//g;
1396*d68f33bcSAndroid Build Coastguard Worker	$name = trim("$quoted $name");
1397*d68f33bcSAndroid Build Coastguard Worker
1398*d68f33bcSAndroid Build Coastguard Worker	$address = trim($address);
1399*d68f33bcSAndroid Build Coastguard Worker	$address =~ s/^\<|\>$//g;
1400*d68f33bcSAndroid Build Coastguard Worker	$comment = trim($comment);
1401*d68f33bcSAndroid Build Coastguard Worker
1402*d68f33bcSAndroid Build Coastguard Worker	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1403*d68f33bcSAndroid Build Coastguard Worker		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1404*d68f33bcSAndroid Build Coastguard Worker		$name = "\"$name\"";
1405*d68f33bcSAndroid Build Coastguard Worker	}
1406*d68f33bcSAndroid Build Coastguard Worker
1407*d68f33bcSAndroid Build Coastguard Worker	return ($name, $name_comment, $address, $comment);
1408*d68f33bcSAndroid Build Coastguard Worker}
1409*d68f33bcSAndroid Build Coastguard Worker
1410*d68f33bcSAndroid Build Coastguard Workersub format_email {
1411*d68f33bcSAndroid Build Coastguard Worker	my ($name, $name_comment, $address, $comment) = @_;
1412*d68f33bcSAndroid Build Coastguard Worker
1413*d68f33bcSAndroid Build Coastguard Worker	my $formatted_email;
1414*d68f33bcSAndroid Build Coastguard Worker
1415*d68f33bcSAndroid Build Coastguard Worker	$name =~ s/^[ \"]+|[ \"]+$//g;
1416*d68f33bcSAndroid Build Coastguard Worker	$address = trim($address);
1417*d68f33bcSAndroid Build Coastguard Worker	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
1418*d68f33bcSAndroid Build Coastguard Worker
1419*d68f33bcSAndroid Build Coastguard Worker	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1420*d68f33bcSAndroid Build Coastguard Worker		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1421*d68f33bcSAndroid Build Coastguard Worker		$name = "\"$name\"";
1422*d68f33bcSAndroid Build Coastguard Worker	}
1423*d68f33bcSAndroid Build Coastguard Worker
1424*d68f33bcSAndroid Build Coastguard Worker	$name_comment = trim($name_comment);
1425*d68f33bcSAndroid Build Coastguard Worker	$name_comment = " $name_comment" if ($name_comment ne "");
1426*d68f33bcSAndroid Build Coastguard Worker	$comment = trim($comment);
1427*d68f33bcSAndroid Build Coastguard Worker	$comment = " $comment" if ($comment ne "");
1428*d68f33bcSAndroid Build Coastguard Worker
1429*d68f33bcSAndroid Build Coastguard Worker	if ("$name" eq "") {
1430*d68f33bcSAndroid Build Coastguard Worker		$formatted_email = "$address";
1431*d68f33bcSAndroid Build Coastguard Worker	} else {
1432*d68f33bcSAndroid Build Coastguard Worker		$formatted_email = "$name$name_comment <$address>";
1433*d68f33bcSAndroid Build Coastguard Worker	}
1434*d68f33bcSAndroid Build Coastguard Worker	$formatted_email .= "$comment";
1435*d68f33bcSAndroid Build Coastguard Worker	return $formatted_email;
1436*d68f33bcSAndroid Build Coastguard Worker}
1437*d68f33bcSAndroid Build Coastguard Worker
1438*d68f33bcSAndroid Build Coastguard Workersub reformat_email {
1439*d68f33bcSAndroid Build Coastguard Worker	my ($email) = @_;
1440*d68f33bcSAndroid Build Coastguard Worker
1441*d68f33bcSAndroid Build Coastguard Worker	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
1442*d68f33bcSAndroid Build Coastguard Worker	return format_email($email_name, $name_comment, $email_address, $comment);
1443*d68f33bcSAndroid Build Coastguard Worker}
1444*d68f33bcSAndroid Build Coastguard Worker
1445*d68f33bcSAndroid Build Coastguard Workersub same_email_addresses {
1446*d68f33bcSAndroid Build Coastguard Worker	my ($email1, $email2) = @_;
1447*d68f33bcSAndroid Build Coastguard Worker
1448*d68f33bcSAndroid Build Coastguard Worker	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1449*d68f33bcSAndroid Build Coastguard Worker	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1450*d68f33bcSAndroid Build Coastguard Worker
1451*d68f33bcSAndroid Build Coastguard Worker	return $email1_name eq $email2_name &&
1452*d68f33bcSAndroid Build Coastguard Worker	       $email1_address eq $email2_address &&
1453*d68f33bcSAndroid Build Coastguard Worker	       $name1_comment eq $name2_comment &&
1454*d68f33bcSAndroid Build Coastguard Worker	       $comment1 eq $comment2;
1455*d68f33bcSAndroid Build Coastguard Worker}
1456*d68f33bcSAndroid Build Coastguard Worker
1457*d68f33bcSAndroid Build Coastguard Workersub which {
1458*d68f33bcSAndroid Build Coastguard Worker	my ($bin) = @_;
1459*d68f33bcSAndroid Build Coastguard Worker
1460*d68f33bcSAndroid Build Coastguard Worker	foreach my $path (split(/:/, $ENV{PATH})) {
1461*d68f33bcSAndroid Build Coastguard Worker		if (-e "$path/$bin") {
1462*d68f33bcSAndroid Build Coastguard Worker			return "$path/$bin";
1463*d68f33bcSAndroid Build Coastguard Worker		}
1464*d68f33bcSAndroid Build Coastguard Worker	}
1465*d68f33bcSAndroid Build Coastguard Worker
1466*d68f33bcSAndroid Build Coastguard Worker	return "";
1467*d68f33bcSAndroid Build Coastguard Worker}
1468*d68f33bcSAndroid Build Coastguard Worker
1469*d68f33bcSAndroid Build Coastguard Workersub which_conf {
1470*d68f33bcSAndroid Build Coastguard Worker	my ($conf) = @_;
1471*d68f33bcSAndroid Build Coastguard Worker
1472*d68f33bcSAndroid Build Coastguard Worker	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1473*d68f33bcSAndroid Build Coastguard Worker		if (-e "$path/$conf") {
1474*d68f33bcSAndroid Build Coastguard Worker			return "$path/$conf";
1475*d68f33bcSAndroid Build Coastguard Worker		}
1476*d68f33bcSAndroid Build Coastguard Worker	}
1477*d68f33bcSAndroid Build Coastguard Worker
1478*d68f33bcSAndroid Build Coastguard Worker	return "";
1479*d68f33bcSAndroid Build Coastguard Worker}
1480*d68f33bcSAndroid Build Coastguard Worker
1481*d68f33bcSAndroid Build Coastguard Workersub expand_tabs {
1482*d68f33bcSAndroid Build Coastguard Worker	my ($str) = @_;
1483*d68f33bcSAndroid Build Coastguard Worker
1484*d68f33bcSAndroid Build Coastguard Worker	my $res = '';
1485*d68f33bcSAndroid Build Coastguard Worker	my $n = 0;
1486*d68f33bcSAndroid Build Coastguard Worker	for my $c (split(//, $str)) {
1487*d68f33bcSAndroid Build Coastguard Worker		if ($c eq "\t") {
1488*d68f33bcSAndroid Build Coastguard Worker			$res .= ' ';
1489*d68f33bcSAndroid Build Coastguard Worker			$n++;
1490*d68f33bcSAndroid Build Coastguard Worker			for (; ($n % $tabsize) != 0; $n++) {
1491*d68f33bcSAndroid Build Coastguard Worker				$res .= ' ';
1492*d68f33bcSAndroid Build Coastguard Worker			}
1493*d68f33bcSAndroid Build Coastguard Worker			next;
1494*d68f33bcSAndroid Build Coastguard Worker		}
1495*d68f33bcSAndroid Build Coastguard Worker		$res .= $c;
1496*d68f33bcSAndroid Build Coastguard Worker		$n++;
1497*d68f33bcSAndroid Build Coastguard Worker	}
1498*d68f33bcSAndroid Build Coastguard Worker
1499*d68f33bcSAndroid Build Coastguard Worker	return $res;
1500*d68f33bcSAndroid Build Coastguard Worker}
1501*d68f33bcSAndroid Build Coastguard Workersub copy_spacing {
1502*d68f33bcSAndroid Build Coastguard Worker	(my $res = shift) =~ tr/\t/ /c;
1503*d68f33bcSAndroid Build Coastguard Worker	return $res;
1504*d68f33bcSAndroid Build Coastguard Worker}
1505*d68f33bcSAndroid Build Coastguard Worker
1506*d68f33bcSAndroid Build Coastguard Workersub line_stats {
1507*d68f33bcSAndroid Build Coastguard Worker	my ($line) = @_;
1508*d68f33bcSAndroid Build Coastguard Worker
1509*d68f33bcSAndroid Build Coastguard Worker	# Drop the diff line leader and expand tabs
1510*d68f33bcSAndroid Build Coastguard Worker	$line =~ s/^.//;
1511*d68f33bcSAndroid Build Coastguard Worker	$line = expand_tabs($line);
1512*d68f33bcSAndroid Build Coastguard Worker
1513*d68f33bcSAndroid Build Coastguard Worker	# Pick the indent from the front of the line.
1514*d68f33bcSAndroid Build Coastguard Worker	my ($white) = ($line =~ /^(\s*)/);
1515*d68f33bcSAndroid Build Coastguard Worker
1516*d68f33bcSAndroid Build Coastguard Worker	return (length($line), length($white));
1517*d68f33bcSAndroid Build Coastguard Worker}
1518*d68f33bcSAndroid Build Coastguard Worker
1519*d68f33bcSAndroid Build Coastguard Workermy $sanitise_quote = '';
1520*d68f33bcSAndroid Build Coastguard Worker
1521*d68f33bcSAndroid Build Coastguard Workersub sanitise_line_reset {
1522*d68f33bcSAndroid Build Coastguard Worker	my ($in_comment) = @_;
1523*d68f33bcSAndroid Build Coastguard Worker
1524*d68f33bcSAndroid Build Coastguard Worker	if ($in_comment) {
1525*d68f33bcSAndroid Build Coastguard Worker		$sanitise_quote = '*/';
1526*d68f33bcSAndroid Build Coastguard Worker	} else {
1527*d68f33bcSAndroid Build Coastguard Worker		$sanitise_quote = '';
1528*d68f33bcSAndroid Build Coastguard Worker	}
1529*d68f33bcSAndroid Build Coastguard Worker}
1530*d68f33bcSAndroid Build Coastguard Workersub sanitise_line {
1531*d68f33bcSAndroid Build Coastguard Worker	my ($line) = @_;
1532*d68f33bcSAndroid Build Coastguard Worker
1533*d68f33bcSAndroid Build Coastguard Worker	my $res = '';
1534*d68f33bcSAndroid Build Coastguard Worker	my $l = '';
1535*d68f33bcSAndroid Build Coastguard Worker
1536*d68f33bcSAndroid Build Coastguard Worker	my $qlen = 0;
1537*d68f33bcSAndroid Build Coastguard Worker	my $off = 0;
1538*d68f33bcSAndroid Build Coastguard Worker	my $c;
1539*d68f33bcSAndroid Build Coastguard Worker
1540*d68f33bcSAndroid Build Coastguard Worker	# Always copy over the diff marker.
1541*d68f33bcSAndroid Build Coastguard Worker	$res = substr($line, 0, 1);
1542*d68f33bcSAndroid Build Coastguard Worker
1543*d68f33bcSAndroid Build Coastguard Worker	for ($off = 1; $off < length($line); $off++) {
1544*d68f33bcSAndroid Build Coastguard Worker		$c = substr($line, $off, 1);
1545*d68f33bcSAndroid Build Coastguard Worker
1546*d68f33bcSAndroid Build Coastguard Worker		# Comments we are whacking completely including the begin
1547*d68f33bcSAndroid Build Coastguard Worker		# and end, all to $;.
1548*d68f33bcSAndroid Build Coastguard Worker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1549*d68f33bcSAndroid Build Coastguard Worker			$sanitise_quote = '*/';
1550*d68f33bcSAndroid Build Coastguard Worker
1551*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 2, "$;$;");
1552*d68f33bcSAndroid Build Coastguard Worker			$off++;
1553*d68f33bcSAndroid Build Coastguard Worker			next;
1554*d68f33bcSAndroid Build Coastguard Worker		}
1555*d68f33bcSAndroid Build Coastguard Worker		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1556*d68f33bcSAndroid Build Coastguard Worker			$sanitise_quote = '';
1557*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 2, "$;$;");
1558*d68f33bcSAndroid Build Coastguard Worker			$off++;
1559*d68f33bcSAndroid Build Coastguard Worker			next;
1560*d68f33bcSAndroid Build Coastguard Worker		}
1561*d68f33bcSAndroid Build Coastguard Worker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1562*d68f33bcSAndroid Build Coastguard Worker			$sanitise_quote = '//';
1563*d68f33bcSAndroid Build Coastguard Worker
1564*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 2, $sanitise_quote);
1565*d68f33bcSAndroid Build Coastguard Worker			$off++;
1566*d68f33bcSAndroid Build Coastguard Worker			next;
1567*d68f33bcSAndroid Build Coastguard Worker		}
1568*d68f33bcSAndroid Build Coastguard Worker
1569*d68f33bcSAndroid Build Coastguard Worker		# A \ in a string means ignore the next character.
1570*d68f33bcSAndroid Build Coastguard Worker		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1571*d68f33bcSAndroid Build Coastguard Worker		    $c eq "\\") {
1572*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 2, 'XX');
1573*d68f33bcSAndroid Build Coastguard Worker			$off++;
1574*d68f33bcSAndroid Build Coastguard Worker			next;
1575*d68f33bcSAndroid Build Coastguard Worker		}
1576*d68f33bcSAndroid Build Coastguard Worker		# Regular quotes.
1577*d68f33bcSAndroid Build Coastguard Worker		if ($c eq "'" || $c eq '"') {
1578*d68f33bcSAndroid Build Coastguard Worker			if ($sanitise_quote eq '') {
1579*d68f33bcSAndroid Build Coastguard Worker				$sanitise_quote = $c;
1580*d68f33bcSAndroid Build Coastguard Worker
1581*d68f33bcSAndroid Build Coastguard Worker				substr($res, $off, 1, $c);
1582*d68f33bcSAndroid Build Coastguard Worker				next;
1583*d68f33bcSAndroid Build Coastguard Worker			} elsif ($sanitise_quote eq $c) {
1584*d68f33bcSAndroid Build Coastguard Worker				$sanitise_quote = '';
1585*d68f33bcSAndroid Build Coastguard Worker			}
1586*d68f33bcSAndroid Build Coastguard Worker		}
1587*d68f33bcSAndroid Build Coastguard Worker
1588*d68f33bcSAndroid Build Coastguard Worker		#print "c<$c> SQ<$sanitise_quote>\n";
1589*d68f33bcSAndroid Build Coastguard Worker		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1590*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 1, $;);
1591*d68f33bcSAndroid Build Coastguard Worker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1592*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 1, $;);
1593*d68f33bcSAndroid Build Coastguard Worker		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1594*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 1, 'X');
1595*d68f33bcSAndroid Build Coastguard Worker		} else {
1596*d68f33bcSAndroid Build Coastguard Worker			substr($res, $off, 1, $c);
1597*d68f33bcSAndroid Build Coastguard Worker		}
1598*d68f33bcSAndroid Build Coastguard Worker	}
1599*d68f33bcSAndroid Build Coastguard Worker
1600*d68f33bcSAndroid Build Coastguard Worker	if ($sanitise_quote eq '//') {
1601*d68f33bcSAndroid Build Coastguard Worker		$sanitise_quote = '';
1602*d68f33bcSAndroid Build Coastguard Worker	}
1603*d68f33bcSAndroid Build Coastguard Worker
1604*d68f33bcSAndroid Build Coastguard Worker	# The pathname on a #include may be surrounded by '<' and '>'.
1605*d68f33bcSAndroid Build Coastguard Worker	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1606*d68f33bcSAndroid Build Coastguard Worker		my $clean = 'X' x length($1);
1607*d68f33bcSAndroid Build Coastguard Worker		$res =~ s@\<.*\>@<$clean>@;
1608*d68f33bcSAndroid Build Coastguard Worker
1609*d68f33bcSAndroid Build Coastguard Worker	# The whole of a #error is a string.
1610*d68f33bcSAndroid Build Coastguard Worker	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1611*d68f33bcSAndroid Build Coastguard Worker		my $clean = 'X' x length($1);
1612*d68f33bcSAndroid Build Coastguard Worker		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1613*d68f33bcSAndroid Build Coastguard Worker	}
1614*d68f33bcSAndroid Build Coastguard Worker
1615*d68f33bcSAndroid Build Coastguard Worker	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1616*d68f33bcSAndroid Build Coastguard Worker		my $match = $1;
1617*d68f33bcSAndroid Build Coastguard Worker		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1618*d68f33bcSAndroid Build Coastguard Worker	}
1619*d68f33bcSAndroid Build Coastguard Worker
1620*d68f33bcSAndroid Build Coastguard Worker	return $res;
1621*d68f33bcSAndroid Build Coastguard Worker}
1622*d68f33bcSAndroid Build Coastguard Worker
1623*d68f33bcSAndroid Build Coastguard Workersub get_quoted_string {
1624*d68f33bcSAndroid Build Coastguard Worker	my ($line, $rawline) = @_;
1625*d68f33bcSAndroid Build Coastguard Worker
1626*d68f33bcSAndroid Build Coastguard Worker	return "" if (!defined($line) || !defined($rawline));
1627*d68f33bcSAndroid Build Coastguard Worker	return "" if ($line !~ m/($String)/g);
1628*d68f33bcSAndroid Build Coastguard Worker	return substr($rawline, $-[0], $+[0] - $-[0]);
1629*d68f33bcSAndroid Build Coastguard Worker}
1630*d68f33bcSAndroid Build Coastguard Worker
1631*d68f33bcSAndroid Build Coastguard Workersub ctx_statement_block {
1632*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain, $off) = @_;
1633*d68f33bcSAndroid Build Coastguard Worker	my $line = $linenr - 1;
1634*d68f33bcSAndroid Build Coastguard Worker	my $blk = '';
1635*d68f33bcSAndroid Build Coastguard Worker	my $soff = $off;
1636*d68f33bcSAndroid Build Coastguard Worker	my $coff = $off - 1;
1637*d68f33bcSAndroid Build Coastguard Worker	my $coff_set = 0;
1638*d68f33bcSAndroid Build Coastguard Worker
1639*d68f33bcSAndroid Build Coastguard Worker	my $loff = 0;
1640*d68f33bcSAndroid Build Coastguard Worker
1641*d68f33bcSAndroid Build Coastguard Worker	my $type = '';
1642*d68f33bcSAndroid Build Coastguard Worker	my $level = 0;
1643*d68f33bcSAndroid Build Coastguard Worker	my @stack = ();
1644*d68f33bcSAndroid Build Coastguard Worker	my $p;
1645*d68f33bcSAndroid Build Coastguard Worker	my $c;
1646*d68f33bcSAndroid Build Coastguard Worker	my $len = 0;
1647*d68f33bcSAndroid Build Coastguard Worker
1648*d68f33bcSAndroid Build Coastguard Worker	my $remainder;
1649*d68f33bcSAndroid Build Coastguard Worker	while (1) {
1650*d68f33bcSAndroid Build Coastguard Worker		@stack = (['', 0]) if ($#stack == -1);
1651*d68f33bcSAndroid Build Coastguard Worker
1652*d68f33bcSAndroid Build Coastguard Worker		#warn "CSB: blk<$blk> remain<$remain>\n";
1653*d68f33bcSAndroid Build Coastguard Worker		# If we are about to drop off the end, pull in more
1654*d68f33bcSAndroid Build Coastguard Worker		# context.
1655*d68f33bcSAndroid Build Coastguard Worker		if ($off >= $len) {
1656*d68f33bcSAndroid Build Coastguard Worker			for (; $remain > 0; $line++) {
1657*d68f33bcSAndroid Build Coastguard Worker				last if (!defined $lines[$line]);
1658*d68f33bcSAndroid Build Coastguard Worker				next if ($lines[$line] =~ /^-/);
1659*d68f33bcSAndroid Build Coastguard Worker				$remain--;
1660*d68f33bcSAndroid Build Coastguard Worker				$loff = $len;
1661*d68f33bcSAndroid Build Coastguard Worker				$blk .= $lines[$line] . "\n";
1662*d68f33bcSAndroid Build Coastguard Worker				$len = length($blk);
1663*d68f33bcSAndroid Build Coastguard Worker				$line++;
1664*d68f33bcSAndroid Build Coastguard Worker				last;
1665*d68f33bcSAndroid Build Coastguard Worker			}
1666*d68f33bcSAndroid Build Coastguard Worker			# Bail if there is no further context.
1667*d68f33bcSAndroid Build Coastguard Worker			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
1668*d68f33bcSAndroid Build Coastguard Worker			if ($off >= $len) {
1669*d68f33bcSAndroid Build Coastguard Worker				last;
1670*d68f33bcSAndroid Build Coastguard Worker			}
1671*d68f33bcSAndroid Build Coastguard Worker			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1672*d68f33bcSAndroid Build Coastguard Worker				$level++;
1673*d68f33bcSAndroid Build Coastguard Worker				$type = '#';
1674*d68f33bcSAndroid Build Coastguard Worker			}
1675*d68f33bcSAndroid Build Coastguard Worker		}
1676*d68f33bcSAndroid Build Coastguard Worker		$p = $c;
1677*d68f33bcSAndroid Build Coastguard Worker		$c = substr($blk, $off, 1);
1678*d68f33bcSAndroid Build Coastguard Worker		$remainder = substr($blk, $off);
1679*d68f33bcSAndroid Build Coastguard Worker
1680*d68f33bcSAndroid Build Coastguard Worker		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1681*d68f33bcSAndroid Build Coastguard Worker
1682*d68f33bcSAndroid Build Coastguard Worker		# Handle nested #if/#else.
1683*d68f33bcSAndroid Build Coastguard Worker		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1684*d68f33bcSAndroid Build Coastguard Worker			push(@stack, [ $type, $level ]);
1685*d68f33bcSAndroid Build Coastguard Worker		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1686*d68f33bcSAndroid Build Coastguard Worker			($type, $level) = @{$stack[$#stack - 1]};
1687*d68f33bcSAndroid Build Coastguard Worker		} elsif ($remainder =~ /^#\s*endif\b/) {
1688*d68f33bcSAndroid Build Coastguard Worker			($type, $level) = @{pop(@stack)};
1689*d68f33bcSAndroid Build Coastguard Worker		}
1690*d68f33bcSAndroid Build Coastguard Worker
1691*d68f33bcSAndroid Build Coastguard Worker		# Statement ends at the ';' or a close '}' at the
1692*d68f33bcSAndroid Build Coastguard Worker		# outermost level.
1693*d68f33bcSAndroid Build Coastguard Worker		if ($level == 0 && $c eq ';') {
1694*d68f33bcSAndroid Build Coastguard Worker			last;
1695*d68f33bcSAndroid Build Coastguard Worker		}
1696*d68f33bcSAndroid Build Coastguard Worker
1697*d68f33bcSAndroid Build Coastguard Worker		# An else is really a conditional as long as its not else if
1698*d68f33bcSAndroid Build Coastguard Worker		if ($level == 0 && $coff_set == 0 &&
1699*d68f33bcSAndroid Build Coastguard Worker				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1700*d68f33bcSAndroid Build Coastguard Worker				$remainder =~ /^(else)(?:\s|{)/ &&
1701*d68f33bcSAndroid Build Coastguard Worker				$remainder !~ /^else\s+if\b/) {
1702*d68f33bcSAndroid Build Coastguard Worker			$coff = $off + length($1) - 1;
1703*d68f33bcSAndroid Build Coastguard Worker			$coff_set = 1;
1704*d68f33bcSAndroid Build Coastguard Worker			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1705*d68f33bcSAndroid Build Coastguard Worker			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1706*d68f33bcSAndroid Build Coastguard Worker		}
1707*d68f33bcSAndroid Build Coastguard Worker
1708*d68f33bcSAndroid Build Coastguard Worker		if (($type eq '' || $type eq '(') && $c eq '(') {
1709*d68f33bcSAndroid Build Coastguard Worker			$level++;
1710*d68f33bcSAndroid Build Coastguard Worker			$type = '(';
1711*d68f33bcSAndroid Build Coastguard Worker		}
1712*d68f33bcSAndroid Build Coastguard Worker		if ($type eq '(' && $c eq ')') {
1713*d68f33bcSAndroid Build Coastguard Worker			$level--;
1714*d68f33bcSAndroid Build Coastguard Worker			$type = ($level != 0)? '(' : '';
1715*d68f33bcSAndroid Build Coastguard Worker
1716*d68f33bcSAndroid Build Coastguard Worker			if ($level == 0 && $coff < $soff) {
1717*d68f33bcSAndroid Build Coastguard Worker				$coff = $off;
1718*d68f33bcSAndroid Build Coastguard Worker				$coff_set = 1;
1719*d68f33bcSAndroid Build Coastguard Worker				#warn "CSB: mark coff<$coff>\n";
1720*d68f33bcSAndroid Build Coastguard Worker			}
1721*d68f33bcSAndroid Build Coastguard Worker		}
1722*d68f33bcSAndroid Build Coastguard Worker		if (($type eq '' || $type eq '{') && $c eq '{') {
1723*d68f33bcSAndroid Build Coastguard Worker			$level++;
1724*d68f33bcSAndroid Build Coastguard Worker			$type = '{';
1725*d68f33bcSAndroid Build Coastguard Worker		}
1726*d68f33bcSAndroid Build Coastguard Worker		if ($type eq '{' && $c eq '}') {
1727*d68f33bcSAndroid Build Coastguard Worker			$level--;
1728*d68f33bcSAndroid Build Coastguard Worker			$type = ($level != 0)? '{' : '';
1729*d68f33bcSAndroid Build Coastguard Worker
1730*d68f33bcSAndroid Build Coastguard Worker			if ($level == 0) {
1731*d68f33bcSAndroid Build Coastguard Worker				if (substr($blk, $off + 1, 1) eq ';') {
1732*d68f33bcSAndroid Build Coastguard Worker					$off++;
1733*d68f33bcSAndroid Build Coastguard Worker				}
1734*d68f33bcSAndroid Build Coastguard Worker				last;
1735*d68f33bcSAndroid Build Coastguard Worker			}
1736*d68f33bcSAndroid Build Coastguard Worker		}
1737*d68f33bcSAndroid Build Coastguard Worker		# Preprocessor commands end at the newline unless escaped.
1738*d68f33bcSAndroid Build Coastguard Worker		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1739*d68f33bcSAndroid Build Coastguard Worker			$level--;
1740*d68f33bcSAndroid Build Coastguard Worker			$type = '';
1741*d68f33bcSAndroid Build Coastguard Worker			$off++;
1742*d68f33bcSAndroid Build Coastguard Worker			last;
1743*d68f33bcSAndroid Build Coastguard Worker		}
1744*d68f33bcSAndroid Build Coastguard Worker		$off++;
1745*d68f33bcSAndroid Build Coastguard Worker	}
1746*d68f33bcSAndroid Build Coastguard Worker	# We are truly at the end, so shuffle to the next line.
1747*d68f33bcSAndroid Build Coastguard Worker	if ($off == $len) {
1748*d68f33bcSAndroid Build Coastguard Worker		$loff = $len + 1;
1749*d68f33bcSAndroid Build Coastguard Worker		$line++;
1750*d68f33bcSAndroid Build Coastguard Worker		$remain--;
1751*d68f33bcSAndroid Build Coastguard Worker	}
1752*d68f33bcSAndroid Build Coastguard Worker
1753*d68f33bcSAndroid Build Coastguard Worker	my $statement = substr($blk, $soff, $off - $soff + 1);
1754*d68f33bcSAndroid Build Coastguard Worker	my $condition = substr($blk, $soff, $coff - $soff + 1);
1755*d68f33bcSAndroid Build Coastguard Worker
1756*d68f33bcSAndroid Build Coastguard Worker	#warn "STATEMENT<$statement>\n";
1757*d68f33bcSAndroid Build Coastguard Worker	#warn "CONDITION<$condition>\n";
1758*d68f33bcSAndroid Build Coastguard Worker
1759*d68f33bcSAndroid Build Coastguard Worker	#print "coff<$coff> soff<$off> loff<$loff>\n";
1760*d68f33bcSAndroid Build Coastguard Worker
1761*d68f33bcSAndroid Build Coastguard Worker	return ($statement, $condition,
1762*d68f33bcSAndroid Build Coastguard Worker			$line, $remain + 1, $off - $loff + 1, $level);
1763*d68f33bcSAndroid Build Coastguard Worker}
1764*d68f33bcSAndroid Build Coastguard Worker
1765*d68f33bcSAndroid Build Coastguard Workersub statement_lines {
1766*d68f33bcSAndroid Build Coastguard Worker	my ($stmt) = @_;
1767*d68f33bcSAndroid Build Coastguard Worker
1768*d68f33bcSAndroid Build Coastguard Worker	# Strip the diff line prefixes and rip blank lines at start and end.
1769*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/(^|\n)./$1/g;
1770*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/^\s*//;
1771*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/\s*$//;
1772*d68f33bcSAndroid Build Coastguard Worker
1773*d68f33bcSAndroid Build Coastguard Worker	my @stmt_lines = ($stmt =~ /\n/g);
1774*d68f33bcSAndroid Build Coastguard Worker
1775*d68f33bcSAndroid Build Coastguard Worker	return $#stmt_lines + 2;
1776*d68f33bcSAndroid Build Coastguard Worker}
1777*d68f33bcSAndroid Build Coastguard Worker
1778*d68f33bcSAndroid Build Coastguard Workersub statement_rawlines {
1779*d68f33bcSAndroid Build Coastguard Worker	my ($stmt) = @_;
1780*d68f33bcSAndroid Build Coastguard Worker
1781*d68f33bcSAndroid Build Coastguard Worker	my @stmt_lines = ($stmt =~ /\n/g);
1782*d68f33bcSAndroid Build Coastguard Worker
1783*d68f33bcSAndroid Build Coastguard Worker	return $#stmt_lines + 2;
1784*d68f33bcSAndroid Build Coastguard Worker}
1785*d68f33bcSAndroid Build Coastguard Worker
1786*d68f33bcSAndroid Build Coastguard Workersub statement_block_size {
1787*d68f33bcSAndroid Build Coastguard Worker	my ($stmt) = @_;
1788*d68f33bcSAndroid Build Coastguard Worker
1789*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/(^|\n)./$1/g;
1790*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/^\s*{//;
1791*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/}\s*$//;
1792*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/^\s*//;
1793*d68f33bcSAndroid Build Coastguard Worker	$stmt =~ s/\s*$//;
1794*d68f33bcSAndroid Build Coastguard Worker
1795*d68f33bcSAndroid Build Coastguard Worker	my @stmt_lines = ($stmt =~ /\n/g);
1796*d68f33bcSAndroid Build Coastguard Worker	my @stmt_statements = ($stmt =~ /;/g);
1797*d68f33bcSAndroid Build Coastguard Worker
1798*d68f33bcSAndroid Build Coastguard Worker	my $stmt_lines = $#stmt_lines + 2;
1799*d68f33bcSAndroid Build Coastguard Worker	my $stmt_statements = $#stmt_statements + 1;
1800*d68f33bcSAndroid Build Coastguard Worker
1801*d68f33bcSAndroid Build Coastguard Worker	if ($stmt_lines > $stmt_statements) {
1802*d68f33bcSAndroid Build Coastguard Worker		return $stmt_lines;
1803*d68f33bcSAndroid Build Coastguard Worker	} else {
1804*d68f33bcSAndroid Build Coastguard Worker		return $stmt_statements;
1805*d68f33bcSAndroid Build Coastguard Worker	}
1806*d68f33bcSAndroid Build Coastguard Worker}
1807*d68f33bcSAndroid Build Coastguard Worker
1808*d68f33bcSAndroid Build Coastguard Workersub ctx_statement_full {
1809*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain, $off) = @_;
1810*d68f33bcSAndroid Build Coastguard Worker	my ($statement, $condition, $level);
1811*d68f33bcSAndroid Build Coastguard Worker
1812*d68f33bcSAndroid Build Coastguard Worker	my (@chunks);
1813*d68f33bcSAndroid Build Coastguard Worker
1814*d68f33bcSAndroid Build Coastguard Worker	# Grab the first conditional/block pair.
1815*d68f33bcSAndroid Build Coastguard Worker	($statement, $condition, $linenr, $remain, $off, $level) =
1816*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $remain, $off);
1817*d68f33bcSAndroid Build Coastguard Worker	#print "F: c<$condition> s<$statement> remain<$remain>\n";
1818*d68f33bcSAndroid Build Coastguard Worker	push(@chunks, [ $condition, $statement ]);
1819*d68f33bcSAndroid Build Coastguard Worker	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1820*d68f33bcSAndroid Build Coastguard Worker		return ($level, $linenr, @chunks);
1821*d68f33bcSAndroid Build Coastguard Worker	}
1822*d68f33bcSAndroid Build Coastguard Worker
1823*d68f33bcSAndroid Build Coastguard Worker	# Pull in the following conditional/block pairs and see if they
1824*d68f33bcSAndroid Build Coastguard Worker	# could continue the statement.
1825*d68f33bcSAndroid Build Coastguard Worker	for (;;) {
1826*d68f33bcSAndroid Build Coastguard Worker		($statement, $condition, $linenr, $remain, $off, $level) =
1827*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $remain, $off);
1828*d68f33bcSAndroid Build Coastguard Worker		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1829*d68f33bcSAndroid Build Coastguard Worker		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1830*d68f33bcSAndroid Build Coastguard Worker		#print "C: push\n";
1831*d68f33bcSAndroid Build Coastguard Worker		push(@chunks, [ $condition, $statement ]);
1832*d68f33bcSAndroid Build Coastguard Worker	}
1833*d68f33bcSAndroid Build Coastguard Worker
1834*d68f33bcSAndroid Build Coastguard Worker	return ($level, $linenr, @chunks);
1835*d68f33bcSAndroid Build Coastguard Worker}
1836*d68f33bcSAndroid Build Coastguard Worker
1837*d68f33bcSAndroid Build Coastguard Workersub ctx_block_get {
1838*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1839*d68f33bcSAndroid Build Coastguard Worker	my $line;
1840*d68f33bcSAndroid Build Coastguard Worker	my $start = $linenr - 1;
1841*d68f33bcSAndroid Build Coastguard Worker	my $blk = '';
1842*d68f33bcSAndroid Build Coastguard Worker	my @o;
1843*d68f33bcSAndroid Build Coastguard Worker	my @c;
1844*d68f33bcSAndroid Build Coastguard Worker	my @res = ();
1845*d68f33bcSAndroid Build Coastguard Worker
1846*d68f33bcSAndroid Build Coastguard Worker	my $level = 0;
1847*d68f33bcSAndroid Build Coastguard Worker	my @stack = ($level);
1848*d68f33bcSAndroid Build Coastguard Worker	for ($line = $start; $remain > 0; $line++) {
1849*d68f33bcSAndroid Build Coastguard Worker		next if ($rawlines[$line] =~ /^-/);
1850*d68f33bcSAndroid Build Coastguard Worker		$remain--;
1851*d68f33bcSAndroid Build Coastguard Worker
1852*d68f33bcSAndroid Build Coastguard Worker		$blk .= $rawlines[$line];
1853*d68f33bcSAndroid Build Coastguard Worker
1854*d68f33bcSAndroid Build Coastguard Worker		# Handle nested #if/#else.
1855*d68f33bcSAndroid Build Coastguard Worker		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1856*d68f33bcSAndroid Build Coastguard Worker			push(@stack, $level);
1857*d68f33bcSAndroid Build Coastguard Worker		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1858*d68f33bcSAndroid Build Coastguard Worker			$level = $stack[$#stack - 1];
1859*d68f33bcSAndroid Build Coastguard Worker		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1860*d68f33bcSAndroid Build Coastguard Worker			$level = pop(@stack);
1861*d68f33bcSAndroid Build Coastguard Worker		}
1862*d68f33bcSAndroid Build Coastguard Worker
1863*d68f33bcSAndroid Build Coastguard Worker		foreach my $c (split(//, $lines[$line])) {
1864*d68f33bcSAndroid Build Coastguard Worker			##print "C<$c>L<$level><$open$close>O<$off>\n";
1865*d68f33bcSAndroid Build Coastguard Worker			if ($off > 0) {
1866*d68f33bcSAndroid Build Coastguard Worker				$off--;
1867*d68f33bcSAndroid Build Coastguard Worker				next;
1868*d68f33bcSAndroid Build Coastguard Worker			}
1869*d68f33bcSAndroid Build Coastguard Worker
1870*d68f33bcSAndroid Build Coastguard Worker			if ($c eq $close && $level > 0) {
1871*d68f33bcSAndroid Build Coastguard Worker				$level--;
1872*d68f33bcSAndroid Build Coastguard Worker				last if ($level == 0);
1873*d68f33bcSAndroid Build Coastguard Worker			} elsif ($c eq $open) {
1874*d68f33bcSAndroid Build Coastguard Worker				$level++;
1875*d68f33bcSAndroid Build Coastguard Worker			}
1876*d68f33bcSAndroid Build Coastguard Worker		}
1877*d68f33bcSAndroid Build Coastguard Worker
1878*d68f33bcSAndroid Build Coastguard Worker		if (!$outer || $level <= 1) {
1879*d68f33bcSAndroid Build Coastguard Worker			push(@res, $rawlines[$line]);
1880*d68f33bcSAndroid Build Coastguard Worker		}
1881*d68f33bcSAndroid Build Coastguard Worker
1882*d68f33bcSAndroid Build Coastguard Worker		last if ($level == 0);
1883*d68f33bcSAndroid Build Coastguard Worker	}
1884*d68f33bcSAndroid Build Coastguard Worker
1885*d68f33bcSAndroid Build Coastguard Worker	return ($level, @res);
1886*d68f33bcSAndroid Build Coastguard Worker}
1887*d68f33bcSAndroid Build Coastguard Workersub ctx_block_outer {
1888*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain) = @_;
1889*d68f33bcSAndroid Build Coastguard Worker
1890*d68f33bcSAndroid Build Coastguard Worker	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1891*d68f33bcSAndroid Build Coastguard Worker	return @r;
1892*d68f33bcSAndroid Build Coastguard Worker}
1893*d68f33bcSAndroid Build Coastguard Workersub ctx_block {
1894*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain) = @_;
1895*d68f33bcSAndroid Build Coastguard Worker
1896*d68f33bcSAndroid Build Coastguard Worker	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1897*d68f33bcSAndroid Build Coastguard Worker	return @r;
1898*d68f33bcSAndroid Build Coastguard Worker}
1899*d68f33bcSAndroid Build Coastguard Workersub ctx_statement {
1900*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain, $off) = @_;
1901*d68f33bcSAndroid Build Coastguard Worker
1902*d68f33bcSAndroid Build Coastguard Worker	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1903*d68f33bcSAndroid Build Coastguard Worker	return @r;
1904*d68f33bcSAndroid Build Coastguard Worker}
1905*d68f33bcSAndroid Build Coastguard Workersub ctx_block_level {
1906*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain) = @_;
1907*d68f33bcSAndroid Build Coastguard Worker
1908*d68f33bcSAndroid Build Coastguard Worker	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1909*d68f33bcSAndroid Build Coastguard Worker}
1910*d68f33bcSAndroid Build Coastguard Workersub ctx_statement_level {
1911*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $remain, $off) = @_;
1912*d68f33bcSAndroid Build Coastguard Worker
1913*d68f33bcSAndroid Build Coastguard Worker	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1914*d68f33bcSAndroid Build Coastguard Worker}
1915*d68f33bcSAndroid Build Coastguard Worker
1916*d68f33bcSAndroid Build Coastguard Workersub ctx_locate_comment {
1917*d68f33bcSAndroid Build Coastguard Worker	my ($first_line, $end_line) = @_;
1918*d68f33bcSAndroid Build Coastguard Worker
1919*d68f33bcSAndroid Build Coastguard Worker	# If c99 comment on the current line, or the line before or after
1920*d68f33bcSAndroid Build Coastguard Worker	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1921*d68f33bcSAndroid Build Coastguard Worker	return $current_comment if (defined $current_comment);
1922*d68f33bcSAndroid Build Coastguard Worker	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1923*d68f33bcSAndroid Build Coastguard Worker	return $current_comment if (defined $current_comment);
1924*d68f33bcSAndroid Build Coastguard Worker	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1925*d68f33bcSAndroid Build Coastguard Worker	return $current_comment if (defined $current_comment);
1926*d68f33bcSAndroid Build Coastguard Worker
1927*d68f33bcSAndroid Build Coastguard Worker	# Catch a comment on the end of the line itself.
1928*d68f33bcSAndroid Build Coastguard Worker	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1929*d68f33bcSAndroid Build Coastguard Worker	return $current_comment if (defined $current_comment);
1930*d68f33bcSAndroid Build Coastguard Worker
1931*d68f33bcSAndroid Build Coastguard Worker	# Look through the context and try and figure out if there is a
1932*d68f33bcSAndroid Build Coastguard Worker	# comment.
1933*d68f33bcSAndroid Build Coastguard Worker	my $in_comment = 0;
1934*d68f33bcSAndroid Build Coastguard Worker	$current_comment = '';
1935*d68f33bcSAndroid Build Coastguard Worker	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1936*d68f33bcSAndroid Build Coastguard Worker		my $line = $rawlines[$linenr - 1];
1937*d68f33bcSAndroid Build Coastguard Worker		#warn "           $line\n";
1938*d68f33bcSAndroid Build Coastguard Worker		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1939*d68f33bcSAndroid Build Coastguard Worker			$in_comment = 1;
1940*d68f33bcSAndroid Build Coastguard Worker		}
1941*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ m@/\*@) {
1942*d68f33bcSAndroid Build Coastguard Worker			$in_comment = 1;
1943*d68f33bcSAndroid Build Coastguard Worker		}
1944*d68f33bcSAndroid Build Coastguard Worker		if (!$in_comment && $current_comment ne '') {
1945*d68f33bcSAndroid Build Coastguard Worker			$current_comment = '';
1946*d68f33bcSAndroid Build Coastguard Worker		}
1947*d68f33bcSAndroid Build Coastguard Worker		$current_comment .= $line . "\n" if ($in_comment);
1948*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ m@\*/@) {
1949*d68f33bcSAndroid Build Coastguard Worker			$in_comment = 0;
1950*d68f33bcSAndroid Build Coastguard Worker		}
1951*d68f33bcSAndroid Build Coastguard Worker	}
1952*d68f33bcSAndroid Build Coastguard Worker
1953*d68f33bcSAndroid Build Coastguard Worker	chomp($current_comment);
1954*d68f33bcSAndroid Build Coastguard Worker	return($current_comment);
1955*d68f33bcSAndroid Build Coastguard Worker}
1956*d68f33bcSAndroid Build Coastguard Workersub ctx_has_comment {
1957*d68f33bcSAndroid Build Coastguard Worker	my ($first_line, $end_line) = @_;
1958*d68f33bcSAndroid Build Coastguard Worker	my $cmt = ctx_locate_comment($first_line, $end_line);
1959*d68f33bcSAndroid Build Coastguard Worker
1960*d68f33bcSAndroid Build Coastguard Worker	##print "LINE: $rawlines[$end_line - 1 ]\n";
1961*d68f33bcSAndroid Build Coastguard Worker	##print "CMMT: $cmt\n";
1962*d68f33bcSAndroid Build Coastguard Worker
1963*d68f33bcSAndroid Build Coastguard Worker	return ($cmt ne '');
1964*d68f33bcSAndroid Build Coastguard Worker}
1965*d68f33bcSAndroid Build Coastguard Worker
1966*d68f33bcSAndroid Build Coastguard Workersub raw_line {
1967*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $cnt) = @_;
1968*d68f33bcSAndroid Build Coastguard Worker
1969*d68f33bcSAndroid Build Coastguard Worker	my $offset = $linenr - 1;
1970*d68f33bcSAndroid Build Coastguard Worker	$cnt++;
1971*d68f33bcSAndroid Build Coastguard Worker
1972*d68f33bcSAndroid Build Coastguard Worker	my $line;
1973*d68f33bcSAndroid Build Coastguard Worker	while ($cnt) {
1974*d68f33bcSAndroid Build Coastguard Worker		$line = $rawlines[$offset++];
1975*d68f33bcSAndroid Build Coastguard Worker		next if (defined($line) && $line =~ /^-/);
1976*d68f33bcSAndroid Build Coastguard Worker		$cnt--;
1977*d68f33bcSAndroid Build Coastguard Worker	}
1978*d68f33bcSAndroid Build Coastguard Worker
1979*d68f33bcSAndroid Build Coastguard Worker	return $line;
1980*d68f33bcSAndroid Build Coastguard Worker}
1981*d68f33bcSAndroid Build Coastguard Worker
1982*d68f33bcSAndroid Build Coastguard Workersub get_stat_real {
1983*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $lc) = @_;
1984*d68f33bcSAndroid Build Coastguard Worker
1985*d68f33bcSAndroid Build Coastguard Worker	my $stat_real = raw_line($linenr, 0);
1986*d68f33bcSAndroid Build Coastguard Worker	for (my $count = $linenr + 1; $count <= $lc; $count++) {
1987*d68f33bcSAndroid Build Coastguard Worker		$stat_real = $stat_real . "\n" . raw_line($count, 0);
1988*d68f33bcSAndroid Build Coastguard Worker	}
1989*d68f33bcSAndroid Build Coastguard Worker
1990*d68f33bcSAndroid Build Coastguard Worker	return $stat_real;
1991*d68f33bcSAndroid Build Coastguard Worker}
1992*d68f33bcSAndroid Build Coastguard Worker
1993*d68f33bcSAndroid Build Coastguard Workersub get_stat_here {
1994*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $cnt, $here) = @_;
1995*d68f33bcSAndroid Build Coastguard Worker
1996*d68f33bcSAndroid Build Coastguard Worker	my $herectx = $here . "\n";
1997*d68f33bcSAndroid Build Coastguard Worker	for (my $n = 0; $n < $cnt; $n++) {
1998*d68f33bcSAndroid Build Coastguard Worker		$herectx .= raw_line($linenr, $n) . "\n";
1999*d68f33bcSAndroid Build Coastguard Worker	}
2000*d68f33bcSAndroid Build Coastguard Worker
2001*d68f33bcSAndroid Build Coastguard Worker	return $herectx;
2002*d68f33bcSAndroid Build Coastguard Worker}
2003*d68f33bcSAndroid Build Coastguard Worker
2004*d68f33bcSAndroid Build Coastguard Workersub cat_vet {
2005*d68f33bcSAndroid Build Coastguard Worker	my ($vet) = @_;
2006*d68f33bcSAndroid Build Coastguard Worker	my ($res, $coded);
2007*d68f33bcSAndroid Build Coastguard Worker
2008*d68f33bcSAndroid Build Coastguard Worker	$res = '';
2009*d68f33bcSAndroid Build Coastguard Worker	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
2010*d68f33bcSAndroid Build Coastguard Worker		$res .= $1;
2011*d68f33bcSAndroid Build Coastguard Worker		if ($2 ne '') {
2012*d68f33bcSAndroid Build Coastguard Worker			$coded = sprintf("^%c", unpack('C', $2) + 64);
2013*d68f33bcSAndroid Build Coastguard Worker			$res .= $coded;
2014*d68f33bcSAndroid Build Coastguard Worker		}
2015*d68f33bcSAndroid Build Coastguard Worker	}
2016*d68f33bcSAndroid Build Coastguard Worker	$res =~ s/$/\$/;
2017*d68f33bcSAndroid Build Coastguard Worker
2018*d68f33bcSAndroid Build Coastguard Worker	return $res;
2019*d68f33bcSAndroid Build Coastguard Worker}
2020*d68f33bcSAndroid Build Coastguard Worker
2021*d68f33bcSAndroid Build Coastguard Workermy $av_preprocessor = 0;
2022*d68f33bcSAndroid Build Coastguard Workermy $av_pending;
2023*d68f33bcSAndroid Build Coastguard Workermy @av_paren_type;
2024*d68f33bcSAndroid Build Coastguard Workermy $av_pend_colon;
2025*d68f33bcSAndroid Build Coastguard Worker
2026*d68f33bcSAndroid Build Coastguard Workersub annotate_reset {
2027*d68f33bcSAndroid Build Coastguard Worker	$av_preprocessor = 0;
2028*d68f33bcSAndroid Build Coastguard Worker	$av_pending = '_';
2029*d68f33bcSAndroid Build Coastguard Worker	@av_paren_type = ('E');
2030*d68f33bcSAndroid Build Coastguard Worker	$av_pend_colon = 'O';
2031*d68f33bcSAndroid Build Coastguard Worker}
2032*d68f33bcSAndroid Build Coastguard Worker
2033*d68f33bcSAndroid Build Coastguard Workersub annotate_values {
2034*d68f33bcSAndroid Build Coastguard Worker	my ($stream, $type) = @_;
2035*d68f33bcSAndroid Build Coastguard Worker
2036*d68f33bcSAndroid Build Coastguard Worker	my $res;
2037*d68f33bcSAndroid Build Coastguard Worker	my $var = '_' x length($stream);
2038*d68f33bcSAndroid Build Coastguard Worker	my $cur = $stream;
2039*d68f33bcSAndroid Build Coastguard Worker
2040*d68f33bcSAndroid Build Coastguard Worker	print "$stream\n" if ($dbg_values > 1);
2041*d68f33bcSAndroid Build Coastguard Worker
2042*d68f33bcSAndroid Build Coastguard Worker	while (length($cur)) {
2043*d68f33bcSAndroid Build Coastguard Worker		@av_paren_type = ('E') if ($#av_paren_type < 0);
2044*d68f33bcSAndroid Build Coastguard Worker		print " <" . join('', @av_paren_type) .
2045*d68f33bcSAndroid Build Coastguard Worker				"> <$type> <$av_pending>" if ($dbg_values > 1);
2046*d68f33bcSAndroid Build Coastguard Worker		if ($cur =~ /^(\s+)/o) {
2047*d68f33bcSAndroid Build Coastguard Worker			print "WS($1)\n" if ($dbg_values > 1);
2048*d68f33bcSAndroid Build Coastguard Worker			if ($1 =~ /\n/ && $av_preprocessor) {
2049*d68f33bcSAndroid Build Coastguard Worker				$type = pop(@av_paren_type);
2050*d68f33bcSAndroid Build Coastguard Worker				$av_preprocessor = 0;
2051*d68f33bcSAndroid Build Coastguard Worker			}
2052*d68f33bcSAndroid Build Coastguard Worker
2053*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
2054*d68f33bcSAndroid Build Coastguard Worker			print "CAST($1)\n" if ($dbg_values > 1);
2055*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2056*d68f33bcSAndroid Build Coastguard Worker			$type = 'c';
2057*d68f33bcSAndroid Build Coastguard Worker
2058*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2059*d68f33bcSAndroid Build Coastguard Worker			print "DECLARE($1)\n" if ($dbg_values > 1);
2060*d68f33bcSAndroid Build Coastguard Worker			$type = 'T';
2061*d68f33bcSAndroid Build Coastguard Worker
2062*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Modifier)\s*/) {
2063*d68f33bcSAndroid Build Coastguard Worker			print "MODIFIER($1)\n" if ($dbg_values > 1);
2064*d68f33bcSAndroid Build Coastguard Worker			$type = 'T';
2065*d68f33bcSAndroid Build Coastguard Worker
2066*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2067*d68f33bcSAndroid Build Coastguard Worker			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2068*d68f33bcSAndroid Build Coastguard Worker			$av_preprocessor = 1;
2069*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2070*d68f33bcSAndroid Build Coastguard Worker			if ($2 ne '') {
2071*d68f33bcSAndroid Build Coastguard Worker				$av_pending = 'N';
2072*d68f33bcSAndroid Build Coastguard Worker			}
2073*d68f33bcSAndroid Build Coastguard Worker			$type = 'E';
2074*d68f33bcSAndroid Build Coastguard Worker
2075*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2076*d68f33bcSAndroid Build Coastguard Worker			print "UNDEF($1)\n" if ($dbg_values > 1);
2077*d68f33bcSAndroid Build Coastguard Worker			$av_preprocessor = 1;
2078*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2079*d68f33bcSAndroid Build Coastguard Worker
2080*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2081*d68f33bcSAndroid Build Coastguard Worker			print "PRE_START($1)\n" if ($dbg_values > 1);
2082*d68f33bcSAndroid Build Coastguard Worker			$av_preprocessor = 1;
2083*d68f33bcSAndroid Build Coastguard Worker
2084*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2085*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2086*d68f33bcSAndroid Build Coastguard Worker			$type = 'E';
2087*d68f33bcSAndroid Build Coastguard Worker
2088*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2089*d68f33bcSAndroid Build Coastguard Worker			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2090*d68f33bcSAndroid Build Coastguard Worker			$av_preprocessor = 1;
2091*d68f33bcSAndroid Build Coastguard Worker
2092*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2093*d68f33bcSAndroid Build Coastguard Worker
2094*d68f33bcSAndroid Build Coastguard Worker			$type = 'E';
2095*d68f33bcSAndroid Build Coastguard Worker
2096*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2097*d68f33bcSAndroid Build Coastguard Worker			print "PRE_END($1)\n" if ($dbg_values > 1);
2098*d68f33bcSAndroid Build Coastguard Worker
2099*d68f33bcSAndroid Build Coastguard Worker			$av_preprocessor = 1;
2100*d68f33bcSAndroid Build Coastguard Worker
2101*d68f33bcSAndroid Build Coastguard Worker			# Assume all arms of the conditional end as this
2102*d68f33bcSAndroid Build Coastguard Worker			# one does, and continue as if the #endif was not here.
2103*d68f33bcSAndroid Build Coastguard Worker			pop(@av_paren_type);
2104*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $type);
2105*d68f33bcSAndroid Build Coastguard Worker			$type = 'E';
2106*d68f33bcSAndroid Build Coastguard Worker
2107*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\\\n)/o) {
2108*d68f33bcSAndroid Build Coastguard Worker			print "PRECONT($1)\n" if ($dbg_values > 1);
2109*d68f33bcSAndroid Build Coastguard Worker
2110*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2111*d68f33bcSAndroid Build Coastguard Worker			print "ATTR($1)\n" if ($dbg_values > 1);
2112*d68f33bcSAndroid Build Coastguard Worker			$av_pending = $type;
2113*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2114*d68f33bcSAndroid Build Coastguard Worker
2115*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2116*d68f33bcSAndroid Build Coastguard Worker			print "SIZEOF($1)\n" if ($dbg_values > 1);
2117*d68f33bcSAndroid Build Coastguard Worker			if (defined $2) {
2118*d68f33bcSAndroid Build Coastguard Worker				$av_pending = 'V';
2119*d68f33bcSAndroid Build Coastguard Worker			}
2120*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2121*d68f33bcSAndroid Build Coastguard Worker
2122*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(if|while|for)\b/o) {
2123*d68f33bcSAndroid Build Coastguard Worker			print "COND($1)\n" if ($dbg_values > 1);
2124*d68f33bcSAndroid Build Coastguard Worker			$av_pending = 'E';
2125*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2126*d68f33bcSAndroid Build Coastguard Worker
2127*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~/^(case)/o) {
2128*d68f33bcSAndroid Build Coastguard Worker			print "CASE($1)\n" if ($dbg_values > 1);
2129*d68f33bcSAndroid Build Coastguard Worker			$av_pend_colon = 'C';
2130*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2131*d68f33bcSAndroid Build Coastguard Worker
2132*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2133*d68f33bcSAndroid Build Coastguard Worker			print "KEYWORD($1)\n" if ($dbg_values > 1);
2134*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2135*d68f33bcSAndroid Build Coastguard Worker
2136*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\()/o) {
2137*d68f33bcSAndroid Build Coastguard Worker			print "PAREN('$1')\n" if ($dbg_values > 1);
2138*d68f33bcSAndroid Build Coastguard Worker			push(@av_paren_type, $av_pending);
2139*d68f33bcSAndroid Build Coastguard Worker			$av_pending = '_';
2140*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2141*d68f33bcSAndroid Build Coastguard Worker
2142*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\))/o) {
2143*d68f33bcSAndroid Build Coastguard Worker			my $new_type = pop(@av_paren_type);
2144*d68f33bcSAndroid Build Coastguard Worker			if ($new_type ne '_') {
2145*d68f33bcSAndroid Build Coastguard Worker				$type = $new_type;
2146*d68f33bcSAndroid Build Coastguard Worker				print "PAREN('$1') -> $type\n"
2147*d68f33bcSAndroid Build Coastguard Worker							if ($dbg_values > 1);
2148*d68f33bcSAndroid Build Coastguard Worker			} else {
2149*d68f33bcSAndroid Build Coastguard Worker				print "PAREN('$1')\n" if ($dbg_values > 1);
2150*d68f33bcSAndroid Build Coastguard Worker			}
2151*d68f33bcSAndroid Build Coastguard Worker
2152*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2153*d68f33bcSAndroid Build Coastguard Worker			print "FUNC($1)\n" if ($dbg_values > 1);
2154*d68f33bcSAndroid Build Coastguard Worker			$type = 'V';
2155*d68f33bcSAndroid Build Coastguard Worker			$av_pending = 'V';
2156*d68f33bcSAndroid Build Coastguard Worker
2157*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
2158*d68f33bcSAndroid Build Coastguard Worker			if (defined $2 && $type eq 'C' || $type eq 'T') {
2159*d68f33bcSAndroid Build Coastguard Worker				$av_pend_colon = 'B';
2160*d68f33bcSAndroid Build Coastguard Worker			} elsif ($type eq 'E') {
2161*d68f33bcSAndroid Build Coastguard Worker				$av_pend_colon = 'L';
2162*d68f33bcSAndroid Build Coastguard Worker			}
2163*d68f33bcSAndroid Build Coastguard Worker			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
2164*d68f33bcSAndroid Build Coastguard Worker			$type = 'V';
2165*d68f33bcSAndroid Build Coastguard Worker
2166*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2167*d68f33bcSAndroid Build Coastguard Worker			print "IDENT($1)\n" if ($dbg_values > 1);
2168*d68f33bcSAndroid Build Coastguard Worker			$type = 'V';
2169*d68f33bcSAndroid Build Coastguard Worker
2170*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Assignment)/o) {
2171*d68f33bcSAndroid Build Coastguard Worker			print "ASSIGN($1)\n" if ($dbg_values > 1);
2172*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2173*d68f33bcSAndroid Build Coastguard Worker
2174*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~/^(;|{|})/) {
2175*d68f33bcSAndroid Build Coastguard Worker			print "END($1)\n" if ($dbg_values > 1);
2176*d68f33bcSAndroid Build Coastguard Worker			$type = 'E';
2177*d68f33bcSAndroid Build Coastguard Worker			$av_pend_colon = 'O';
2178*d68f33bcSAndroid Build Coastguard Worker
2179*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~/^(,)/) {
2180*d68f33bcSAndroid Build Coastguard Worker			print "COMMA($1)\n" if ($dbg_values > 1);
2181*d68f33bcSAndroid Build Coastguard Worker			$type = 'C';
2182*d68f33bcSAndroid Build Coastguard Worker
2183*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\?)/o) {
2184*d68f33bcSAndroid Build Coastguard Worker			print "QUESTION($1)\n" if ($dbg_values > 1);
2185*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2186*d68f33bcSAndroid Build Coastguard Worker
2187*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(:)/o) {
2188*d68f33bcSAndroid Build Coastguard Worker			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
2189*d68f33bcSAndroid Build Coastguard Worker
2190*d68f33bcSAndroid Build Coastguard Worker			substr($var, length($res), 1, $av_pend_colon);
2191*d68f33bcSAndroid Build Coastguard Worker			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
2192*d68f33bcSAndroid Build Coastguard Worker				$type = 'E';
2193*d68f33bcSAndroid Build Coastguard Worker			} else {
2194*d68f33bcSAndroid Build Coastguard Worker				$type = 'N';
2195*d68f33bcSAndroid Build Coastguard Worker			}
2196*d68f33bcSAndroid Build Coastguard Worker			$av_pend_colon = 'O';
2197*d68f33bcSAndroid Build Coastguard Worker
2198*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(\[)/o) {
2199*d68f33bcSAndroid Build Coastguard Worker			print "CLOSE($1)\n" if ($dbg_values > 1);
2200*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2201*d68f33bcSAndroid Build Coastguard Worker
2202*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
2203*d68f33bcSAndroid Build Coastguard Worker			my $variant;
2204*d68f33bcSAndroid Build Coastguard Worker
2205*d68f33bcSAndroid Build Coastguard Worker			print "OPV($1)\n" if ($dbg_values > 1);
2206*d68f33bcSAndroid Build Coastguard Worker			if ($type eq 'V') {
2207*d68f33bcSAndroid Build Coastguard Worker				$variant = 'B';
2208*d68f33bcSAndroid Build Coastguard Worker			} else {
2209*d68f33bcSAndroid Build Coastguard Worker				$variant = 'U';
2210*d68f33bcSAndroid Build Coastguard Worker			}
2211*d68f33bcSAndroid Build Coastguard Worker
2212*d68f33bcSAndroid Build Coastguard Worker			substr($var, length($res), 1, $variant);
2213*d68f33bcSAndroid Build Coastguard Worker			$type = 'N';
2214*d68f33bcSAndroid Build Coastguard Worker
2215*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /^($Operators)/o) {
2216*d68f33bcSAndroid Build Coastguard Worker			print "OP($1)\n" if ($dbg_values > 1);
2217*d68f33bcSAndroid Build Coastguard Worker			if ($1 ne '++' && $1 ne '--') {
2218*d68f33bcSAndroid Build Coastguard Worker				$type = 'N';
2219*d68f33bcSAndroid Build Coastguard Worker			}
2220*d68f33bcSAndroid Build Coastguard Worker
2221*d68f33bcSAndroid Build Coastguard Worker		} elsif ($cur =~ /(^.)/o) {
2222*d68f33bcSAndroid Build Coastguard Worker			print "C($1)\n" if ($dbg_values > 1);
2223*d68f33bcSAndroid Build Coastguard Worker		}
2224*d68f33bcSAndroid Build Coastguard Worker		if (defined $1) {
2225*d68f33bcSAndroid Build Coastguard Worker			$cur = substr($cur, length($1));
2226*d68f33bcSAndroid Build Coastguard Worker			$res .= $type x length($1);
2227*d68f33bcSAndroid Build Coastguard Worker		}
2228*d68f33bcSAndroid Build Coastguard Worker	}
2229*d68f33bcSAndroid Build Coastguard Worker
2230*d68f33bcSAndroid Build Coastguard Worker	return ($res, $var);
2231*d68f33bcSAndroid Build Coastguard Worker}
2232*d68f33bcSAndroid Build Coastguard Worker
2233*d68f33bcSAndroid Build Coastguard Workersub possible {
2234*d68f33bcSAndroid Build Coastguard Worker	my ($possible, $line) = @_;
2235*d68f33bcSAndroid Build Coastguard Worker	my $notPermitted = qr{(?:
2236*d68f33bcSAndroid Build Coastguard Worker		^(?:
2237*d68f33bcSAndroid Build Coastguard Worker			$Modifier|
2238*d68f33bcSAndroid Build Coastguard Worker			$Storage|
2239*d68f33bcSAndroid Build Coastguard Worker			$Type|
2240*d68f33bcSAndroid Build Coastguard Worker			DEFINE_\S+
2241*d68f33bcSAndroid Build Coastguard Worker		)$|
2242*d68f33bcSAndroid Build Coastguard Worker		^(?:
2243*d68f33bcSAndroid Build Coastguard Worker			goto|
2244*d68f33bcSAndroid Build Coastguard Worker			return|
2245*d68f33bcSAndroid Build Coastguard Worker			case|
2246*d68f33bcSAndroid Build Coastguard Worker			else|
2247*d68f33bcSAndroid Build Coastguard Worker			asm|__asm__|
2248*d68f33bcSAndroid Build Coastguard Worker			do|
2249*d68f33bcSAndroid Build Coastguard Worker			\#|
2250*d68f33bcSAndroid Build Coastguard Worker			\#\#|
2251*d68f33bcSAndroid Build Coastguard Worker		)(?:\s|$)|
2252*d68f33bcSAndroid Build Coastguard Worker		^(?:typedef|struct|enum)\b
2253*d68f33bcSAndroid Build Coastguard Worker	    )}x;
2254*d68f33bcSAndroid Build Coastguard Worker	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
2255*d68f33bcSAndroid Build Coastguard Worker	if ($possible !~ $notPermitted) {
2256*d68f33bcSAndroid Build Coastguard Worker		# Check for modifiers.
2257*d68f33bcSAndroid Build Coastguard Worker		$possible =~ s/\s*$Storage\s*//g;
2258*d68f33bcSAndroid Build Coastguard Worker		$possible =~ s/\s*$Sparse\s*//g;
2259*d68f33bcSAndroid Build Coastguard Worker		if ($possible =~ /^\s*$/) {
2260*d68f33bcSAndroid Build Coastguard Worker
2261*d68f33bcSAndroid Build Coastguard Worker		} elsif ($possible =~ /\s/) {
2262*d68f33bcSAndroid Build Coastguard Worker			$possible =~ s/\s*$Type\s*//g;
2263*d68f33bcSAndroid Build Coastguard Worker			for my $modifier (split(' ', $possible)) {
2264*d68f33bcSAndroid Build Coastguard Worker				if ($modifier !~ $notPermitted) {
2265*d68f33bcSAndroid Build Coastguard Worker					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2266*d68f33bcSAndroid Build Coastguard Worker					push(@modifierListFile, $modifier);
2267*d68f33bcSAndroid Build Coastguard Worker				}
2268*d68f33bcSAndroid Build Coastguard Worker			}
2269*d68f33bcSAndroid Build Coastguard Worker
2270*d68f33bcSAndroid Build Coastguard Worker		} else {
2271*d68f33bcSAndroid Build Coastguard Worker			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2272*d68f33bcSAndroid Build Coastguard Worker			push(@typeListFile, $possible);
2273*d68f33bcSAndroid Build Coastguard Worker		}
2274*d68f33bcSAndroid Build Coastguard Worker		build_types();
2275*d68f33bcSAndroid Build Coastguard Worker	} else {
2276*d68f33bcSAndroid Build Coastguard Worker		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
2277*d68f33bcSAndroid Build Coastguard Worker	}
2278*d68f33bcSAndroid Build Coastguard Worker}
2279*d68f33bcSAndroid Build Coastguard Worker
2280*d68f33bcSAndroid Build Coastguard Workermy $prefix = '';
2281*d68f33bcSAndroid Build Coastguard Worker
2282*d68f33bcSAndroid Build Coastguard Workersub show_type {
2283*d68f33bcSAndroid Build Coastguard Worker	my ($type) = @_;
2284*d68f33bcSAndroid Build Coastguard Worker
2285*d68f33bcSAndroid Build Coastguard Worker	$type =~ tr/[a-z]/[A-Z]/;
2286*d68f33bcSAndroid Build Coastguard Worker
2287*d68f33bcSAndroid Build Coastguard Worker	return defined $use_type{$type} if (scalar keys %use_type > 0);
2288*d68f33bcSAndroid Build Coastguard Worker
2289*d68f33bcSAndroid Build Coastguard Worker	return !defined $ignore_type{$type};
2290*d68f33bcSAndroid Build Coastguard Worker}
2291*d68f33bcSAndroid Build Coastguard Worker
2292*d68f33bcSAndroid Build Coastguard Workersub report {
2293*d68f33bcSAndroid Build Coastguard Worker	my ($level, $type, $msg) = @_;
2294*d68f33bcSAndroid Build Coastguard Worker
2295*d68f33bcSAndroid Build Coastguard Worker	if (!show_type($type) ||
2296*d68f33bcSAndroid Build Coastguard Worker	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2297*d68f33bcSAndroid Build Coastguard Worker		return 0;
2298*d68f33bcSAndroid Build Coastguard Worker	}
2299*d68f33bcSAndroid Build Coastguard Worker	my $output = '';
2300*d68f33bcSAndroid Build Coastguard Worker	if ($color) {
2301*d68f33bcSAndroid Build Coastguard Worker		if ($level eq 'ERROR') {
2302*d68f33bcSAndroid Build Coastguard Worker			$output .= RED;
2303*d68f33bcSAndroid Build Coastguard Worker		} elsif ($level eq 'WARNING') {
2304*d68f33bcSAndroid Build Coastguard Worker			$output .= YELLOW;
2305*d68f33bcSAndroid Build Coastguard Worker		} else {
2306*d68f33bcSAndroid Build Coastguard Worker			$output .= GREEN;
2307*d68f33bcSAndroid Build Coastguard Worker		}
2308*d68f33bcSAndroid Build Coastguard Worker	}
2309*d68f33bcSAndroid Build Coastguard Worker	$output .= $prefix . $level . ':';
2310*d68f33bcSAndroid Build Coastguard Worker	if ($show_types) {
2311*d68f33bcSAndroid Build Coastguard Worker		$output .= BLUE if ($color);
2312*d68f33bcSAndroid Build Coastguard Worker		$output .= "$type:";
2313*d68f33bcSAndroid Build Coastguard Worker	}
2314*d68f33bcSAndroid Build Coastguard Worker	$output .= RESET if ($color);
2315*d68f33bcSAndroid Build Coastguard Worker	$output .= ' ' . $msg . "\n";
2316*d68f33bcSAndroid Build Coastguard Worker
2317*d68f33bcSAndroid Build Coastguard Worker	if ($showfile) {
2318*d68f33bcSAndroid Build Coastguard Worker		my @lines = split("\n", $output, -1);
2319*d68f33bcSAndroid Build Coastguard Worker		splice(@lines, 1, 1);
2320*d68f33bcSAndroid Build Coastguard Worker		$output = join("\n", @lines);
2321*d68f33bcSAndroid Build Coastguard Worker	}
2322*d68f33bcSAndroid Build Coastguard Worker
2323*d68f33bcSAndroid Build Coastguard Worker	if ($terse) {
2324*d68f33bcSAndroid Build Coastguard Worker		$output = (split('\n', $output))[0] . "\n";
2325*d68f33bcSAndroid Build Coastguard Worker	}
2326*d68f33bcSAndroid Build Coastguard Worker
2327*d68f33bcSAndroid Build Coastguard Worker	if ($verbose && exists($verbose_messages{$type}) &&
2328*d68f33bcSAndroid Build Coastguard Worker	    !exists($verbose_emitted{$type})) {
2329*d68f33bcSAndroid Build Coastguard Worker		$output .= $verbose_messages{$type} . "\n\n";
2330*d68f33bcSAndroid Build Coastguard Worker		$verbose_emitted{$type} = 1;
2331*d68f33bcSAndroid Build Coastguard Worker	}
2332*d68f33bcSAndroid Build Coastguard Worker
2333*d68f33bcSAndroid Build Coastguard Worker	push(our @report, $output);
2334*d68f33bcSAndroid Build Coastguard Worker
2335*d68f33bcSAndroid Build Coastguard Worker	return 1;
2336*d68f33bcSAndroid Build Coastguard Worker}
2337*d68f33bcSAndroid Build Coastguard Worker
2338*d68f33bcSAndroid Build Coastguard Workersub report_dump {
2339*d68f33bcSAndroid Build Coastguard Worker	our @report;
2340*d68f33bcSAndroid Build Coastguard Worker}
2341*d68f33bcSAndroid Build Coastguard Worker
2342*d68f33bcSAndroid Build Coastguard Workersub fixup_current_range {
2343*d68f33bcSAndroid Build Coastguard Worker	my ($lineRef, $offset, $length) = @_;
2344*d68f33bcSAndroid Build Coastguard Worker
2345*d68f33bcSAndroid Build Coastguard Worker	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2346*d68f33bcSAndroid Build Coastguard Worker		my $o = $1;
2347*d68f33bcSAndroid Build Coastguard Worker		my $l = $2;
2348*d68f33bcSAndroid Build Coastguard Worker		my $no = $o + $offset;
2349*d68f33bcSAndroid Build Coastguard Worker		my $nl = $l + $length;
2350*d68f33bcSAndroid Build Coastguard Worker		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2351*d68f33bcSAndroid Build Coastguard Worker	}
2352*d68f33bcSAndroid Build Coastguard Worker}
2353*d68f33bcSAndroid Build Coastguard Worker
2354*d68f33bcSAndroid Build Coastguard Workersub fix_inserted_deleted_lines {
2355*d68f33bcSAndroid Build Coastguard Worker	my ($linesRef, $insertedRef, $deletedRef) = @_;
2356*d68f33bcSAndroid Build Coastguard Worker
2357*d68f33bcSAndroid Build Coastguard Worker	my $range_last_linenr = 0;
2358*d68f33bcSAndroid Build Coastguard Worker	my $delta_offset = 0;
2359*d68f33bcSAndroid Build Coastguard Worker
2360*d68f33bcSAndroid Build Coastguard Worker	my $old_linenr = 0;
2361*d68f33bcSAndroid Build Coastguard Worker	my $new_linenr = 0;
2362*d68f33bcSAndroid Build Coastguard Worker
2363*d68f33bcSAndroid Build Coastguard Worker	my $next_insert = 0;
2364*d68f33bcSAndroid Build Coastguard Worker	my $next_delete = 0;
2365*d68f33bcSAndroid Build Coastguard Worker
2366*d68f33bcSAndroid Build Coastguard Worker	my @lines = ();
2367*d68f33bcSAndroid Build Coastguard Worker
2368*d68f33bcSAndroid Build Coastguard Worker	my $inserted = @{$insertedRef}[$next_insert++];
2369*d68f33bcSAndroid Build Coastguard Worker	my $deleted = @{$deletedRef}[$next_delete++];
2370*d68f33bcSAndroid Build Coastguard Worker
2371*d68f33bcSAndroid Build Coastguard Worker	foreach my $old_line (@{$linesRef}) {
2372*d68f33bcSAndroid Build Coastguard Worker		my $save_line = 1;
2373*d68f33bcSAndroid Build Coastguard Worker		my $line = $old_line;	#don't modify the array
2374*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2375*d68f33bcSAndroid Build Coastguard Worker			$delta_offset = 0;
2376*d68f33bcSAndroid Build Coastguard Worker		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2377*d68f33bcSAndroid Build Coastguard Worker			$range_last_linenr = $new_linenr;
2378*d68f33bcSAndroid Build Coastguard Worker			fixup_current_range(\$line, $delta_offset, 0);
2379*d68f33bcSAndroid Build Coastguard Worker		}
2380*d68f33bcSAndroid Build Coastguard Worker
2381*d68f33bcSAndroid Build Coastguard Worker		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2382*d68f33bcSAndroid Build Coastguard Worker			$deleted = @{$deletedRef}[$next_delete++];
2383*d68f33bcSAndroid Build Coastguard Worker			$save_line = 0;
2384*d68f33bcSAndroid Build Coastguard Worker			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2385*d68f33bcSAndroid Build Coastguard Worker		}
2386*d68f33bcSAndroid Build Coastguard Worker
2387*d68f33bcSAndroid Build Coastguard Worker		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2388*d68f33bcSAndroid Build Coastguard Worker			push(@lines, ${$inserted}{'LINE'});
2389*d68f33bcSAndroid Build Coastguard Worker			$inserted = @{$insertedRef}[$next_insert++];
2390*d68f33bcSAndroid Build Coastguard Worker			$new_linenr++;
2391*d68f33bcSAndroid Build Coastguard Worker			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2392*d68f33bcSAndroid Build Coastguard Worker		}
2393*d68f33bcSAndroid Build Coastguard Worker
2394*d68f33bcSAndroid Build Coastguard Worker		if ($save_line) {
2395*d68f33bcSAndroid Build Coastguard Worker			push(@lines, $line);
2396*d68f33bcSAndroid Build Coastguard Worker			$new_linenr++;
2397*d68f33bcSAndroid Build Coastguard Worker		}
2398*d68f33bcSAndroid Build Coastguard Worker
2399*d68f33bcSAndroid Build Coastguard Worker		$old_linenr++;
2400*d68f33bcSAndroid Build Coastguard Worker	}
2401*d68f33bcSAndroid Build Coastguard Worker
2402*d68f33bcSAndroid Build Coastguard Worker	return @lines;
2403*d68f33bcSAndroid Build Coastguard Worker}
2404*d68f33bcSAndroid Build Coastguard Worker
2405*d68f33bcSAndroid Build Coastguard Workersub fix_insert_line {
2406*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $line) = @_;
2407*d68f33bcSAndroid Build Coastguard Worker
2408*d68f33bcSAndroid Build Coastguard Worker	my $inserted = {
2409*d68f33bcSAndroid Build Coastguard Worker		LINENR => $linenr,
2410*d68f33bcSAndroid Build Coastguard Worker		LINE => $line,
2411*d68f33bcSAndroid Build Coastguard Worker	};
2412*d68f33bcSAndroid Build Coastguard Worker	push(@fixed_inserted, $inserted);
2413*d68f33bcSAndroid Build Coastguard Worker}
2414*d68f33bcSAndroid Build Coastguard Worker
2415*d68f33bcSAndroid Build Coastguard Workersub fix_delete_line {
2416*d68f33bcSAndroid Build Coastguard Worker	my ($linenr, $line) = @_;
2417*d68f33bcSAndroid Build Coastguard Worker
2418*d68f33bcSAndroid Build Coastguard Worker	my $deleted = {
2419*d68f33bcSAndroid Build Coastguard Worker		LINENR => $linenr,
2420*d68f33bcSAndroid Build Coastguard Worker		LINE => $line,
2421*d68f33bcSAndroid Build Coastguard Worker	};
2422*d68f33bcSAndroid Build Coastguard Worker
2423*d68f33bcSAndroid Build Coastguard Worker	push(@fixed_deleted, $deleted);
2424*d68f33bcSAndroid Build Coastguard Worker}
2425*d68f33bcSAndroid Build Coastguard Worker
2426*d68f33bcSAndroid Build Coastguard Workersub ERROR {
2427*d68f33bcSAndroid Build Coastguard Worker	my ($type, $msg) = @_;
2428*d68f33bcSAndroid Build Coastguard Worker
2429*d68f33bcSAndroid Build Coastguard Worker	if (report("ERROR", $type, $msg)) {
2430*d68f33bcSAndroid Build Coastguard Worker		our $clean = 0;
2431*d68f33bcSAndroid Build Coastguard Worker		our $cnt_error++;
2432*d68f33bcSAndroid Build Coastguard Worker		return 1;
2433*d68f33bcSAndroid Build Coastguard Worker	}
2434*d68f33bcSAndroid Build Coastguard Worker	return 0;
2435*d68f33bcSAndroid Build Coastguard Worker}
2436*d68f33bcSAndroid Build Coastguard Workersub WARN {
2437*d68f33bcSAndroid Build Coastguard Worker	my ($type, $msg) = @_;
2438*d68f33bcSAndroid Build Coastguard Worker
2439*d68f33bcSAndroid Build Coastguard Worker	if (report("WARNING", $type, $msg)) {
2440*d68f33bcSAndroid Build Coastguard Worker		our $clean = 0;
2441*d68f33bcSAndroid Build Coastguard Worker		our $cnt_warn++;
2442*d68f33bcSAndroid Build Coastguard Worker		return 1;
2443*d68f33bcSAndroid Build Coastguard Worker	}
2444*d68f33bcSAndroid Build Coastguard Worker	return 0;
2445*d68f33bcSAndroid Build Coastguard Worker}
2446*d68f33bcSAndroid Build Coastguard Workersub CHK {
2447*d68f33bcSAndroid Build Coastguard Worker	my ($type, $msg) = @_;
2448*d68f33bcSAndroid Build Coastguard Worker
2449*d68f33bcSAndroid Build Coastguard Worker	if ($check && report("CHECK", $type, $msg)) {
2450*d68f33bcSAndroid Build Coastguard Worker		our $clean = 0;
2451*d68f33bcSAndroid Build Coastguard Worker		our $cnt_chk++;
2452*d68f33bcSAndroid Build Coastguard Worker		return 1;
2453*d68f33bcSAndroid Build Coastguard Worker	}
2454*d68f33bcSAndroid Build Coastguard Worker	return 0;
2455*d68f33bcSAndroid Build Coastguard Worker}
2456*d68f33bcSAndroid Build Coastguard Worker
2457*d68f33bcSAndroid Build Coastguard Workersub check_absolute_file {
2458*d68f33bcSAndroid Build Coastguard Worker	my ($absolute, $herecurr) = @_;
2459*d68f33bcSAndroid Build Coastguard Worker	my $file = $absolute;
2460*d68f33bcSAndroid Build Coastguard Worker
2461*d68f33bcSAndroid Build Coastguard Worker	##print "absolute<$absolute>\n";
2462*d68f33bcSAndroid Build Coastguard Worker
2463*d68f33bcSAndroid Build Coastguard Worker	# See if any suffix of this path is a path within the tree.
2464*d68f33bcSAndroid Build Coastguard Worker	while ($file =~ s@^[^/]*/@@) {
2465*d68f33bcSAndroid Build Coastguard Worker		if (-f "$root/$file") {
2466*d68f33bcSAndroid Build Coastguard Worker			##print "file<$file>\n";
2467*d68f33bcSAndroid Build Coastguard Worker			last;
2468*d68f33bcSAndroid Build Coastguard Worker		}
2469*d68f33bcSAndroid Build Coastguard Worker	}
2470*d68f33bcSAndroid Build Coastguard Worker	if (! -f _)  {
2471*d68f33bcSAndroid Build Coastguard Worker		return 0;
2472*d68f33bcSAndroid Build Coastguard Worker	}
2473*d68f33bcSAndroid Build Coastguard Worker
2474*d68f33bcSAndroid Build Coastguard Worker	# It is, so see if the prefix is acceptable.
2475*d68f33bcSAndroid Build Coastguard Worker	my $prefix = $absolute;
2476*d68f33bcSAndroid Build Coastguard Worker	substr($prefix, -length($file)) = '';
2477*d68f33bcSAndroid Build Coastguard Worker
2478*d68f33bcSAndroid Build Coastguard Worker	##print "prefix<$prefix>\n";
2479*d68f33bcSAndroid Build Coastguard Worker	if ($prefix ne ".../") {
2480*d68f33bcSAndroid Build Coastguard Worker		WARN("USE_RELATIVE_PATH",
2481*d68f33bcSAndroid Build Coastguard Worker		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2482*d68f33bcSAndroid Build Coastguard Worker	}
2483*d68f33bcSAndroid Build Coastguard Worker}
2484*d68f33bcSAndroid Build Coastguard Worker
2485*d68f33bcSAndroid Build Coastguard Workersub trim {
2486*d68f33bcSAndroid Build Coastguard Worker	my ($string) = @_;
2487*d68f33bcSAndroid Build Coastguard Worker
2488*d68f33bcSAndroid Build Coastguard Worker	$string =~ s/^\s+|\s+$//g;
2489*d68f33bcSAndroid Build Coastguard Worker
2490*d68f33bcSAndroid Build Coastguard Worker	return $string;
2491*d68f33bcSAndroid Build Coastguard Worker}
2492*d68f33bcSAndroid Build Coastguard Worker
2493*d68f33bcSAndroid Build Coastguard Workersub ltrim {
2494*d68f33bcSAndroid Build Coastguard Worker	my ($string) = @_;
2495*d68f33bcSAndroid Build Coastguard Worker
2496*d68f33bcSAndroid Build Coastguard Worker	$string =~ s/^\s+//;
2497*d68f33bcSAndroid Build Coastguard Worker
2498*d68f33bcSAndroid Build Coastguard Worker	return $string;
2499*d68f33bcSAndroid Build Coastguard Worker}
2500*d68f33bcSAndroid Build Coastguard Worker
2501*d68f33bcSAndroid Build Coastguard Workersub rtrim {
2502*d68f33bcSAndroid Build Coastguard Worker	my ($string) = @_;
2503*d68f33bcSAndroid Build Coastguard Worker
2504*d68f33bcSAndroid Build Coastguard Worker	$string =~ s/\s+$//;
2505*d68f33bcSAndroid Build Coastguard Worker
2506*d68f33bcSAndroid Build Coastguard Worker	return $string;
2507*d68f33bcSAndroid Build Coastguard Worker}
2508*d68f33bcSAndroid Build Coastguard Worker
2509*d68f33bcSAndroid Build Coastguard Workersub string_find_replace {
2510*d68f33bcSAndroid Build Coastguard Worker	my ($string, $find, $replace) = @_;
2511*d68f33bcSAndroid Build Coastguard Worker
2512*d68f33bcSAndroid Build Coastguard Worker	$string =~ s/$find/$replace/g;
2513*d68f33bcSAndroid Build Coastguard Worker
2514*d68f33bcSAndroid Build Coastguard Worker	return $string;
2515*d68f33bcSAndroid Build Coastguard Worker}
2516*d68f33bcSAndroid Build Coastguard Worker
2517*d68f33bcSAndroid Build Coastguard Workersub tabify {
2518*d68f33bcSAndroid Build Coastguard Worker	my ($leading) = @_;
2519*d68f33bcSAndroid Build Coastguard Worker
2520*d68f33bcSAndroid Build Coastguard Worker	my $source_indent = $tabsize;
2521*d68f33bcSAndroid Build Coastguard Worker	my $max_spaces_before_tab = $source_indent - 1;
2522*d68f33bcSAndroid Build Coastguard Worker	my $spaces_to_tab = " " x $source_indent;
2523*d68f33bcSAndroid Build Coastguard Worker
2524*d68f33bcSAndroid Build Coastguard Worker	#convert leading spaces to tabs
2525*d68f33bcSAndroid Build Coastguard Worker	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2526*d68f33bcSAndroid Build Coastguard Worker	#Remove spaces before a tab
2527*d68f33bcSAndroid Build Coastguard Worker	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2528*d68f33bcSAndroid Build Coastguard Worker
2529*d68f33bcSAndroid Build Coastguard Worker	return "$leading";
2530*d68f33bcSAndroid Build Coastguard Worker}
2531*d68f33bcSAndroid Build Coastguard Worker
2532*d68f33bcSAndroid Build Coastguard Workersub pos_last_openparen {
2533*d68f33bcSAndroid Build Coastguard Worker	my ($line) = @_;
2534*d68f33bcSAndroid Build Coastguard Worker
2535*d68f33bcSAndroid Build Coastguard Worker	my $pos = 0;
2536*d68f33bcSAndroid Build Coastguard Worker
2537*d68f33bcSAndroid Build Coastguard Worker	my $opens = $line =~ tr/\(/\(/;
2538*d68f33bcSAndroid Build Coastguard Worker	my $closes = $line =~ tr/\)/\)/;
2539*d68f33bcSAndroid Build Coastguard Worker
2540*d68f33bcSAndroid Build Coastguard Worker	my $last_openparen = 0;
2541*d68f33bcSAndroid Build Coastguard Worker
2542*d68f33bcSAndroid Build Coastguard Worker	if (($opens == 0) || ($closes >= $opens)) {
2543*d68f33bcSAndroid Build Coastguard Worker		return -1;
2544*d68f33bcSAndroid Build Coastguard Worker	}
2545*d68f33bcSAndroid Build Coastguard Worker
2546*d68f33bcSAndroid Build Coastguard Worker	my $len = length($line);
2547*d68f33bcSAndroid Build Coastguard Worker
2548*d68f33bcSAndroid Build Coastguard Worker	for ($pos = 0; $pos < $len; $pos++) {
2549*d68f33bcSAndroid Build Coastguard Worker		my $string = substr($line, $pos);
2550*d68f33bcSAndroid Build Coastguard Worker		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2551*d68f33bcSAndroid Build Coastguard Worker			$pos += length($1) - 1;
2552*d68f33bcSAndroid Build Coastguard Worker		} elsif (substr($line, $pos, 1) eq '(') {
2553*d68f33bcSAndroid Build Coastguard Worker			$last_openparen = $pos;
2554*d68f33bcSAndroid Build Coastguard Worker		} elsif (index($string, '(') == -1) {
2555*d68f33bcSAndroid Build Coastguard Worker			last;
2556*d68f33bcSAndroid Build Coastguard Worker		}
2557*d68f33bcSAndroid Build Coastguard Worker	}
2558*d68f33bcSAndroid Build Coastguard Worker
2559*d68f33bcSAndroid Build Coastguard Worker	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2560*d68f33bcSAndroid Build Coastguard Worker}
2561*d68f33bcSAndroid Build Coastguard Worker
2562*d68f33bcSAndroid Build Coastguard Workersub get_raw_comment {
2563*d68f33bcSAndroid Build Coastguard Worker	my ($line, $rawline) = @_;
2564*d68f33bcSAndroid Build Coastguard Worker	my $comment = '';
2565*d68f33bcSAndroid Build Coastguard Worker
2566*d68f33bcSAndroid Build Coastguard Worker	for my $i (0 .. (length($line) - 1)) {
2567*d68f33bcSAndroid Build Coastguard Worker		if (substr($line, $i, 1) eq "$;") {
2568*d68f33bcSAndroid Build Coastguard Worker			$comment .= substr($rawline, $i, 1);
2569*d68f33bcSAndroid Build Coastguard Worker		}
2570*d68f33bcSAndroid Build Coastguard Worker	}
2571*d68f33bcSAndroid Build Coastguard Worker
2572*d68f33bcSAndroid Build Coastguard Worker	return $comment;
2573*d68f33bcSAndroid Build Coastguard Worker}
2574*d68f33bcSAndroid Build Coastguard Worker
2575*d68f33bcSAndroid Build Coastguard Workersub exclude_global_initialisers {
2576*d68f33bcSAndroid Build Coastguard Worker	my ($realfile) = @_;
2577*d68f33bcSAndroid Build Coastguard Worker
2578*d68f33bcSAndroid Build Coastguard Worker	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
2579*d68f33bcSAndroid Build Coastguard Worker	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
2580*d68f33bcSAndroid Build Coastguard Worker		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
2581*d68f33bcSAndroid Build Coastguard Worker		$realfile =~ m@/bpf/.*\.bpf\.c$@;
2582*d68f33bcSAndroid Build Coastguard Worker}
2583*d68f33bcSAndroid Build Coastguard Worker
2584*d68f33bcSAndroid Build Coastguard Workersub process {
2585*d68f33bcSAndroid Build Coastguard Worker	my $filename = shift;
2586*d68f33bcSAndroid Build Coastguard Worker
2587*d68f33bcSAndroid Build Coastguard Worker	my $linenr=0;
2588*d68f33bcSAndroid Build Coastguard Worker	my $prevline="";
2589*d68f33bcSAndroid Build Coastguard Worker	my $prevrawline="";
2590*d68f33bcSAndroid Build Coastguard Worker	my $stashline="";
2591*d68f33bcSAndroid Build Coastguard Worker	my $stashrawline="";
2592*d68f33bcSAndroid Build Coastguard Worker
2593*d68f33bcSAndroid Build Coastguard Worker	my $length;
2594*d68f33bcSAndroid Build Coastguard Worker	my $indent;
2595*d68f33bcSAndroid Build Coastguard Worker	my $previndent=0;
2596*d68f33bcSAndroid Build Coastguard Worker	my $stashindent=0;
2597*d68f33bcSAndroid Build Coastguard Worker
2598*d68f33bcSAndroid Build Coastguard Worker	our $clean = 1;
2599*d68f33bcSAndroid Build Coastguard Worker	my $signoff = 0;
2600*d68f33bcSAndroid Build Coastguard Worker	my $author = '';
2601*d68f33bcSAndroid Build Coastguard Worker	my $authorsignoff = 0;
2602*d68f33bcSAndroid Build Coastguard Worker	my $author_sob = '';
2603*d68f33bcSAndroid Build Coastguard Worker	my $is_patch = 0;
2604*d68f33bcSAndroid Build Coastguard Worker	my $is_binding_patch = -1;
2605*d68f33bcSAndroid Build Coastguard Worker	my $in_header_lines = $file ? 0 : 1;
2606*d68f33bcSAndroid Build Coastguard Worker	my $in_commit_log = 0;		#Scanning lines before patch
2607*d68f33bcSAndroid Build Coastguard Worker	my $has_patch_separator = 0;	#Found a --- line
2608*d68f33bcSAndroid Build Coastguard Worker	my $has_commit_log = 0;		#Encountered lines before patch
2609*d68f33bcSAndroid Build Coastguard Worker	my $commit_log_lines = 0;	#Number of commit log lines
2610*d68f33bcSAndroid Build Coastguard Worker	my $commit_log_possible_stack_dump = 0;
2611*d68f33bcSAndroid Build Coastguard Worker	my $commit_log_long_line = 0;
2612*d68f33bcSAndroid Build Coastguard Worker	my $commit_log_has_diff = 0;
2613*d68f33bcSAndroid Build Coastguard Worker	my $reported_maintainer_file = 0;
2614*d68f33bcSAndroid Build Coastguard Worker	my $non_utf8_charset = 0;
2615*d68f33bcSAndroid Build Coastguard Worker
2616*d68f33bcSAndroid Build Coastguard Worker	my $last_git_commit_id_linenr = -1;
2617*d68f33bcSAndroid Build Coastguard Worker
2618*d68f33bcSAndroid Build Coastguard Worker	my $last_blank_line = 0;
2619*d68f33bcSAndroid Build Coastguard Worker	my $last_coalesced_string_linenr = -1;
2620*d68f33bcSAndroid Build Coastguard Worker
2621*d68f33bcSAndroid Build Coastguard Worker	our @report = ();
2622*d68f33bcSAndroid Build Coastguard Worker	our $cnt_lines = 0;
2623*d68f33bcSAndroid Build Coastguard Worker	our $cnt_error = 0;
2624*d68f33bcSAndroid Build Coastguard Worker	our $cnt_warn = 0;
2625*d68f33bcSAndroid Build Coastguard Worker	our $cnt_chk = 0;
2626*d68f33bcSAndroid Build Coastguard Worker
2627*d68f33bcSAndroid Build Coastguard Worker	# Trace the real file/line as we go.
2628*d68f33bcSAndroid Build Coastguard Worker	my $realfile = '';
2629*d68f33bcSAndroid Build Coastguard Worker	my $realline = 0;
2630*d68f33bcSAndroid Build Coastguard Worker	my $realcnt = 0;
2631*d68f33bcSAndroid Build Coastguard Worker	my $here = '';
2632*d68f33bcSAndroid Build Coastguard Worker	my $context_function;		#undef'd unless there's a known function
2633*d68f33bcSAndroid Build Coastguard Worker	my $in_comment = 0;
2634*d68f33bcSAndroid Build Coastguard Worker	my $comment_edge = 0;
2635*d68f33bcSAndroid Build Coastguard Worker	my $first_line = 0;
2636*d68f33bcSAndroid Build Coastguard Worker	my $p1_prefix = '';
2637*d68f33bcSAndroid Build Coastguard Worker
2638*d68f33bcSAndroid Build Coastguard Worker	my $prev_values = 'E';
2639*d68f33bcSAndroid Build Coastguard Worker
2640*d68f33bcSAndroid Build Coastguard Worker	# suppression flags
2641*d68f33bcSAndroid Build Coastguard Worker	my %suppress_ifbraces;
2642*d68f33bcSAndroid Build Coastguard Worker	my %suppress_whiletrailers;
2643*d68f33bcSAndroid Build Coastguard Worker	my %suppress_export;
2644*d68f33bcSAndroid Build Coastguard Worker	my $suppress_statement = 0;
2645*d68f33bcSAndroid Build Coastguard Worker
2646*d68f33bcSAndroid Build Coastguard Worker	my %signatures = ();
2647*d68f33bcSAndroid Build Coastguard Worker
2648*d68f33bcSAndroid Build Coastguard Worker	# Pre-scan the patch sanitizing the lines.
2649*d68f33bcSAndroid Build Coastguard Worker	# Pre-scan the patch looking for any __setup documentation.
2650*d68f33bcSAndroid Build Coastguard Worker	#
2651*d68f33bcSAndroid Build Coastguard Worker	my @setup_docs = ();
2652*d68f33bcSAndroid Build Coastguard Worker	my $setup_docs = 0;
2653*d68f33bcSAndroid Build Coastguard Worker
2654*d68f33bcSAndroid Build Coastguard Worker	my $camelcase_file_seeded = 0;
2655*d68f33bcSAndroid Build Coastguard Worker
2656*d68f33bcSAndroid Build Coastguard Worker	my $checklicenseline = 1;
2657*d68f33bcSAndroid Build Coastguard Worker
2658*d68f33bcSAndroid Build Coastguard Worker	sanitise_line_reset();
2659*d68f33bcSAndroid Build Coastguard Worker	my $line;
2660*d68f33bcSAndroid Build Coastguard Worker	foreach my $rawline (@rawlines) {
2661*d68f33bcSAndroid Build Coastguard Worker		$linenr++;
2662*d68f33bcSAndroid Build Coastguard Worker		$line = $rawline;
2663*d68f33bcSAndroid Build Coastguard Worker
2664*d68f33bcSAndroid Build Coastguard Worker		push(@fixed, $rawline) if ($fix);
2665*d68f33bcSAndroid Build Coastguard Worker
2666*d68f33bcSAndroid Build Coastguard Worker		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2667*d68f33bcSAndroid Build Coastguard Worker			$setup_docs = 0;
2668*d68f33bcSAndroid Build Coastguard Worker			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2669*d68f33bcSAndroid Build Coastguard Worker				$setup_docs = 1;
2670*d68f33bcSAndroid Build Coastguard Worker			}
2671*d68f33bcSAndroid Build Coastguard Worker			#next;
2672*d68f33bcSAndroid Build Coastguard Worker		}
2673*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2674*d68f33bcSAndroid Build Coastguard Worker			$realline=$1-1;
2675*d68f33bcSAndroid Build Coastguard Worker			if (defined $2) {
2676*d68f33bcSAndroid Build Coastguard Worker				$realcnt=$3+1;
2677*d68f33bcSAndroid Build Coastguard Worker			} else {
2678*d68f33bcSAndroid Build Coastguard Worker				$realcnt=1+1;
2679*d68f33bcSAndroid Build Coastguard Worker			}
2680*d68f33bcSAndroid Build Coastguard Worker			$in_comment = 0;
2681*d68f33bcSAndroid Build Coastguard Worker
2682*d68f33bcSAndroid Build Coastguard Worker			# Guestimate if this is a continuing comment.  Run
2683*d68f33bcSAndroid Build Coastguard Worker			# the context looking for a comment "edge".  If this
2684*d68f33bcSAndroid Build Coastguard Worker			# edge is a close comment then we must be in a comment
2685*d68f33bcSAndroid Build Coastguard Worker			# at context start.
2686*d68f33bcSAndroid Build Coastguard Worker			my $edge;
2687*d68f33bcSAndroid Build Coastguard Worker			my $cnt = $realcnt;
2688*d68f33bcSAndroid Build Coastguard Worker			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2689*d68f33bcSAndroid Build Coastguard Worker				next if (defined $rawlines[$ln - 1] &&
2690*d68f33bcSAndroid Build Coastguard Worker					 $rawlines[$ln - 1] =~ /^-/);
2691*d68f33bcSAndroid Build Coastguard Worker				$cnt--;
2692*d68f33bcSAndroid Build Coastguard Worker				#print "RAW<$rawlines[$ln - 1]>\n";
2693*d68f33bcSAndroid Build Coastguard Worker				last if (!defined $rawlines[$ln - 1]);
2694*d68f33bcSAndroid Build Coastguard Worker				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2695*d68f33bcSAndroid Build Coastguard Worker				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2696*d68f33bcSAndroid Build Coastguard Worker					($edge) = $1;
2697*d68f33bcSAndroid Build Coastguard Worker					last;
2698*d68f33bcSAndroid Build Coastguard Worker				}
2699*d68f33bcSAndroid Build Coastguard Worker			}
2700*d68f33bcSAndroid Build Coastguard Worker			if (defined $edge && $edge eq '*/') {
2701*d68f33bcSAndroid Build Coastguard Worker				$in_comment = 1;
2702*d68f33bcSAndroid Build Coastguard Worker			}
2703*d68f33bcSAndroid Build Coastguard Worker
2704*d68f33bcSAndroid Build Coastguard Worker			# Guestimate if this is a continuing comment.  If this
2705*d68f33bcSAndroid Build Coastguard Worker			# is the start of a diff block and this line starts
2706*d68f33bcSAndroid Build Coastguard Worker			# ' *' then it is very likely a comment.
2707*d68f33bcSAndroid Build Coastguard Worker			if (!defined $edge &&
2708*d68f33bcSAndroid Build Coastguard Worker			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2709*d68f33bcSAndroid Build Coastguard Worker			{
2710*d68f33bcSAndroid Build Coastguard Worker				$in_comment = 1;
2711*d68f33bcSAndroid Build Coastguard Worker			}
2712*d68f33bcSAndroid Build Coastguard Worker
2713*d68f33bcSAndroid Build Coastguard Worker			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2714*d68f33bcSAndroid Build Coastguard Worker			sanitise_line_reset($in_comment);
2715*d68f33bcSAndroid Build Coastguard Worker
2716*d68f33bcSAndroid Build Coastguard Worker		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2717*d68f33bcSAndroid Build Coastguard Worker			# Standardise the strings and chars within the input to
2718*d68f33bcSAndroid Build Coastguard Worker			# simplify matching -- only bother with positive lines.
2719*d68f33bcSAndroid Build Coastguard Worker			$line = sanitise_line($rawline);
2720*d68f33bcSAndroid Build Coastguard Worker		}
2721*d68f33bcSAndroid Build Coastguard Worker		push(@lines, $line);
2722*d68f33bcSAndroid Build Coastguard Worker
2723*d68f33bcSAndroid Build Coastguard Worker		if ($realcnt > 1) {
2724*d68f33bcSAndroid Build Coastguard Worker			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2725*d68f33bcSAndroid Build Coastguard Worker		} else {
2726*d68f33bcSAndroid Build Coastguard Worker			$realcnt = 0;
2727*d68f33bcSAndroid Build Coastguard Worker		}
2728*d68f33bcSAndroid Build Coastguard Worker
2729*d68f33bcSAndroid Build Coastguard Worker		#print "==>$rawline\n";
2730*d68f33bcSAndroid Build Coastguard Worker		#print "-->$line\n";
2731*d68f33bcSAndroid Build Coastguard Worker
2732*d68f33bcSAndroid Build Coastguard Worker		if ($setup_docs && $line =~ /^\+/) {
2733*d68f33bcSAndroid Build Coastguard Worker			push(@setup_docs, $line);
2734*d68f33bcSAndroid Build Coastguard Worker		}
2735*d68f33bcSAndroid Build Coastguard Worker	}
2736*d68f33bcSAndroid Build Coastguard Worker
2737*d68f33bcSAndroid Build Coastguard Worker	$prefix = '';
2738*d68f33bcSAndroid Build Coastguard Worker
2739*d68f33bcSAndroid Build Coastguard Worker	$realcnt = 0;
2740*d68f33bcSAndroid Build Coastguard Worker	$linenr = 0;
2741*d68f33bcSAndroid Build Coastguard Worker	$fixlinenr = -1;
2742*d68f33bcSAndroid Build Coastguard Worker	foreach my $line (@lines) {
2743*d68f33bcSAndroid Build Coastguard Worker		$linenr++;
2744*d68f33bcSAndroid Build Coastguard Worker		$fixlinenr++;
2745*d68f33bcSAndroid Build Coastguard Worker		my $sline = $line;	#copy of $line
2746*d68f33bcSAndroid Build Coastguard Worker		$sline =~ s/$;/ /g;	#with comments as spaces
2747*d68f33bcSAndroid Build Coastguard Worker
2748*d68f33bcSAndroid Build Coastguard Worker		my $rawline = $rawlines[$linenr - 1];
2749*d68f33bcSAndroid Build Coastguard Worker		my $raw_comment = get_raw_comment($line, $rawline);
2750*d68f33bcSAndroid Build Coastguard Worker
2751*d68f33bcSAndroid Build Coastguard Worker# check if it's a mode change, rename or start of a patch
2752*d68f33bcSAndroid Build Coastguard Worker		if (!$in_commit_log &&
2753*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2754*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2755*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2756*d68f33bcSAndroid Build Coastguard Worker			$is_patch = 1;
2757*d68f33bcSAndroid Build Coastguard Worker		}
2758*d68f33bcSAndroid Build Coastguard Worker
2759*d68f33bcSAndroid Build Coastguard Worker#extract the line range in the file after the patch is applied
2760*d68f33bcSAndroid Build Coastguard Worker		if (!$in_commit_log &&
2761*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2762*d68f33bcSAndroid Build Coastguard Worker			my $context = $4;
2763*d68f33bcSAndroid Build Coastguard Worker			$is_patch = 1;
2764*d68f33bcSAndroid Build Coastguard Worker			$first_line = $linenr + 1;
2765*d68f33bcSAndroid Build Coastguard Worker			$realline=$1-1;
2766*d68f33bcSAndroid Build Coastguard Worker			if (defined $2) {
2767*d68f33bcSAndroid Build Coastguard Worker				$realcnt=$3+1;
2768*d68f33bcSAndroid Build Coastguard Worker			} else {
2769*d68f33bcSAndroid Build Coastguard Worker				$realcnt=1+1;
2770*d68f33bcSAndroid Build Coastguard Worker			}
2771*d68f33bcSAndroid Build Coastguard Worker			annotate_reset();
2772*d68f33bcSAndroid Build Coastguard Worker			$prev_values = 'E';
2773*d68f33bcSAndroid Build Coastguard Worker
2774*d68f33bcSAndroid Build Coastguard Worker			%suppress_ifbraces = ();
2775*d68f33bcSAndroid Build Coastguard Worker			%suppress_whiletrailers = ();
2776*d68f33bcSAndroid Build Coastguard Worker			%suppress_export = ();
2777*d68f33bcSAndroid Build Coastguard Worker			$suppress_statement = 0;
2778*d68f33bcSAndroid Build Coastguard Worker			if ($context =~ /\b(\w+)\s*\(/) {
2779*d68f33bcSAndroid Build Coastguard Worker				$context_function = $1;
2780*d68f33bcSAndroid Build Coastguard Worker			} else {
2781*d68f33bcSAndroid Build Coastguard Worker				undef $context_function;
2782*d68f33bcSAndroid Build Coastguard Worker			}
2783*d68f33bcSAndroid Build Coastguard Worker			next;
2784*d68f33bcSAndroid Build Coastguard Worker
2785*d68f33bcSAndroid Build Coastguard Worker# track the line number as we move through the hunk, note that
2786*d68f33bcSAndroid Build Coastguard Worker# new versions of GNU diff omit the leading space on completely
2787*d68f33bcSAndroid Build Coastguard Worker# blank context lines so we need to count that too.
2788*d68f33bcSAndroid Build Coastguard Worker		} elsif ($line =~ /^( |\+|$)/) {
2789*d68f33bcSAndroid Build Coastguard Worker			$realline++;
2790*d68f33bcSAndroid Build Coastguard Worker			$realcnt-- if ($realcnt != 0);
2791*d68f33bcSAndroid Build Coastguard Worker
2792*d68f33bcSAndroid Build Coastguard Worker			# Measure the line length and indent.
2793*d68f33bcSAndroid Build Coastguard Worker			($length, $indent) = line_stats($rawline);
2794*d68f33bcSAndroid Build Coastguard Worker
2795*d68f33bcSAndroid Build Coastguard Worker			# Track the previous line.
2796*d68f33bcSAndroid Build Coastguard Worker			($prevline, $stashline) = ($stashline, $line);
2797*d68f33bcSAndroid Build Coastguard Worker			($previndent, $stashindent) = ($stashindent, $indent);
2798*d68f33bcSAndroid Build Coastguard Worker			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2799*d68f33bcSAndroid Build Coastguard Worker
2800*d68f33bcSAndroid Build Coastguard Worker			#warn "line<$line>\n";
2801*d68f33bcSAndroid Build Coastguard Worker
2802*d68f33bcSAndroid Build Coastguard Worker		} elsif ($realcnt == 1) {
2803*d68f33bcSAndroid Build Coastguard Worker			$realcnt--;
2804*d68f33bcSAndroid Build Coastguard Worker		}
2805*d68f33bcSAndroid Build Coastguard Worker
2806*d68f33bcSAndroid Build Coastguard Worker		my $hunk_line = ($realcnt != 0);
2807*d68f33bcSAndroid Build Coastguard Worker
2808*d68f33bcSAndroid Build Coastguard Worker		$here = "#$linenr: " if (!$file);
2809*d68f33bcSAndroid Build Coastguard Worker		$here = "#$realline: " if ($file);
2810*d68f33bcSAndroid Build Coastguard Worker
2811*d68f33bcSAndroid Build Coastguard Worker		my $found_file = 0;
2812*d68f33bcSAndroid Build Coastguard Worker		# extract the filename as it passes
2813*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^diff --git.*?(\S+)$/) {
2814*d68f33bcSAndroid Build Coastguard Worker			$realfile = $1;
2815*d68f33bcSAndroid Build Coastguard Worker			$realfile =~ s@^([^/]*)/@@ if (!$file);
2816*d68f33bcSAndroid Build Coastguard Worker			$in_commit_log = 0;
2817*d68f33bcSAndroid Build Coastguard Worker			$found_file = 1;
2818*d68f33bcSAndroid Build Coastguard Worker		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2819*d68f33bcSAndroid Build Coastguard Worker			$realfile = $1;
2820*d68f33bcSAndroid Build Coastguard Worker			$realfile =~ s@^([^/]*)/@@ if (!$file);
2821*d68f33bcSAndroid Build Coastguard Worker			$in_commit_log = 0;
2822*d68f33bcSAndroid Build Coastguard Worker
2823*d68f33bcSAndroid Build Coastguard Worker			$p1_prefix = $1;
2824*d68f33bcSAndroid Build Coastguard Worker			if (!$file && $tree && $p1_prefix ne '' &&
2825*d68f33bcSAndroid Build Coastguard Worker			    -e "$root/$p1_prefix") {
2826*d68f33bcSAndroid Build Coastguard Worker				WARN("PATCH_PREFIX",
2827*d68f33bcSAndroid Build Coastguard Worker				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2828*d68f33bcSAndroid Build Coastguard Worker			}
2829*d68f33bcSAndroid Build Coastguard Worker
2830*d68f33bcSAndroid Build Coastguard Worker			if ($realfile =~ m@^include/asm/@) {
2831*d68f33bcSAndroid Build Coastguard Worker				ERROR("MODIFIED_INCLUDE_ASM",
2832*d68f33bcSAndroid Build Coastguard Worker				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2833*d68f33bcSAndroid Build Coastguard Worker			}
2834*d68f33bcSAndroid Build Coastguard Worker			$found_file = 1;
2835*d68f33bcSAndroid Build Coastguard Worker		}
2836*d68f33bcSAndroid Build Coastguard Worker
2837*d68f33bcSAndroid Build Coastguard Worker#make up the handle for any error we report on this line
2838*d68f33bcSAndroid Build Coastguard Worker		if ($showfile) {
2839*d68f33bcSAndroid Build Coastguard Worker			$prefix = "$realfile:$realline: "
2840*d68f33bcSAndroid Build Coastguard Worker		} elsif ($emacs) {
2841*d68f33bcSAndroid Build Coastguard Worker			if ($file) {
2842*d68f33bcSAndroid Build Coastguard Worker				$prefix = "$filename:$realline: ";
2843*d68f33bcSAndroid Build Coastguard Worker			} else {
2844*d68f33bcSAndroid Build Coastguard Worker				$prefix = "$filename:$linenr: ";
2845*d68f33bcSAndroid Build Coastguard Worker			}
2846*d68f33bcSAndroid Build Coastguard Worker		}
2847*d68f33bcSAndroid Build Coastguard Worker
2848*d68f33bcSAndroid Build Coastguard Worker		if ($found_file) {
2849*d68f33bcSAndroid Build Coastguard Worker			if (is_maintained_obsolete($realfile)) {
2850*d68f33bcSAndroid Build Coastguard Worker				WARN("OBSOLETE",
2851*d68f33bcSAndroid Build Coastguard Worker				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
2852*d68f33bcSAndroid Build Coastguard Worker			}
2853*d68f33bcSAndroid Build Coastguard Worker			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
2854*d68f33bcSAndroid Build Coastguard Worker				$check = 1;
2855*d68f33bcSAndroid Build Coastguard Worker			} else {
2856*d68f33bcSAndroid Build Coastguard Worker				$check = $check_orig;
2857*d68f33bcSAndroid Build Coastguard Worker			}
2858*d68f33bcSAndroid Build Coastguard Worker			$checklicenseline = 1;
2859*d68f33bcSAndroid Build Coastguard Worker
2860*d68f33bcSAndroid Build Coastguard Worker			if ($realfile !~ /^MAINTAINERS/) {
2861*d68f33bcSAndroid Build Coastguard Worker				my $last_binding_patch = $is_binding_patch;
2862*d68f33bcSAndroid Build Coastguard Worker
2863*d68f33bcSAndroid Build Coastguard Worker				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2864*d68f33bcSAndroid Build Coastguard Worker
2865*d68f33bcSAndroid Build Coastguard Worker				if (($last_binding_patch != -1) &&
2866*d68f33bcSAndroid Build Coastguard Worker				    ($last_binding_patch ^ $is_binding_patch)) {
2867*d68f33bcSAndroid Build Coastguard Worker					WARN("DT_SPLIT_BINDING_PATCH",
2868*d68f33bcSAndroid Build Coastguard Worker					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2869*d68f33bcSAndroid Build Coastguard Worker				}
2870*d68f33bcSAndroid Build Coastguard Worker			}
2871*d68f33bcSAndroid Build Coastguard Worker
2872*d68f33bcSAndroid Build Coastguard Worker			next;
2873*d68f33bcSAndroid Build Coastguard Worker		}
2874*d68f33bcSAndroid Build Coastguard Worker
2875*d68f33bcSAndroid Build Coastguard Worker		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2876*d68f33bcSAndroid Build Coastguard Worker
2877*d68f33bcSAndroid Build Coastguard Worker		my $hereline = "$here\n$rawline\n";
2878*d68f33bcSAndroid Build Coastguard Worker		my $herecurr = "$here\n$rawline\n";
2879*d68f33bcSAndroid Build Coastguard Worker		my $hereprev = "$here\n$prevrawline\n$rawline\n";
2880*d68f33bcSAndroid Build Coastguard Worker
2881*d68f33bcSAndroid Build Coastguard Worker		$cnt_lines++ if ($realcnt != 0);
2882*d68f33bcSAndroid Build Coastguard Worker
2883*d68f33bcSAndroid Build Coastguard Worker# Verify the existence of a commit log if appropriate
2884*d68f33bcSAndroid Build Coastguard Worker# 2 is used because a $signature is counted in $commit_log_lines
2885*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log) {
2886*d68f33bcSAndroid Build Coastguard Worker			if ($line !~ /^\s*$/) {
2887*d68f33bcSAndroid Build Coastguard Worker				$commit_log_lines++;	#could be a $signature
2888*d68f33bcSAndroid Build Coastguard Worker			}
2889*d68f33bcSAndroid Build Coastguard Worker		} elsif ($has_commit_log && $commit_log_lines < 2) {
2890*d68f33bcSAndroid Build Coastguard Worker			WARN("COMMIT_MESSAGE",
2891*d68f33bcSAndroid Build Coastguard Worker			     "Missing commit description - Add an appropriate one\n");
2892*d68f33bcSAndroid Build Coastguard Worker			$commit_log_lines = 2;	#warn only once
2893*d68f33bcSAndroid Build Coastguard Worker		}
2894*d68f33bcSAndroid Build Coastguard Worker
2895*d68f33bcSAndroid Build Coastguard Worker# Check if the commit log has what seems like a diff which can confuse patch
2896*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && !$commit_log_has_diff &&
2897*d68f33bcSAndroid Build Coastguard Worker		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
2898*d68f33bcSAndroid Build Coastguard Worker		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2899*d68f33bcSAndroid Build Coastguard Worker		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2900*d68f33bcSAndroid Build Coastguard Worker		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2901*d68f33bcSAndroid Build Coastguard Worker			ERROR("DIFF_IN_COMMIT_MSG",
2902*d68f33bcSAndroid Build Coastguard Worker			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2903*d68f33bcSAndroid Build Coastguard Worker			$commit_log_has_diff = 1;
2904*d68f33bcSAndroid Build Coastguard Worker		}
2905*d68f33bcSAndroid Build Coastguard Worker
2906*d68f33bcSAndroid Build Coastguard Worker# Check for incorrect file permissions
2907*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2908*d68f33bcSAndroid Build Coastguard Worker			my $permhere = $here . "FILE: $realfile\n";
2909*d68f33bcSAndroid Build Coastguard Worker			if ($realfile !~ m@scripts/@ &&
2910*d68f33bcSAndroid Build Coastguard Worker			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2911*d68f33bcSAndroid Build Coastguard Worker				ERROR("EXECUTE_PERMISSIONS",
2912*d68f33bcSAndroid Build Coastguard Worker				      "do not set execute permissions for source files\n" . $permhere);
2913*d68f33bcSAndroid Build Coastguard Worker			}
2914*d68f33bcSAndroid Build Coastguard Worker		}
2915*d68f33bcSAndroid Build Coastguard Worker
2916*d68f33bcSAndroid Build Coastguard Worker# Check the patch for a From:
2917*d68f33bcSAndroid Build Coastguard Worker		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2918*d68f33bcSAndroid Build Coastguard Worker			$author = $1;
2919*d68f33bcSAndroid Build Coastguard Worker			my $curline = $linenr;
2920*d68f33bcSAndroid Build Coastguard Worker			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2921*d68f33bcSAndroid Build Coastguard Worker				$author .= $1;
2922*d68f33bcSAndroid Build Coastguard Worker			}
2923*d68f33bcSAndroid Build Coastguard Worker			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2924*d68f33bcSAndroid Build Coastguard Worker			$author =~ s/"//g;
2925*d68f33bcSAndroid Build Coastguard Worker			$author = reformat_email($author);
2926*d68f33bcSAndroid Build Coastguard Worker		}
2927*d68f33bcSAndroid Build Coastguard Worker
2928*d68f33bcSAndroid Build Coastguard Worker# Check the patch for a signoff:
2929*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
2930*d68f33bcSAndroid Build Coastguard Worker			$signoff++;
2931*d68f33bcSAndroid Build Coastguard Worker			$in_commit_log = 0;
2932*d68f33bcSAndroid Build Coastguard Worker			if ($author ne ''  && $authorsignoff != 1) {
2933*d68f33bcSAndroid Build Coastguard Worker				if (same_email_addresses($1, $author)) {
2934*d68f33bcSAndroid Build Coastguard Worker					$authorsignoff = 1;
2935*d68f33bcSAndroid Build Coastguard Worker				} else {
2936*d68f33bcSAndroid Build Coastguard Worker					my $ctx = $1;
2937*d68f33bcSAndroid Build Coastguard Worker					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
2938*d68f33bcSAndroid Build Coastguard Worker					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
2939*d68f33bcSAndroid Build Coastguard Worker
2940*d68f33bcSAndroid Build Coastguard Worker					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
2941*d68f33bcSAndroid Build Coastguard Worker						$author_sob = $ctx;
2942*d68f33bcSAndroid Build Coastguard Worker						$authorsignoff = 2;
2943*d68f33bcSAndroid Build Coastguard Worker					} elsif (lc $email_address eq lc $author_address) {
2944*d68f33bcSAndroid Build Coastguard Worker						$author_sob = $ctx;
2945*d68f33bcSAndroid Build Coastguard Worker						$authorsignoff = 3;
2946*d68f33bcSAndroid Build Coastguard Worker					} elsif ($email_name eq $author_name) {
2947*d68f33bcSAndroid Build Coastguard Worker						$author_sob = $ctx;
2948*d68f33bcSAndroid Build Coastguard Worker						$authorsignoff = 4;
2949*d68f33bcSAndroid Build Coastguard Worker
2950*d68f33bcSAndroid Build Coastguard Worker						my $address1 = $email_address;
2951*d68f33bcSAndroid Build Coastguard Worker						my $address2 = $author_address;
2952*d68f33bcSAndroid Build Coastguard Worker
2953*d68f33bcSAndroid Build Coastguard Worker						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
2954*d68f33bcSAndroid Build Coastguard Worker							$address1 = "$1$2";
2955*d68f33bcSAndroid Build Coastguard Worker						}
2956*d68f33bcSAndroid Build Coastguard Worker						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
2957*d68f33bcSAndroid Build Coastguard Worker							$address2 = "$1$2";
2958*d68f33bcSAndroid Build Coastguard Worker						}
2959*d68f33bcSAndroid Build Coastguard Worker						if ($address1 eq $address2) {
2960*d68f33bcSAndroid Build Coastguard Worker							$authorsignoff = 5;
2961*d68f33bcSAndroid Build Coastguard Worker						}
2962*d68f33bcSAndroid Build Coastguard Worker					}
2963*d68f33bcSAndroid Build Coastguard Worker				}
2964*d68f33bcSAndroid Build Coastguard Worker			}
2965*d68f33bcSAndroid Build Coastguard Worker		}
2966*d68f33bcSAndroid Build Coastguard Worker
2967*d68f33bcSAndroid Build Coastguard Worker# Check for patch separator
2968*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^---$/) {
2969*d68f33bcSAndroid Build Coastguard Worker			$has_patch_separator = 1;
2970*d68f33bcSAndroid Build Coastguard Worker			$in_commit_log = 0;
2971*d68f33bcSAndroid Build Coastguard Worker		}
2972*d68f33bcSAndroid Build Coastguard Worker
2973*d68f33bcSAndroid Build Coastguard Worker# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2974*d68f33bcSAndroid Build Coastguard Worker# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2975*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2976*d68f33bcSAndroid Build Coastguard Worker			$reported_maintainer_file = 1;
2977*d68f33bcSAndroid Build Coastguard Worker		}
2978*d68f33bcSAndroid Build Coastguard Worker
2979*d68f33bcSAndroid Build Coastguard Worker# Check signature styles
2980*d68f33bcSAndroid Build Coastguard Worker		if (!$in_header_lines &&
2981*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2982*d68f33bcSAndroid Build Coastguard Worker			my $space_before = $1;
2983*d68f33bcSAndroid Build Coastguard Worker			my $sign_off = $2;
2984*d68f33bcSAndroid Build Coastguard Worker			my $space_after = $3;
2985*d68f33bcSAndroid Build Coastguard Worker			my $email = $4;
2986*d68f33bcSAndroid Build Coastguard Worker			my $ucfirst_sign_off = ucfirst(lc($sign_off));
2987*d68f33bcSAndroid Build Coastguard Worker
2988*d68f33bcSAndroid Build Coastguard Worker			if ($sign_off !~ /$signature_tags/) {
2989*d68f33bcSAndroid Build Coastguard Worker				my $suggested_signature = find_standard_signature($sign_off);
2990*d68f33bcSAndroid Build Coastguard Worker				if ($suggested_signature eq "") {
2991*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
2992*d68f33bcSAndroid Build Coastguard Worker					     "Non-standard signature: $sign_off\n" . $herecurr);
2993*d68f33bcSAndroid Build Coastguard Worker				} else {
2994*d68f33bcSAndroid Build Coastguard Worker					if (WARN("BAD_SIGN_OFF",
2995*d68f33bcSAndroid Build Coastguard Worker						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2996*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
2997*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2998*d68f33bcSAndroid Build Coastguard Worker					}
2999*d68f33bcSAndroid Build Coastguard Worker				}
3000*d68f33bcSAndroid Build Coastguard Worker			}
3001*d68f33bcSAndroid Build Coastguard Worker			if (defined $space_before && $space_before ne "") {
3002*d68f33bcSAndroid Build Coastguard Worker				if (WARN("BAD_SIGN_OFF",
3003*d68f33bcSAndroid Build Coastguard Worker					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
3004*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3005*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =
3006*d68f33bcSAndroid Build Coastguard Worker					    "$ucfirst_sign_off $email";
3007*d68f33bcSAndroid Build Coastguard Worker				}
3008*d68f33bcSAndroid Build Coastguard Worker			}
3009*d68f33bcSAndroid Build Coastguard Worker			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
3010*d68f33bcSAndroid Build Coastguard Worker				if (WARN("BAD_SIGN_OFF",
3011*d68f33bcSAndroid Build Coastguard Worker					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
3012*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3013*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =
3014*d68f33bcSAndroid Build Coastguard Worker					    "$ucfirst_sign_off $email";
3015*d68f33bcSAndroid Build Coastguard Worker				}
3016*d68f33bcSAndroid Build Coastguard Worker
3017*d68f33bcSAndroid Build Coastguard Worker			}
3018*d68f33bcSAndroid Build Coastguard Worker			if (!defined $space_after || $space_after ne " ") {
3019*d68f33bcSAndroid Build Coastguard Worker				if (WARN("BAD_SIGN_OFF",
3020*d68f33bcSAndroid Build Coastguard Worker					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
3021*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3022*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =
3023*d68f33bcSAndroid Build Coastguard Worker					    "$ucfirst_sign_off $email";
3024*d68f33bcSAndroid Build Coastguard Worker				}
3025*d68f33bcSAndroid Build Coastguard Worker			}
3026*d68f33bcSAndroid Build Coastguard Worker
3027*d68f33bcSAndroid Build Coastguard Worker			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
3028*d68f33bcSAndroid Build Coastguard Worker			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
3029*d68f33bcSAndroid Build Coastguard Worker			if ($suggested_email eq "") {
3030*d68f33bcSAndroid Build Coastguard Worker				ERROR("BAD_SIGN_OFF",
3031*d68f33bcSAndroid Build Coastguard Worker				      "Unrecognized email address: '$email'\n" . $herecurr);
3032*d68f33bcSAndroid Build Coastguard Worker			} else {
3033*d68f33bcSAndroid Build Coastguard Worker				my $dequoted = $suggested_email;
3034*d68f33bcSAndroid Build Coastguard Worker				$dequoted =~ s/^"//;
3035*d68f33bcSAndroid Build Coastguard Worker				$dequoted =~ s/" </ </;
3036*d68f33bcSAndroid Build Coastguard Worker				# Don't force email to have quotes
3037*d68f33bcSAndroid Build Coastguard Worker				# Allow just an angle bracketed address
3038*d68f33bcSAndroid Build Coastguard Worker				if (!same_email_addresses($email, $suggested_email)) {
3039*d68f33bcSAndroid Build Coastguard Worker					if (WARN("BAD_SIGN_OFF",
3040*d68f33bcSAndroid Build Coastguard Worker						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3041*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
3042*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3043*d68f33bcSAndroid Build Coastguard Worker					}
3044*d68f33bcSAndroid Build Coastguard Worker				}
3045*d68f33bcSAndroid Build Coastguard Worker
3046*d68f33bcSAndroid Build Coastguard Worker				# Address part shouldn't have comments
3047*d68f33bcSAndroid Build Coastguard Worker				my $stripped_address = $email_address;
3048*d68f33bcSAndroid Build Coastguard Worker				$stripped_address =~ s/\([^\(\)]*\)//g;
3049*d68f33bcSAndroid Build Coastguard Worker				if ($email_address ne $stripped_address) {
3050*d68f33bcSAndroid Build Coastguard Worker					if (WARN("BAD_SIGN_OFF",
3051*d68f33bcSAndroid Build Coastguard Worker						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3052*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
3053*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3054*d68f33bcSAndroid Build Coastguard Worker					}
3055*d68f33bcSAndroid Build Coastguard Worker				}
3056*d68f33bcSAndroid Build Coastguard Worker
3057*d68f33bcSAndroid Build Coastguard Worker				# Only one name comment should be allowed
3058*d68f33bcSAndroid Build Coastguard Worker				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3059*d68f33bcSAndroid Build Coastguard Worker				if ($comment_count > 1) {
3060*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
3061*d68f33bcSAndroid Build Coastguard Worker					     "Use a single name comment in email: '$email'\n" . $herecurr);
3062*d68f33bcSAndroid Build Coastguard Worker				}
3063*d68f33bcSAndroid Build Coastguard Worker
3064*d68f33bcSAndroid Build Coastguard Worker
3065*d68f33bcSAndroid Build Coastguard Worker				# [email protected] or [email protected] shouldn't
3066*d68f33bcSAndroid Build Coastguard Worker				# have an email name. In addition comments should strictly
3067*d68f33bcSAndroid Build Coastguard Worker				# begin with a #
3068*d68f33bcSAndroid Build Coastguard Worker				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3069*d68f33bcSAndroid Build Coastguard Worker					if (($comment ne "" && $comment !~ /^#.+/) ||
3070*d68f33bcSAndroid Build Coastguard Worker					    ($email_name ne "")) {
3071*d68f33bcSAndroid Build Coastguard Worker						my $cur_name = $email_name;
3072*d68f33bcSAndroid Build Coastguard Worker						my $new_comment = $comment;
3073*d68f33bcSAndroid Build Coastguard Worker						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3074*d68f33bcSAndroid Build Coastguard Worker
3075*d68f33bcSAndroid Build Coastguard Worker						# Remove brackets enclosing comment text
3076*d68f33bcSAndroid Build Coastguard Worker						# and # from start of comments to get comment text
3077*d68f33bcSAndroid Build Coastguard Worker						$new_comment =~ s/^\((.*)\)$/$1/;
3078*d68f33bcSAndroid Build Coastguard Worker						$new_comment =~ s/^\[(.*)\]$/$1/;
3079*d68f33bcSAndroid Build Coastguard Worker						$new_comment =~ s/^[\s\#]+|\s+$//g;
3080*d68f33bcSAndroid Build Coastguard Worker
3081*d68f33bcSAndroid Build Coastguard Worker						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3082*d68f33bcSAndroid Build Coastguard Worker						$new_comment = " # $new_comment" if ($new_comment ne "");
3083*d68f33bcSAndroid Build Coastguard Worker						my $new_email = "$email_address$new_comment";
3084*d68f33bcSAndroid Build Coastguard Worker
3085*d68f33bcSAndroid Build Coastguard Worker						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3086*d68f33bcSAndroid Build Coastguard Worker							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3087*d68f33bcSAndroid Build Coastguard Worker						    $fix) {
3088*d68f33bcSAndroid Build Coastguard Worker							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3089*d68f33bcSAndroid Build Coastguard Worker						}
3090*d68f33bcSAndroid Build Coastguard Worker					}
3091*d68f33bcSAndroid Build Coastguard Worker				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3092*d68f33bcSAndroid Build Coastguard Worker					my $new_comment = $comment;
3093*d68f33bcSAndroid Build Coastguard Worker
3094*d68f33bcSAndroid Build Coastguard Worker					# Extract comment text from within brackets or
3095*d68f33bcSAndroid Build Coastguard Worker					# c89 style /*...*/ comments
3096*d68f33bcSAndroid Build Coastguard Worker					$new_comment =~ s/^\[(.*)\]$/$1/;
3097*d68f33bcSAndroid Build Coastguard Worker					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3098*d68f33bcSAndroid Build Coastguard Worker
3099*d68f33bcSAndroid Build Coastguard Worker					$new_comment = trim($new_comment);
3100*d68f33bcSAndroid Build Coastguard Worker					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3101*d68f33bcSAndroid Build Coastguard Worker					$new_comment = "($new_comment)" if ($new_comment ne "");
3102*d68f33bcSAndroid Build Coastguard Worker					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3103*d68f33bcSAndroid Build Coastguard Worker
3104*d68f33bcSAndroid Build Coastguard Worker					if (WARN("BAD_SIGN_OFF",
3105*d68f33bcSAndroid Build Coastguard Worker						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3106*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
3107*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3108*d68f33bcSAndroid Build Coastguard Worker					}
3109*d68f33bcSAndroid Build Coastguard Worker				}
3110*d68f33bcSAndroid Build Coastguard Worker			}
3111*d68f33bcSAndroid Build Coastguard Worker
3112*d68f33bcSAndroid Build Coastguard Worker# Check for duplicate signatures
3113*d68f33bcSAndroid Build Coastguard Worker			my $sig_nospace = $line;
3114*d68f33bcSAndroid Build Coastguard Worker			$sig_nospace =~ s/\s//g;
3115*d68f33bcSAndroid Build Coastguard Worker			$sig_nospace = lc($sig_nospace);
3116*d68f33bcSAndroid Build Coastguard Worker			if (defined $signatures{$sig_nospace}) {
3117*d68f33bcSAndroid Build Coastguard Worker				WARN("BAD_SIGN_OFF",
3118*d68f33bcSAndroid Build Coastguard Worker				     "Duplicate signature\n" . $herecurr);
3119*d68f33bcSAndroid Build Coastguard Worker			} else {
3120*d68f33bcSAndroid Build Coastguard Worker				$signatures{$sig_nospace} = 1;
3121*d68f33bcSAndroid Build Coastguard Worker			}
3122*d68f33bcSAndroid Build Coastguard Worker
3123*d68f33bcSAndroid Build Coastguard Worker# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
3124*d68f33bcSAndroid Build Coastguard Worker			if ($sign_off =~ /^co-developed-by:$/i) {
3125*d68f33bcSAndroid Build Coastguard Worker				if ($email eq $author) {
3126*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
3127*d68f33bcSAndroid Build Coastguard Worker					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
3128*d68f33bcSAndroid Build Coastguard Worker				}
3129*d68f33bcSAndroid Build Coastguard Worker				if (!defined $lines[$linenr]) {
3130*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
3131*d68f33bcSAndroid Build Coastguard Worker					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
3132*d68f33bcSAndroid Build Coastguard Worker				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
3133*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
3134*d68f33bcSAndroid Build Coastguard Worker					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
3135*d68f33bcSAndroid Build Coastguard Worker				} elsif ($1 ne $email) {
3136*d68f33bcSAndroid Build Coastguard Worker					WARN("BAD_SIGN_OFF",
3137*d68f33bcSAndroid Build Coastguard Worker					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
3138*d68f33bcSAndroid Build Coastguard Worker				}
3139*d68f33bcSAndroid Build Coastguard Worker			}
3140*d68f33bcSAndroid Build Coastguard Worker		}
3141*d68f33bcSAndroid Build Coastguard Worker
3142*d68f33bcSAndroid Build Coastguard Worker# Check email subject for common tools that don't need to be mentioned
3143*d68f33bcSAndroid Build Coastguard Worker		if ($in_header_lines &&
3144*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3145*d68f33bcSAndroid Build Coastguard Worker			WARN("EMAIL_SUBJECT",
3146*d68f33bcSAndroid Build Coastguard Worker			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3147*d68f33bcSAndroid Build Coastguard Worker		}
3148*d68f33bcSAndroid Build Coastguard Worker
3149*d68f33bcSAndroid Build Coastguard Worker# Check for Gerrit Change-Ids not in any patch context
3150*d68f33bcSAndroid Build Coastguard Worker		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
3151*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("GERRIT_CHANGE_ID",
3152*d68f33bcSAndroid Build Coastguard Worker			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
3153*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3154*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
3155*d68f33bcSAndroid Build Coastguard Worker			}
3156*d68f33bcSAndroid Build Coastguard Worker		}
3157*d68f33bcSAndroid Build Coastguard Worker
3158*d68f33bcSAndroid Build Coastguard Worker# Check if the commit log is in a possible stack dump
3159*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3160*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3161*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3162*d68f33bcSAndroid Build Coastguard Worker					# timestamp
3163*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3164*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3165*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3166*d68f33bcSAndroid Build Coastguard Worker					# stack dump address styles
3167*d68f33bcSAndroid Build Coastguard Worker			$commit_log_possible_stack_dump = 1;
3168*d68f33bcSAndroid Build Coastguard Worker		}
3169*d68f33bcSAndroid Build Coastguard Worker
3170*d68f33bcSAndroid Build Coastguard Worker# Check for line lengths > 75 in commit log, warn once
3171*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && !$commit_log_long_line &&
3172*d68f33bcSAndroid Build Coastguard Worker		    length($line) > 75 &&
3173*d68f33bcSAndroid Build Coastguard Worker		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3174*d68f33bcSAndroid Build Coastguard Worker					# file delta changes
3175*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
3176*d68f33bcSAndroid Build Coastguard Worker					# filename then :
3177*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
3178*d68f33bcSAndroid Build Coastguard Worker					# A Fixes: or Link: line or signature tag line
3179*d68f33bcSAndroid Build Coastguard Worker		      $commit_log_possible_stack_dump)) {
3180*d68f33bcSAndroid Build Coastguard Worker			WARN("COMMIT_LOG_LONG_LINE",
3181*d68f33bcSAndroid Build Coastguard Worker			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
3182*d68f33bcSAndroid Build Coastguard Worker			$commit_log_long_line = 1;
3183*d68f33bcSAndroid Build Coastguard Worker		}
3184*d68f33bcSAndroid Build Coastguard Worker
3185*d68f33bcSAndroid Build Coastguard Worker# Reset possible stack dump if a blank line is found
3186*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && $commit_log_possible_stack_dump &&
3187*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\s*$/) {
3188*d68f33bcSAndroid Build Coastguard Worker			$commit_log_possible_stack_dump = 0;
3189*d68f33bcSAndroid Build Coastguard Worker		}
3190*d68f33bcSAndroid Build Coastguard Worker
3191*d68f33bcSAndroid Build Coastguard Worker# Check for lines starting with a #
3192*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && $line =~ /^#/) {
3193*d68f33bcSAndroid Build Coastguard Worker			if (WARN("COMMIT_COMMENT_SYMBOL",
3194*d68f33bcSAndroid Build Coastguard Worker				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3195*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3196*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/^/ /;
3197*d68f33bcSAndroid Build Coastguard Worker			}
3198*d68f33bcSAndroid Build Coastguard Worker		}
3199*d68f33bcSAndroid Build Coastguard Worker
3200*d68f33bcSAndroid Build Coastguard Worker# Check for git id commit length and improperly formed commit descriptions
3201*d68f33bcSAndroid Build Coastguard Worker# A correctly formed commit description is:
3202*d68f33bcSAndroid Build Coastguard Worker#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
3203*d68f33bcSAndroid Build Coastguard Worker# with the commit subject '("' prefix and '")' suffix
3204*d68f33bcSAndroid Build Coastguard Worker# This is a fairly compilicated block as it tests for what appears to be
3205*d68f33bcSAndroid Build Coastguard Worker# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
3206*d68f33bcSAndroid Build Coastguard Worker# possible SHA-1 matches.
3207*d68f33bcSAndroid Build Coastguard Worker# A commit match can span multiple lines so this block attempts to find a
3208*d68f33bcSAndroid Build Coastguard Worker# complete typical commit on a maximum of 3 lines
3209*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
3210*d68f33bcSAndroid Build Coastguard Worker		    $in_commit_log && !$commit_log_possible_stack_dump &&
3211*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3212*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
3213*d68f33bcSAndroid Build Coastguard Worker		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3214*d68f33bcSAndroid Build Coastguard Worker		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
3215*d68f33bcSAndroid Build Coastguard Worker		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3216*d68f33bcSAndroid Build Coastguard Worker		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3217*d68f33bcSAndroid Build Coastguard Worker		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3218*d68f33bcSAndroid Build Coastguard Worker			my $init_char = "c";
3219*d68f33bcSAndroid Build Coastguard Worker			my $orig_commit = "";
3220*d68f33bcSAndroid Build Coastguard Worker			my $short = 1;
3221*d68f33bcSAndroid Build Coastguard Worker			my $long = 0;
3222*d68f33bcSAndroid Build Coastguard Worker			my $case = 1;
3223*d68f33bcSAndroid Build Coastguard Worker			my $space = 1;
3224*d68f33bcSAndroid Build Coastguard Worker			my $id = '0123456789ab';
3225*d68f33bcSAndroid Build Coastguard Worker			my $orig_desc = "commit description";
3226*d68f33bcSAndroid Build Coastguard Worker			my $description = "";
3227*d68f33bcSAndroid Build Coastguard Worker			my $herectx = $herecurr;
3228*d68f33bcSAndroid Build Coastguard Worker			my $has_parens = 0;
3229*d68f33bcSAndroid Build Coastguard Worker			my $has_quotes = 0;
3230*d68f33bcSAndroid Build Coastguard Worker
3231*d68f33bcSAndroid Build Coastguard Worker			my $input = $line;
3232*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
3233*d68f33bcSAndroid Build Coastguard Worker				for (my $n = 0; $n < 2; $n++) {
3234*d68f33bcSAndroid Build Coastguard Worker					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
3235*d68f33bcSAndroid Build Coastguard Worker						$orig_desc = $1;
3236*d68f33bcSAndroid Build Coastguard Worker						$has_parens = 1;
3237*d68f33bcSAndroid Build Coastguard Worker						# Always strip leading/trailing parens then double quotes if existing
3238*d68f33bcSAndroid Build Coastguard Worker						$orig_desc = substr($orig_desc, 1, -1);
3239*d68f33bcSAndroid Build Coastguard Worker						if ($orig_desc =~ /^".*"$/) {
3240*d68f33bcSAndroid Build Coastguard Worker							$orig_desc = substr($orig_desc, 1, -1);
3241*d68f33bcSAndroid Build Coastguard Worker							$has_quotes = 1;
3242*d68f33bcSAndroid Build Coastguard Worker						}
3243*d68f33bcSAndroid Build Coastguard Worker						last;
3244*d68f33bcSAndroid Build Coastguard Worker					}
3245*d68f33bcSAndroid Build Coastguard Worker					last if ($#lines < $linenr + $n);
3246*d68f33bcSAndroid Build Coastguard Worker					$input .= " " . trim($rawlines[$linenr + $n]);
3247*d68f33bcSAndroid Build Coastguard Worker					$herectx .= "$rawlines[$linenr + $n]\n";
3248*d68f33bcSAndroid Build Coastguard Worker				}
3249*d68f33bcSAndroid Build Coastguard Worker				$herectx = $herecurr if (!$has_parens);
3250*d68f33bcSAndroid Build Coastguard Worker			}
3251*d68f33bcSAndroid Build Coastguard Worker
3252*d68f33bcSAndroid Build Coastguard Worker			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3253*d68f33bcSAndroid Build Coastguard Worker				$init_char = $1;
3254*d68f33bcSAndroid Build Coastguard Worker				$orig_commit = lc($2);
3255*d68f33bcSAndroid Build Coastguard Worker				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
3256*d68f33bcSAndroid Build Coastguard Worker				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
3257*d68f33bcSAndroid Build Coastguard Worker				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
3258*d68f33bcSAndroid Build Coastguard Worker				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
3259*d68f33bcSAndroid Build Coastguard Worker			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
3260*d68f33bcSAndroid Build Coastguard Worker				$orig_commit = lc($1);
3261*d68f33bcSAndroid Build Coastguard Worker			}
3262*d68f33bcSAndroid Build Coastguard Worker
3263*d68f33bcSAndroid Build Coastguard Worker			($id, $description) = git_commit_info($orig_commit,
3264*d68f33bcSAndroid Build Coastguard Worker							      $id, $orig_desc);
3265*d68f33bcSAndroid Build Coastguard Worker
3266*d68f33bcSAndroid Build Coastguard Worker			if (defined($id) &&
3267*d68f33bcSAndroid Build Coastguard Worker			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
3268*d68f33bcSAndroid Build Coastguard Worker			    $last_git_commit_id_linenr != $linenr - 1) {
3269*d68f33bcSAndroid Build Coastguard Worker				ERROR("GIT_COMMIT_ID",
3270*d68f33bcSAndroid Build Coastguard Worker				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
3271*d68f33bcSAndroid Build Coastguard Worker			}
3272*d68f33bcSAndroid Build Coastguard Worker			#don't report the next line if this line ends in commit and the sha1 hash is the next line
3273*d68f33bcSAndroid Build Coastguard Worker			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
3274*d68f33bcSAndroid Build Coastguard Worker		}
3275*d68f33bcSAndroid Build Coastguard Worker
3276*d68f33bcSAndroid Build Coastguard Worker# Check for added, moved or deleted files
3277*d68f33bcSAndroid Build Coastguard Worker		if (!$reported_maintainer_file && !$in_commit_log &&
3278*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
3279*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
3280*d68f33bcSAndroid Build Coastguard Worker		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
3281*d68f33bcSAndroid Build Coastguard Worker		      (defined($1) || defined($2))))) {
3282*d68f33bcSAndroid Build Coastguard Worker			$is_patch = 1;
3283*d68f33bcSAndroid Build Coastguard Worker			$reported_maintainer_file = 1;
3284*d68f33bcSAndroid Build Coastguard Worker			WARN("FILE_PATH_CHANGES",
3285*d68f33bcSAndroid Build Coastguard Worker			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
3286*d68f33bcSAndroid Build Coastguard Worker		}
3287*d68f33bcSAndroid Build Coastguard Worker
3288*d68f33bcSAndroid Build Coastguard Worker# Check for adding new DT bindings not in schema format
3289*d68f33bcSAndroid Build Coastguard Worker		if (!$in_commit_log &&
3290*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3291*d68f33bcSAndroid Build Coastguard Worker		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3292*d68f33bcSAndroid Build Coastguard Worker			WARN("DT_SCHEMA_BINDING_PATCH",
3293*d68f33bcSAndroid Build Coastguard Worker			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3294*d68f33bcSAndroid Build Coastguard Worker		}
3295*d68f33bcSAndroid Build Coastguard Worker
3296*d68f33bcSAndroid Build Coastguard Worker# Check for wrappage within a valid hunk of the file
3297*d68f33bcSAndroid Build Coastguard Worker		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3298*d68f33bcSAndroid Build Coastguard Worker			ERROR("CORRUPTED_PATCH",
3299*d68f33bcSAndroid Build Coastguard Worker			      "patch seems to be corrupt (line wrapped?)\n" .
3300*d68f33bcSAndroid Build Coastguard Worker				$herecurr) if (!$emitted_corrupt++);
3301*d68f33bcSAndroid Build Coastguard Worker		}
3302*d68f33bcSAndroid Build Coastguard Worker
3303*d68f33bcSAndroid Build Coastguard Worker# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3304*d68f33bcSAndroid Build Coastguard Worker		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3305*d68f33bcSAndroid Build Coastguard Worker		    $rawline !~ m/^$UTF8*$/) {
3306*d68f33bcSAndroid Build Coastguard Worker			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3307*d68f33bcSAndroid Build Coastguard Worker
3308*d68f33bcSAndroid Build Coastguard Worker			my $blank = copy_spacing($rawline);
3309*d68f33bcSAndroid Build Coastguard Worker			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3310*d68f33bcSAndroid Build Coastguard Worker			my $hereptr = "$hereline$ptr\n";
3311*d68f33bcSAndroid Build Coastguard Worker
3312*d68f33bcSAndroid Build Coastguard Worker			CHK("INVALID_UTF8",
3313*d68f33bcSAndroid Build Coastguard Worker			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
3314*d68f33bcSAndroid Build Coastguard Worker		}
3315*d68f33bcSAndroid Build Coastguard Worker
3316*d68f33bcSAndroid Build Coastguard Worker# Check if it's the start of a commit log
3317*d68f33bcSAndroid Build Coastguard Worker# (not a header line and we haven't seen the patch filename)
3318*d68f33bcSAndroid Build Coastguard Worker		if ($in_header_lines && $realfile =~ /^$/ &&
3319*d68f33bcSAndroid Build Coastguard Worker		    !($rawline =~ /^\s+(?:\S|$)/ ||
3320*d68f33bcSAndroid Build Coastguard Worker		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
3321*d68f33bcSAndroid Build Coastguard Worker			$in_header_lines = 0;
3322*d68f33bcSAndroid Build Coastguard Worker			$in_commit_log = 1;
3323*d68f33bcSAndroid Build Coastguard Worker			$has_commit_log = 1;
3324*d68f33bcSAndroid Build Coastguard Worker		}
3325*d68f33bcSAndroid Build Coastguard Worker
3326*d68f33bcSAndroid Build Coastguard Worker# Check if there is UTF-8 in a commit log when a mail header has explicitly
3327*d68f33bcSAndroid Build Coastguard Worker# declined it, i.e defined some charset where it is missing.
3328*d68f33bcSAndroid Build Coastguard Worker		if ($in_header_lines &&
3329*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3330*d68f33bcSAndroid Build Coastguard Worker		    $1 !~ /utf-8/i) {
3331*d68f33bcSAndroid Build Coastguard Worker			$non_utf8_charset = 1;
3332*d68f33bcSAndroid Build Coastguard Worker		}
3333*d68f33bcSAndroid Build Coastguard Worker
3334*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
3335*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /$NON_ASCII_UTF8/) {
3336*d68f33bcSAndroid Build Coastguard Worker			WARN("UTF8_BEFORE_PATCH",
3337*d68f33bcSAndroid Build Coastguard Worker			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
3338*d68f33bcSAndroid Build Coastguard Worker		}
3339*d68f33bcSAndroid Build Coastguard Worker
3340*d68f33bcSAndroid Build Coastguard Worker# Check for absolute kernel paths in commit message
3341*d68f33bcSAndroid Build Coastguard Worker		if ($tree && $in_commit_log) {
3342*d68f33bcSAndroid Build Coastguard Worker			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3343*d68f33bcSAndroid Build Coastguard Worker				my $file = $1;
3344*d68f33bcSAndroid Build Coastguard Worker
3345*d68f33bcSAndroid Build Coastguard Worker				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3346*d68f33bcSAndroid Build Coastguard Worker				    check_absolute_file($1, $herecurr)) {
3347*d68f33bcSAndroid Build Coastguard Worker					#
3348*d68f33bcSAndroid Build Coastguard Worker				} else {
3349*d68f33bcSAndroid Build Coastguard Worker					check_absolute_file($file, $herecurr);
3350*d68f33bcSAndroid Build Coastguard Worker				}
3351*d68f33bcSAndroid Build Coastguard Worker			}
3352*d68f33bcSAndroid Build Coastguard Worker		}
3353*d68f33bcSAndroid Build Coastguard Worker
3354*d68f33bcSAndroid Build Coastguard Worker# Check for various typo / spelling mistakes
3355*d68f33bcSAndroid Build Coastguard Worker		if (defined($misspellings) &&
3356*d68f33bcSAndroid Build Coastguard Worker		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
3357*d68f33bcSAndroid Build Coastguard Worker			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
3358*d68f33bcSAndroid Build Coastguard Worker				my $typo = $1;
3359*d68f33bcSAndroid Build Coastguard Worker				my $blank = copy_spacing($rawline);
3360*d68f33bcSAndroid Build Coastguard Worker				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
3361*d68f33bcSAndroid Build Coastguard Worker				my $hereptr = "$hereline$ptr\n";
3362*d68f33bcSAndroid Build Coastguard Worker				my $typo_fix = $spelling_fix{lc($typo)};
3363*d68f33bcSAndroid Build Coastguard Worker				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
3364*d68f33bcSAndroid Build Coastguard Worker				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
3365*d68f33bcSAndroid Build Coastguard Worker				my $msg_level = \&WARN;
3366*d68f33bcSAndroid Build Coastguard Worker				$msg_level = \&CHK if ($file);
3367*d68f33bcSAndroid Build Coastguard Worker				if (&{$msg_level}("TYPO_SPELLING",
3368*d68f33bcSAndroid Build Coastguard Worker						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
3369*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3370*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
3371*d68f33bcSAndroid Build Coastguard Worker				}
3372*d68f33bcSAndroid Build Coastguard Worker			}
3373*d68f33bcSAndroid Build Coastguard Worker		}
3374*d68f33bcSAndroid Build Coastguard Worker
3375*d68f33bcSAndroid Build Coastguard Worker# check for invalid commit id
3376*d68f33bcSAndroid Build Coastguard Worker		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3377*d68f33bcSAndroid Build Coastguard Worker			my $id;
3378*d68f33bcSAndroid Build Coastguard Worker			my $description;
3379*d68f33bcSAndroid Build Coastguard Worker			($id, $description) = git_commit_info($2, undef, undef);
3380*d68f33bcSAndroid Build Coastguard Worker			if (!defined($id)) {
3381*d68f33bcSAndroid Build Coastguard Worker				WARN("UNKNOWN_COMMIT_ID",
3382*d68f33bcSAndroid Build Coastguard Worker				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3383*d68f33bcSAndroid Build Coastguard Worker			}
3384*d68f33bcSAndroid Build Coastguard Worker		}
3385*d68f33bcSAndroid Build Coastguard Worker
3386*d68f33bcSAndroid Build Coastguard Worker# check for repeated words separated by a single space
3387*d68f33bcSAndroid Build Coastguard Worker# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
3388*d68f33bcSAndroid Build Coastguard Worker		if (($rawline =~ /^\+/ || $in_commit_log) &&
3389*d68f33bcSAndroid Build Coastguard Worker		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
3390*d68f33bcSAndroid Build Coastguard Worker			pos($rawline) = 1 if (!$in_commit_log);
3391*d68f33bcSAndroid Build Coastguard Worker			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3392*d68f33bcSAndroid Build Coastguard Worker
3393*d68f33bcSAndroid Build Coastguard Worker				my $first = $1;
3394*d68f33bcSAndroid Build Coastguard Worker				my $second = $2;
3395*d68f33bcSAndroid Build Coastguard Worker				my $start_pos = $-[1];
3396*d68f33bcSAndroid Build Coastguard Worker				my $end_pos = $+[2];
3397*d68f33bcSAndroid Build Coastguard Worker				if ($first =~ /(?:struct|union|enum)/) {
3398*d68f33bcSAndroid Build Coastguard Worker					pos($rawline) += length($first) + length($second) + 1;
3399*d68f33bcSAndroid Build Coastguard Worker					next;
3400*d68f33bcSAndroid Build Coastguard Worker				}
3401*d68f33bcSAndroid Build Coastguard Worker
3402*d68f33bcSAndroid Build Coastguard Worker				next if (lc($first) ne lc($second));
3403*d68f33bcSAndroid Build Coastguard Worker				next if ($first eq 'long');
3404*d68f33bcSAndroid Build Coastguard Worker
3405*d68f33bcSAndroid Build Coastguard Worker				# check for character before and after the word matches
3406*d68f33bcSAndroid Build Coastguard Worker				my $start_char = '';
3407*d68f33bcSAndroid Build Coastguard Worker				my $end_char = '';
3408*d68f33bcSAndroid Build Coastguard Worker				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
3409*d68f33bcSAndroid Build Coastguard Worker				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
3410*d68f33bcSAndroid Build Coastguard Worker
3411*d68f33bcSAndroid Build Coastguard Worker				next if ($start_char =~ /^\S$/);
3412*d68f33bcSAndroid Build Coastguard Worker				next if (index(" \t.,;?!", $end_char) == -1);
3413*d68f33bcSAndroid Build Coastguard Worker
3414*d68f33bcSAndroid Build Coastguard Worker				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
3415*d68f33bcSAndroid Build Coastguard Worker				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
3416*d68f33bcSAndroid Build Coastguard Worker					next if (!exists($allow_repeated_words{lc($first)}));
3417*d68f33bcSAndroid Build Coastguard Worker				}
3418*d68f33bcSAndroid Build Coastguard Worker
3419*d68f33bcSAndroid Build Coastguard Worker				if (WARN("REPEATED_WORD",
3420*d68f33bcSAndroid Build Coastguard Worker					 "Possible repeated word: '$first'\n" . $herecurr) &&
3421*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3422*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3423*d68f33bcSAndroid Build Coastguard Worker				}
3424*d68f33bcSAndroid Build Coastguard Worker			}
3425*d68f33bcSAndroid Build Coastguard Worker
3426*d68f33bcSAndroid Build Coastguard Worker			# if it's a repeated word on consecutive lines in a comment block
3427*d68f33bcSAndroid Build Coastguard Worker			if ($prevline =~ /$;+\s*$/ &&
3428*d68f33bcSAndroid Build Coastguard Worker			    $prevrawline =~ /($word_pattern)\s*$/) {
3429*d68f33bcSAndroid Build Coastguard Worker				my $last_word = $1;
3430*d68f33bcSAndroid Build Coastguard Worker				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3431*d68f33bcSAndroid Build Coastguard Worker					if (WARN("REPEATED_WORD",
3432*d68f33bcSAndroid Build Coastguard Worker						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3433*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
3434*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3435*d68f33bcSAndroid Build Coastguard Worker					}
3436*d68f33bcSAndroid Build Coastguard Worker				}
3437*d68f33bcSAndroid Build Coastguard Worker			}
3438*d68f33bcSAndroid Build Coastguard Worker		}
3439*d68f33bcSAndroid Build Coastguard Worker
3440*d68f33bcSAndroid Build Coastguard Worker# ignore non-hunk lines and lines being removed
3441*d68f33bcSAndroid Build Coastguard Worker		next if (!$hunk_line || $line =~ /^-/);
3442*d68f33bcSAndroid Build Coastguard Worker
3443*d68f33bcSAndroid Build Coastguard Worker#trailing whitespace
3444*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*\015/) {
3445*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3446*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("DOS_LINE_ENDINGS",
3447*d68f33bcSAndroid Build Coastguard Worker				  "DOS line endings\n" . $herevet) &&
3448*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3449*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3450*d68f33bcSAndroid Build Coastguard Worker			}
3451*d68f33bcSAndroid Build Coastguard Worker		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3452*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3453*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("TRAILING_WHITESPACE",
3454*d68f33bcSAndroid Build Coastguard Worker				  "trailing whitespace\n" . $herevet) &&
3455*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3456*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\s+$//;
3457*d68f33bcSAndroid Build Coastguard Worker			}
3458*d68f33bcSAndroid Build Coastguard Worker
3459*d68f33bcSAndroid Build Coastguard Worker			$rpt_cleaners = 1;
3460*d68f33bcSAndroid Build Coastguard Worker		}
3461*d68f33bcSAndroid Build Coastguard Worker
3462*d68f33bcSAndroid Build Coastguard Worker# Check for FSF mailing addresses.
3463*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /\bwrite to the Free/i ||
3464*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
3465*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
3466*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /\b51\s+Franklin\s+St/i) {
3467*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3468*d68f33bcSAndroid Build Coastguard Worker			my $msg_level = \&ERROR;
3469*d68f33bcSAndroid Build Coastguard Worker			$msg_level = \&CHK if ($file);
3470*d68f33bcSAndroid Build Coastguard Worker			&{$msg_level}("FSF_MAILING_ADDRESS",
3471*d68f33bcSAndroid Build Coastguard Worker				      "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)
3472*d68f33bcSAndroid Build Coastguard Worker		}
3473*d68f33bcSAndroid Build Coastguard Worker
3474*d68f33bcSAndroid Build Coastguard Worker# check for Kconfig help text having a real description
3475*d68f33bcSAndroid Build Coastguard Worker# Only applies when adding the entry originally, after that we do not have
3476*d68f33bcSAndroid Build Coastguard Worker# sufficient context to determine whether it is indeed long enough.
3477*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ /Kconfig/ &&
3478*d68f33bcSAndroid Build Coastguard Worker		    # 'choice' is usually the last thing on the line (though
3479*d68f33bcSAndroid Build Coastguard Worker		    # Kconfig supports named choices), so use a word boundary
3480*d68f33bcSAndroid Build Coastguard Worker		    # (\b) rather than a whitespace character (\s)
3481*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
3482*d68f33bcSAndroid Build Coastguard Worker			my $ln = $linenr;
3483*d68f33bcSAndroid Build Coastguard Worker			my $needs_help = 0;
3484*d68f33bcSAndroid Build Coastguard Worker			my $has_help = 0;
3485*d68f33bcSAndroid Build Coastguard Worker			my $help_length = 0;
3486*d68f33bcSAndroid Build Coastguard Worker			while (defined $lines[$ln]) {
3487*d68f33bcSAndroid Build Coastguard Worker				my $f = $lines[$ln++];
3488*d68f33bcSAndroid Build Coastguard Worker
3489*d68f33bcSAndroid Build Coastguard Worker				next if ($f =~ /^-/);
3490*d68f33bcSAndroid Build Coastguard Worker				last if ($f !~ /^[\+ ]/);	# !patch context
3491*d68f33bcSAndroid Build Coastguard Worker
3492*d68f33bcSAndroid Build Coastguard Worker				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3493*d68f33bcSAndroid Build Coastguard Worker					$needs_help = 1;
3494*d68f33bcSAndroid Build Coastguard Worker					next;
3495*d68f33bcSAndroid Build Coastguard Worker				}
3496*d68f33bcSAndroid Build Coastguard Worker				if ($f =~ /^\+\s*help\s*$/) {
3497*d68f33bcSAndroid Build Coastguard Worker					$has_help = 1;
3498*d68f33bcSAndroid Build Coastguard Worker					next;
3499*d68f33bcSAndroid Build Coastguard Worker				}
3500*d68f33bcSAndroid Build Coastguard Worker
3501*d68f33bcSAndroid Build Coastguard Worker				$f =~ s/^.//;	# strip patch context [+ ]
3502*d68f33bcSAndroid Build Coastguard Worker				$f =~ s/#.*//;	# strip # directives
3503*d68f33bcSAndroid Build Coastguard Worker				$f =~ s/^\s+//;	# strip leading blanks
3504*d68f33bcSAndroid Build Coastguard Worker				next if ($f =~ /^$/);	# skip blank lines
3505*d68f33bcSAndroid Build Coastguard Worker
3506*d68f33bcSAndroid Build Coastguard Worker				# At the end of this Kconfig block:
3507*d68f33bcSAndroid Build Coastguard Worker				# This only checks context lines in the patch
3508*d68f33bcSAndroid Build Coastguard Worker				# and so hopefully shouldn't trigger false
3509*d68f33bcSAndroid Build Coastguard Worker				# positives, even though some of these are
3510*d68f33bcSAndroid Build Coastguard Worker				# common words in help texts
3511*d68f33bcSAndroid Build Coastguard Worker				if ($f =~ /^(?:config|menuconfig|choice|endchoice|
3512*d68f33bcSAndroid Build Coastguard Worker					       if|endif|menu|endmenu|source)\b/x) {
3513*d68f33bcSAndroid Build Coastguard Worker					last;
3514*d68f33bcSAndroid Build Coastguard Worker				}
3515*d68f33bcSAndroid Build Coastguard Worker				$help_length++ if ($has_help);
3516*d68f33bcSAndroid Build Coastguard Worker			}
3517*d68f33bcSAndroid Build Coastguard Worker			if ($needs_help &&
3518*d68f33bcSAndroid Build Coastguard Worker			    $help_length < $min_conf_desc_length) {
3519*d68f33bcSAndroid Build Coastguard Worker				my $stat_real = get_stat_real($linenr, $ln - 1);
3520*d68f33bcSAndroid Build Coastguard Worker				WARN("CONFIG_DESCRIPTION",
3521*d68f33bcSAndroid Build Coastguard Worker				     "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n");
3522*d68f33bcSAndroid Build Coastguard Worker			}
3523*d68f33bcSAndroid Build Coastguard Worker		}
3524*d68f33bcSAndroid Build Coastguard Worker
3525*d68f33bcSAndroid Build Coastguard Worker# check MAINTAINERS entries
3526*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ /^MAINTAINERS$/) {
3527*d68f33bcSAndroid Build Coastguard Worker# check MAINTAINERS entries for the right form
3528*d68f33bcSAndroid Build Coastguard Worker			if ($rawline =~ /^\+[A-Z]:/ &&
3529*d68f33bcSAndroid Build Coastguard Worker			    $rawline !~ /^\+[A-Z]:\t\S/) {
3530*d68f33bcSAndroid Build Coastguard Worker				if (WARN("MAINTAINERS_STYLE",
3531*d68f33bcSAndroid Build Coastguard Worker					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3532*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3533*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3534*d68f33bcSAndroid Build Coastguard Worker				}
3535*d68f33bcSAndroid Build Coastguard Worker			}
3536*d68f33bcSAndroid Build Coastguard Worker# check MAINTAINERS entries for the right ordering too
3537*d68f33bcSAndroid Build Coastguard Worker			my $preferred_order = 'MRLSWQBCPTFXNK';
3538*d68f33bcSAndroid Build Coastguard Worker			if ($rawline =~ /^\+[A-Z]:/ &&
3539*d68f33bcSAndroid Build Coastguard Worker			    $prevrawline =~ /^[\+ ][A-Z]:/) {
3540*d68f33bcSAndroid Build Coastguard Worker				$rawline =~ /^\+([A-Z]):\s*(.*)/;
3541*d68f33bcSAndroid Build Coastguard Worker				my $cur = $1;
3542*d68f33bcSAndroid Build Coastguard Worker				my $curval = $2;
3543*d68f33bcSAndroid Build Coastguard Worker				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
3544*d68f33bcSAndroid Build Coastguard Worker				my $prev = $1;
3545*d68f33bcSAndroid Build Coastguard Worker				my $prevval = $2;
3546*d68f33bcSAndroid Build Coastguard Worker				my $curindex = index($preferred_order, $cur);
3547*d68f33bcSAndroid Build Coastguard Worker				my $previndex = index($preferred_order, $prev);
3548*d68f33bcSAndroid Build Coastguard Worker				if ($curindex < 0) {
3549*d68f33bcSAndroid Build Coastguard Worker					WARN("MAINTAINERS_STYLE",
3550*d68f33bcSAndroid Build Coastguard Worker					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
3551*d68f33bcSAndroid Build Coastguard Worker				} else {
3552*d68f33bcSAndroid Build Coastguard Worker					if ($previndex >= 0 && $curindex < $previndex) {
3553*d68f33bcSAndroid Build Coastguard Worker						WARN("MAINTAINERS_STYLE",
3554*d68f33bcSAndroid Build Coastguard Worker						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3555*d68f33bcSAndroid Build Coastguard Worker					} elsif ((($prev eq 'F' && $cur eq 'F') ||
3556*d68f33bcSAndroid Build Coastguard Worker						  ($prev eq 'X' && $cur eq 'X')) &&
3557*d68f33bcSAndroid Build Coastguard Worker						 ($prevval cmp $curval) > 0) {
3558*d68f33bcSAndroid Build Coastguard Worker						WARN("MAINTAINERS_STYLE",
3559*d68f33bcSAndroid Build Coastguard Worker						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3560*d68f33bcSAndroid Build Coastguard Worker					}
3561*d68f33bcSAndroid Build Coastguard Worker				}
3562*d68f33bcSAndroid Build Coastguard Worker			}
3563*d68f33bcSAndroid Build Coastguard Worker		}
3564*d68f33bcSAndroid Build Coastguard Worker
3565*d68f33bcSAndroid Build Coastguard Worker		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3566*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3567*d68f33bcSAndroid Build Coastguard Worker			my $flag = $1;
3568*d68f33bcSAndroid Build Coastguard Worker			my $replacement = {
3569*d68f33bcSAndroid Build Coastguard Worker				'EXTRA_AFLAGS' =>   'asflags-y',
3570*d68f33bcSAndroid Build Coastguard Worker				'EXTRA_CFLAGS' =>   'ccflags-y',
3571*d68f33bcSAndroid Build Coastguard Worker				'EXTRA_CPPFLAGS' => 'cppflags-y',
3572*d68f33bcSAndroid Build Coastguard Worker				'EXTRA_LDFLAGS' =>  'ldflags-y',
3573*d68f33bcSAndroid Build Coastguard Worker			};
3574*d68f33bcSAndroid Build Coastguard Worker
3575*d68f33bcSAndroid Build Coastguard Worker			WARN("DEPRECATED_VARIABLE",
3576*d68f33bcSAndroid Build Coastguard Worker			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3577*d68f33bcSAndroid Build Coastguard Worker		}
3578*d68f33bcSAndroid Build Coastguard Worker
3579*d68f33bcSAndroid Build Coastguard Worker# check for DT compatible documentation
3580*d68f33bcSAndroid Build Coastguard Worker		if (defined $root &&
3581*d68f33bcSAndroid Build Coastguard Worker			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3582*d68f33bcSAndroid Build Coastguard Worker			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3583*d68f33bcSAndroid Build Coastguard Worker
3584*d68f33bcSAndroid Build Coastguard Worker			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3585*d68f33bcSAndroid Build Coastguard Worker
3586*d68f33bcSAndroid Build Coastguard Worker			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3587*d68f33bcSAndroid Build Coastguard Worker			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3588*d68f33bcSAndroid Build Coastguard Worker
3589*d68f33bcSAndroid Build Coastguard Worker			foreach my $compat (@compats) {
3590*d68f33bcSAndroid Build Coastguard Worker				my $compat2 = $compat;
3591*d68f33bcSAndroid Build Coastguard Worker				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3592*d68f33bcSAndroid Build Coastguard Worker				my $compat3 = $compat;
3593*d68f33bcSAndroid Build Coastguard Worker				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3594*d68f33bcSAndroid Build Coastguard Worker				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3595*d68f33bcSAndroid Build Coastguard Worker				if ( $? >> 8 ) {
3596*d68f33bcSAndroid Build Coastguard Worker					WARN("UNDOCUMENTED_DT_STRING",
3597*d68f33bcSAndroid Build Coastguard Worker					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3598*d68f33bcSAndroid Build Coastguard Worker				}
3599*d68f33bcSAndroid Build Coastguard Worker
3600*d68f33bcSAndroid Build Coastguard Worker				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3601*d68f33bcSAndroid Build Coastguard Worker				my $vendor = $1;
3602*d68f33bcSAndroid Build Coastguard Worker				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3603*d68f33bcSAndroid Build Coastguard Worker				if ( $? >> 8 ) {
3604*d68f33bcSAndroid Build Coastguard Worker					WARN("UNDOCUMENTED_DT_STRING",
3605*d68f33bcSAndroid Build Coastguard Worker					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3606*d68f33bcSAndroid Build Coastguard Worker				}
3607*d68f33bcSAndroid Build Coastguard Worker			}
3608*d68f33bcSAndroid Build Coastguard Worker		}
3609*d68f33bcSAndroid Build Coastguard Worker
3610*d68f33bcSAndroid Build Coastguard Worker# check for using SPDX license tag at beginning of files
3611*d68f33bcSAndroid Build Coastguard Worker		if ($realline == $checklicenseline) {
3612*d68f33bcSAndroid Build Coastguard Worker			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3613*d68f33bcSAndroid Build Coastguard Worker				$checklicenseline = 2;
3614*d68f33bcSAndroid Build Coastguard Worker			} elsif ($rawline =~ /^\+/) {
3615*d68f33bcSAndroid Build Coastguard Worker				my $comment = "";
3616*d68f33bcSAndroid Build Coastguard Worker				if ($realfile =~ /\.(h|s|S)$/) {
3617*d68f33bcSAndroid Build Coastguard Worker					$comment = '/*';
3618*d68f33bcSAndroid Build Coastguard Worker				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3619*d68f33bcSAndroid Build Coastguard Worker					$comment = '//';
3620*d68f33bcSAndroid Build Coastguard Worker				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
3621*d68f33bcSAndroid Build Coastguard Worker					$comment = '#';
3622*d68f33bcSAndroid Build Coastguard Worker				} elsif ($realfile =~ /\.rst$/) {
3623*d68f33bcSAndroid Build Coastguard Worker					$comment = '..';
3624*d68f33bcSAndroid Build Coastguard Worker				}
3625*d68f33bcSAndroid Build Coastguard Worker
3626*d68f33bcSAndroid Build Coastguard Worker# check SPDX comment style for .[chsS] files
3627*d68f33bcSAndroid Build Coastguard Worker				if ($realfile =~ /\.[chsS]$/ &&
3628*d68f33bcSAndroid Build Coastguard Worker				    $rawline =~ /SPDX-License-Identifier:/ &&
3629*d68f33bcSAndroid Build Coastguard Worker				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3630*d68f33bcSAndroid Build Coastguard Worker					WARN("SPDX_LICENSE_TAG",
3631*d68f33bcSAndroid Build Coastguard Worker					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3632*d68f33bcSAndroid Build Coastguard Worker				}
3633*d68f33bcSAndroid Build Coastguard Worker
3634*d68f33bcSAndroid Build Coastguard Worker				if ($comment !~ /^$/ &&
3635*d68f33bcSAndroid Build Coastguard Worker				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
3636*d68f33bcSAndroid Build Coastguard Worker					WARN("SPDX_LICENSE_TAG",
3637*d68f33bcSAndroid Build Coastguard Worker					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3638*d68f33bcSAndroid Build Coastguard Worker				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
3639*d68f33bcSAndroid Build Coastguard Worker					my $spdx_license = $1;
3640*d68f33bcSAndroid Build Coastguard Worker					if (!is_SPDX_License_valid($spdx_license)) {
3641*d68f33bcSAndroid Build Coastguard Worker						WARN("SPDX_LICENSE_TAG",
3642*d68f33bcSAndroid Build Coastguard Worker						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3643*d68f33bcSAndroid Build Coastguard Worker					}
3644*d68f33bcSAndroid Build Coastguard Worker					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3645*d68f33bcSAndroid Build Coastguard Worker					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
3646*d68f33bcSAndroid Build Coastguard Worker						my $msg_level = \&WARN;
3647*d68f33bcSAndroid Build Coastguard Worker						$msg_level = \&CHK if ($file);
3648*d68f33bcSAndroid Build Coastguard Worker						if (&{$msg_level}("SPDX_LICENSE_TAG",
3649*d68f33bcSAndroid Build Coastguard Worker
3650*d68f33bcSAndroid Build Coastguard Worker								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3651*d68f33bcSAndroid Build Coastguard Worker						    $fix) {
3652*d68f33bcSAndroid Build Coastguard Worker							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3653*d68f33bcSAndroid Build Coastguard Worker						}
3654*d68f33bcSAndroid Build Coastguard Worker					}
3655*d68f33bcSAndroid Build Coastguard Worker				}
3656*d68f33bcSAndroid Build Coastguard Worker			}
3657*d68f33bcSAndroid Build Coastguard Worker		}
3658*d68f33bcSAndroid Build Coastguard Worker
3659*d68f33bcSAndroid Build Coastguard Worker# check for embedded filenames
3660*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3661*d68f33bcSAndroid Build Coastguard Worker			WARN("EMBEDDED_FILENAME",
3662*d68f33bcSAndroid Build Coastguard Worker			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3663*d68f33bcSAndroid Build Coastguard Worker		}
3664*d68f33bcSAndroid Build Coastguard Worker
3665*d68f33bcSAndroid Build Coastguard Worker# check we are in a valid source file if not then ignore this hunk
3666*d68f33bcSAndroid Build Coastguard Worker		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
3667*d68f33bcSAndroid Build Coastguard Worker
3668*d68f33bcSAndroid Build Coastguard Worker# check for using SPDX-License-Identifier on the wrong line number
3669*d68f33bcSAndroid Build Coastguard Worker		if ($realline != $checklicenseline &&
3670*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3671*d68f33bcSAndroid Build Coastguard Worker		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3672*d68f33bcSAndroid Build Coastguard Worker			WARN("SPDX_LICENSE_TAG",
3673*d68f33bcSAndroid Build Coastguard Worker			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3674*d68f33bcSAndroid Build Coastguard Worker		}
3675*d68f33bcSAndroid Build Coastguard Worker
3676*d68f33bcSAndroid Build Coastguard Worker# line length limit (with some exclusions)
3677*d68f33bcSAndroid Build Coastguard Worker#
3678*d68f33bcSAndroid Build Coastguard Worker# There are a few types of lines that may extend beyond $max_line_length:
3679*d68f33bcSAndroid Build Coastguard Worker#	logging functions like pr_info that end in a string
3680*d68f33bcSAndroid Build Coastguard Worker#	lines with a single string
3681*d68f33bcSAndroid Build Coastguard Worker#	#defines that are a single string
3682*d68f33bcSAndroid Build Coastguard Worker#	lines with an RFC3986 like URL
3683*d68f33bcSAndroid Build Coastguard Worker#
3684*d68f33bcSAndroid Build Coastguard Worker# There are 3 different line length message types:
3685*d68f33bcSAndroid Build Coastguard Worker# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
3686*d68f33bcSAndroid Build Coastguard Worker# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
3687*d68f33bcSAndroid Build Coastguard Worker# LONG_LINE		all other lines longer than $max_line_length
3688*d68f33bcSAndroid Build Coastguard Worker#
3689*d68f33bcSAndroid Build Coastguard Worker# if LONG_LINE is ignored, the other 2 types are also ignored
3690*d68f33bcSAndroid Build Coastguard Worker#
3691*d68f33bcSAndroid Build Coastguard Worker
3692*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+/ && $length > $max_line_length) {
3693*d68f33bcSAndroid Build Coastguard Worker			my $msg_type = "LONG_LINE";
3694*d68f33bcSAndroid Build Coastguard Worker
3695*d68f33bcSAndroid Build Coastguard Worker			# Check the allowed long line types first
3696*d68f33bcSAndroid Build Coastguard Worker
3697*d68f33bcSAndroid Build Coastguard Worker			# logging functions that end in a string that starts
3698*d68f33bcSAndroid Build Coastguard Worker			# before $max_line_length
3699*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3700*d68f33bcSAndroid Build Coastguard Worker			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3701*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "";
3702*d68f33bcSAndroid Build Coastguard Worker
3703*d68f33bcSAndroid Build Coastguard Worker			# lines with only strings (w/ possible termination)
3704*d68f33bcSAndroid Build Coastguard Worker			# #defines with only strings
3705*d68f33bcSAndroid Build Coastguard Worker			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3706*d68f33bcSAndroid Build Coastguard Worker				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3707*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "";
3708*d68f33bcSAndroid Build Coastguard Worker
3709*d68f33bcSAndroid Build Coastguard Worker			# More special cases
3710*d68f33bcSAndroid Build Coastguard Worker			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3711*d68f33bcSAndroid Build Coastguard Worker				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3712*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "";
3713*d68f33bcSAndroid Build Coastguard Worker
3714*d68f33bcSAndroid Build Coastguard Worker			# URL ($rawline is used in case the URL is in a comment)
3715*d68f33bcSAndroid Build Coastguard Worker			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
3716*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "";
3717*d68f33bcSAndroid Build Coastguard Worker
3718*d68f33bcSAndroid Build Coastguard Worker			# Otherwise set the alternate message types
3719*d68f33bcSAndroid Build Coastguard Worker
3720*d68f33bcSAndroid Build Coastguard Worker			# a comment starts before $max_line_length
3721*d68f33bcSAndroid Build Coastguard Worker			} elsif ($line =~ /($;[\s$;]*)$/ &&
3722*d68f33bcSAndroid Build Coastguard Worker				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3723*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "LONG_LINE_COMMENT"
3724*d68f33bcSAndroid Build Coastguard Worker
3725*d68f33bcSAndroid Build Coastguard Worker			# a quoted string starts before $max_line_length
3726*d68f33bcSAndroid Build Coastguard Worker			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3727*d68f33bcSAndroid Build Coastguard Worker				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3728*d68f33bcSAndroid Build Coastguard Worker				$msg_type = "LONG_LINE_STRING"
3729*d68f33bcSAndroid Build Coastguard Worker			}
3730*d68f33bcSAndroid Build Coastguard Worker
3731*d68f33bcSAndroid Build Coastguard Worker			if ($msg_type ne "" &&
3732*d68f33bcSAndroid Build Coastguard Worker			    (show_type("LONG_LINE") || show_type($msg_type))) {
3733*d68f33bcSAndroid Build Coastguard Worker				my $msg_level = \&WARN;
3734*d68f33bcSAndroid Build Coastguard Worker				$msg_level = \&CHK if ($file);
3735*d68f33bcSAndroid Build Coastguard Worker				&{$msg_level}($msg_type,
3736*d68f33bcSAndroid Build Coastguard Worker					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
3737*d68f33bcSAndroid Build Coastguard Worker			}
3738*d68f33bcSAndroid Build Coastguard Worker		}
3739*d68f33bcSAndroid Build Coastguard Worker
3740*d68f33bcSAndroid Build Coastguard Worker# check for adding lines without a newline.
3741*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3742*d68f33bcSAndroid Build Coastguard Worker			if (WARN("MISSING_EOF_NEWLINE",
3743*d68f33bcSAndroid Build Coastguard Worker			         "adding a line without newline at end of file\n" . $herecurr) &&
3744*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3745*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr+1, "No newline at end of file");
3746*d68f33bcSAndroid Build Coastguard Worker			}
3747*d68f33bcSAndroid Build Coastguard Worker		}
3748*d68f33bcSAndroid Build Coastguard Worker
3749*d68f33bcSAndroid Build Coastguard Worker# check for .L prefix local symbols in .S files
3750*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ /\.S$/ &&
3751*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3752*d68f33bcSAndroid Build Coastguard Worker			WARN("AVOID_L_PREFIX",
3753*d68f33bcSAndroid Build Coastguard Worker			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr);
3754*d68f33bcSAndroid Build Coastguard Worker		}
3755*d68f33bcSAndroid Build Coastguard Worker
3756*d68f33bcSAndroid Build Coastguard Worker# check we are in a valid source file C or perl if not then ignore this hunk
3757*d68f33bcSAndroid Build Coastguard Worker		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
3758*d68f33bcSAndroid Build Coastguard Worker
3759*d68f33bcSAndroid Build Coastguard Worker# at the beginning of a line any tabs must come first and anything
3760*d68f33bcSAndroid Build Coastguard Worker# more than $tabsize must use tabs.
3761*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3762*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /^\+\s*        \s*/) {
3763*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3764*d68f33bcSAndroid Build Coastguard Worker			$rpt_cleaners = 1;
3765*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("CODE_INDENT",
3766*d68f33bcSAndroid Build Coastguard Worker				  "code indent should use tabs where possible\n" . $herevet) &&
3767*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3768*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3769*d68f33bcSAndroid Build Coastguard Worker			}
3770*d68f33bcSAndroid Build Coastguard Worker		}
3771*d68f33bcSAndroid Build Coastguard Worker
3772*d68f33bcSAndroid Build Coastguard Worker# check for space before tabs.
3773*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3774*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3775*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SPACE_BEFORE_TAB",
3776*d68f33bcSAndroid Build Coastguard Worker				"please, no space before tabs\n" . $herevet) &&
3777*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3778*d68f33bcSAndroid Build Coastguard Worker				while ($fixed[$fixlinenr] =~
3779*d68f33bcSAndroid Build Coastguard Worker					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3780*d68f33bcSAndroid Build Coastguard Worker				while ($fixed[$fixlinenr] =~
3781*d68f33bcSAndroid Build Coastguard Worker					   s/(^\+.*) +\t/$1\t/) {}
3782*d68f33bcSAndroid Build Coastguard Worker			}
3783*d68f33bcSAndroid Build Coastguard Worker		}
3784*d68f33bcSAndroid Build Coastguard Worker
3785*d68f33bcSAndroid Build Coastguard Worker# check for assignments on the start of a line
3786*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3787*d68f33bcSAndroid Build Coastguard Worker			my $operator = $1;
3788*d68f33bcSAndroid Build Coastguard Worker			if (CHK("ASSIGNMENT_CONTINUATIONS",
3789*d68f33bcSAndroid Build Coastguard Worker				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3790*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevrawline =~ /^\+/) {
3791*d68f33bcSAndroid Build Coastguard Worker				# add assignment operator to the previous line, remove from current line
3792*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr - 1] .= " $operator";
3793*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3794*d68f33bcSAndroid Build Coastguard Worker			}
3795*d68f33bcSAndroid Build Coastguard Worker		}
3796*d68f33bcSAndroid Build Coastguard Worker
3797*d68f33bcSAndroid Build Coastguard Worker# check for && or || at the start of a line
3798*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3799*d68f33bcSAndroid Build Coastguard Worker			my $operator = $1;
3800*d68f33bcSAndroid Build Coastguard Worker			if (CHK("LOGICAL_CONTINUATIONS",
3801*d68f33bcSAndroid Build Coastguard Worker				"Logical continuations should be on the previous line\n" . $hereprev) &&
3802*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevrawline =~ /^\+/) {
3803*d68f33bcSAndroid Build Coastguard Worker				# insert logical operator at last non-comment, non-whitepsace char on previous line
3804*d68f33bcSAndroid Build Coastguard Worker				$prevline =~ /[\s$;]*$/;
3805*d68f33bcSAndroid Build Coastguard Worker				my $line_end = substr($prevrawline, $-[0]);
3806*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
3807*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3808*d68f33bcSAndroid Build Coastguard Worker			}
3809*d68f33bcSAndroid Build Coastguard Worker		}
3810*d68f33bcSAndroid Build Coastguard Worker
3811*d68f33bcSAndroid Build Coastguard Worker# check indentation starts on a tab stop
3812*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
3813*d68f33bcSAndroid Build Coastguard Worker		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3814*d68f33bcSAndroid Build Coastguard Worker			my $indent = length($1);
3815*d68f33bcSAndroid Build Coastguard Worker			if ($indent % $tabsize) {
3816*d68f33bcSAndroid Build Coastguard Worker				if (WARN("TABSTOP",
3817*d68f33bcSAndroid Build Coastguard Worker					 "Statements should start on a tabstop\n" . $herecurr) &&
3818*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3819*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3820*d68f33bcSAndroid Build Coastguard Worker				}
3821*d68f33bcSAndroid Build Coastguard Worker			}
3822*d68f33bcSAndroid Build Coastguard Worker		}
3823*d68f33bcSAndroid Build Coastguard Worker
3824*d68f33bcSAndroid Build Coastguard Worker# check multi-line statement indentation matches previous line
3825*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
3826*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3827*d68f33bcSAndroid Build Coastguard Worker			$prevline =~ /^\+(\t*)(.*)$/;
3828*d68f33bcSAndroid Build Coastguard Worker			my $oldindent = $1;
3829*d68f33bcSAndroid Build Coastguard Worker			my $rest = $2;
3830*d68f33bcSAndroid Build Coastguard Worker
3831*d68f33bcSAndroid Build Coastguard Worker			my $pos = pos_last_openparen($rest);
3832*d68f33bcSAndroid Build Coastguard Worker			if ($pos >= 0) {
3833*d68f33bcSAndroid Build Coastguard Worker				$line =~ /^(\+| )([ \t]*)/;
3834*d68f33bcSAndroid Build Coastguard Worker				my $newindent = $2;
3835*d68f33bcSAndroid Build Coastguard Worker
3836*d68f33bcSAndroid Build Coastguard Worker				my $goodtabindent = $oldindent .
3837*d68f33bcSAndroid Build Coastguard Worker					"\t" x ($pos / $tabsize) .
3838*d68f33bcSAndroid Build Coastguard Worker					" "  x ($pos % $tabsize);
3839*d68f33bcSAndroid Build Coastguard Worker				my $goodspaceindent = $oldindent . " "  x $pos;
3840*d68f33bcSAndroid Build Coastguard Worker
3841*d68f33bcSAndroid Build Coastguard Worker				if ($newindent ne $goodtabindent &&
3842*d68f33bcSAndroid Build Coastguard Worker				    $newindent ne $goodspaceindent) {
3843*d68f33bcSAndroid Build Coastguard Worker
3844*d68f33bcSAndroid Build Coastguard Worker					if (CHK("PARENTHESIS_ALIGNMENT",
3845*d68f33bcSAndroid Build Coastguard Worker						"Alignment should match open parenthesis\n" . $hereprev) &&
3846*d68f33bcSAndroid Build Coastguard Worker					    $fix && $line =~ /^\+/) {
3847*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~
3848*d68f33bcSAndroid Build Coastguard Worker						    s/^\+[ \t]*/\+$goodtabindent/;
3849*d68f33bcSAndroid Build Coastguard Worker					}
3850*d68f33bcSAndroid Build Coastguard Worker				}
3851*d68f33bcSAndroid Build Coastguard Worker			}
3852*d68f33bcSAndroid Build Coastguard Worker		}
3853*d68f33bcSAndroid Build Coastguard Worker
3854*d68f33bcSAndroid Build Coastguard Worker# check for space after cast like "(int) foo" or "(struct foo) bar"
3855*d68f33bcSAndroid Build Coastguard Worker# avoid checking a few false positives:
3856*d68f33bcSAndroid Build Coastguard Worker#   "sizeof(<type>)" or "__alignof__(<type>)"
3857*d68f33bcSAndroid Build Coastguard Worker#   function pointer declarations like "(*foo)(int) = bar;"
3858*d68f33bcSAndroid Build Coastguard Worker#   structure definitions like "(struct foo) { 0 };"
3859*d68f33bcSAndroid Build Coastguard Worker#   multiline macros that define functions
3860*d68f33bcSAndroid Build Coastguard Worker#   known attributes or the __attribute__ keyword
3861*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3862*d68f33bcSAndroid Build Coastguard Worker		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
3863*d68f33bcSAndroid Build Coastguard Worker			if (CHK("SPACING",
3864*d68f33bcSAndroid Build Coastguard Worker				"No space is necessary after a cast\n" . $herecurr) &&
3865*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3866*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
3867*d68f33bcSAndroid Build Coastguard Worker				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
3868*d68f33bcSAndroid Build Coastguard Worker			}
3869*d68f33bcSAndroid Build Coastguard Worker		}
3870*d68f33bcSAndroid Build Coastguard Worker
3871*d68f33bcSAndroid Build Coastguard Worker# Block comment styles
3872*d68f33bcSAndroid Build Coastguard Worker# Networking with an initial /*
3873*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3874*d68f33bcSAndroid Build Coastguard Worker		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
3875*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /^\+[ \t]*\*/ &&
3876*d68f33bcSAndroid Build Coastguard Worker		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
3877*d68f33bcSAndroid Build Coastguard Worker			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3878*d68f33bcSAndroid Build Coastguard Worker			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3879*d68f33bcSAndroid Build Coastguard Worker		}
3880*d68f33bcSAndroid Build Coastguard Worker
3881*d68f33bcSAndroid Build Coastguard Worker# Block comments use * on subsequent lines
3882*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3883*d68f33bcSAndroid Build Coastguard Worker		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3884*d68f33bcSAndroid Build Coastguard Worker		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
3885*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /^\+/ &&			#line is new
3886*d68f33bcSAndroid Build Coastguard Worker		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
3887*d68f33bcSAndroid Build Coastguard Worker			WARN("BLOCK_COMMENT_STYLE",
3888*d68f33bcSAndroid Build Coastguard Worker			     "Block comments use * on subsequent lines\n" . $hereprev);
3889*d68f33bcSAndroid Build Coastguard Worker		}
3890*d68f33bcSAndroid Build Coastguard Worker
3891*d68f33bcSAndroid Build Coastguard Worker# Block comments use */ on trailing lines
3892*d68f33bcSAndroid Build Coastguard Worker		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3893*d68f33bcSAndroid Build Coastguard Worker		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3894*d68f33bcSAndroid Build Coastguard Worker		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3895*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
3896*d68f33bcSAndroid Build Coastguard Worker			WARN("BLOCK_COMMENT_STYLE",
3897*d68f33bcSAndroid Build Coastguard Worker			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
3898*d68f33bcSAndroid Build Coastguard Worker		}
3899*d68f33bcSAndroid Build Coastguard Worker
3900*d68f33bcSAndroid Build Coastguard Worker# Block comment * alignment
3901*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3902*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3903*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3904*d68f33bcSAndroid Build Coastguard Worker		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
3905*d68f33bcSAndroid Build Coastguard Worker		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3906*d68f33bcSAndroid Build Coastguard Worker		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3907*d68f33bcSAndroid Build Coastguard Worker			my $oldindent;
3908*d68f33bcSAndroid Build Coastguard Worker			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3909*d68f33bcSAndroid Build Coastguard Worker			if (defined($1)) {
3910*d68f33bcSAndroid Build Coastguard Worker				$oldindent = expand_tabs($1);
3911*d68f33bcSAndroid Build Coastguard Worker			} else {
3912*d68f33bcSAndroid Build Coastguard Worker				$prevrawline =~ m@^\+(.*/?)\*@;
3913*d68f33bcSAndroid Build Coastguard Worker				$oldindent = expand_tabs($1);
3914*d68f33bcSAndroid Build Coastguard Worker			}
3915*d68f33bcSAndroid Build Coastguard Worker			$rawline =~ m@^\+([ \t]*)\*@;
3916*d68f33bcSAndroid Build Coastguard Worker			my $newindent = $1;
3917*d68f33bcSAndroid Build Coastguard Worker			$newindent = expand_tabs($newindent);
3918*d68f33bcSAndroid Build Coastguard Worker			if (length($oldindent) ne length($newindent)) {
3919*d68f33bcSAndroid Build Coastguard Worker				WARN("BLOCK_COMMENT_STYLE",
3920*d68f33bcSAndroid Build Coastguard Worker				     "Block comments should align the * on each line\n" . $hereprev);
3921*d68f33bcSAndroid Build Coastguard Worker			}
3922*d68f33bcSAndroid Build Coastguard Worker		}
3923*d68f33bcSAndroid Build Coastguard Worker
3924*d68f33bcSAndroid Build Coastguard Worker# check for missing blank lines after struct/union declarations
3925*d68f33bcSAndroid Build Coastguard Worker# with exceptions for various attributes and macros
3926*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /^[\+ ]};?\s*$/ &&
3927*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+/ &&
3928*d68f33bcSAndroid Build Coastguard Worker		    !($line =~ /^\+\s*$/ ||
3929*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
3930*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*MODULE_/i ||
3931*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
3932*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+[a-z_]*init/ ||
3933*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
3934*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*DECLARE/ ||
3935*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
3936*d68f33bcSAndroid Build Coastguard Worker		      $line =~ /^\+\s*__setup/)) {
3937*d68f33bcSAndroid Build Coastguard Worker			if (CHK("LINE_SPACING",
3938*d68f33bcSAndroid Build Coastguard Worker				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3939*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3940*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, "\+");
3941*d68f33bcSAndroid Build Coastguard Worker			}
3942*d68f33bcSAndroid Build Coastguard Worker		}
3943*d68f33bcSAndroid Build Coastguard Worker
3944*d68f33bcSAndroid Build Coastguard Worker# check for multiple consecutive blank lines
3945*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /^[\+ ]\s*$/ &&
3946*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+\s*$/ &&
3947*d68f33bcSAndroid Build Coastguard Worker		    $last_blank_line != ($linenr - 1)) {
3948*d68f33bcSAndroid Build Coastguard Worker			if (CHK("LINE_SPACING",
3949*d68f33bcSAndroid Build Coastguard Worker				"Please don't use multiple blank lines\n" . $hereprev) &&
3950*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
3951*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
3952*d68f33bcSAndroid Build Coastguard Worker			}
3953*d68f33bcSAndroid Build Coastguard Worker
3954*d68f33bcSAndroid Build Coastguard Worker			$last_blank_line = $linenr;
3955*d68f33bcSAndroid Build Coastguard Worker		}
3956*d68f33bcSAndroid Build Coastguard Worker
3957*d68f33bcSAndroid Build Coastguard Worker# check for missing blank lines after declarations
3958*d68f33bcSAndroid Build Coastguard Worker# (declarations must have the same indentation and not be at the start of line)
3959*d68f33bcSAndroid Build Coastguard Worker		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3960*d68f33bcSAndroid Build Coastguard Worker			# use temporaries
3961*d68f33bcSAndroid Build Coastguard Worker			my $sl = $sline;
3962*d68f33bcSAndroid Build Coastguard Worker			my $pl = $prevline;
3963*d68f33bcSAndroid Build Coastguard Worker			# remove $Attribute/$Sparse uses to simplify comparisons
3964*d68f33bcSAndroid Build Coastguard Worker			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3965*d68f33bcSAndroid Build Coastguard Worker			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3966*d68f33bcSAndroid Build Coastguard Worker			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3967*d68f33bcSAndroid Build Coastguard Worker			# function pointer declarations
3968*d68f33bcSAndroid Build Coastguard Worker			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3969*d68f33bcSAndroid Build Coastguard Worker			# foo bar; where foo is some local typedef or #define
3970*d68f33bcSAndroid Build Coastguard Worker			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3971*d68f33bcSAndroid Build Coastguard Worker			# known declaration macros
3972*d68f33bcSAndroid Build Coastguard Worker			     $pl =~ /^\+\s+$declaration_macros/) &&
3973*d68f33bcSAndroid Build Coastguard Worker			# for "else if" which can look like "$Ident $Ident"
3974*d68f33bcSAndroid Build Coastguard Worker			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
3975*d68f33bcSAndroid Build Coastguard Worker			# other possible extensions of declaration lines
3976*d68f33bcSAndroid Build Coastguard Worker			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
3977*d68f33bcSAndroid Build Coastguard Worker			# not starting a section or a macro "\" extended line
3978*d68f33bcSAndroid Build Coastguard Worker			      $pl =~ /(?:\{\s*|\\)$/) &&
3979*d68f33bcSAndroid Build Coastguard Worker			# looks like a declaration
3980*d68f33bcSAndroid Build Coastguard Worker			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
3981*d68f33bcSAndroid Build Coastguard Worker			# function pointer declarations
3982*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
3983*d68f33bcSAndroid Build Coastguard Worker			# foo bar; where foo is some local typedef or #define
3984*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
3985*d68f33bcSAndroid Build Coastguard Worker			# known declaration macros
3986*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+$declaration_macros/ ||
3987*d68f33bcSAndroid Build Coastguard Worker			# start of struct or union or enum
3988*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
3989*d68f33bcSAndroid Build Coastguard Worker			# start or end of block or continuation of declaration
3990*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
3991*d68f33bcSAndroid Build Coastguard Worker			# bitfield continuation
3992*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
3993*d68f33bcSAndroid Build Coastguard Worker			# other possible extensions of declaration lines
3994*d68f33bcSAndroid Build Coastguard Worker			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3995*d68f33bcSAndroid Build Coastguard Worker				if (WARN("LINE_SPACING",
3996*d68f33bcSAndroid Build Coastguard Worker					 "Missing a blank line after declarations\n" . $hereprev) &&
3997*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
3998*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, "\+");
3999*d68f33bcSAndroid Build Coastguard Worker				}
4000*d68f33bcSAndroid Build Coastguard Worker			}
4001*d68f33bcSAndroid Build Coastguard Worker		}
4002*d68f33bcSAndroid Build Coastguard Worker
4003*d68f33bcSAndroid Build Coastguard Worker# check for spaces at the beginning of a line.
4004*d68f33bcSAndroid Build Coastguard Worker# Exceptions:
4005*d68f33bcSAndroid Build Coastguard Worker#  1) within comments
4006*d68f33bcSAndroid Build Coastguard Worker#  2) indented preprocessor commands
4007*d68f33bcSAndroid Build Coastguard Worker#  3) hanging labels
4008*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
4009*d68f33bcSAndroid Build Coastguard Worker			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
4010*d68f33bcSAndroid Build Coastguard Worker			if (WARN("LEADING_SPACE",
4011*d68f33bcSAndroid Build Coastguard Worker				 "please, no spaces at the start of a line\n" . $herevet) &&
4012*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4013*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
4014*d68f33bcSAndroid Build Coastguard Worker			}
4015*d68f33bcSAndroid Build Coastguard Worker		}
4016*d68f33bcSAndroid Build Coastguard Worker
4017*d68f33bcSAndroid Build Coastguard Worker# check we are in a valid C source file if not then ignore this hunk
4018*d68f33bcSAndroid Build Coastguard Worker		next if ($realfile !~ /\.(h|c)$/);
4019*d68f33bcSAndroid Build Coastguard Worker
4020*d68f33bcSAndroid Build Coastguard Worker# check for unusual line ending [ or (
4021*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*([\[\(])\s*$/) {
4022*d68f33bcSAndroid Build Coastguard Worker			CHK("OPEN_ENDED_LINE",
4023*d68f33bcSAndroid Build Coastguard Worker			    "Lines should not end with a '$1'\n" . $herecurr);
4024*d68f33bcSAndroid Build Coastguard Worker		}
4025*d68f33bcSAndroid Build Coastguard Worker
4026*d68f33bcSAndroid Build Coastguard Worker# check if this appears to be the start function declaration, save the name
4027*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+\{\s*$/ &&
4028*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
4029*d68f33bcSAndroid Build Coastguard Worker			$context_function = $1;
4030*d68f33bcSAndroid Build Coastguard Worker		}
4031*d68f33bcSAndroid Build Coastguard Worker
4032*d68f33bcSAndroid Build Coastguard Worker# check if this appears to be the end of function declaration
4033*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+\}\s*$/) {
4034*d68f33bcSAndroid Build Coastguard Worker			undef $context_function;
4035*d68f33bcSAndroid Build Coastguard Worker		}
4036*d68f33bcSAndroid Build Coastguard Worker
4037*d68f33bcSAndroid Build Coastguard Worker# check indentation of any line with a bare else
4038*d68f33bcSAndroid Build Coastguard Worker# (but not if it is a multiple line "if (foo) return bar; else return baz;")
4039*d68f33bcSAndroid Build Coastguard Worker# if the previous line is a break or return and is indented 1 tab more...
4040*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
4041*d68f33bcSAndroid Build Coastguard Worker			my $tabs = length($1) + 1;
4042*d68f33bcSAndroid Build Coastguard Worker			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
4043*d68f33bcSAndroid Build Coastguard Worker			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
4044*d68f33bcSAndroid Build Coastguard Worker			     defined $lines[$linenr] &&
4045*d68f33bcSAndroid Build Coastguard Worker			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
4046*d68f33bcSAndroid Build Coastguard Worker				WARN("UNNECESSARY_ELSE",
4047*d68f33bcSAndroid Build Coastguard Worker				     "else is not generally useful after a break or return\n" . $hereprev);
4048*d68f33bcSAndroid Build Coastguard Worker			}
4049*d68f33bcSAndroid Build Coastguard Worker		}
4050*d68f33bcSAndroid Build Coastguard Worker
4051*d68f33bcSAndroid Build Coastguard Worker# check indentation of a line with a break;
4052*d68f33bcSAndroid Build Coastguard Worker# if the previous line is a goto, return or break
4053*d68f33bcSAndroid Build Coastguard Worker# and is indented the same # of tabs
4054*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4055*d68f33bcSAndroid Build Coastguard Worker			my $tabs = $1;
4056*d68f33bcSAndroid Build Coastguard Worker			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4057*d68f33bcSAndroid Build Coastguard Worker				if (WARN("UNNECESSARY_BREAK",
4058*d68f33bcSAndroid Build Coastguard Worker					 "break is not useful after a $1\n" . $hereprev) &&
4059*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4060*d68f33bcSAndroid Build Coastguard Worker					fix_delete_line($fixlinenr, $rawline);
4061*d68f33bcSAndroid Build Coastguard Worker				}
4062*d68f33bcSAndroid Build Coastguard Worker			}
4063*d68f33bcSAndroid Build Coastguard Worker		}
4064*d68f33bcSAndroid Build Coastguard Worker
4065*d68f33bcSAndroid Build Coastguard Worker# check for RCS/CVS revision markers
4066*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4067*d68f33bcSAndroid Build Coastguard Worker			WARN("CVS_KEYWORD",
4068*d68f33bcSAndroid Build Coastguard Worker			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4069*d68f33bcSAndroid Build Coastguard Worker		}
4070*d68f33bcSAndroid Build Coastguard Worker
4071*d68f33bcSAndroid Build Coastguard Worker# check for old HOTPLUG __dev<foo> section markings
4072*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
4073*d68f33bcSAndroid Build Coastguard Worker			WARN("HOTPLUG_SECTION",
4074*d68f33bcSAndroid Build Coastguard Worker			     "Using $1 is unnecessary\n" . $herecurr);
4075*d68f33bcSAndroid Build Coastguard Worker		}
4076*d68f33bcSAndroid Build Coastguard Worker
4077*d68f33bcSAndroid Build Coastguard Worker# Check for potential 'bare' types
4078*d68f33bcSAndroid Build Coastguard Worker		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
4079*d68f33bcSAndroid Build Coastguard Worker		    $realline_next);
4080*d68f33bcSAndroid Build Coastguard Worker#print "LINE<$line>\n";
4081*d68f33bcSAndroid Build Coastguard Worker		if ($linenr > $suppress_statement &&
4082*d68f33bcSAndroid Build Coastguard Worker		    $realcnt && $sline =~ /.\s*\S/) {
4083*d68f33bcSAndroid Build Coastguard Worker			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4084*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $realcnt, 0);
4085*d68f33bcSAndroid Build Coastguard Worker			$stat =~ s/\n./\n /g;
4086*d68f33bcSAndroid Build Coastguard Worker			$cond =~ s/\n./\n /g;
4087*d68f33bcSAndroid Build Coastguard Worker
4088*d68f33bcSAndroid Build Coastguard Worker#print "linenr<$linenr> <$stat>\n";
4089*d68f33bcSAndroid Build Coastguard Worker			# If this statement has no statement boundaries within
4090*d68f33bcSAndroid Build Coastguard Worker			# it there is no point in retrying a statement scan
4091*d68f33bcSAndroid Build Coastguard Worker			# until we hit end of it.
4092*d68f33bcSAndroid Build Coastguard Worker			my $frag = $stat; $frag =~ s/;+\s*$//;
4093*d68f33bcSAndroid Build Coastguard Worker			if ($frag !~ /(?:{|;)/) {
4094*d68f33bcSAndroid Build Coastguard Worker#print "skip<$line_nr_next>\n";
4095*d68f33bcSAndroid Build Coastguard Worker				$suppress_statement = $line_nr_next;
4096*d68f33bcSAndroid Build Coastguard Worker			}
4097*d68f33bcSAndroid Build Coastguard Worker
4098*d68f33bcSAndroid Build Coastguard Worker			# Find the real next line.
4099*d68f33bcSAndroid Build Coastguard Worker			$realline_next = $line_nr_next;
4100*d68f33bcSAndroid Build Coastguard Worker			if (defined $realline_next &&
4101*d68f33bcSAndroid Build Coastguard Worker			    (!defined $lines[$realline_next - 1] ||
4102*d68f33bcSAndroid Build Coastguard Worker			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
4103*d68f33bcSAndroid Build Coastguard Worker				$realline_next++;
4104*d68f33bcSAndroid Build Coastguard Worker			}
4105*d68f33bcSAndroid Build Coastguard Worker
4106*d68f33bcSAndroid Build Coastguard Worker			my $s = $stat;
4107*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/{.*$//s;
4108*d68f33bcSAndroid Build Coastguard Worker
4109*d68f33bcSAndroid Build Coastguard Worker			# Ignore goto labels.
4110*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ /$Ident:\*$/s) {
4111*d68f33bcSAndroid Build Coastguard Worker
4112*d68f33bcSAndroid Build Coastguard Worker			# Ignore functions being called
4113*d68f33bcSAndroid Build Coastguard Worker			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
4114*d68f33bcSAndroid Build Coastguard Worker
4115*d68f33bcSAndroid Build Coastguard Worker			} elsif ($s =~ /^.\s*else\b/s) {
4116*d68f33bcSAndroid Build Coastguard Worker
4117*d68f33bcSAndroid Build Coastguard Worker			# declarations always start with types
4118*d68f33bcSAndroid Build Coastguard Worker			} 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) {
4119*d68f33bcSAndroid Build Coastguard Worker				my $type = $1;
4120*d68f33bcSAndroid Build Coastguard Worker				$type =~ s/\s+/ /g;
4121*d68f33bcSAndroid Build Coastguard Worker				possible($type, "A:" . $s);
4122*d68f33bcSAndroid Build Coastguard Worker
4123*d68f33bcSAndroid Build Coastguard Worker			# definitions in global scope can only start with types
4124*d68f33bcSAndroid Build Coastguard Worker			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4125*d68f33bcSAndroid Build Coastguard Worker				possible($1, "B:" . $s);
4126*d68f33bcSAndroid Build Coastguard Worker			}
4127*d68f33bcSAndroid Build Coastguard Worker
4128*d68f33bcSAndroid Build Coastguard Worker			# any (foo ... *) is a pointer cast, and foo is a type
4129*d68f33bcSAndroid Build Coastguard Worker			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4130*d68f33bcSAndroid Build Coastguard Worker				possible($1, "C:" . $s);
4131*d68f33bcSAndroid Build Coastguard Worker			}
4132*d68f33bcSAndroid Build Coastguard Worker
4133*d68f33bcSAndroid Build Coastguard Worker			# Check for any sort of function declaration.
4134*d68f33bcSAndroid Build Coastguard Worker			# int foo(something bar, other baz);
4135*d68f33bcSAndroid Build Coastguard Worker			# void (*store_gdt)(x86_descr_ptr *);
4136*d68f33bcSAndroid Build Coastguard Worker			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
4137*d68f33bcSAndroid Build Coastguard Worker				my ($name_len) = length($1);
4138*d68f33bcSAndroid Build Coastguard Worker
4139*d68f33bcSAndroid Build Coastguard Worker				my $ctx = $s;
4140*d68f33bcSAndroid Build Coastguard Worker				substr($ctx, 0, $name_len + 1, '');
4141*d68f33bcSAndroid Build Coastguard Worker				$ctx =~ s/\)[^\)]*$//;
4142*d68f33bcSAndroid Build Coastguard Worker
4143*d68f33bcSAndroid Build Coastguard Worker				for my $arg (split(/\s*,\s*/, $ctx)) {
4144*d68f33bcSAndroid Build Coastguard Worker					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
4145*d68f33bcSAndroid Build Coastguard Worker
4146*d68f33bcSAndroid Build Coastguard Worker						possible($1, "D:" . $s);
4147*d68f33bcSAndroid Build Coastguard Worker					}
4148*d68f33bcSAndroid Build Coastguard Worker				}
4149*d68f33bcSAndroid Build Coastguard Worker			}
4150*d68f33bcSAndroid Build Coastguard Worker
4151*d68f33bcSAndroid Build Coastguard Worker		}
4152*d68f33bcSAndroid Build Coastguard Worker
4153*d68f33bcSAndroid Build Coastguard Worker#
4154*d68f33bcSAndroid Build Coastguard Worker# Checks which may be anchored in the context.
4155*d68f33bcSAndroid Build Coastguard Worker#
4156*d68f33bcSAndroid Build Coastguard Worker
4157*d68f33bcSAndroid Build Coastguard Worker# Check for switch () and associated case and default
4158*d68f33bcSAndroid Build Coastguard Worker# statements should be at the same indent.
4159*d68f33bcSAndroid Build Coastguard Worker		if ($line=~/\bswitch\s*\(.*\)/) {
4160*d68f33bcSAndroid Build Coastguard Worker			my $err = '';
4161*d68f33bcSAndroid Build Coastguard Worker			my $sep = '';
4162*d68f33bcSAndroid Build Coastguard Worker			my @ctx = ctx_block_outer($linenr, $realcnt);
4163*d68f33bcSAndroid Build Coastguard Worker			shift(@ctx);
4164*d68f33bcSAndroid Build Coastguard Worker			for my $ctx (@ctx) {
4165*d68f33bcSAndroid Build Coastguard Worker				my ($clen, $cindent) = line_stats($ctx);
4166*d68f33bcSAndroid Build Coastguard Worker				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
4167*d68f33bcSAndroid Build Coastguard Worker							$indent != $cindent) {
4168*d68f33bcSAndroid Build Coastguard Worker					$err .= "$sep$ctx\n";
4169*d68f33bcSAndroid Build Coastguard Worker					$sep = '';
4170*d68f33bcSAndroid Build Coastguard Worker				} else {
4171*d68f33bcSAndroid Build Coastguard Worker					$sep = "[...]\n";
4172*d68f33bcSAndroid Build Coastguard Worker				}
4173*d68f33bcSAndroid Build Coastguard Worker			}
4174*d68f33bcSAndroid Build Coastguard Worker			if ($err ne '') {
4175*d68f33bcSAndroid Build Coastguard Worker				ERROR("SWITCH_CASE_INDENT_LEVEL",
4176*d68f33bcSAndroid Build Coastguard Worker				      "switch and case should be at the same indent\n$hereline$err");
4177*d68f33bcSAndroid Build Coastguard Worker			}
4178*d68f33bcSAndroid Build Coastguard Worker		}
4179*d68f33bcSAndroid Build Coastguard Worker
4180*d68f33bcSAndroid Build Coastguard Worker# if/while/etc brace do not go on next line, unless defining a do while loop,
4181*d68f33bcSAndroid Build Coastguard Worker# or if that brace on the next line is for something else
4182*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4183*d68f33bcSAndroid Build Coastguard Worker			my $pre_ctx = "$1$2";
4184*d68f33bcSAndroid Build Coastguard Worker
4185*d68f33bcSAndroid Build Coastguard Worker			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
4186*d68f33bcSAndroid Build Coastguard Worker
4187*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^\+\t{6,}/) {
4188*d68f33bcSAndroid Build Coastguard Worker				WARN("DEEP_INDENTATION",
4189*d68f33bcSAndroid Build Coastguard Worker				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
4190*d68f33bcSAndroid Build Coastguard Worker			}
4191*d68f33bcSAndroid Build Coastguard Worker
4192*d68f33bcSAndroid Build Coastguard Worker			my $ctx_cnt = $realcnt - $#ctx - 1;
4193*d68f33bcSAndroid Build Coastguard Worker			my $ctx = join("\n", @ctx);
4194*d68f33bcSAndroid Build Coastguard Worker
4195*d68f33bcSAndroid Build Coastguard Worker			my $ctx_ln = $linenr;
4196*d68f33bcSAndroid Build Coastguard Worker			my $ctx_skip = $realcnt;
4197*d68f33bcSAndroid Build Coastguard Worker
4198*d68f33bcSAndroid Build Coastguard Worker			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4199*d68f33bcSAndroid Build Coastguard Worker					defined $lines[$ctx_ln - 1] &&
4200*d68f33bcSAndroid Build Coastguard Worker					$lines[$ctx_ln - 1] =~ /^-/)) {
4201*d68f33bcSAndroid Build Coastguard Worker				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4202*d68f33bcSAndroid Build Coastguard Worker				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4203*d68f33bcSAndroid Build Coastguard Worker				$ctx_ln++;
4204*d68f33bcSAndroid Build Coastguard Worker			}
4205*d68f33bcSAndroid Build Coastguard Worker
4206*d68f33bcSAndroid Build Coastguard Worker			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
4207*d68f33bcSAndroid Build Coastguard Worker			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4208*d68f33bcSAndroid Build Coastguard Worker
4209*d68f33bcSAndroid Build Coastguard Worker			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4210*d68f33bcSAndroid Build Coastguard Worker				ERROR("OPEN_BRACE",
4211*d68f33bcSAndroid Build Coastguard Worker				      "that open brace { should be on the previous line\n" .
4212*d68f33bcSAndroid Build Coastguard Worker					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
4213*d68f33bcSAndroid Build Coastguard Worker			}
4214*d68f33bcSAndroid Build Coastguard Worker			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4215*d68f33bcSAndroid Build Coastguard Worker			    $ctx =~ /\)\s*\;\s*$/ &&
4216*d68f33bcSAndroid Build Coastguard Worker			    defined $lines[$ctx_ln - 1])
4217*d68f33bcSAndroid Build Coastguard Worker			{
4218*d68f33bcSAndroid Build Coastguard Worker				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
4219*d68f33bcSAndroid Build Coastguard Worker				if ($nindent > $indent) {
4220*d68f33bcSAndroid Build Coastguard Worker					WARN("TRAILING_SEMICOLON",
4221*d68f33bcSAndroid Build Coastguard Worker					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
4222*d68f33bcSAndroid Build Coastguard Worker						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
4223*d68f33bcSAndroid Build Coastguard Worker				}
4224*d68f33bcSAndroid Build Coastguard Worker			}
4225*d68f33bcSAndroid Build Coastguard Worker		}
4226*d68f33bcSAndroid Build Coastguard Worker
4227*d68f33bcSAndroid Build Coastguard Worker# Check relative indent for conditionals and blocks.
4228*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
4229*d68f33bcSAndroid Build Coastguard Worker			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4230*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $realcnt, 0)
4231*d68f33bcSAndroid Build Coastguard Worker					if (!defined $stat);
4232*d68f33bcSAndroid Build Coastguard Worker			my ($s, $c) = ($stat, $cond);
4233*d68f33bcSAndroid Build Coastguard Worker
4234*d68f33bcSAndroid Build Coastguard Worker			substr($s, 0, length($c), '');
4235*d68f33bcSAndroid Build Coastguard Worker
4236*d68f33bcSAndroid Build Coastguard Worker			# remove inline comments
4237*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/$;/ /g;
4238*d68f33bcSAndroid Build Coastguard Worker			$c =~ s/$;/ /g;
4239*d68f33bcSAndroid Build Coastguard Worker
4240*d68f33bcSAndroid Build Coastguard Worker			# Find out how long the conditional actually is.
4241*d68f33bcSAndroid Build Coastguard Worker			my @newlines = ($c =~ /\n/gs);
4242*d68f33bcSAndroid Build Coastguard Worker			my $cond_lines = 1 + $#newlines;
4243*d68f33bcSAndroid Build Coastguard Worker
4244*d68f33bcSAndroid Build Coastguard Worker			# Make sure we remove the line prefixes as we have
4245*d68f33bcSAndroid Build Coastguard Worker			# none on the first line, and are going to readd them
4246*d68f33bcSAndroid Build Coastguard Worker			# where necessary.
4247*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/\n./\n/gs;
4248*d68f33bcSAndroid Build Coastguard Worker			while ($s =~ /\n\s+\\\n/) {
4249*d68f33bcSAndroid Build Coastguard Worker				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
4250*d68f33bcSAndroid Build Coastguard Worker			}
4251*d68f33bcSAndroid Build Coastguard Worker
4252*d68f33bcSAndroid Build Coastguard Worker			# We want to check the first line inside the block
4253*d68f33bcSAndroid Build Coastguard Worker			# starting at the end of the conditional, so remove:
4254*d68f33bcSAndroid Build Coastguard Worker			#  1) any blank line termination
4255*d68f33bcSAndroid Build Coastguard Worker			#  2) any opening brace { on end of the line
4256*d68f33bcSAndroid Build Coastguard Worker			#  3) any do (...) {
4257*d68f33bcSAndroid Build Coastguard Worker			my $continuation = 0;
4258*d68f33bcSAndroid Build Coastguard Worker			my $check = 0;
4259*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/^.*\bdo\b//;
4260*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/^\s*{//;
4261*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ s/^\s*\\//) {
4262*d68f33bcSAndroid Build Coastguard Worker				$continuation = 1;
4263*d68f33bcSAndroid Build Coastguard Worker			}
4264*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ s/^\s*?\n//) {
4265*d68f33bcSAndroid Build Coastguard Worker				$check = 1;
4266*d68f33bcSAndroid Build Coastguard Worker				$cond_lines++;
4267*d68f33bcSAndroid Build Coastguard Worker			}
4268*d68f33bcSAndroid Build Coastguard Worker
4269*d68f33bcSAndroid Build Coastguard Worker			# Also ignore a loop construct at the end of a
4270*d68f33bcSAndroid Build Coastguard Worker			# preprocessor statement.
4271*d68f33bcSAndroid Build Coastguard Worker			if (($prevline =~ /^.\s*#\s*define\s/ ||
4272*d68f33bcSAndroid Build Coastguard Worker			    $prevline =~ /\\\s*$/) && $continuation == 0) {
4273*d68f33bcSAndroid Build Coastguard Worker				$check = 0;
4274*d68f33bcSAndroid Build Coastguard Worker			}
4275*d68f33bcSAndroid Build Coastguard Worker
4276*d68f33bcSAndroid Build Coastguard Worker			my $cond_ptr = -1;
4277*d68f33bcSAndroid Build Coastguard Worker			$continuation = 0;
4278*d68f33bcSAndroid Build Coastguard Worker			while ($cond_ptr != $cond_lines) {
4279*d68f33bcSAndroid Build Coastguard Worker				$cond_ptr = $cond_lines;
4280*d68f33bcSAndroid Build Coastguard Worker
4281*d68f33bcSAndroid Build Coastguard Worker				# If we see an #else/#elif then the code
4282*d68f33bcSAndroid Build Coastguard Worker				# is not linear.
4283*d68f33bcSAndroid Build Coastguard Worker				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4284*d68f33bcSAndroid Build Coastguard Worker					$check = 0;
4285*d68f33bcSAndroid Build Coastguard Worker				}
4286*d68f33bcSAndroid Build Coastguard Worker
4287*d68f33bcSAndroid Build Coastguard Worker				# Ignore:
4288*d68f33bcSAndroid Build Coastguard Worker				#  1) blank lines, they should be at 0,
4289*d68f33bcSAndroid Build Coastguard Worker				#  2) preprocessor lines, and
4290*d68f33bcSAndroid Build Coastguard Worker				#  3) labels.
4291*d68f33bcSAndroid Build Coastguard Worker				if ($continuation ||
4292*d68f33bcSAndroid Build Coastguard Worker				    $s =~ /^\s*?\n/ ||
4293*d68f33bcSAndroid Build Coastguard Worker				    $s =~ /^\s*#\s*?/ ||
4294*d68f33bcSAndroid Build Coastguard Worker				    $s =~ /^\s*$Ident\s*:/) {
4295*d68f33bcSAndroid Build Coastguard Worker					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
4296*d68f33bcSAndroid Build Coastguard Worker					if ($s =~ s/^.*?\n//) {
4297*d68f33bcSAndroid Build Coastguard Worker						$cond_lines++;
4298*d68f33bcSAndroid Build Coastguard Worker					}
4299*d68f33bcSAndroid Build Coastguard Worker				}
4300*d68f33bcSAndroid Build Coastguard Worker			}
4301*d68f33bcSAndroid Build Coastguard Worker
4302*d68f33bcSAndroid Build Coastguard Worker			my (undef, $sindent) = line_stats("+" . $s);
4303*d68f33bcSAndroid Build Coastguard Worker			my $stat_real = raw_line($linenr, $cond_lines);
4304*d68f33bcSAndroid Build Coastguard Worker
4305*d68f33bcSAndroid Build Coastguard Worker			# Check if either of these lines are modified, else
4306*d68f33bcSAndroid Build Coastguard Worker			# this is not this patch's fault.
4307*d68f33bcSAndroid Build Coastguard Worker			if (!defined($stat_real) ||
4308*d68f33bcSAndroid Build Coastguard Worker			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
4309*d68f33bcSAndroid Build Coastguard Worker				$check = 0;
4310*d68f33bcSAndroid Build Coastguard Worker			}
4311*d68f33bcSAndroid Build Coastguard Worker			if (defined($stat_real) && $cond_lines > 1) {
4312*d68f33bcSAndroid Build Coastguard Worker				$stat_real = "[...]\n$stat_real";
4313*d68f33bcSAndroid Build Coastguard Worker			}
4314*d68f33bcSAndroid Build Coastguard Worker
4315*d68f33bcSAndroid Build Coastguard Worker			#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";
4316*d68f33bcSAndroid Build Coastguard Worker
4317*d68f33bcSAndroid Build Coastguard Worker			if ($check && $s ne '' &&
4318*d68f33bcSAndroid Build Coastguard Worker			    (($sindent % $tabsize) != 0 ||
4319*d68f33bcSAndroid Build Coastguard Worker			     ($sindent < $indent) ||
4320*d68f33bcSAndroid Build Coastguard Worker			     ($sindent == $indent &&
4321*d68f33bcSAndroid Build Coastguard Worker			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4322*d68f33bcSAndroid Build Coastguard Worker			     ($sindent > $indent + $tabsize))) {
4323*d68f33bcSAndroid Build Coastguard Worker				WARN("SUSPECT_CODE_INDENT",
4324*d68f33bcSAndroid Build Coastguard Worker				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
4325*d68f33bcSAndroid Build Coastguard Worker			}
4326*d68f33bcSAndroid Build Coastguard Worker		}
4327*d68f33bcSAndroid Build Coastguard Worker
4328*d68f33bcSAndroid Build Coastguard Worker		# Track the 'values' across context and added lines.
4329*d68f33bcSAndroid Build Coastguard Worker		my $opline = $line; $opline =~ s/^./ /;
4330*d68f33bcSAndroid Build Coastguard Worker		my ($curr_values, $curr_vars) =
4331*d68f33bcSAndroid Build Coastguard Worker				annotate_values($opline . "\n", $prev_values);
4332*d68f33bcSAndroid Build Coastguard Worker		$curr_values = $prev_values . $curr_values;
4333*d68f33bcSAndroid Build Coastguard Worker		if ($dbg_values) {
4334*d68f33bcSAndroid Build Coastguard Worker			my $outline = $opline; $outline =~ s/\t/ /g;
4335*d68f33bcSAndroid Build Coastguard Worker			print "$linenr > .$outline\n";
4336*d68f33bcSAndroid Build Coastguard Worker			print "$linenr > $curr_values\n";
4337*d68f33bcSAndroid Build Coastguard Worker			print "$linenr >  $curr_vars\n";
4338*d68f33bcSAndroid Build Coastguard Worker		}
4339*d68f33bcSAndroid Build Coastguard Worker		$prev_values = substr($curr_values, -1);
4340*d68f33bcSAndroid Build Coastguard Worker
4341*d68f33bcSAndroid Build Coastguard Worker#ignore lines not being added
4342*d68f33bcSAndroid Build Coastguard Worker		next if ($line =~ /^[^\+]/);
4343*d68f33bcSAndroid Build Coastguard Worker
4344*d68f33bcSAndroid Build Coastguard Worker# check for self assignments used to avoid compiler warnings
4345*d68f33bcSAndroid Build Coastguard Worker# e.g.:	int foo = foo, *bar = NULL;
4346*d68f33bcSAndroid Build Coastguard Worker#	struct foo bar = *(&(bar));
4347*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
4348*d68f33bcSAndroid Build Coastguard Worker			my $var = $1;
4349*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
4350*d68f33bcSAndroid Build Coastguard Worker				WARN("SELF_ASSIGNMENT",
4351*d68f33bcSAndroid Build Coastguard Worker				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
4352*d68f33bcSAndroid Build Coastguard Worker			}
4353*d68f33bcSAndroid Build Coastguard Worker		}
4354*d68f33bcSAndroid Build Coastguard Worker
4355*d68f33bcSAndroid Build Coastguard Worker# check for dereferences that span multiple lines
4356*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
4357*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
4358*d68f33bcSAndroid Build Coastguard Worker			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
4359*d68f33bcSAndroid Build Coastguard Worker			my $ref = $1;
4360*d68f33bcSAndroid Build Coastguard Worker			$line =~ /^.\s*($Lval)/;
4361*d68f33bcSAndroid Build Coastguard Worker			$ref .= $1;
4362*d68f33bcSAndroid Build Coastguard Worker			$ref =~ s/\s//g;
4363*d68f33bcSAndroid Build Coastguard Worker			WARN("MULTILINE_DEREFERENCE",
4364*d68f33bcSAndroid Build Coastguard Worker			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
4365*d68f33bcSAndroid Build Coastguard Worker		}
4366*d68f33bcSAndroid Build Coastguard Worker
4367*d68f33bcSAndroid Build Coastguard Worker# check for declarations of signed or unsigned without int
4368*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4369*d68f33bcSAndroid Build Coastguard Worker			my $type = $1;
4370*d68f33bcSAndroid Build Coastguard Worker			my $var = $2;
4371*d68f33bcSAndroid Build Coastguard Worker			$var = "" if (!defined $var);
4372*d68f33bcSAndroid Build Coastguard Worker			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4373*d68f33bcSAndroid Build Coastguard Worker				my $sign = $1;
4374*d68f33bcSAndroid Build Coastguard Worker				my $pointer = $2;
4375*d68f33bcSAndroid Build Coastguard Worker
4376*d68f33bcSAndroid Build Coastguard Worker				$pointer = "" if (!defined $pointer);
4377*d68f33bcSAndroid Build Coastguard Worker
4378*d68f33bcSAndroid Build Coastguard Worker				if (WARN("UNSPECIFIED_INT",
4379*d68f33bcSAndroid Build Coastguard Worker					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4380*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4381*d68f33bcSAndroid Build Coastguard Worker					my $decl = trim($sign) . " int ";
4382*d68f33bcSAndroid Build Coastguard Worker					my $comp_pointer = $pointer;
4383*d68f33bcSAndroid Build Coastguard Worker					$comp_pointer =~ s/\s//g;
4384*d68f33bcSAndroid Build Coastguard Worker					$decl .= $comp_pointer;
4385*d68f33bcSAndroid Build Coastguard Worker					$decl = rtrim($decl) if ($var eq "");
4386*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4387*d68f33bcSAndroid Build Coastguard Worker				}
4388*d68f33bcSAndroid Build Coastguard Worker			}
4389*d68f33bcSAndroid Build Coastguard Worker		}
4390*d68f33bcSAndroid Build Coastguard Worker
4391*d68f33bcSAndroid Build Coastguard Worker# TEST: allow direct testing of the type matcher.
4392*d68f33bcSAndroid Build Coastguard Worker		if ($dbg_type) {
4393*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^.\s*$Declare\s*$/) {
4394*d68f33bcSAndroid Build Coastguard Worker				ERROR("TEST_TYPE",
4395*d68f33bcSAndroid Build Coastguard Worker				      "TEST: is type\n" . $herecurr);
4396*d68f33bcSAndroid Build Coastguard Worker			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4397*d68f33bcSAndroid Build Coastguard Worker				ERROR("TEST_NOT_TYPE",
4398*d68f33bcSAndroid Build Coastguard Worker				      "TEST: is not type ($1 is)\n". $herecurr);
4399*d68f33bcSAndroid Build Coastguard Worker			}
4400*d68f33bcSAndroid Build Coastguard Worker			next;
4401*d68f33bcSAndroid Build Coastguard Worker		}
4402*d68f33bcSAndroid Build Coastguard Worker# TEST: allow direct testing of the attribute matcher.
4403*d68f33bcSAndroid Build Coastguard Worker		if ($dbg_attr) {
4404*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^.\s*$Modifier\s*$/) {
4405*d68f33bcSAndroid Build Coastguard Worker				ERROR("TEST_ATTR",
4406*d68f33bcSAndroid Build Coastguard Worker				      "TEST: is attr\n" . $herecurr);
4407*d68f33bcSAndroid Build Coastguard Worker			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4408*d68f33bcSAndroid Build Coastguard Worker				ERROR("TEST_NOT_ATTR",
4409*d68f33bcSAndroid Build Coastguard Worker				      "TEST: is not attr ($1 is)\n". $herecurr);
4410*d68f33bcSAndroid Build Coastguard Worker			}
4411*d68f33bcSAndroid Build Coastguard Worker			next;
4412*d68f33bcSAndroid Build Coastguard Worker		}
4413*d68f33bcSAndroid Build Coastguard Worker
4414*d68f33bcSAndroid Build Coastguard Worker# check for initialisation to aggregates open brace on the next line
4415*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*{/ &&
4416*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /(?:^|[^=])=\s*$/) {
4417*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("OPEN_BRACE",
4418*d68f33bcSAndroid Build Coastguard Worker				  "that open brace { should be on the previous line\n" . $hereprev) &&
4419*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4420*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr - 1, $prevrawline);
4421*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
4422*d68f33bcSAndroid Build Coastguard Worker				my $fixedline = $prevrawline;
4423*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/\s*=\s*$/ = {/;
4424*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, $fixedline);
4425*d68f33bcSAndroid Build Coastguard Worker				$fixedline = $line;
4426*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4427*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, $fixedline);
4428*d68f33bcSAndroid Build Coastguard Worker			}
4429*d68f33bcSAndroid Build Coastguard Worker		}
4430*d68f33bcSAndroid Build Coastguard Worker
4431*d68f33bcSAndroid Build Coastguard Worker#
4432*d68f33bcSAndroid Build Coastguard Worker# Checks which are anchored on the added line.
4433*d68f33bcSAndroid Build Coastguard Worker#
4434*d68f33bcSAndroid Build Coastguard Worker
4435*d68f33bcSAndroid Build Coastguard Worker# check for malformed paths in #include statements (uses RAW line)
4436*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4437*d68f33bcSAndroid Build Coastguard Worker			my $path = $1;
4438*d68f33bcSAndroid Build Coastguard Worker			if ($path =~ m{//}) {
4439*d68f33bcSAndroid Build Coastguard Worker				ERROR("MALFORMED_INCLUDE",
4440*d68f33bcSAndroid Build Coastguard Worker				      "malformed #include filename\n" . $herecurr);
4441*d68f33bcSAndroid Build Coastguard Worker			}
4442*d68f33bcSAndroid Build Coastguard Worker			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4443*d68f33bcSAndroid Build Coastguard Worker				ERROR("UAPI_INCLUDE",
4444*d68f33bcSAndroid Build Coastguard Worker				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4445*d68f33bcSAndroid Build Coastguard Worker			}
4446*d68f33bcSAndroid Build Coastguard Worker		}
4447*d68f33bcSAndroid Build Coastguard Worker
4448*d68f33bcSAndroid Build Coastguard Worker# no C99 // comments
4449*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ m{//}) {
4450*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("C99_COMMENTS",
4451*d68f33bcSAndroid Build Coastguard Worker				  "do not use C99 // comments\n" . $herecurr) &&
4452*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4453*d68f33bcSAndroid Build Coastguard Worker				my $line = $fixed[$fixlinenr];
4454*d68f33bcSAndroid Build Coastguard Worker				if ($line =~ /\/\/(.*)$/) {
4455*d68f33bcSAndroid Build Coastguard Worker					my $comment = trim($1);
4456*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
4457*d68f33bcSAndroid Build Coastguard Worker				}
4458*d68f33bcSAndroid Build Coastguard Worker			}
4459*d68f33bcSAndroid Build Coastguard Worker		}
4460*d68f33bcSAndroid Build Coastguard Worker		# Remove C99 comments.
4461*d68f33bcSAndroid Build Coastguard Worker		$line =~ s@//.*@@;
4462*d68f33bcSAndroid Build Coastguard Worker		$opline =~ s@//.*@@;
4463*d68f33bcSAndroid Build Coastguard Worker
4464*d68f33bcSAndroid Build Coastguard Worker# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
4465*d68f33bcSAndroid Build Coastguard Worker# the whole statement.
4466*d68f33bcSAndroid Build Coastguard Worker#print "APW <$lines[$realline_next - 1]>\n";
4467*d68f33bcSAndroid Build Coastguard Worker		if (defined $realline_next &&
4468*d68f33bcSAndroid Build Coastguard Worker		    exists $lines[$realline_next - 1] &&
4469*d68f33bcSAndroid Build Coastguard Worker		    !defined $suppress_export{$realline_next} &&
4470*d68f33bcSAndroid Build Coastguard Worker		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
4471*d68f33bcSAndroid Build Coastguard Worker			# Handle definitions which produce identifiers with
4472*d68f33bcSAndroid Build Coastguard Worker			# a prefix:
4473*d68f33bcSAndroid Build Coastguard Worker			#   XXX(foo);
4474*d68f33bcSAndroid Build Coastguard Worker			#   EXPORT_SYMBOL(something_foo);
4475*d68f33bcSAndroid Build Coastguard Worker			my $name = $1;
4476*d68f33bcSAndroid Build Coastguard Worker			$name =~ s/^\s*($Ident).*/$1/;
4477*d68f33bcSAndroid Build Coastguard Worker			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
4478*d68f33bcSAndroid Build Coastguard Worker			    $name =~ /^${Ident}_$2/) {
4479*d68f33bcSAndroid Build Coastguard Worker#print "FOO C name<$name>\n";
4480*d68f33bcSAndroid Build Coastguard Worker				$suppress_export{$realline_next} = 1;
4481*d68f33bcSAndroid Build Coastguard Worker
4482*d68f33bcSAndroid Build Coastguard Worker			} elsif ($stat !~ /(?:
4483*d68f33bcSAndroid Build Coastguard Worker				\n.}\s*$|
4484*d68f33bcSAndroid Build Coastguard Worker				^.DEFINE_$Ident\(\Q$name\E\)|
4485*d68f33bcSAndroid Build Coastguard Worker				^.DECLARE_$Ident\(\Q$name\E\)|
4486*d68f33bcSAndroid Build Coastguard Worker				^.LIST_HEAD\(\Q$name\E\)|
4487*d68f33bcSAndroid Build Coastguard Worker				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
4488*d68f33bcSAndroid Build Coastguard Worker				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
4489*d68f33bcSAndroid Build Coastguard Worker			    )/x) {
4490*d68f33bcSAndroid Build Coastguard Worker#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
4491*d68f33bcSAndroid Build Coastguard Worker				$suppress_export{$realline_next} = 2;
4492*d68f33bcSAndroid Build Coastguard Worker			} else {
4493*d68f33bcSAndroid Build Coastguard Worker				$suppress_export{$realline_next} = 1;
4494*d68f33bcSAndroid Build Coastguard Worker			}
4495*d68f33bcSAndroid Build Coastguard Worker		}
4496*d68f33bcSAndroid Build Coastguard Worker		if (!defined $suppress_export{$linenr} &&
4497*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^.\s*$/ &&
4498*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
4499*d68f33bcSAndroid Build Coastguard Worker#print "FOO B <$lines[$linenr - 1]>\n";
4500*d68f33bcSAndroid Build Coastguard Worker			$suppress_export{$linenr} = 2;
4501*d68f33bcSAndroid Build Coastguard Worker		}
4502*d68f33bcSAndroid Build Coastguard Worker		if (defined $suppress_export{$linenr} &&
4503*d68f33bcSAndroid Build Coastguard Worker		    $suppress_export{$linenr} == 2) {
4504*d68f33bcSAndroid Build Coastguard Worker			WARN("EXPORT_SYMBOL",
4505*d68f33bcSAndroid Build Coastguard Worker			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
4506*d68f33bcSAndroid Build Coastguard Worker		}
4507*d68f33bcSAndroid Build Coastguard Worker
4508*d68f33bcSAndroid Build Coastguard Worker# check for global initialisers.
4509*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
4510*d68f33bcSAndroid Build Coastguard Worker		    !exclude_global_initialisers($realfile)) {
4511*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("GLOBAL_INITIALISERS",
4512*d68f33bcSAndroid Build Coastguard Worker				  "do not initialise globals to $1\n" . $herecurr) &&
4513*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4514*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4515*d68f33bcSAndroid Build Coastguard Worker			}
4516*d68f33bcSAndroid Build Coastguard Worker		}
4517*d68f33bcSAndroid Build Coastguard Worker# check for static initialisers.
4518*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4519*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("INITIALISED_STATIC",
4520*d68f33bcSAndroid Build Coastguard Worker				  "do not initialise statics to $1\n" .
4521*d68f33bcSAndroid Build Coastguard Worker				      $herecurr) &&
4522*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4523*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4524*d68f33bcSAndroid Build Coastguard Worker			}
4525*d68f33bcSAndroid Build Coastguard Worker		}
4526*d68f33bcSAndroid Build Coastguard Worker
4527*d68f33bcSAndroid Build Coastguard Worker# check for misordered declarations of char/short/int/long with signed/unsigned
4528*d68f33bcSAndroid Build Coastguard Worker		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
4529*d68f33bcSAndroid Build Coastguard Worker			my $tmp = trim($1);
4530*d68f33bcSAndroid Build Coastguard Worker			WARN("MISORDERED_TYPE",
4531*d68f33bcSAndroid Build Coastguard Worker			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
4532*d68f33bcSAndroid Build Coastguard Worker		}
4533*d68f33bcSAndroid Build Coastguard Worker
4534*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary <signed> int declarations of short/long/long long
4535*d68f33bcSAndroid Build Coastguard Worker		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4536*d68f33bcSAndroid Build Coastguard Worker			my $type = trim($1);
4537*d68f33bcSAndroid Build Coastguard Worker			next if ($type !~ /\bint\b/);
4538*d68f33bcSAndroid Build Coastguard Worker			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4539*d68f33bcSAndroid Build Coastguard Worker			my $new_type = $type;
4540*d68f33bcSAndroid Build Coastguard Worker			$new_type =~ s/\b\s*int\s*\b/ /;
4541*d68f33bcSAndroid Build Coastguard Worker			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4542*d68f33bcSAndroid Build Coastguard Worker			$new_type =~ s/^const\s+//;
4543*d68f33bcSAndroid Build Coastguard Worker			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4544*d68f33bcSAndroid Build Coastguard Worker			$new_type = "const $new_type" if ($type =~ /^const\b/);
4545*d68f33bcSAndroid Build Coastguard Worker			$new_type =~ s/\s+/ /g;
4546*d68f33bcSAndroid Build Coastguard Worker			$new_type = trim($new_type);
4547*d68f33bcSAndroid Build Coastguard Worker			if (WARN("UNNECESSARY_INT",
4548*d68f33bcSAndroid Build Coastguard Worker				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4549*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4550*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4551*d68f33bcSAndroid Build Coastguard Worker			}
4552*d68f33bcSAndroid Build Coastguard Worker		}
4553*d68f33bcSAndroid Build Coastguard Worker
4554*d68f33bcSAndroid Build Coastguard Worker# check for static const char * arrays.
4555*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4556*d68f33bcSAndroid Build Coastguard Worker			WARN("STATIC_CONST_CHAR_ARRAY",
4557*d68f33bcSAndroid Build Coastguard Worker			     "static const char * array should probably be static const char * const\n" .
4558*d68f33bcSAndroid Build Coastguard Worker				$herecurr);
4559*d68f33bcSAndroid Build Coastguard Worker		}
4560*d68f33bcSAndroid Build Coastguard Worker
4561*d68f33bcSAndroid Build Coastguard Worker# check for initialized const char arrays that should be static const
4562*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
4563*d68f33bcSAndroid Build Coastguard Worker			if (WARN("STATIC_CONST_CHAR_ARRAY",
4564*d68f33bcSAndroid Build Coastguard Worker				 "const array should probably be static const\n" . $herecurr) &&
4565*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4566*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
4567*d68f33bcSAndroid Build Coastguard Worker			}
4568*d68f33bcSAndroid Build Coastguard Worker		}
4569*d68f33bcSAndroid Build Coastguard Worker
4570*d68f33bcSAndroid Build Coastguard Worker# check for static char foo[] = "bar" declarations.
4571*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4572*d68f33bcSAndroid Build Coastguard Worker			WARN("STATIC_CONST_CHAR_ARRAY",
4573*d68f33bcSAndroid Build Coastguard Worker			     "static char array declaration should probably be static const char\n" .
4574*d68f33bcSAndroid Build Coastguard Worker				$herecurr);
4575*d68f33bcSAndroid Build Coastguard Worker		}
4576*d68f33bcSAndroid Build Coastguard Worker
4577*d68f33bcSAndroid Build Coastguard Worker# check for const <foo> const where <foo> is not a pointer or array type
4578*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4579*d68f33bcSAndroid Build Coastguard Worker			my $found = $1;
4580*d68f33bcSAndroid Build Coastguard Worker			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4581*d68f33bcSAndroid Build Coastguard Worker				WARN("CONST_CONST",
4582*d68f33bcSAndroid Build Coastguard Worker				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4583*d68f33bcSAndroid Build Coastguard Worker			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4584*d68f33bcSAndroid Build Coastguard Worker				WARN("CONST_CONST",
4585*d68f33bcSAndroid Build Coastguard Worker				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4586*d68f33bcSAndroid Build Coastguard Worker			}
4587*d68f33bcSAndroid Build Coastguard Worker		}
4588*d68f33bcSAndroid Build Coastguard Worker
4589*d68f33bcSAndroid Build Coastguard Worker# check for const static or static <non ptr type> const declarations
4590*d68f33bcSAndroid Build Coastguard Worker# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
4591*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
4592*d68f33bcSAndroid Build Coastguard Worker		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
4593*d68f33bcSAndroid Build Coastguard Worker			if (WARN("STATIC_CONST",
4594*d68f33bcSAndroid Build Coastguard Worker				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
4595*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4596*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
4597*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
4598*d68f33bcSAndroid Build Coastguard Worker			}
4599*d68f33bcSAndroid Build Coastguard Worker		}
4600*d68f33bcSAndroid Build Coastguard Worker
4601*d68f33bcSAndroid Build Coastguard Worker# check for non-global char *foo[] = {"bar", ...} declarations.
4602*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
4603*d68f33bcSAndroid Build Coastguard Worker			WARN("STATIC_CONST_CHAR_ARRAY",
4604*d68f33bcSAndroid Build Coastguard Worker			     "char * array declaration might be better as static const\n" .
4605*d68f33bcSAndroid Build Coastguard Worker				$herecurr);
4606*d68f33bcSAndroid Build Coastguard Worker		}
4607*d68f33bcSAndroid Build Coastguard Worker
4608*d68f33bcSAndroid Build Coastguard Worker# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4609*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4610*d68f33bcSAndroid Build Coastguard Worker			my $array = $1;
4611*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
4612*d68f33bcSAndroid Build Coastguard Worker				my $array_div = $1;
4613*d68f33bcSAndroid Build Coastguard Worker				if (WARN("ARRAY_SIZE",
4614*d68f33bcSAndroid Build Coastguard Worker					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4615*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4616*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4617*d68f33bcSAndroid Build Coastguard Worker				}
4618*d68f33bcSAndroid Build Coastguard Worker			}
4619*d68f33bcSAndroid Build Coastguard Worker		}
4620*d68f33bcSAndroid Build Coastguard Worker
4621*d68f33bcSAndroid Build Coastguard Worker# check for function declarations without arguments like "int foo()"
4622*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4623*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("FUNCTION_WITHOUT_ARGS",
4624*d68f33bcSAndroid Build Coastguard Worker				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4625*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4626*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4627*d68f33bcSAndroid Build Coastguard Worker			}
4628*d68f33bcSAndroid Build Coastguard Worker		}
4629*d68f33bcSAndroid Build Coastguard Worker
4630*d68f33bcSAndroid Build Coastguard Worker# check for new typedefs, only function parameters and sparse annotations
4631*d68f33bcSAndroid Build Coastguard Worker# make sense.
4632*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\btypedef\s/ &&
4633*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4634*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
4635*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\b$typeTypedefs\b/ &&
4636*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\b__bitwise\b/) {
4637*d68f33bcSAndroid Build Coastguard Worker			WARN("NEW_TYPEDEFS",
4638*d68f33bcSAndroid Build Coastguard Worker			     "do not add new typedefs\n" . $herecurr);
4639*d68f33bcSAndroid Build Coastguard Worker		}
4640*d68f33bcSAndroid Build Coastguard Worker
4641*d68f33bcSAndroid Build Coastguard Worker# * goes on variable not on type
4642*d68f33bcSAndroid Build Coastguard Worker		# (char*[ const])
4643*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4644*d68f33bcSAndroid Build Coastguard Worker			#print "AA<$1>\n";
4645*d68f33bcSAndroid Build Coastguard Worker			my ($ident, $from, $to) = ($1, $2, $2);
4646*d68f33bcSAndroid Build Coastguard Worker
4647*d68f33bcSAndroid Build Coastguard Worker			# Should start with a space.
4648*d68f33bcSAndroid Build Coastguard Worker			$to =~ s/^(\S)/ $1/;
4649*d68f33bcSAndroid Build Coastguard Worker			# Should not end with a space.
4650*d68f33bcSAndroid Build Coastguard Worker			$to =~ s/\s+$//;
4651*d68f33bcSAndroid Build Coastguard Worker			# '*'s should not have spaces between.
4652*d68f33bcSAndroid Build Coastguard Worker			while ($to =~ s/\*\s+\*/\*\*/) {
4653*d68f33bcSAndroid Build Coastguard Worker			}
4654*d68f33bcSAndroid Build Coastguard Worker
4655*d68f33bcSAndroid Build Coastguard Worker##			print "1: from<$from> to<$to> ident<$ident>\n";
4656*d68f33bcSAndroid Build Coastguard Worker			if ($from ne $to) {
4657*d68f33bcSAndroid Build Coastguard Worker				if (ERROR("POINTER_LOCATION",
4658*d68f33bcSAndroid Build Coastguard Worker					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
4659*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4660*d68f33bcSAndroid Build Coastguard Worker					my $sub_from = $ident;
4661*d68f33bcSAndroid Build Coastguard Worker					my $sub_to = $ident;
4662*d68f33bcSAndroid Build Coastguard Worker					$sub_to =~ s/\Q$from\E/$to/;
4663*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~
4664*d68f33bcSAndroid Build Coastguard Worker					    s@\Q$sub_from\E@$sub_to@;
4665*d68f33bcSAndroid Build Coastguard Worker				}
4666*d68f33bcSAndroid Build Coastguard Worker			}
4667*d68f33bcSAndroid Build Coastguard Worker		}
4668*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4669*d68f33bcSAndroid Build Coastguard Worker			#print "BB<$1>\n";
4670*d68f33bcSAndroid Build Coastguard Worker			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4671*d68f33bcSAndroid Build Coastguard Worker
4672*d68f33bcSAndroid Build Coastguard Worker			# Should start with a space.
4673*d68f33bcSAndroid Build Coastguard Worker			$to =~ s/^(\S)/ $1/;
4674*d68f33bcSAndroid Build Coastguard Worker			# Should not end with a space.
4675*d68f33bcSAndroid Build Coastguard Worker			$to =~ s/\s+$//;
4676*d68f33bcSAndroid Build Coastguard Worker			# '*'s should not have spaces between.
4677*d68f33bcSAndroid Build Coastguard Worker			while ($to =~ s/\*\s+\*/\*\*/) {
4678*d68f33bcSAndroid Build Coastguard Worker			}
4679*d68f33bcSAndroid Build Coastguard Worker			# Modifiers should have spaces.
4680*d68f33bcSAndroid Build Coastguard Worker			$to =~ s/(\b$Modifier$)/$1 /;
4681*d68f33bcSAndroid Build Coastguard Worker
4682*d68f33bcSAndroid Build Coastguard Worker##			print "2: from<$from> to<$to> ident<$ident>\n";
4683*d68f33bcSAndroid Build Coastguard Worker			if ($from ne $to && $ident !~ /^$Modifier$/) {
4684*d68f33bcSAndroid Build Coastguard Worker				if (ERROR("POINTER_LOCATION",
4685*d68f33bcSAndroid Build Coastguard Worker					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
4686*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4687*d68f33bcSAndroid Build Coastguard Worker
4688*d68f33bcSAndroid Build Coastguard Worker					my $sub_from = $match;
4689*d68f33bcSAndroid Build Coastguard Worker					my $sub_to = $match;
4690*d68f33bcSAndroid Build Coastguard Worker					$sub_to =~ s/\Q$from\E/$to/;
4691*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~
4692*d68f33bcSAndroid Build Coastguard Worker					    s@\Q$sub_from\E@$sub_to@;
4693*d68f33bcSAndroid Build Coastguard Worker				}
4694*d68f33bcSAndroid Build Coastguard Worker			}
4695*d68f33bcSAndroid Build Coastguard Worker		}
4696*d68f33bcSAndroid Build Coastguard Worker
4697*d68f33bcSAndroid Build Coastguard Worker# avoid BUG() or BUG_ON()
4698*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
4699*d68f33bcSAndroid Build Coastguard Worker			my $msg_level = \&WARN;
4700*d68f33bcSAndroid Build Coastguard Worker			$msg_level = \&CHK if ($file);
4701*d68f33bcSAndroid Build Coastguard Worker			&{$msg_level}("AVOID_BUG",
4702*d68f33bcSAndroid Build Coastguard Worker				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
4703*d68f33bcSAndroid Build Coastguard Worker		}
4704*d68f33bcSAndroid Build Coastguard Worker
4705*d68f33bcSAndroid Build Coastguard Worker# avoid LINUX_VERSION_CODE
4706*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4707*d68f33bcSAndroid Build Coastguard Worker			WARN("LINUX_VERSION_CODE",
4708*d68f33bcSAndroid Build Coastguard Worker			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
4709*d68f33bcSAndroid Build Coastguard Worker		}
4710*d68f33bcSAndroid Build Coastguard Worker
4711*d68f33bcSAndroid Build Coastguard Worker# check for uses of printk_ratelimit
4712*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4713*d68f33bcSAndroid Build Coastguard Worker			WARN("PRINTK_RATELIMITED",
4714*d68f33bcSAndroid Build Coastguard Worker			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
4715*d68f33bcSAndroid Build Coastguard Worker		}
4716*d68f33bcSAndroid Build Coastguard Worker
4717*d68f33bcSAndroid Build Coastguard Worker# printk should use KERN_* levels
4718*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4719*d68f33bcSAndroid Build Coastguard Worker			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4720*d68f33bcSAndroid Build Coastguard Worker			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
4721*d68f33bcSAndroid Build Coastguard Worker		}
4722*d68f33bcSAndroid Build Coastguard Worker
4723*d68f33bcSAndroid Build Coastguard Worker# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4724*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4725*d68f33bcSAndroid Build Coastguard Worker			my $printk = $1;
4726*d68f33bcSAndroid Build Coastguard Worker			my $modifier = $2;
4727*d68f33bcSAndroid Build Coastguard Worker			my $orig = $3;
4728*d68f33bcSAndroid Build Coastguard Worker			$modifier = "" if (!defined($modifier));
4729*d68f33bcSAndroid Build Coastguard Worker			my $level = lc($orig);
4730*d68f33bcSAndroid Build Coastguard Worker			$level = "warn" if ($level eq "warning");
4731*d68f33bcSAndroid Build Coastguard Worker			my $level2 = $level;
4732*d68f33bcSAndroid Build Coastguard Worker			$level2 = "dbg" if ($level eq "debug");
4733*d68f33bcSAndroid Build Coastguard Worker			$level .= $modifier;
4734*d68f33bcSAndroid Build Coastguard Worker			$level2 .= $modifier;
4735*d68f33bcSAndroid Build Coastguard Worker			WARN("PREFER_PR_LEVEL",
4736*d68f33bcSAndroid Build Coastguard Worker			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4737*d68f33bcSAndroid Build Coastguard Worker		}
4738*d68f33bcSAndroid Build Coastguard Worker
4739*d68f33bcSAndroid Build Coastguard Worker# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4740*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4741*d68f33bcSAndroid Build Coastguard Worker			my $orig = $1;
4742*d68f33bcSAndroid Build Coastguard Worker			my $level = lc($orig);
4743*d68f33bcSAndroid Build Coastguard Worker			$level = "warn" if ($level eq "warning");
4744*d68f33bcSAndroid Build Coastguard Worker			$level = "dbg" if ($level eq "debug");
4745*d68f33bcSAndroid Build Coastguard Worker			WARN("PREFER_DEV_LEVEL",
4746*d68f33bcSAndroid Build Coastguard Worker			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4747*d68f33bcSAndroid Build Coastguard Worker		}
4748*d68f33bcSAndroid Build Coastguard Worker
4749*d68f33bcSAndroid Build Coastguard Worker# trace_printk should not be used in production code.
4750*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
4751*d68f33bcSAndroid Build Coastguard Worker			WARN("TRACE_PRINTK",
4752*d68f33bcSAndroid Build Coastguard Worker			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
4753*d68f33bcSAndroid Build Coastguard Worker		}
4754*d68f33bcSAndroid Build Coastguard Worker
4755*d68f33bcSAndroid Build Coastguard Worker# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
4756*d68f33bcSAndroid Build Coastguard Worker# number of false positives, but assembly files are not checked, so at
4757*d68f33bcSAndroid Build Coastguard Worker# least the arch entry code will not trigger this warning.
4758*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bENOSYS\b/) {
4759*d68f33bcSAndroid Build Coastguard Worker			WARN("ENOSYS",
4760*d68f33bcSAndroid Build Coastguard Worker			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
4761*d68f33bcSAndroid Build Coastguard Worker		}
4762*d68f33bcSAndroid Build Coastguard Worker
4763*d68f33bcSAndroid Build Coastguard Worker# ENOTSUPP is not a standard error code and should be avoided in new patches.
4764*d68f33bcSAndroid Build Coastguard Worker# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
4765*d68f33bcSAndroid Build Coastguard Worker# Similarly to ENOSYS warning a small number of false positives is expected.
4766*d68f33bcSAndroid Build Coastguard Worker		if (!$file && $line =~ /\bENOTSUPP\b/) {
4767*d68f33bcSAndroid Build Coastguard Worker			if (WARN("ENOTSUPP",
4768*d68f33bcSAndroid Build Coastguard Worker				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
4769*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4770*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
4771*d68f33bcSAndroid Build Coastguard Worker			}
4772*d68f33bcSAndroid Build Coastguard Worker		}
4773*d68f33bcSAndroid Build Coastguard Worker
4774*d68f33bcSAndroid Build Coastguard Worker# function brace can't be on same line, except for #defines of do while,
4775*d68f33bcSAndroid Build Coastguard Worker# or if closed on same line
4776*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
4777*d68f33bcSAndroid Build Coastguard Worker		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
4778*d68f33bcSAndroid Build Coastguard Worker		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
4779*d68f33bcSAndroid Build Coastguard Worker		    $sline !~ /}/) {
4780*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("OPEN_BRACE",
4781*d68f33bcSAndroid Build Coastguard Worker				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
4782*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4783*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
4784*d68f33bcSAndroid Build Coastguard Worker				my $fixed_line = $rawline;
4785*d68f33bcSAndroid Build Coastguard Worker				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
4786*d68f33bcSAndroid Build Coastguard Worker				my $line1 = $1;
4787*d68f33bcSAndroid Build Coastguard Worker				my $line2 = $2;
4788*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, ltrim($line1));
4789*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, "\+{");
4790*d68f33bcSAndroid Build Coastguard Worker				if ($line2 !~ /^\s*$/) {
4791*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
4792*d68f33bcSAndroid Build Coastguard Worker				}
4793*d68f33bcSAndroid Build Coastguard Worker			}
4794*d68f33bcSAndroid Build Coastguard Worker		}
4795*d68f33bcSAndroid Build Coastguard Worker
4796*d68f33bcSAndroid Build Coastguard Worker# open braces for enum, union and struct go on the same line.
4797*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*{/ &&
4798*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
4799*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("OPEN_BRACE",
4800*d68f33bcSAndroid Build Coastguard Worker				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
4801*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4802*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr - 1, $prevrawline);
4803*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
4804*d68f33bcSAndroid Build Coastguard Worker				my $fixedline = rtrim($prevrawline) . " {";
4805*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, $fixedline);
4806*d68f33bcSAndroid Build Coastguard Worker				$fixedline = $rawline;
4807*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
4808*d68f33bcSAndroid Build Coastguard Worker				if ($fixedline !~ /^\+\s*$/) {
4809*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, $fixedline);
4810*d68f33bcSAndroid Build Coastguard Worker				}
4811*d68f33bcSAndroid Build Coastguard Worker			}
4812*d68f33bcSAndroid Build Coastguard Worker		}
4813*d68f33bcSAndroid Build Coastguard Worker
4814*d68f33bcSAndroid Build Coastguard Worker# missing space after union, struct or enum definition
4815*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
4816*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SPACING",
4817*d68f33bcSAndroid Build Coastguard Worker				 "missing space after $1 definition\n" . $herecurr) &&
4818*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
4819*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
4820*d68f33bcSAndroid Build Coastguard Worker				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
4821*d68f33bcSAndroid Build Coastguard Worker			}
4822*d68f33bcSAndroid Build Coastguard Worker		}
4823*d68f33bcSAndroid Build Coastguard Worker
4824*d68f33bcSAndroid Build Coastguard Worker# Function pointer declarations
4825*d68f33bcSAndroid Build Coastguard Worker# check spacing between type, funcptr, and args
4826*d68f33bcSAndroid Build Coastguard Worker# canonical declaration is "type (*funcptr)(args...)"
4827*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
4828*d68f33bcSAndroid Build Coastguard Worker			my $declare = $1;
4829*d68f33bcSAndroid Build Coastguard Worker			my $pre_pointer_space = $2;
4830*d68f33bcSAndroid Build Coastguard Worker			my $post_pointer_space = $3;
4831*d68f33bcSAndroid Build Coastguard Worker			my $funcname = $4;
4832*d68f33bcSAndroid Build Coastguard Worker			my $post_funcname_space = $5;
4833*d68f33bcSAndroid Build Coastguard Worker			my $pre_args_space = $6;
4834*d68f33bcSAndroid Build Coastguard Worker
4835*d68f33bcSAndroid Build Coastguard Worker# the $Declare variable will capture all spaces after the type
4836*d68f33bcSAndroid Build Coastguard Worker# so check it for a missing trailing missing space but pointer return types
4837*d68f33bcSAndroid Build Coastguard Worker# don't need a space so don't warn for those.
4838*d68f33bcSAndroid Build Coastguard Worker			my $post_declare_space = "";
4839*d68f33bcSAndroid Build Coastguard Worker			if ($declare =~ /(\s+)$/) {
4840*d68f33bcSAndroid Build Coastguard Worker				$post_declare_space = $1;
4841*d68f33bcSAndroid Build Coastguard Worker				$declare = rtrim($declare);
4842*d68f33bcSAndroid Build Coastguard Worker			}
4843*d68f33bcSAndroid Build Coastguard Worker			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
4844*d68f33bcSAndroid Build Coastguard Worker				WARN("SPACING",
4845*d68f33bcSAndroid Build Coastguard Worker				     "missing space after return type\n" . $herecurr);
4846*d68f33bcSAndroid Build Coastguard Worker				$post_declare_space = " ";
4847*d68f33bcSAndroid Build Coastguard Worker			}
4848*d68f33bcSAndroid Build Coastguard Worker
4849*d68f33bcSAndroid Build Coastguard Worker# unnecessary space "type  (*funcptr)(args...)"
4850*d68f33bcSAndroid Build Coastguard Worker# This test is not currently implemented because these declarations are
4851*d68f33bcSAndroid Build Coastguard Worker# equivalent to
4852*d68f33bcSAndroid Build Coastguard Worker#	int  foo(int bar, ...)
4853*d68f33bcSAndroid Build Coastguard Worker# and this is form shouldn't/doesn't generate a checkpatch warning.
4854*d68f33bcSAndroid Build Coastguard Worker#
4855*d68f33bcSAndroid Build Coastguard Worker#			elsif ($declare =~ /\s{2,}$/) {
4856*d68f33bcSAndroid Build Coastguard Worker#				WARN("SPACING",
4857*d68f33bcSAndroid Build Coastguard Worker#				     "Multiple spaces after return type\n" . $herecurr);
4858*d68f33bcSAndroid Build Coastguard Worker#			}
4859*d68f33bcSAndroid Build Coastguard Worker
4860*d68f33bcSAndroid Build Coastguard Worker# unnecessary space "type ( *funcptr)(args...)"
4861*d68f33bcSAndroid Build Coastguard Worker			if (defined $pre_pointer_space &&
4862*d68f33bcSAndroid Build Coastguard Worker			    $pre_pointer_space =~ /^\s/) {
4863*d68f33bcSAndroid Build Coastguard Worker				WARN("SPACING",
4864*d68f33bcSAndroid Build Coastguard Worker				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
4865*d68f33bcSAndroid Build Coastguard Worker			}
4866*d68f33bcSAndroid Build Coastguard Worker
4867*d68f33bcSAndroid Build Coastguard Worker# unnecessary space "type (* funcptr)(args...)"
4868*d68f33bcSAndroid Build Coastguard Worker			if (defined $post_pointer_space &&
4869*d68f33bcSAndroid Build Coastguard Worker			    $post_pointer_space =~ /^\s/) {
4870*d68f33bcSAndroid Build Coastguard Worker				WARN("SPACING",
4871*d68f33bcSAndroid Build Coastguard Worker				     "Unnecessary space before function pointer name\n" . $herecurr);
4872*d68f33bcSAndroid Build Coastguard Worker			}
4873*d68f33bcSAndroid Build Coastguard Worker
4874*d68f33bcSAndroid Build Coastguard Worker# unnecessary space "type (*funcptr )(args...)"
4875*d68f33bcSAndroid Build Coastguard Worker			if (defined $post_funcname_space &&
4876*d68f33bcSAndroid Build Coastguard Worker			    $post_funcname_space =~ /^\s/) {
4877*d68f33bcSAndroid Build Coastguard Worker				WARN("SPACING",
4878*d68f33bcSAndroid Build Coastguard Worker				     "Unnecessary space after function pointer name\n" . $herecurr);
4879*d68f33bcSAndroid Build Coastguard Worker			}
4880*d68f33bcSAndroid Build Coastguard Worker
4881*d68f33bcSAndroid Build Coastguard Worker# unnecessary space "type (*funcptr) (args...)"
4882*d68f33bcSAndroid Build Coastguard Worker			if (defined $pre_args_space &&
4883*d68f33bcSAndroid Build Coastguard Worker			    $pre_args_space =~ /^\s/) {
4884*d68f33bcSAndroid Build Coastguard Worker				WARN("SPACING",
4885*d68f33bcSAndroid Build Coastguard Worker				     "Unnecessary space before function pointer arguments\n" . $herecurr);
4886*d68f33bcSAndroid Build Coastguard Worker			}
4887*d68f33bcSAndroid Build Coastguard Worker
4888*d68f33bcSAndroid Build Coastguard Worker			if (show_type("SPACING") && $fix) {
4889*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
4890*d68f33bcSAndroid Build Coastguard Worker				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
4891*d68f33bcSAndroid Build Coastguard Worker			}
4892*d68f33bcSAndroid Build Coastguard Worker		}
4893*d68f33bcSAndroid Build Coastguard Worker
4894*d68f33bcSAndroid Build Coastguard Worker# check for spacing round square brackets; allowed:
4895*d68f33bcSAndroid Build Coastguard Worker#  1. with a type on the left -- int [] a;
4896*d68f33bcSAndroid Build Coastguard Worker#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4897*d68f33bcSAndroid Build Coastguard Worker#  3. inside a curly brace -- = { [0...10] = 5 }
4898*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ /(.*?\s)\[/g) {
4899*d68f33bcSAndroid Build Coastguard Worker			my ($where, $prefix) = ($-[1], $1);
4900*d68f33bcSAndroid Build Coastguard Worker			if ($prefix !~ /$Type\s+$/ &&
4901*d68f33bcSAndroid Build Coastguard Worker			    ($where != 0 || $prefix !~ /^.\s+$/) &&
4902*d68f33bcSAndroid Build Coastguard Worker			    $prefix !~ /[{,:]\s+$/) {
4903*d68f33bcSAndroid Build Coastguard Worker				if (ERROR("BRACKET_SPACE",
4904*d68f33bcSAndroid Build Coastguard Worker					  "space prohibited before open square bracket '['\n" . $herecurr) &&
4905*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
4906*d68f33bcSAndroid Build Coastguard Worker				    $fixed[$fixlinenr] =~
4907*d68f33bcSAndroid Build Coastguard Worker					s/^(\+.*?)\s+\[/$1\[/;
4908*d68f33bcSAndroid Build Coastguard Worker				}
4909*d68f33bcSAndroid Build Coastguard Worker			}
4910*d68f33bcSAndroid Build Coastguard Worker		}
4911*d68f33bcSAndroid Build Coastguard Worker
4912*d68f33bcSAndroid Build Coastguard Worker# check for spaces between functions and their parentheses.
4913*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ /($Ident)\s+\(/g) {
4914*d68f33bcSAndroid Build Coastguard Worker			my $name = $1;
4915*d68f33bcSAndroid Build Coastguard Worker			my $ctx_before = substr($line, 0, $-[1]);
4916*d68f33bcSAndroid Build Coastguard Worker			my $ctx = "$ctx_before$name";
4917*d68f33bcSAndroid Build Coastguard Worker
4918*d68f33bcSAndroid Build Coastguard Worker			# Ignore those directives where spaces _are_ permitted.
4919*d68f33bcSAndroid Build Coastguard Worker			if ($name =~ /^(?:
4920*d68f33bcSAndroid Build Coastguard Worker				if|for|while|switch|return|case|
4921*d68f33bcSAndroid Build Coastguard Worker				volatile|__volatile__|
4922*d68f33bcSAndroid Build Coastguard Worker				__attribute__|format|__extension__|
4923*d68f33bcSAndroid Build Coastguard Worker				asm|__asm__)$/x)
4924*d68f33bcSAndroid Build Coastguard Worker			{
4925*d68f33bcSAndroid Build Coastguard Worker			# cpp #define statements have non-optional spaces, ie
4926*d68f33bcSAndroid Build Coastguard Worker			# if there is a space between the name and the open
4927*d68f33bcSAndroid Build Coastguard Worker			# parenthesis it is simply not a parameter group.
4928*d68f33bcSAndroid Build Coastguard Worker			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4929*d68f33bcSAndroid Build Coastguard Worker
4930*d68f33bcSAndroid Build Coastguard Worker			# cpp #elif statement condition may start with a (
4931*d68f33bcSAndroid Build Coastguard Worker			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4932*d68f33bcSAndroid Build Coastguard Worker
4933*d68f33bcSAndroid Build Coastguard Worker			# If this whole things ends with a type its most
4934*d68f33bcSAndroid Build Coastguard Worker			# likely a typedef for a function.
4935*d68f33bcSAndroid Build Coastguard Worker			} elsif ($ctx =~ /$Type$/) {
4936*d68f33bcSAndroid Build Coastguard Worker
4937*d68f33bcSAndroid Build Coastguard Worker			} else {
4938*d68f33bcSAndroid Build Coastguard Worker				if (WARN("SPACING",
4939*d68f33bcSAndroid Build Coastguard Worker					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
4940*d68f33bcSAndroid Build Coastguard Worker					     $fix) {
4941*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~
4942*d68f33bcSAndroid Build Coastguard Worker					    s/\b$name\s+\(/$name\(/;
4943*d68f33bcSAndroid Build Coastguard Worker				}
4944*d68f33bcSAndroid Build Coastguard Worker			}
4945*d68f33bcSAndroid Build Coastguard Worker		}
4946*d68f33bcSAndroid Build Coastguard Worker
4947*d68f33bcSAndroid Build Coastguard Worker# Check operator spacing.
4948*d68f33bcSAndroid Build Coastguard Worker		if (!($line=~/\#\s*include/)) {
4949*d68f33bcSAndroid Build Coastguard Worker			my $fixed_line = "";
4950*d68f33bcSAndroid Build Coastguard Worker			my $line_fixed = 0;
4951*d68f33bcSAndroid Build Coastguard Worker
4952*d68f33bcSAndroid Build Coastguard Worker			my $ops = qr{
4953*d68f33bcSAndroid Build Coastguard Worker				<<=|>>=|<=|>=|==|!=|
4954*d68f33bcSAndroid Build Coastguard Worker				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
4955*d68f33bcSAndroid Build Coastguard Worker				=>|->|<<|>>|<|>|=|!|~|
4956*d68f33bcSAndroid Build Coastguard Worker				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
4957*d68f33bcSAndroid Build Coastguard Worker				\?:|\?|:
4958*d68f33bcSAndroid Build Coastguard Worker			}x;
4959*d68f33bcSAndroid Build Coastguard Worker			my @elements = split(/($ops|;)/, $opline);
4960*d68f33bcSAndroid Build Coastguard Worker
4961*d68f33bcSAndroid Build Coastguard Worker##			print("element count: <" . $#elements . ">\n");
4962*d68f33bcSAndroid Build Coastguard Worker##			foreach my $el (@elements) {
4963*d68f33bcSAndroid Build Coastguard Worker##				print("el: <$el>\n");
4964*d68f33bcSAndroid Build Coastguard Worker##			}
4965*d68f33bcSAndroid Build Coastguard Worker
4966*d68f33bcSAndroid Build Coastguard Worker			my @fix_elements = ();
4967*d68f33bcSAndroid Build Coastguard Worker			my $off = 0;
4968*d68f33bcSAndroid Build Coastguard Worker
4969*d68f33bcSAndroid Build Coastguard Worker			foreach my $el (@elements) {
4970*d68f33bcSAndroid Build Coastguard Worker				push(@fix_elements, substr($rawline, $off, length($el)));
4971*d68f33bcSAndroid Build Coastguard Worker				$off += length($el);
4972*d68f33bcSAndroid Build Coastguard Worker			}
4973*d68f33bcSAndroid Build Coastguard Worker
4974*d68f33bcSAndroid Build Coastguard Worker			$off = 0;
4975*d68f33bcSAndroid Build Coastguard Worker
4976*d68f33bcSAndroid Build Coastguard Worker			my $blank = copy_spacing($opline);
4977*d68f33bcSAndroid Build Coastguard Worker			my $last_after = -1;
4978*d68f33bcSAndroid Build Coastguard Worker
4979*d68f33bcSAndroid Build Coastguard Worker			for (my $n = 0; $n < $#elements; $n += 2) {
4980*d68f33bcSAndroid Build Coastguard Worker
4981*d68f33bcSAndroid Build Coastguard Worker				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
4982*d68f33bcSAndroid Build Coastguard Worker
4983*d68f33bcSAndroid Build Coastguard Worker##				print("n: <$n> good: <$good>\n");
4984*d68f33bcSAndroid Build Coastguard Worker
4985*d68f33bcSAndroid Build Coastguard Worker				$off += length($elements[$n]);
4986*d68f33bcSAndroid Build Coastguard Worker
4987*d68f33bcSAndroid Build Coastguard Worker				# Pick up the preceding and succeeding characters.
4988*d68f33bcSAndroid Build Coastguard Worker				my $ca = substr($opline, 0, $off);
4989*d68f33bcSAndroid Build Coastguard Worker				my $cc = '';
4990*d68f33bcSAndroid Build Coastguard Worker				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4991*d68f33bcSAndroid Build Coastguard Worker					$cc = substr($opline, $off + length($elements[$n + 1]));
4992*d68f33bcSAndroid Build Coastguard Worker				}
4993*d68f33bcSAndroid Build Coastguard Worker				my $cb = "$ca$;$cc";
4994*d68f33bcSAndroid Build Coastguard Worker
4995*d68f33bcSAndroid Build Coastguard Worker				my $a = '';
4996*d68f33bcSAndroid Build Coastguard Worker				$a = 'V' if ($elements[$n] ne '');
4997*d68f33bcSAndroid Build Coastguard Worker				$a = 'W' if ($elements[$n] =~ /\s$/);
4998*d68f33bcSAndroid Build Coastguard Worker				$a = 'C' if ($elements[$n] =~ /$;$/);
4999*d68f33bcSAndroid Build Coastguard Worker				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
5000*d68f33bcSAndroid Build Coastguard Worker				$a = 'O' if ($elements[$n] eq '');
5001*d68f33bcSAndroid Build Coastguard Worker				$a = 'E' if ($ca =~ /^\s*$/);
5002*d68f33bcSAndroid Build Coastguard Worker
5003*d68f33bcSAndroid Build Coastguard Worker				my $op = $elements[$n + 1];
5004*d68f33bcSAndroid Build Coastguard Worker
5005*d68f33bcSAndroid Build Coastguard Worker				my $c = '';
5006*d68f33bcSAndroid Build Coastguard Worker				if (defined $elements[$n + 2]) {
5007*d68f33bcSAndroid Build Coastguard Worker					$c = 'V' if ($elements[$n + 2] ne '');
5008*d68f33bcSAndroid Build Coastguard Worker					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
5009*d68f33bcSAndroid Build Coastguard Worker					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
5010*d68f33bcSAndroid Build Coastguard Worker					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
5011*d68f33bcSAndroid Build Coastguard Worker					$c = 'O' if ($elements[$n + 2] eq '');
5012*d68f33bcSAndroid Build Coastguard Worker					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
5013*d68f33bcSAndroid Build Coastguard Worker				} else {
5014*d68f33bcSAndroid Build Coastguard Worker					$c = 'E';
5015*d68f33bcSAndroid Build Coastguard Worker				}
5016*d68f33bcSAndroid Build Coastguard Worker
5017*d68f33bcSAndroid Build Coastguard Worker				my $ctx = "${a}x${c}";
5018*d68f33bcSAndroid Build Coastguard Worker
5019*d68f33bcSAndroid Build Coastguard Worker				my $at = "(ctx:$ctx)";
5020*d68f33bcSAndroid Build Coastguard Worker
5021*d68f33bcSAndroid Build Coastguard Worker				my $ptr = substr($blank, 0, $off) . "^";
5022*d68f33bcSAndroid Build Coastguard Worker				my $hereptr = "$hereline$ptr\n";
5023*d68f33bcSAndroid Build Coastguard Worker
5024*d68f33bcSAndroid Build Coastguard Worker				# Pull out the value of this operator.
5025*d68f33bcSAndroid Build Coastguard Worker				my $op_type = substr($curr_values, $off + 1, 1);
5026*d68f33bcSAndroid Build Coastguard Worker
5027*d68f33bcSAndroid Build Coastguard Worker				# Get the full operator variant.
5028*d68f33bcSAndroid Build Coastguard Worker				my $opv = $op . substr($curr_vars, $off, 1);
5029*d68f33bcSAndroid Build Coastguard Worker
5030*d68f33bcSAndroid Build Coastguard Worker				# Ignore operators passed as parameters.
5031*d68f33bcSAndroid Build Coastguard Worker				if ($op_type ne 'V' &&
5032*d68f33bcSAndroid Build Coastguard Worker				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
5033*d68f33bcSAndroid Build Coastguard Worker
5034*d68f33bcSAndroid Build Coastguard Worker#				# Ignore comments
5035*d68f33bcSAndroid Build Coastguard Worker#				} elsif ($op =~ /^$;+$/) {
5036*d68f33bcSAndroid Build Coastguard Worker
5037*d68f33bcSAndroid Build Coastguard Worker				# ; should have either the end of line or a space or \ after it
5038*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq ';') {
5039*d68f33bcSAndroid Build Coastguard Worker					if ($ctx !~ /.x[WEBC]/ &&
5040*d68f33bcSAndroid Build Coastguard Worker					    $cc !~ /^\\/ && $cc !~ /^;/) {
5041*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5042*d68f33bcSAndroid Build Coastguard Worker							  "space required after that '$op' $at\n" . $hereptr)) {
5043*d68f33bcSAndroid Build Coastguard Worker							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
5044*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5045*d68f33bcSAndroid Build Coastguard Worker						}
5046*d68f33bcSAndroid Build Coastguard Worker					}
5047*d68f33bcSAndroid Build Coastguard Worker
5048*d68f33bcSAndroid Build Coastguard Worker				# // is a comment
5049*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq '//') {
5050*d68f33bcSAndroid Build Coastguard Worker
5051*d68f33bcSAndroid Build Coastguard Worker				#   :   when part of a bitfield
5052*d68f33bcSAndroid Build Coastguard Worker				} elsif ($opv eq ':B') {
5053*d68f33bcSAndroid Build Coastguard Worker					# skip the bitfield test for now
5054*d68f33bcSAndroid Build Coastguard Worker
5055*d68f33bcSAndroid Build Coastguard Worker				# No spaces for:
5056*d68f33bcSAndroid Build Coastguard Worker				#   ->
5057*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq '->') {
5058*d68f33bcSAndroid Build Coastguard Worker					if ($ctx =~ /Wx.|.xW/) {
5059*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5060*d68f33bcSAndroid Build Coastguard Worker							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5061*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5062*d68f33bcSAndroid Build Coastguard Worker							if (defined $fix_elements[$n + 2]) {
5063*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5064*d68f33bcSAndroid Build Coastguard Worker							}
5065*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5066*d68f33bcSAndroid Build Coastguard Worker						}
5067*d68f33bcSAndroid Build Coastguard Worker					}
5068*d68f33bcSAndroid Build Coastguard Worker
5069*d68f33bcSAndroid Build Coastguard Worker				# , must not have a space before and must have a space on the right.
5070*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq ',') {
5071*d68f33bcSAndroid Build Coastguard Worker					my $rtrim_before = 0;
5072*d68f33bcSAndroid Build Coastguard Worker					my $space_after = 0;
5073*d68f33bcSAndroid Build Coastguard Worker					if ($ctx =~ /Wx./) {
5074*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5075*d68f33bcSAndroid Build Coastguard Worker							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5076*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5077*d68f33bcSAndroid Build Coastguard Worker							$rtrim_before = 1;
5078*d68f33bcSAndroid Build Coastguard Worker						}
5079*d68f33bcSAndroid Build Coastguard Worker					}
5080*d68f33bcSAndroid Build Coastguard Worker					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
5081*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5082*d68f33bcSAndroid Build Coastguard Worker							  "space required after that '$op' $at\n" . $hereptr)) {
5083*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5084*d68f33bcSAndroid Build Coastguard Worker							$last_after = $n;
5085*d68f33bcSAndroid Build Coastguard Worker							$space_after = 1;
5086*d68f33bcSAndroid Build Coastguard Worker						}
5087*d68f33bcSAndroid Build Coastguard Worker					}
5088*d68f33bcSAndroid Build Coastguard Worker					if ($rtrim_before || $space_after) {
5089*d68f33bcSAndroid Build Coastguard Worker						if ($rtrim_before) {
5090*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5091*d68f33bcSAndroid Build Coastguard Worker						} else {
5092*d68f33bcSAndroid Build Coastguard Worker							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
5093*d68f33bcSAndroid Build Coastguard Worker						}
5094*d68f33bcSAndroid Build Coastguard Worker						if ($space_after) {
5095*d68f33bcSAndroid Build Coastguard Worker							$good .= " ";
5096*d68f33bcSAndroid Build Coastguard Worker						}
5097*d68f33bcSAndroid Build Coastguard Worker					}
5098*d68f33bcSAndroid Build Coastguard Worker
5099*d68f33bcSAndroid Build Coastguard Worker				# '*' as part of a type definition -- reported already.
5100*d68f33bcSAndroid Build Coastguard Worker				} elsif ($opv eq '*_') {
5101*d68f33bcSAndroid Build Coastguard Worker					#warn "'*' is part of type\n";
5102*d68f33bcSAndroid Build Coastguard Worker
5103*d68f33bcSAndroid Build Coastguard Worker				# unary operators should have a space before and
5104*d68f33bcSAndroid Build Coastguard Worker				# none after.  May be left adjacent to another
5105*d68f33bcSAndroid Build Coastguard Worker				# unary operator, or a cast
5106*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq '!' || $op eq '~' ||
5107*d68f33bcSAndroid Build Coastguard Worker					 $opv eq '*U' || $opv eq '-U' ||
5108*d68f33bcSAndroid Build Coastguard Worker					 $opv eq '&U' || $opv eq '&&U') {
5109*d68f33bcSAndroid Build Coastguard Worker					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
5110*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5111*d68f33bcSAndroid Build Coastguard Worker							  "space required before that '$op' $at\n" . $hereptr)) {
5112*d68f33bcSAndroid Build Coastguard Worker							if ($n != $last_after + 2) {
5113*d68f33bcSAndroid Build Coastguard Worker								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
5114*d68f33bcSAndroid Build Coastguard Worker								$line_fixed = 1;
5115*d68f33bcSAndroid Build Coastguard Worker							}
5116*d68f33bcSAndroid Build Coastguard Worker						}
5117*d68f33bcSAndroid Build Coastguard Worker					}
5118*d68f33bcSAndroid Build Coastguard Worker					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
5119*d68f33bcSAndroid Build Coastguard Worker						# A unary '*' may be const
5120*d68f33bcSAndroid Build Coastguard Worker
5121*d68f33bcSAndroid Build Coastguard Worker					} elsif ($ctx =~ /.xW/) {
5122*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5123*d68f33bcSAndroid Build Coastguard Worker							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5124*d68f33bcSAndroid Build Coastguard Worker							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
5125*d68f33bcSAndroid Build Coastguard Worker							if (defined $fix_elements[$n + 2]) {
5126*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5127*d68f33bcSAndroid Build Coastguard Worker							}
5128*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5129*d68f33bcSAndroid Build Coastguard Worker						}
5130*d68f33bcSAndroid Build Coastguard Worker					}
5131*d68f33bcSAndroid Build Coastguard Worker
5132*d68f33bcSAndroid Build Coastguard Worker				# unary ++ and unary -- are allowed no space on one side.
5133*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq '++' or $op eq '--') {
5134*d68f33bcSAndroid Build Coastguard Worker					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
5135*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5136*d68f33bcSAndroid Build Coastguard Worker							  "space required one side of that '$op' $at\n" . $hereptr)) {
5137*d68f33bcSAndroid Build Coastguard Worker							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
5138*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5139*d68f33bcSAndroid Build Coastguard Worker						}
5140*d68f33bcSAndroid Build Coastguard Worker					}
5141*d68f33bcSAndroid Build Coastguard Worker					if ($ctx =~ /Wx[BE]/ ||
5142*d68f33bcSAndroid Build Coastguard Worker					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
5143*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5144*d68f33bcSAndroid Build Coastguard Worker							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5145*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5146*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5147*d68f33bcSAndroid Build Coastguard Worker						}
5148*d68f33bcSAndroid Build Coastguard Worker					}
5149*d68f33bcSAndroid Build Coastguard Worker					if ($ctx =~ /ExW/) {
5150*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5151*d68f33bcSAndroid Build Coastguard Worker							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5152*d68f33bcSAndroid Build Coastguard Worker							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
5153*d68f33bcSAndroid Build Coastguard Worker							if (defined $fix_elements[$n + 2]) {
5154*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5155*d68f33bcSAndroid Build Coastguard Worker							}
5156*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5157*d68f33bcSAndroid Build Coastguard Worker						}
5158*d68f33bcSAndroid Build Coastguard Worker					}
5159*d68f33bcSAndroid Build Coastguard Worker
5160*d68f33bcSAndroid Build Coastguard Worker				# << and >> may either have or not have spaces both sides
5161*d68f33bcSAndroid Build Coastguard Worker				} elsif ($op eq '<<' or $op eq '>>' or
5162*d68f33bcSAndroid Build Coastguard Worker					 $op eq '&' or $op eq '^' or $op eq '|' or
5163*d68f33bcSAndroid Build Coastguard Worker					 $op eq '+' or $op eq '-' or
5164*d68f33bcSAndroid Build Coastguard Worker					 $op eq '*' or $op eq '/' or
5165*d68f33bcSAndroid Build Coastguard Worker					 $op eq '%')
5166*d68f33bcSAndroid Build Coastguard Worker				{
5167*d68f33bcSAndroid Build Coastguard Worker					if ($check) {
5168*d68f33bcSAndroid Build Coastguard Worker						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5169*d68f33bcSAndroid Build Coastguard Worker							if (CHK("SPACING",
5170*d68f33bcSAndroid Build Coastguard Worker								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5171*d68f33bcSAndroid Build Coastguard Worker								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5172*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5173*d68f33bcSAndroid Build Coastguard Worker								$line_fixed = 1;
5174*d68f33bcSAndroid Build Coastguard Worker							}
5175*d68f33bcSAndroid Build Coastguard Worker						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5176*d68f33bcSAndroid Build Coastguard Worker							if (CHK("SPACING",
5177*d68f33bcSAndroid Build Coastguard Worker								"space preferred before that '$op' $at\n" . $hereptr)) {
5178*d68f33bcSAndroid Build Coastguard Worker								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5179*d68f33bcSAndroid Build Coastguard Worker								$line_fixed = 1;
5180*d68f33bcSAndroid Build Coastguard Worker							}
5181*d68f33bcSAndroid Build Coastguard Worker						}
5182*d68f33bcSAndroid Build Coastguard Worker					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
5183*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5184*d68f33bcSAndroid Build Coastguard Worker							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5185*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5186*d68f33bcSAndroid Build Coastguard Worker							if (defined $fix_elements[$n + 2]) {
5187*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5188*d68f33bcSAndroid Build Coastguard Worker							}
5189*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5190*d68f33bcSAndroid Build Coastguard Worker						}
5191*d68f33bcSAndroid Build Coastguard Worker					}
5192*d68f33bcSAndroid Build Coastguard Worker
5193*d68f33bcSAndroid Build Coastguard Worker				# A colon needs no spaces before when it is
5194*d68f33bcSAndroid Build Coastguard Worker				# terminating a case value or a label.
5195*d68f33bcSAndroid Build Coastguard Worker				} elsif ($opv eq ':C' || $opv eq ':L') {
5196*d68f33bcSAndroid Build Coastguard Worker					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
5197*d68f33bcSAndroid Build Coastguard Worker						if (ERROR("SPACING",
5198*d68f33bcSAndroid Build Coastguard Worker							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5199*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
5200*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5201*d68f33bcSAndroid Build Coastguard Worker						}
5202*d68f33bcSAndroid Build Coastguard Worker					}
5203*d68f33bcSAndroid Build Coastguard Worker
5204*d68f33bcSAndroid Build Coastguard Worker				# All the others need spaces both sides.
5205*d68f33bcSAndroid Build Coastguard Worker				} elsif ($ctx !~ /[EWC]x[CWE]/) {
5206*d68f33bcSAndroid Build Coastguard Worker					my $ok = 0;
5207*d68f33bcSAndroid Build Coastguard Worker
5208*d68f33bcSAndroid Build Coastguard Worker					# Ignore email addresses <foo@bar>
5209*d68f33bcSAndroid Build Coastguard Worker					if (($op eq '<' &&
5210*d68f33bcSAndroid Build Coastguard Worker					     $cc =~ /^\S+\@\S+>/) ||
5211*d68f33bcSAndroid Build Coastguard Worker					    ($op eq '>' &&
5212*d68f33bcSAndroid Build Coastguard Worker					     $ca =~ /<\S+\@\S+$/))
5213*d68f33bcSAndroid Build Coastguard Worker					{
5214*d68f33bcSAndroid Build Coastguard Worker						$ok = 1;
5215*d68f33bcSAndroid Build Coastguard Worker					}
5216*d68f33bcSAndroid Build Coastguard Worker
5217*d68f33bcSAndroid Build Coastguard Worker					# for asm volatile statements
5218*d68f33bcSAndroid Build Coastguard Worker					# ignore a colon with another
5219*d68f33bcSAndroid Build Coastguard Worker					# colon immediately before or after
5220*d68f33bcSAndroid Build Coastguard Worker					if (($op eq ':') &&
5221*d68f33bcSAndroid Build Coastguard Worker					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5222*d68f33bcSAndroid Build Coastguard Worker						$ok = 1;
5223*d68f33bcSAndroid Build Coastguard Worker					}
5224*d68f33bcSAndroid Build Coastguard Worker
5225*d68f33bcSAndroid Build Coastguard Worker					# messages are ERROR, but ?: are CHK
5226*d68f33bcSAndroid Build Coastguard Worker					if ($ok == 0) {
5227*d68f33bcSAndroid Build Coastguard Worker						my $msg_level = \&ERROR;
5228*d68f33bcSAndroid Build Coastguard Worker						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
5229*d68f33bcSAndroid Build Coastguard Worker
5230*d68f33bcSAndroid Build Coastguard Worker						if (&{$msg_level}("SPACING",
5231*d68f33bcSAndroid Build Coastguard Worker								  "spaces required around that '$op' $at\n" . $hereptr)) {
5232*d68f33bcSAndroid Build Coastguard Worker							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5233*d68f33bcSAndroid Build Coastguard Worker							if (defined $fix_elements[$n + 2]) {
5234*d68f33bcSAndroid Build Coastguard Worker								$fix_elements[$n + 2] =~ s/^\s+//;
5235*d68f33bcSAndroid Build Coastguard Worker							}
5236*d68f33bcSAndroid Build Coastguard Worker							$line_fixed = 1;
5237*d68f33bcSAndroid Build Coastguard Worker						}
5238*d68f33bcSAndroid Build Coastguard Worker					}
5239*d68f33bcSAndroid Build Coastguard Worker				}
5240*d68f33bcSAndroid Build Coastguard Worker				$off += length($elements[$n + 1]);
5241*d68f33bcSAndroid Build Coastguard Worker
5242*d68f33bcSAndroid Build Coastguard Worker##				print("n: <$n> GOOD: <$good>\n");
5243*d68f33bcSAndroid Build Coastguard Worker
5244*d68f33bcSAndroid Build Coastguard Worker				$fixed_line = $fixed_line . $good;
5245*d68f33bcSAndroid Build Coastguard Worker			}
5246*d68f33bcSAndroid Build Coastguard Worker
5247*d68f33bcSAndroid Build Coastguard Worker			if (($#elements % 2) == 0) {
5248*d68f33bcSAndroid Build Coastguard Worker				$fixed_line = $fixed_line . $fix_elements[$#elements];
5249*d68f33bcSAndroid Build Coastguard Worker			}
5250*d68f33bcSAndroid Build Coastguard Worker
5251*d68f33bcSAndroid Build Coastguard Worker			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5252*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] = $fixed_line;
5253*d68f33bcSAndroid Build Coastguard Worker			}
5254*d68f33bcSAndroid Build Coastguard Worker
5255*d68f33bcSAndroid Build Coastguard Worker
5256*d68f33bcSAndroid Build Coastguard Worker		}
5257*d68f33bcSAndroid Build Coastguard Worker
5258*d68f33bcSAndroid Build Coastguard Worker# check for whitespace before a non-naked semicolon
5259*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*\S\s+;\s*$/) {
5260*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SPACING",
5261*d68f33bcSAndroid Build Coastguard Worker				 "space prohibited before semicolon\n" . $herecurr) &&
5262*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5263*d68f33bcSAndroid Build Coastguard Worker				1 while $fixed[$fixlinenr] =~
5264*d68f33bcSAndroid Build Coastguard Worker				    s/^(\+.*\S)\s+;/$1;/;
5265*d68f33bcSAndroid Build Coastguard Worker			}
5266*d68f33bcSAndroid Build Coastguard Worker		}
5267*d68f33bcSAndroid Build Coastguard Worker
5268*d68f33bcSAndroid Build Coastguard Worker# check for multiple assignments
5269*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5270*d68f33bcSAndroid Build Coastguard Worker			CHK("MULTIPLE_ASSIGNMENTS",
5271*d68f33bcSAndroid Build Coastguard Worker			    "multiple assignments should be avoided\n" . $herecurr);
5272*d68f33bcSAndroid Build Coastguard Worker		}
5273*d68f33bcSAndroid Build Coastguard Worker
5274*d68f33bcSAndroid Build Coastguard Worker## # check for multiple declarations, allowing for a function declaration
5275*d68f33bcSAndroid Build Coastguard Worker## # continuation.
5276*d68f33bcSAndroid Build Coastguard Worker## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
5277*d68f33bcSAndroid Build Coastguard Worker## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
5278*d68f33bcSAndroid Build Coastguard Worker##
5279*d68f33bcSAndroid Build Coastguard Worker## 			# Remove any bracketed sections to ensure we do not
5280*d68f33bcSAndroid Build Coastguard Worker## 			# falsely report the parameters of functions.
5281*d68f33bcSAndroid Build Coastguard Worker## 			my $ln = $line;
5282*d68f33bcSAndroid Build Coastguard Worker## 			while ($ln =~ s/\([^\(\)]*\)//g) {
5283*d68f33bcSAndroid Build Coastguard Worker## 			}
5284*d68f33bcSAndroid Build Coastguard Worker## 			if ($ln =~ /,/) {
5285*d68f33bcSAndroid Build Coastguard Worker## 				WARN("MULTIPLE_DECLARATION",
5286*d68f33bcSAndroid Build Coastguard Worker##				     "declaring multiple variables together should be avoided\n" . $herecurr);
5287*d68f33bcSAndroid Build Coastguard Worker## 			}
5288*d68f33bcSAndroid Build Coastguard Worker## 		}
5289*d68f33bcSAndroid Build Coastguard Worker
5290*d68f33bcSAndroid Build Coastguard Worker#need space before brace following if, while, etc
5291*d68f33bcSAndroid Build Coastguard Worker		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
5292*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b(?:else|do)\{/) {
5293*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5294*d68f33bcSAndroid Build Coastguard Worker				  "space required before the open brace '{'\n" . $herecurr) &&
5295*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5296*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
5297*d68f33bcSAndroid Build Coastguard Worker			}
5298*d68f33bcSAndroid Build Coastguard Worker		}
5299*d68f33bcSAndroid Build Coastguard Worker
5300*d68f33bcSAndroid Build Coastguard Worker## # check for blank lines before declarations
5301*d68f33bcSAndroid Build Coastguard Worker##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5302*d68f33bcSAndroid Build Coastguard Worker##		    $prevrawline =~ /^.\s*$/) {
5303*d68f33bcSAndroid Build Coastguard Worker##			WARN("SPACING",
5304*d68f33bcSAndroid Build Coastguard Worker##			     "No blank lines before declarations\n" . $hereprev);
5305*d68f33bcSAndroid Build Coastguard Worker##		}
5306*d68f33bcSAndroid Build Coastguard Worker##
5307*d68f33bcSAndroid Build Coastguard Worker
5308*d68f33bcSAndroid Build Coastguard Worker# closing brace should have a space following it when it has anything
5309*d68f33bcSAndroid Build Coastguard Worker# on the line
5310*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5311*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5312*d68f33bcSAndroid Build Coastguard Worker				  "space required after that close brace '}'\n" . $herecurr) &&
5313*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5314*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5315*d68f33bcSAndroid Build Coastguard Worker				    s/}((?!(?:,|;|\)))\S)/} $1/;
5316*d68f33bcSAndroid Build Coastguard Worker			}
5317*d68f33bcSAndroid Build Coastguard Worker		}
5318*d68f33bcSAndroid Build Coastguard Worker
5319*d68f33bcSAndroid Build Coastguard Worker# check spacing on square brackets
5320*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
5321*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5322*d68f33bcSAndroid Build Coastguard Worker				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
5323*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5324*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5325*d68f33bcSAndroid Build Coastguard Worker				    s/\[\s+/\[/;
5326*d68f33bcSAndroid Build Coastguard Worker			}
5327*d68f33bcSAndroid Build Coastguard Worker		}
5328*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\s\]/) {
5329*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5330*d68f33bcSAndroid Build Coastguard Worker				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
5331*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5332*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5333*d68f33bcSAndroid Build Coastguard Worker				    s/\s+\]/\]/;
5334*d68f33bcSAndroid Build Coastguard Worker			}
5335*d68f33bcSAndroid Build Coastguard Worker		}
5336*d68f33bcSAndroid Build Coastguard Worker
5337*d68f33bcSAndroid Build Coastguard Worker# check spacing on parentheses
5338*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
5339*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /for\s*\(\s+;/) {
5340*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5341*d68f33bcSAndroid Build Coastguard Worker				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
5342*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5343*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5344*d68f33bcSAndroid Build Coastguard Worker				    s/\(\s+/\(/;
5345*d68f33bcSAndroid Build Coastguard Worker			}
5346*d68f33bcSAndroid Build Coastguard Worker		}
5347*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5348*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /for\s*\(.*;\s+\)/ &&
5349*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /:\s+\)/) {
5350*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5351*d68f33bcSAndroid Build Coastguard Worker				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
5352*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5353*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5354*d68f33bcSAndroid Build Coastguard Worker				    s/\s+\)/\)/;
5355*d68f33bcSAndroid Build Coastguard Worker			}
5356*d68f33bcSAndroid Build Coastguard Worker		}
5357*d68f33bcSAndroid Build Coastguard Worker
5358*d68f33bcSAndroid Build Coastguard Worker# check unnecessary parentheses around addressof/dereference single $Lvals
5359*d68f33bcSAndroid Build Coastguard Worker# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5360*d68f33bcSAndroid Build Coastguard Worker
5361*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5362*d68f33bcSAndroid Build Coastguard Worker			my $var = $1;
5363*d68f33bcSAndroid Build Coastguard Worker			if (CHK("UNNECESSARY_PARENTHESES",
5364*d68f33bcSAndroid Build Coastguard Worker				"Unnecessary parentheses around $var\n" . $herecurr) &&
5365*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5366*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5367*d68f33bcSAndroid Build Coastguard Worker			}
5368*d68f33bcSAndroid Build Coastguard Worker		}
5369*d68f33bcSAndroid Build Coastguard Worker
5370*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary parentheses around function pointer uses
5371*d68f33bcSAndroid Build Coastguard Worker# ie: (foo->bar)(); should be foo->bar();
5372*d68f33bcSAndroid Build Coastguard Worker# but not "if (foo->bar) (" to avoid some false positives
5373*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5374*d68f33bcSAndroid Build Coastguard Worker			my $var = $2;
5375*d68f33bcSAndroid Build Coastguard Worker			if (CHK("UNNECESSARY_PARENTHESES",
5376*d68f33bcSAndroid Build Coastguard Worker				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5377*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5378*d68f33bcSAndroid Build Coastguard Worker				my $var2 = deparenthesize($var);
5379*d68f33bcSAndroid Build Coastguard Worker				$var2 =~ s/\s//g;
5380*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5381*d68f33bcSAndroid Build Coastguard Worker			}
5382*d68f33bcSAndroid Build Coastguard Worker		}
5383*d68f33bcSAndroid Build Coastguard Worker
5384*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary parentheses around comparisons in if uses
5385*d68f33bcSAndroid Build Coastguard Worker# when !drivers/staging or command-line uses --strict
5386*d68f33bcSAndroid Build Coastguard Worker		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
5387*d68f33bcSAndroid Build Coastguard Worker		    $perl_version_ok && defined($stat) &&
5388*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
5389*d68f33bcSAndroid Build Coastguard Worker			my $if_stat = $1;
5390*d68f33bcSAndroid Build Coastguard Worker			my $test = substr($2, 1, -1);
5391*d68f33bcSAndroid Build Coastguard Worker			my $herectx;
5392*d68f33bcSAndroid Build Coastguard Worker			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
5393*d68f33bcSAndroid Build Coastguard Worker				my $match = $1;
5394*d68f33bcSAndroid Build Coastguard Worker				# avoid parentheses around potential macro args
5395*d68f33bcSAndroid Build Coastguard Worker				next if ($match =~ /^\s*\w+\s*$/);
5396*d68f33bcSAndroid Build Coastguard Worker				if (!defined($herectx)) {
5397*d68f33bcSAndroid Build Coastguard Worker					$herectx = $here . "\n";
5398*d68f33bcSAndroid Build Coastguard Worker					my $cnt = statement_rawlines($if_stat);
5399*d68f33bcSAndroid Build Coastguard Worker					for (my $n = 0; $n < $cnt; $n++) {
5400*d68f33bcSAndroid Build Coastguard Worker						my $rl = raw_line($linenr, $n);
5401*d68f33bcSAndroid Build Coastguard Worker						$herectx .=  $rl . "\n";
5402*d68f33bcSAndroid Build Coastguard Worker						last if $rl =~ /^[ \+].*\{/;
5403*d68f33bcSAndroid Build Coastguard Worker					}
5404*d68f33bcSAndroid Build Coastguard Worker				}
5405*d68f33bcSAndroid Build Coastguard Worker				CHK("UNNECESSARY_PARENTHESES",
5406*d68f33bcSAndroid Build Coastguard Worker				    "Unnecessary parentheses around '$match'\n" . $herectx);
5407*d68f33bcSAndroid Build Coastguard Worker			}
5408*d68f33bcSAndroid Build Coastguard Worker		}
5409*d68f33bcSAndroid Build Coastguard Worker
5410*d68f33bcSAndroid Build Coastguard Worker# check that goto labels aren't indented (allow a single space indentation)
5411*d68f33bcSAndroid Build Coastguard Worker# and ignore bitfield definitions like foo:1
5412*d68f33bcSAndroid Build Coastguard Worker# Strictly, labels can have whitespace after the identifier and before the :
5413*d68f33bcSAndroid Build Coastguard Worker# but this is not allowed here as many ?: uses would appear to be labels
5414*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
5415*d68f33bcSAndroid Build Coastguard Worker		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
5416*d68f33bcSAndroid Build Coastguard Worker		    $sline !~ /^.\s+default:/) {
5417*d68f33bcSAndroid Build Coastguard Worker			if (WARN("INDENTED_LABEL",
5418*d68f33bcSAndroid Build Coastguard Worker				 "labels should not be indented\n" . $herecurr) &&
5419*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5420*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5421*d68f33bcSAndroid Build Coastguard Worker				    s/^(.)\s+/$1/;
5422*d68f33bcSAndroid Build Coastguard Worker			}
5423*d68f33bcSAndroid Build Coastguard Worker		}
5424*d68f33bcSAndroid Build Coastguard Worker
5425*d68f33bcSAndroid Build Coastguard Worker# check if a statement with a comma should be two statements like:
5426*d68f33bcSAndroid Build Coastguard Worker#	foo = bar(),	/* comma should be semicolon */
5427*d68f33bcSAndroid Build Coastguard Worker#	bar = baz();
5428*d68f33bcSAndroid Build Coastguard Worker		if (defined($stat) &&
5429*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
5430*d68f33bcSAndroid Build Coastguard Worker			my $cnt = statement_rawlines($stat);
5431*d68f33bcSAndroid Build Coastguard Worker			my $herectx = get_stat_here($linenr, $cnt, $here);
5432*d68f33bcSAndroid Build Coastguard Worker			WARN("SUSPECT_COMMA_SEMICOLON",
5433*d68f33bcSAndroid Build Coastguard Worker			     "Possible comma where semicolon could be used\n" . $herectx);
5434*d68f33bcSAndroid Build Coastguard Worker		}
5435*d68f33bcSAndroid Build Coastguard Worker
5436*d68f33bcSAndroid Build Coastguard Worker# return is not a function
5437*d68f33bcSAndroid Build Coastguard Worker		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5438*d68f33bcSAndroid Build Coastguard Worker			my $spacing = $1;
5439*d68f33bcSAndroid Build Coastguard Worker			if ($perl_version_ok &&
5440*d68f33bcSAndroid Build Coastguard Worker			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
5441*d68f33bcSAndroid Build Coastguard Worker				my $value = $1;
5442*d68f33bcSAndroid Build Coastguard Worker				$value = deparenthesize($value);
5443*d68f33bcSAndroid Build Coastguard Worker				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5444*d68f33bcSAndroid Build Coastguard Worker					ERROR("RETURN_PARENTHESES",
5445*d68f33bcSAndroid Build Coastguard Worker					      "return is not a function, parentheses are not required\n" . $herecurr);
5446*d68f33bcSAndroid Build Coastguard Worker				}
5447*d68f33bcSAndroid Build Coastguard Worker			} elsif ($spacing !~ /\s+/) {
5448*d68f33bcSAndroid Build Coastguard Worker				ERROR("SPACING",
5449*d68f33bcSAndroid Build Coastguard Worker				      "space required before the open parenthesis '('\n" . $herecurr);
5450*d68f33bcSAndroid Build Coastguard Worker			}
5451*d68f33bcSAndroid Build Coastguard Worker		}
5452*d68f33bcSAndroid Build Coastguard Worker
5453*d68f33bcSAndroid Build Coastguard Worker# unnecessary return in a void function
5454*d68f33bcSAndroid Build Coastguard Worker# at end-of-function, with the previous line a single leading tab, then return;
5455*d68f33bcSAndroid Build Coastguard Worker# and the line before that not a goto label target like "out:"
5456*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^[ \+]}\s*$/ &&
5457*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5458*d68f33bcSAndroid Build Coastguard Worker		    $linenr >= 3 &&
5459*d68f33bcSAndroid Build Coastguard Worker		    $lines[$linenr - 3] =~ /^[ +]/ &&
5460*d68f33bcSAndroid Build Coastguard Worker		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
5461*d68f33bcSAndroid Build Coastguard Worker			WARN("RETURN_VOID",
5462*d68f33bcSAndroid Build Coastguard Worker			     "void function return statements are not generally useful\n" . $hereprev);
5463*d68f33bcSAndroid Build Coastguard Worker		}
5464*d68f33bcSAndroid Build Coastguard Worker
5465*d68f33bcSAndroid Build Coastguard Worker# if statements using unnecessary parentheses - ie: if ((foo == bar))
5466*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
5467*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5468*d68f33bcSAndroid Build Coastguard Worker			my $openparens = $1;
5469*d68f33bcSAndroid Build Coastguard Worker			my $count = $openparens =~ tr@\(@\(@;
5470*d68f33bcSAndroid Build Coastguard Worker			my $msg = "";
5471*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5472*d68f33bcSAndroid Build Coastguard Worker				my $comp = $4;	#Not $1 because of $LvalOrFunc
5473*d68f33bcSAndroid Build Coastguard Worker				$msg = " - maybe == should be = ?" if ($comp eq "==");
5474*d68f33bcSAndroid Build Coastguard Worker				WARN("UNNECESSARY_PARENTHESES",
5475*d68f33bcSAndroid Build Coastguard Worker				     "Unnecessary parentheses$msg\n" . $herecurr);
5476*d68f33bcSAndroid Build Coastguard Worker			}
5477*d68f33bcSAndroid Build Coastguard Worker		}
5478*d68f33bcSAndroid Build Coastguard Worker
5479*d68f33bcSAndroid Build Coastguard Worker# comparisons with a constant or upper case identifier on the left
5480*d68f33bcSAndroid Build Coastguard Worker#	avoid cases like "foo + BAR < baz"
5481*d68f33bcSAndroid Build Coastguard Worker#	only fix matches surrounded by parentheses to avoid incorrect
5482*d68f33bcSAndroid Build Coastguard Worker#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
5483*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
5484*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5485*d68f33bcSAndroid Build Coastguard Worker			my $lead = $1;
5486*d68f33bcSAndroid Build Coastguard Worker			my $const = $2;
5487*d68f33bcSAndroid Build Coastguard Worker			my $comp = $3;
5488*d68f33bcSAndroid Build Coastguard Worker			my $to = $4;
5489*d68f33bcSAndroid Build Coastguard Worker			my $newcomp = $comp;
5490*d68f33bcSAndroid Build Coastguard Worker			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5491*d68f33bcSAndroid Build Coastguard Worker			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5492*d68f33bcSAndroid Build Coastguard Worker			    WARN("CONSTANT_COMPARISON",
5493*d68f33bcSAndroid Build Coastguard Worker				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5494*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5495*d68f33bcSAndroid Build Coastguard Worker				if ($comp eq "<") {
5496*d68f33bcSAndroid Build Coastguard Worker					$newcomp = ">";
5497*d68f33bcSAndroid Build Coastguard Worker				} elsif ($comp eq "<=") {
5498*d68f33bcSAndroid Build Coastguard Worker					$newcomp = ">=";
5499*d68f33bcSAndroid Build Coastguard Worker				} elsif ($comp eq ">") {
5500*d68f33bcSAndroid Build Coastguard Worker					$newcomp = "<";
5501*d68f33bcSAndroid Build Coastguard Worker				} elsif ($comp eq ">=") {
5502*d68f33bcSAndroid Build Coastguard Worker					$newcomp = "<=";
5503*d68f33bcSAndroid Build Coastguard Worker				}
5504*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5505*d68f33bcSAndroid Build Coastguard Worker			}
5506*d68f33bcSAndroid Build Coastguard Worker		}
5507*d68f33bcSAndroid Build Coastguard Worker
5508*d68f33bcSAndroid Build Coastguard Worker# Return of what appears to be an errno should normally be negative
5509*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
5510*d68f33bcSAndroid Build Coastguard Worker			my $name = $1;
5511*d68f33bcSAndroid Build Coastguard Worker			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5512*d68f33bcSAndroid Build Coastguard Worker				WARN("USE_NEGATIVE_ERRNO",
5513*d68f33bcSAndroid Build Coastguard Worker				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
5514*d68f33bcSAndroid Build Coastguard Worker			}
5515*d68f33bcSAndroid Build Coastguard Worker		}
5516*d68f33bcSAndroid Build Coastguard Worker
5517*d68f33bcSAndroid Build Coastguard Worker# Need a space before open parenthesis after if, while etc
5518*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(if|while|for|switch)\(/) {
5519*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
5520*d68f33bcSAndroid Build Coastguard Worker				  "space required before the open parenthesis '('\n" . $herecurr) &&
5521*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5522*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
5523*d68f33bcSAndroid Build Coastguard Worker				    s/\b(if|while|for|switch)\(/$1 \(/;
5524*d68f33bcSAndroid Build Coastguard Worker			}
5525*d68f33bcSAndroid Build Coastguard Worker		}
5526*d68f33bcSAndroid Build Coastguard Worker
5527*d68f33bcSAndroid Build Coastguard Worker# Check for illegal assignment in if conditional -- and check for trailing
5528*d68f33bcSAndroid Build Coastguard Worker# statements after the conditional.
5529*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /do\s*(?!{)/) {
5530*d68f33bcSAndroid Build Coastguard Worker			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
5531*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $realcnt, 0)
5532*d68f33bcSAndroid Build Coastguard Worker					if (!defined $stat);
5533*d68f33bcSAndroid Build Coastguard Worker			my ($stat_next) = ctx_statement_block($line_nr_next,
5534*d68f33bcSAndroid Build Coastguard Worker						$remain_next, $off_next);
5535*d68f33bcSAndroid Build Coastguard Worker			$stat_next =~ s/\n./\n /g;
5536*d68f33bcSAndroid Build Coastguard Worker			##print "stat<$stat> stat_next<$stat_next>\n";
5537*d68f33bcSAndroid Build Coastguard Worker
5538*d68f33bcSAndroid Build Coastguard Worker			if ($stat_next =~ /^\s*while\b/) {
5539*d68f33bcSAndroid Build Coastguard Worker				# If the statement carries leading newlines,
5540*d68f33bcSAndroid Build Coastguard Worker				# then count those as offsets.
5541*d68f33bcSAndroid Build Coastguard Worker				my ($whitespace) =
5542*d68f33bcSAndroid Build Coastguard Worker					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5543*d68f33bcSAndroid Build Coastguard Worker				my $offset =
5544*d68f33bcSAndroid Build Coastguard Worker					statement_rawlines($whitespace) - 1;
5545*d68f33bcSAndroid Build Coastguard Worker
5546*d68f33bcSAndroid Build Coastguard Worker				$suppress_whiletrailers{$line_nr_next +
5547*d68f33bcSAndroid Build Coastguard Worker								$offset} = 1;
5548*d68f33bcSAndroid Build Coastguard Worker			}
5549*d68f33bcSAndroid Build Coastguard Worker		}
5550*d68f33bcSAndroid Build Coastguard Worker		if (!defined $suppress_whiletrailers{$linenr} &&
5551*d68f33bcSAndroid Build Coastguard Worker		    defined($stat) && defined($cond) &&
5552*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5553*d68f33bcSAndroid Build Coastguard Worker			my ($s, $c) = ($stat, $cond);
5554*d68f33bcSAndroid Build Coastguard Worker
5555*d68f33bcSAndroid Build Coastguard Worker			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
5556*d68f33bcSAndroid Build Coastguard Worker				if (ERROR("ASSIGN_IN_IF",
5557*d68f33bcSAndroid Build Coastguard Worker					  "do not use assignment in if condition\n" . $herecurr) &&
5558*d68f33bcSAndroid Build Coastguard Worker				    $fix && $perl_version_ok) {
5559*d68f33bcSAndroid Build Coastguard Worker					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
5560*d68f33bcSAndroid Build Coastguard Worker						my $space = $1;
5561*d68f33bcSAndroid Build Coastguard Worker						my $not = $2;
5562*d68f33bcSAndroid Build Coastguard Worker						my $statement = $3;
5563*d68f33bcSAndroid Build Coastguard Worker						my $assigned = $4;
5564*d68f33bcSAndroid Build Coastguard Worker						my $test = $8;
5565*d68f33bcSAndroid Build Coastguard Worker						my $against = $9;
5566*d68f33bcSAndroid Build Coastguard Worker						my $brace = $15;
5567*d68f33bcSAndroid Build Coastguard Worker						fix_delete_line($fixlinenr, $rawline);
5568*d68f33bcSAndroid Build Coastguard Worker						fix_insert_line($fixlinenr, "$space$statement;");
5569*d68f33bcSAndroid Build Coastguard Worker						my $newline = "${space}if (";
5570*d68f33bcSAndroid Build Coastguard Worker						$newline .= '!' if defined($not);
5571*d68f33bcSAndroid Build Coastguard Worker						$newline .= '(' if (defined $not && defined($test) && defined($against));
5572*d68f33bcSAndroid Build Coastguard Worker						$newline .= "$assigned";
5573*d68f33bcSAndroid Build Coastguard Worker						$newline .= " $test $against" if (defined($test) && defined($against));
5574*d68f33bcSAndroid Build Coastguard Worker						$newline .= ')' if (defined $not && defined($test) && defined($against));
5575*d68f33bcSAndroid Build Coastguard Worker						$newline .= ')';
5576*d68f33bcSAndroid Build Coastguard Worker						$newline .= " {" if (defined($brace));
5577*d68f33bcSAndroid Build Coastguard Worker						fix_insert_line($fixlinenr + 1, $newline);
5578*d68f33bcSAndroid Build Coastguard Worker					}
5579*d68f33bcSAndroid Build Coastguard Worker				}
5580*d68f33bcSAndroid Build Coastguard Worker			}
5581*d68f33bcSAndroid Build Coastguard Worker
5582*d68f33bcSAndroid Build Coastguard Worker			# Find out what is on the end of the line after the
5583*d68f33bcSAndroid Build Coastguard Worker			# conditional.
5584*d68f33bcSAndroid Build Coastguard Worker			substr($s, 0, length($c), '');
5585*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/\n.*//g;
5586*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/$;//g;	# Remove any comments
5587*d68f33bcSAndroid Build Coastguard Worker			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
5588*d68f33bcSAndroid Build Coastguard Worker			    $c !~ /}\s*while\s*/)
5589*d68f33bcSAndroid Build Coastguard Worker			{
5590*d68f33bcSAndroid Build Coastguard Worker				# Find out how long the conditional actually is.
5591*d68f33bcSAndroid Build Coastguard Worker				my @newlines = ($c =~ /\n/gs);
5592*d68f33bcSAndroid Build Coastguard Worker				my $cond_lines = 1 + $#newlines;
5593*d68f33bcSAndroid Build Coastguard Worker				my $stat_real = '';
5594*d68f33bcSAndroid Build Coastguard Worker
5595*d68f33bcSAndroid Build Coastguard Worker				$stat_real = raw_line($linenr, $cond_lines)
5596*d68f33bcSAndroid Build Coastguard Worker							. "\n" if ($cond_lines);
5597*d68f33bcSAndroid Build Coastguard Worker				if (defined($stat_real) && $cond_lines > 1) {
5598*d68f33bcSAndroid Build Coastguard Worker					$stat_real = "[...]\n$stat_real";
5599*d68f33bcSAndroid Build Coastguard Worker				}
5600*d68f33bcSAndroid Build Coastguard Worker
5601*d68f33bcSAndroid Build Coastguard Worker				ERROR("TRAILING_STATEMENTS",
5602*d68f33bcSAndroid Build Coastguard Worker				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
5603*d68f33bcSAndroid Build Coastguard Worker			}
5604*d68f33bcSAndroid Build Coastguard Worker		}
5605*d68f33bcSAndroid Build Coastguard Worker
5606*d68f33bcSAndroid Build Coastguard Worker# Check for bitwise tests written as boolean
5607*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /
5608*d68f33bcSAndroid Build Coastguard Worker			(?:
5609*d68f33bcSAndroid Build Coastguard Worker				(?:\[|\(|\&\&|\|\|)
5610*d68f33bcSAndroid Build Coastguard Worker				\s*0[xX][0-9]+\s*
5611*d68f33bcSAndroid Build Coastguard Worker				(?:\&\&|\|\|)
5612*d68f33bcSAndroid Build Coastguard Worker			|
5613*d68f33bcSAndroid Build Coastguard Worker				(?:\&\&|\|\|)
5614*d68f33bcSAndroid Build Coastguard Worker				\s*0[xX][0-9]+\s*
5615*d68f33bcSAndroid Build Coastguard Worker				(?:\&\&|\|\||\)|\])
5616*d68f33bcSAndroid Build Coastguard Worker			)/x)
5617*d68f33bcSAndroid Build Coastguard Worker		{
5618*d68f33bcSAndroid Build Coastguard Worker			WARN("HEXADECIMAL_BOOLEAN_TEST",
5619*d68f33bcSAndroid Build Coastguard Worker			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
5620*d68f33bcSAndroid Build Coastguard Worker		}
5621*d68f33bcSAndroid Build Coastguard Worker
5622*d68f33bcSAndroid Build Coastguard Worker# if and else should not have general statements after it
5623*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
5624*d68f33bcSAndroid Build Coastguard Worker			my $s = $1;
5625*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/$;//g;	# Remove any comments
5626*d68f33bcSAndroid Build Coastguard Worker			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5627*d68f33bcSAndroid Build Coastguard Worker				ERROR("TRAILING_STATEMENTS",
5628*d68f33bcSAndroid Build Coastguard Worker				      "trailing statements should be on next line\n" . $herecurr);
5629*d68f33bcSAndroid Build Coastguard Worker			}
5630*d68f33bcSAndroid Build Coastguard Worker		}
5631*d68f33bcSAndroid Build Coastguard Worker# if should not continue a brace
5632*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /}\s*if\b/) {
5633*d68f33bcSAndroid Build Coastguard Worker			ERROR("TRAILING_STATEMENTS",
5634*d68f33bcSAndroid Build Coastguard Worker			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
5635*d68f33bcSAndroid Build Coastguard Worker				$herecurr);
5636*d68f33bcSAndroid Build Coastguard Worker		}
5637*d68f33bcSAndroid Build Coastguard Worker# case and default should not have general statements after them
5638*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5639*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\G(?:
5640*d68f33bcSAndroid Build Coastguard Worker			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5641*d68f33bcSAndroid Build Coastguard Worker			\s*return\s+
5642*d68f33bcSAndroid Build Coastguard Worker		    )/xg)
5643*d68f33bcSAndroid Build Coastguard Worker		{
5644*d68f33bcSAndroid Build Coastguard Worker			ERROR("TRAILING_STATEMENTS",
5645*d68f33bcSAndroid Build Coastguard Worker			      "trailing statements should be on next line\n" . $herecurr);
5646*d68f33bcSAndroid Build Coastguard Worker		}
5647*d68f33bcSAndroid Build Coastguard Worker
5648*d68f33bcSAndroid Build Coastguard Worker		# Check for }<nl>else {, these must be at the same
5649*d68f33bcSAndroid Build Coastguard Worker		# indent level to be relevant to each other.
5650*d68f33bcSAndroid Build Coastguard Worker		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
5651*d68f33bcSAndroid Build Coastguard Worker		    $previndent == $indent) {
5652*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("ELSE_AFTER_BRACE",
5653*d68f33bcSAndroid Build Coastguard Worker				  "else should follow close brace '}'\n" . $hereprev) &&
5654*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5655*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr - 1, $prevrawline);
5656*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
5657*d68f33bcSAndroid Build Coastguard Worker				my $fixedline = $prevrawline;
5658*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/}\s*$//;
5659*d68f33bcSAndroid Build Coastguard Worker				if ($fixedline !~ /^\+\s*$/) {
5660*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, $fixedline);
5661*d68f33bcSAndroid Build Coastguard Worker				}
5662*d68f33bcSAndroid Build Coastguard Worker				$fixedline = $rawline;
5663*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/^(.\s*)else/$1} else/;
5664*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr, $fixedline);
5665*d68f33bcSAndroid Build Coastguard Worker			}
5666*d68f33bcSAndroid Build Coastguard Worker		}
5667*d68f33bcSAndroid Build Coastguard Worker
5668*d68f33bcSAndroid Build Coastguard Worker		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5669*d68f33bcSAndroid Build Coastguard Worker		    $previndent == $indent) {
5670*d68f33bcSAndroid Build Coastguard Worker			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5671*d68f33bcSAndroid Build Coastguard Worker
5672*d68f33bcSAndroid Build Coastguard Worker			# Find out what is on the end of the line after the
5673*d68f33bcSAndroid Build Coastguard Worker			# conditional.
5674*d68f33bcSAndroid Build Coastguard Worker			substr($s, 0, length($c), '');
5675*d68f33bcSAndroid Build Coastguard Worker			$s =~ s/\n.*//g;
5676*d68f33bcSAndroid Build Coastguard Worker
5677*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ /^\s*;/) {
5678*d68f33bcSAndroid Build Coastguard Worker				if (ERROR("WHILE_AFTER_BRACE",
5679*d68f33bcSAndroid Build Coastguard Worker					  "while should follow close brace '}'\n" . $hereprev) &&
5680*d68f33bcSAndroid Build Coastguard Worker				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
5681*d68f33bcSAndroid Build Coastguard Worker					fix_delete_line($fixlinenr - 1, $prevrawline);
5682*d68f33bcSAndroid Build Coastguard Worker					fix_delete_line($fixlinenr, $rawline);
5683*d68f33bcSAndroid Build Coastguard Worker					my $fixedline = $prevrawline;
5684*d68f33bcSAndroid Build Coastguard Worker					my $trailing = $rawline;
5685*d68f33bcSAndroid Build Coastguard Worker					$trailing =~ s/^\+//;
5686*d68f33bcSAndroid Build Coastguard Worker					$trailing = trim($trailing);
5687*d68f33bcSAndroid Build Coastguard Worker					$fixedline =~ s/}\s*$/} $trailing/;
5688*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, $fixedline);
5689*d68f33bcSAndroid Build Coastguard Worker				}
5690*d68f33bcSAndroid Build Coastguard Worker			}
5691*d68f33bcSAndroid Build Coastguard Worker		}
5692*d68f33bcSAndroid Build Coastguard Worker
5693*d68f33bcSAndroid Build Coastguard Worker#Specific variable tests
5694*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ m{($Constant|$Lval)}g) {
5695*d68f33bcSAndroid Build Coastguard Worker			my $var = $1;
5696*d68f33bcSAndroid Build Coastguard Worker
5697*d68f33bcSAndroid Build Coastguard Worker#CamelCase
5698*d68f33bcSAndroid Build Coastguard Worker			if ($var !~ /^$Constant$/ &&
5699*d68f33bcSAndroid Build Coastguard Worker			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
5700*d68f33bcSAndroid Build Coastguard Worker#Ignore some autogenerated defines and enum values
5701*d68f33bcSAndroid Build Coastguard Worker			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
5702*d68f33bcSAndroid Build Coastguard Worker#Ignore Page<foo> variants
5703*d68f33bcSAndroid Build Coastguard Worker			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5704*d68f33bcSAndroid Build Coastguard Worker#Ignore SI style variants like nS, mV and dB
5705*d68f33bcSAndroid Build Coastguard Worker#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5706*d68f33bcSAndroid Build Coastguard Worker			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5707*d68f33bcSAndroid Build Coastguard Worker#Ignore some three character SI units explicitly, like MiB and KHz
5708*d68f33bcSAndroid Build Coastguard Worker			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
5709*d68f33bcSAndroid Build Coastguard Worker				while ($var =~ m{($Ident)}g) {
5710*d68f33bcSAndroid Build Coastguard Worker					my $word = $1;
5711*d68f33bcSAndroid Build Coastguard Worker					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5712*d68f33bcSAndroid Build Coastguard Worker					if ($check) {
5713*d68f33bcSAndroid Build Coastguard Worker						seed_camelcase_includes();
5714*d68f33bcSAndroid Build Coastguard Worker						if (!$file && !$camelcase_file_seeded) {
5715*d68f33bcSAndroid Build Coastguard Worker							seed_camelcase_file($realfile);
5716*d68f33bcSAndroid Build Coastguard Worker							$camelcase_file_seeded = 1;
5717*d68f33bcSAndroid Build Coastguard Worker						}
5718*d68f33bcSAndroid Build Coastguard Worker					}
5719*d68f33bcSAndroid Build Coastguard Worker					if (!defined $camelcase{$word}) {
5720*d68f33bcSAndroid Build Coastguard Worker						$camelcase{$word} = 1;
5721*d68f33bcSAndroid Build Coastguard Worker						CHK("CAMELCASE",
5722*d68f33bcSAndroid Build Coastguard Worker						    "Avoid CamelCase: <$word>\n" . $herecurr);
5723*d68f33bcSAndroid Build Coastguard Worker					}
5724*d68f33bcSAndroid Build Coastguard Worker				}
5725*d68f33bcSAndroid Build Coastguard Worker			}
5726*d68f33bcSAndroid Build Coastguard Worker		}
5727*d68f33bcSAndroid Build Coastguard Worker
5728*d68f33bcSAndroid Build Coastguard Worker#no spaces allowed after \ in define
5729*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\#\s*define.*\\\s+$/) {
5730*d68f33bcSAndroid Build Coastguard Worker			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5731*d68f33bcSAndroid Build Coastguard Worker				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5732*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
5733*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\s+$//;
5734*d68f33bcSAndroid Build Coastguard Worker			}
5735*d68f33bcSAndroid Build Coastguard Worker		}
5736*d68f33bcSAndroid Build Coastguard Worker
5737*d68f33bcSAndroid Build Coastguard Worker# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
5738*d68f33bcSAndroid Build Coastguard Worker# itself <asm/foo.h> (uses RAW line)
5739*d68f33bcSAndroid Build Coastguard Worker		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5740*d68f33bcSAndroid Build Coastguard Worker			my $file = "$1.h";
5741*d68f33bcSAndroid Build Coastguard Worker			my $checkfile = "include/linux/$file";
5742*d68f33bcSAndroid Build Coastguard Worker			if (-f "$root/$checkfile" &&
5743*d68f33bcSAndroid Build Coastguard Worker			    $realfile ne $checkfile &&
5744*d68f33bcSAndroid Build Coastguard Worker			    $1 !~ /$allowed_asm_includes/)
5745*d68f33bcSAndroid Build Coastguard Worker			{
5746*d68f33bcSAndroid Build Coastguard Worker				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
5747*d68f33bcSAndroid Build Coastguard Worker				if ($asminclude > 0) {
5748*d68f33bcSAndroid Build Coastguard Worker					if ($realfile =~ m{^arch/}) {
5749*d68f33bcSAndroid Build Coastguard Worker						CHK("ARCH_INCLUDE_LINUX",
5750*d68f33bcSAndroid Build Coastguard Worker						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5751*d68f33bcSAndroid Build Coastguard Worker					} else {
5752*d68f33bcSAndroid Build Coastguard Worker						WARN("INCLUDE_LINUX",
5753*d68f33bcSAndroid Build Coastguard Worker						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5754*d68f33bcSAndroid Build Coastguard Worker					}
5755*d68f33bcSAndroid Build Coastguard Worker				}
5756*d68f33bcSAndroid Build Coastguard Worker			}
5757*d68f33bcSAndroid Build Coastguard Worker		}
5758*d68f33bcSAndroid Build Coastguard Worker
5759*d68f33bcSAndroid Build Coastguard Worker# multi-statement macros should be enclosed in a do while loop, grab the
5760*d68f33bcSAndroid Build Coastguard Worker# first statement and ensure its the whole macro if its not enclosed
5761*d68f33bcSAndroid Build Coastguard Worker# in a known good container
5762*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5763*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5764*d68f33bcSAndroid Build Coastguard Worker			my $ln = $linenr;
5765*d68f33bcSAndroid Build Coastguard Worker			my $cnt = $realcnt;
5766*d68f33bcSAndroid Build Coastguard Worker			my ($off, $dstat, $dcond, $rest);
5767*d68f33bcSAndroid Build Coastguard Worker			my $ctx = '';
5768*d68f33bcSAndroid Build Coastguard Worker			my $has_flow_statement = 0;
5769*d68f33bcSAndroid Build Coastguard Worker			my $has_arg_concat = 0;
5770*d68f33bcSAndroid Build Coastguard Worker			($dstat, $dcond, $ln, $cnt, $off) =
5771*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $realcnt, 0);
5772*d68f33bcSAndroid Build Coastguard Worker			$ctx = $dstat;
5773*d68f33bcSAndroid Build Coastguard Worker			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5774*d68f33bcSAndroid Build Coastguard Worker			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5775*d68f33bcSAndroid Build Coastguard Worker
5776*d68f33bcSAndroid Build Coastguard Worker			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
5777*d68f33bcSAndroid Build Coastguard Worker			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
5778*d68f33bcSAndroid Build Coastguard Worker
5779*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5780*d68f33bcSAndroid Build Coastguard Worker			my $define_args = $1;
5781*d68f33bcSAndroid Build Coastguard Worker			my $define_stmt = $dstat;
5782*d68f33bcSAndroid Build Coastguard Worker			my @def_args = ();
5783*d68f33bcSAndroid Build Coastguard Worker
5784*d68f33bcSAndroid Build Coastguard Worker			if (defined $define_args && $define_args ne "") {
5785*d68f33bcSAndroid Build Coastguard Worker				$define_args = substr($define_args, 1, length($define_args) - 2);
5786*d68f33bcSAndroid Build Coastguard Worker				$define_args =~ s/\s*//g;
5787*d68f33bcSAndroid Build Coastguard Worker				$define_args =~ s/\\\+?//g;
5788*d68f33bcSAndroid Build Coastguard Worker				@def_args = split(",", $define_args);
5789*d68f33bcSAndroid Build Coastguard Worker			}
5790*d68f33bcSAndroid Build Coastguard Worker
5791*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/$;//g;
5792*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/\\\n.//g;
5793*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/^\s*//s;
5794*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/\s*$//s;
5795*d68f33bcSAndroid Build Coastguard Worker
5796*d68f33bcSAndroid Build Coastguard Worker			# Flatten any parentheses and braces
5797*d68f33bcSAndroid Build Coastguard Worker			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
5798*d68f33bcSAndroid Build Coastguard Worker			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
5799*d68f33bcSAndroid Build Coastguard Worker			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5800*d68f33bcSAndroid Build Coastguard Worker			{
5801*d68f33bcSAndroid Build Coastguard Worker			}
5802*d68f33bcSAndroid Build Coastguard Worker
5803*d68f33bcSAndroid Build Coastguard Worker			# Flatten any obvious string concatenation.
5804*d68f33bcSAndroid Build Coastguard Worker			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
5805*d68f33bcSAndroid Build Coastguard Worker			       $dstat =~ s/$Ident\s*($String)/$1/)
5806*d68f33bcSAndroid Build Coastguard Worker			{
5807*d68f33bcSAndroid Build Coastguard Worker			}
5808*d68f33bcSAndroid Build Coastguard Worker
5809*d68f33bcSAndroid Build Coastguard Worker			# Make asm volatile uses seem like a generic function
5810*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
5811*d68f33bcSAndroid Build Coastguard Worker
5812*d68f33bcSAndroid Build Coastguard Worker			my $exceptions = qr{
5813*d68f33bcSAndroid Build Coastguard Worker				$Declare|
5814*d68f33bcSAndroid Build Coastguard Worker				module_param_named|
5815*d68f33bcSAndroid Build Coastguard Worker				MODULE_PARM_DESC|
5816*d68f33bcSAndroid Build Coastguard Worker				DECLARE_PER_CPU|
5817*d68f33bcSAndroid Build Coastguard Worker				DEFINE_PER_CPU|
5818*d68f33bcSAndroid Build Coastguard Worker				__typeof__\(|
5819*d68f33bcSAndroid Build Coastguard Worker				union|
5820*d68f33bcSAndroid Build Coastguard Worker				struct|
5821*d68f33bcSAndroid Build Coastguard Worker				\.$Ident\s*=\s*|
5822*d68f33bcSAndroid Build Coastguard Worker				^\"|\"$|
5823*d68f33bcSAndroid Build Coastguard Worker				^\[
5824*d68f33bcSAndroid Build Coastguard Worker			}x;
5825*d68f33bcSAndroid Build Coastguard Worker			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5826*d68f33bcSAndroid Build Coastguard Worker
5827*d68f33bcSAndroid Build Coastguard Worker			$ctx =~ s/\n*$//;
5828*d68f33bcSAndroid Build Coastguard Worker			my $stmt_cnt = statement_rawlines($ctx);
5829*d68f33bcSAndroid Build Coastguard Worker			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5830*d68f33bcSAndroid Build Coastguard Worker
5831*d68f33bcSAndroid Build Coastguard Worker			if ($dstat ne '' &&
5832*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5833*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
5834*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5835*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5836*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /$exceptions/ &&
5837*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5838*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
5839*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
5840*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5841*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5842*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5843*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^do\s*{/ &&					# do {...
5844*d68f33bcSAndroid Build Coastguard Worker			    $dstat !~ /^\(\{/ &&						# ({...
5845*d68f33bcSAndroid Build Coastguard Worker			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5846*d68f33bcSAndroid Build Coastguard Worker			{
5847*d68f33bcSAndroid Build Coastguard Worker				if ($dstat =~ /^\s*if\b/) {
5848*d68f33bcSAndroid Build Coastguard Worker					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5849*d68f33bcSAndroid Build Coastguard Worker					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5850*d68f33bcSAndroid Build Coastguard Worker				} elsif ($dstat =~ /;/) {
5851*d68f33bcSAndroid Build Coastguard Worker					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5852*d68f33bcSAndroid Build Coastguard Worker					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5853*d68f33bcSAndroid Build Coastguard Worker				} else {
5854*d68f33bcSAndroid Build Coastguard Worker					ERROR("COMPLEX_MACRO",
5855*d68f33bcSAndroid Build Coastguard Worker					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5856*d68f33bcSAndroid Build Coastguard Worker				}
5857*d68f33bcSAndroid Build Coastguard Worker
5858*d68f33bcSAndroid Build Coastguard Worker			}
5859*d68f33bcSAndroid Build Coastguard Worker
5860*d68f33bcSAndroid Build Coastguard Worker			# Make $define_stmt single line, comment-free, etc
5861*d68f33bcSAndroid Build Coastguard Worker			my @stmt_array = split('\n', $define_stmt);
5862*d68f33bcSAndroid Build Coastguard Worker			my $first = 1;
5863*d68f33bcSAndroid Build Coastguard Worker			$define_stmt = "";
5864*d68f33bcSAndroid Build Coastguard Worker			foreach my $l (@stmt_array) {
5865*d68f33bcSAndroid Build Coastguard Worker				$l =~ s/\\$//;
5866*d68f33bcSAndroid Build Coastguard Worker				if ($first) {
5867*d68f33bcSAndroid Build Coastguard Worker					$define_stmt = $l;
5868*d68f33bcSAndroid Build Coastguard Worker					$first = 0;
5869*d68f33bcSAndroid Build Coastguard Worker				} elsif ($l =~ /^[\+ ]/) {
5870*d68f33bcSAndroid Build Coastguard Worker					$define_stmt .= substr($l, 1);
5871*d68f33bcSAndroid Build Coastguard Worker				}
5872*d68f33bcSAndroid Build Coastguard Worker			}
5873*d68f33bcSAndroid Build Coastguard Worker			$define_stmt =~ s/$;//g;
5874*d68f33bcSAndroid Build Coastguard Worker			$define_stmt =~ s/\s+/ /g;
5875*d68f33bcSAndroid Build Coastguard Worker			$define_stmt = trim($define_stmt);
5876*d68f33bcSAndroid Build Coastguard Worker
5877*d68f33bcSAndroid Build Coastguard Worker# check if any macro arguments are reused (ignore '...' and 'type')
5878*d68f33bcSAndroid Build Coastguard Worker			foreach my $arg (@def_args) {
5879*d68f33bcSAndroid Build Coastguard Worker			        next if ($arg =~ /\.\.\./);
5880*d68f33bcSAndroid Build Coastguard Worker			        next if ($arg =~ /^type$/i);
5881*d68f33bcSAndroid Build Coastguard Worker				my $tmp_stmt = $define_stmt;
5882*d68f33bcSAndroid Build Coastguard Worker				$tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
5883*d68f33bcSAndroid Build Coastguard Worker				$tmp_stmt =~ s/\#+\s*$arg\b//g;
5884*d68f33bcSAndroid Build Coastguard Worker				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5885*d68f33bcSAndroid Build Coastguard Worker				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5886*d68f33bcSAndroid Build Coastguard Worker				if ($use_cnt > 1) {
5887*d68f33bcSAndroid Build Coastguard Worker					CHK("MACRO_ARG_REUSE",
5888*d68f33bcSAndroid Build Coastguard Worker					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5889*d68f33bcSAndroid Build Coastguard Worker				    }
5890*d68f33bcSAndroid Build Coastguard Worker# check if any macro arguments may have other precedence issues
5891*d68f33bcSAndroid Build Coastguard Worker				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
5892*d68f33bcSAndroid Build Coastguard Worker				    ((defined($1) && $1 ne ',') ||
5893*d68f33bcSAndroid Build Coastguard Worker				     (defined($2) && $2 ne ','))) {
5894*d68f33bcSAndroid Build Coastguard Worker					CHK("MACRO_ARG_PRECEDENCE",
5895*d68f33bcSAndroid Build Coastguard Worker					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
5896*d68f33bcSAndroid Build Coastguard Worker				}
5897*d68f33bcSAndroid Build Coastguard Worker			}
5898*d68f33bcSAndroid Build Coastguard Worker
5899*d68f33bcSAndroid Build Coastguard Worker# check for macros with flow control, but without ## concatenation
5900*d68f33bcSAndroid Build Coastguard Worker# ## concatenation is commonly a macro that defines a function so ignore those
5901*d68f33bcSAndroid Build Coastguard Worker			if ($has_flow_statement && !$has_arg_concat) {
5902*d68f33bcSAndroid Build Coastguard Worker				my $cnt = statement_rawlines($ctx);
5903*d68f33bcSAndroid Build Coastguard Worker				my $herectx = get_stat_here($linenr, $cnt, $here);
5904*d68f33bcSAndroid Build Coastguard Worker
5905*d68f33bcSAndroid Build Coastguard Worker				WARN("MACRO_WITH_FLOW_CONTROL",
5906*d68f33bcSAndroid Build Coastguard Worker				     "Macros with flow control statements should be avoided\n" . "$herectx");
5907*d68f33bcSAndroid Build Coastguard Worker			}
5908*d68f33bcSAndroid Build Coastguard Worker
5909*d68f33bcSAndroid Build Coastguard Worker# check for line continuations outside of #defines, preprocessor #, and asm
5910*d68f33bcSAndroid Build Coastguard Worker
5911*d68f33bcSAndroid Build Coastguard Worker		} else {
5912*d68f33bcSAndroid Build Coastguard Worker			if ($prevline !~ /^..*\\$/ &&
5913*d68f33bcSAndroid Build Coastguard Worker			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5914*d68f33bcSAndroid Build Coastguard Worker			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
5915*d68f33bcSAndroid Build Coastguard Worker			    $line =~ /^\+.*\\$/) {
5916*d68f33bcSAndroid Build Coastguard Worker				WARN("LINE_CONTINUATIONS",
5917*d68f33bcSAndroid Build Coastguard Worker				     "Avoid unnecessary line continuations\n" . $herecurr);
5918*d68f33bcSAndroid Build Coastguard Worker			}
5919*d68f33bcSAndroid Build Coastguard Worker		}
5920*d68f33bcSAndroid Build Coastguard Worker
5921*d68f33bcSAndroid Build Coastguard Worker# do {} while (0) macro tests:
5922*d68f33bcSAndroid Build Coastguard Worker# single-statement macros do not need to be enclosed in do while (0) loop,
5923*d68f33bcSAndroid Build Coastguard Worker# macro should not end with a semicolon
5924*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
5925*d68f33bcSAndroid Build Coastguard Worker		    $realfile !~ m@/vmlinux.lds.h$@ &&
5926*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5927*d68f33bcSAndroid Build Coastguard Worker			my $ln = $linenr;
5928*d68f33bcSAndroid Build Coastguard Worker			my $cnt = $realcnt;
5929*d68f33bcSAndroid Build Coastguard Worker			my ($off, $dstat, $dcond, $rest);
5930*d68f33bcSAndroid Build Coastguard Worker			my $ctx = '';
5931*d68f33bcSAndroid Build Coastguard Worker			($dstat, $dcond, $ln, $cnt, $off) =
5932*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_block($linenr, $realcnt, 0);
5933*d68f33bcSAndroid Build Coastguard Worker			$ctx = $dstat;
5934*d68f33bcSAndroid Build Coastguard Worker
5935*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/\\\n.//g;
5936*d68f33bcSAndroid Build Coastguard Worker			$dstat =~ s/$;/ /g;
5937*d68f33bcSAndroid Build Coastguard Worker
5938*d68f33bcSAndroid Build Coastguard Worker			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5939*d68f33bcSAndroid Build Coastguard Worker				my $stmts = $2;
5940*d68f33bcSAndroid Build Coastguard Worker				my $semis = $3;
5941*d68f33bcSAndroid Build Coastguard Worker
5942*d68f33bcSAndroid Build Coastguard Worker				$ctx =~ s/\n*$//;
5943*d68f33bcSAndroid Build Coastguard Worker				my $cnt = statement_rawlines($ctx);
5944*d68f33bcSAndroid Build Coastguard Worker				my $herectx = get_stat_here($linenr, $cnt, $here);
5945*d68f33bcSAndroid Build Coastguard Worker
5946*d68f33bcSAndroid Build Coastguard Worker				if (($stmts =~ tr/;/;/) == 1 &&
5947*d68f33bcSAndroid Build Coastguard Worker				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5948*d68f33bcSAndroid Build Coastguard Worker					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5949*d68f33bcSAndroid Build Coastguard Worker					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5950*d68f33bcSAndroid Build Coastguard Worker				}
5951*d68f33bcSAndroid Build Coastguard Worker				if (defined $semis && $semis ne "") {
5952*d68f33bcSAndroid Build Coastguard Worker					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5953*d68f33bcSAndroid Build Coastguard Worker					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5954*d68f33bcSAndroid Build Coastguard Worker				}
5955*d68f33bcSAndroid Build Coastguard Worker			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5956*d68f33bcSAndroid Build Coastguard Worker				$ctx =~ s/\n*$//;
5957*d68f33bcSAndroid Build Coastguard Worker				my $cnt = statement_rawlines($ctx);
5958*d68f33bcSAndroid Build Coastguard Worker				my $herectx = get_stat_here($linenr, $cnt, $here);
5959*d68f33bcSAndroid Build Coastguard Worker
5960*d68f33bcSAndroid Build Coastguard Worker				WARN("TRAILING_SEMICOLON",
5961*d68f33bcSAndroid Build Coastguard Worker				     "macros should not use a trailing semicolon\n" . "$herectx");
5962*d68f33bcSAndroid Build Coastguard Worker			}
5963*d68f33bcSAndroid Build Coastguard Worker		}
5964*d68f33bcSAndroid Build Coastguard Worker
5965*d68f33bcSAndroid Build Coastguard Worker# check for redundant bracing round if etc
5966*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
5967*d68f33bcSAndroid Build Coastguard Worker			my ($level, $endln, @chunks) =
5968*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_full($linenr, $realcnt, 1);
5969*d68f33bcSAndroid Build Coastguard Worker			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5970*d68f33bcSAndroid Build Coastguard Worker			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5971*d68f33bcSAndroid Build Coastguard Worker			if ($#chunks > 0 && $level == 0) {
5972*d68f33bcSAndroid Build Coastguard Worker				my @allowed = ();
5973*d68f33bcSAndroid Build Coastguard Worker				my $allow = 0;
5974*d68f33bcSAndroid Build Coastguard Worker				my $seen = 0;
5975*d68f33bcSAndroid Build Coastguard Worker				my $herectx = $here . "\n";
5976*d68f33bcSAndroid Build Coastguard Worker				my $ln = $linenr - 1;
5977*d68f33bcSAndroid Build Coastguard Worker				for my $chunk (@chunks) {
5978*d68f33bcSAndroid Build Coastguard Worker					my ($cond, $block) = @{$chunk};
5979*d68f33bcSAndroid Build Coastguard Worker
5980*d68f33bcSAndroid Build Coastguard Worker					# If the condition carries leading newlines, then count those as offsets.
5981*d68f33bcSAndroid Build Coastguard Worker					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5982*d68f33bcSAndroid Build Coastguard Worker					my $offset = statement_rawlines($whitespace) - 1;
5983*d68f33bcSAndroid Build Coastguard Worker
5984*d68f33bcSAndroid Build Coastguard Worker					$allowed[$allow] = 0;
5985*d68f33bcSAndroid Build Coastguard Worker					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5986*d68f33bcSAndroid Build Coastguard Worker
5987*d68f33bcSAndroid Build Coastguard Worker					# We have looked at and allowed this specific line.
5988*d68f33bcSAndroid Build Coastguard Worker					$suppress_ifbraces{$ln + $offset} = 1;
5989*d68f33bcSAndroid Build Coastguard Worker
5990*d68f33bcSAndroid Build Coastguard Worker					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5991*d68f33bcSAndroid Build Coastguard Worker					$ln += statement_rawlines($block) - 1;
5992*d68f33bcSAndroid Build Coastguard Worker
5993*d68f33bcSAndroid Build Coastguard Worker					substr($block, 0, length($cond), '');
5994*d68f33bcSAndroid Build Coastguard Worker
5995*d68f33bcSAndroid Build Coastguard Worker					$seen++ if ($block =~ /^\s*{/);
5996*d68f33bcSAndroid Build Coastguard Worker
5997*d68f33bcSAndroid Build Coastguard Worker					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5998*d68f33bcSAndroid Build Coastguard Worker					if (statement_lines($cond) > 1) {
5999*d68f33bcSAndroid Build Coastguard Worker						#print "APW: ALLOWED: cond<$cond>\n";
6000*d68f33bcSAndroid Build Coastguard Worker						$allowed[$allow] = 1;
6001*d68f33bcSAndroid Build Coastguard Worker					}
6002*d68f33bcSAndroid Build Coastguard Worker					if ($block =~/\b(?:if|for|while)\b/) {
6003*d68f33bcSAndroid Build Coastguard Worker						#print "APW: ALLOWED: block<$block>\n";
6004*d68f33bcSAndroid Build Coastguard Worker						$allowed[$allow] = 1;
6005*d68f33bcSAndroid Build Coastguard Worker					}
6006*d68f33bcSAndroid Build Coastguard Worker					if (statement_block_size($block) > 1) {
6007*d68f33bcSAndroid Build Coastguard Worker						#print "APW: ALLOWED: lines block<$block>\n";
6008*d68f33bcSAndroid Build Coastguard Worker						$allowed[$allow] = 1;
6009*d68f33bcSAndroid Build Coastguard Worker					}
6010*d68f33bcSAndroid Build Coastguard Worker					$allow++;
6011*d68f33bcSAndroid Build Coastguard Worker				}
6012*d68f33bcSAndroid Build Coastguard Worker				if ($seen) {
6013*d68f33bcSAndroid Build Coastguard Worker					my $sum_allowed = 0;
6014*d68f33bcSAndroid Build Coastguard Worker					foreach (@allowed) {
6015*d68f33bcSAndroid Build Coastguard Worker						$sum_allowed += $_;
6016*d68f33bcSAndroid Build Coastguard Worker					}
6017*d68f33bcSAndroid Build Coastguard Worker					if ($sum_allowed == 0) {
6018*d68f33bcSAndroid Build Coastguard Worker						WARN("BRACES",
6019*d68f33bcSAndroid Build Coastguard Worker						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
6020*d68f33bcSAndroid Build Coastguard Worker					} elsif ($sum_allowed != $allow &&
6021*d68f33bcSAndroid Build Coastguard Worker						 $seen != $allow) {
6022*d68f33bcSAndroid Build Coastguard Worker						CHK("BRACES",
6023*d68f33bcSAndroid Build Coastguard Worker						    "braces {} should be used on all arms of this statement\n" . $herectx);
6024*d68f33bcSAndroid Build Coastguard Worker					}
6025*d68f33bcSAndroid Build Coastguard Worker				}
6026*d68f33bcSAndroid Build Coastguard Worker			}
6027*d68f33bcSAndroid Build Coastguard Worker		}
6028*d68f33bcSAndroid Build Coastguard Worker		if (!defined $suppress_ifbraces{$linenr - 1} &&
6029*d68f33bcSAndroid Build Coastguard Worker					$line =~ /\b(if|while|for|else)\b/) {
6030*d68f33bcSAndroid Build Coastguard Worker			my $allowed = 0;
6031*d68f33bcSAndroid Build Coastguard Worker
6032*d68f33bcSAndroid Build Coastguard Worker			# Check the pre-context.
6033*d68f33bcSAndroid Build Coastguard Worker			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6034*d68f33bcSAndroid Build Coastguard Worker				#print "APW: ALLOWED: pre<$1>\n";
6035*d68f33bcSAndroid Build Coastguard Worker				$allowed = 1;
6036*d68f33bcSAndroid Build Coastguard Worker			}
6037*d68f33bcSAndroid Build Coastguard Worker
6038*d68f33bcSAndroid Build Coastguard Worker			my ($level, $endln, @chunks) =
6039*d68f33bcSAndroid Build Coastguard Worker				ctx_statement_full($linenr, $realcnt, $-[0]);
6040*d68f33bcSAndroid Build Coastguard Worker
6041*d68f33bcSAndroid Build Coastguard Worker			# Check the condition.
6042*d68f33bcSAndroid Build Coastguard Worker			my ($cond, $block) = @{$chunks[0]};
6043*d68f33bcSAndroid Build Coastguard Worker			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
6044*d68f33bcSAndroid Build Coastguard Worker			if (defined $cond) {
6045*d68f33bcSAndroid Build Coastguard Worker				substr($block, 0, length($cond), '');
6046*d68f33bcSAndroid Build Coastguard Worker			}
6047*d68f33bcSAndroid Build Coastguard Worker			if (statement_lines($cond) > 1) {
6048*d68f33bcSAndroid Build Coastguard Worker				#print "APW: ALLOWED: cond<$cond>\n";
6049*d68f33bcSAndroid Build Coastguard Worker				$allowed = 1;
6050*d68f33bcSAndroid Build Coastguard Worker			}
6051*d68f33bcSAndroid Build Coastguard Worker			if ($block =~/\b(?:if|for|while)\b/) {
6052*d68f33bcSAndroid Build Coastguard Worker				#print "APW: ALLOWED: block<$block>\n";
6053*d68f33bcSAndroid Build Coastguard Worker				$allowed = 1;
6054*d68f33bcSAndroid Build Coastguard Worker			}
6055*d68f33bcSAndroid Build Coastguard Worker			if (statement_block_size($block) > 1) {
6056*d68f33bcSAndroid Build Coastguard Worker				#print "APW: ALLOWED: lines block<$block>\n";
6057*d68f33bcSAndroid Build Coastguard Worker				$allowed = 1;
6058*d68f33bcSAndroid Build Coastguard Worker			}
6059*d68f33bcSAndroid Build Coastguard Worker			# Check the post-context.
6060*d68f33bcSAndroid Build Coastguard Worker			if (defined $chunks[1]) {
6061*d68f33bcSAndroid Build Coastguard Worker				my ($cond, $block) = @{$chunks[1]};
6062*d68f33bcSAndroid Build Coastguard Worker				if (defined $cond) {
6063*d68f33bcSAndroid Build Coastguard Worker					substr($block, 0, length($cond), '');
6064*d68f33bcSAndroid Build Coastguard Worker				}
6065*d68f33bcSAndroid Build Coastguard Worker				if ($block =~ /^\s*\{/) {
6066*d68f33bcSAndroid Build Coastguard Worker					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6067*d68f33bcSAndroid Build Coastguard Worker					$allowed = 1;
6068*d68f33bcSAndroid Build Coastguard Worker				}
6069*d68f33bcSAndroid Build Coastguard Worker			}
6070*d68f33bcSAndroid Build Coastguard Worker			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6071*d68f33bcSAndroid Build Coastguard Worker				my $cnt = statement_rawlines($block);
6072*d68f33bcSAndroid Build Coastguard Worker				my $herectx = get_stat_here($linenr, $cnt, $here);
6073*d68f33bcSAndroid Build Coastguard Worker
6074*d68f33bcSAndroid Build Coastguard Worker				WARN("BRACES",
6075*d68f33bcSAndroid Build Coastguard Worker				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6076*d68f33bcSAndroid Build Coastguard Worker			}
6077*d68f33bcSAndroid Build Coastguard Worker		}
6078*d68f33bcSAndroid Build Coastguard Worker
6079*d68f33bcSAndroid Build Coastguard Worker# check for single line unbalanced braces
6080*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
6081*d68f33bcSAndroid Build Coastguard Worker		    $sline =~ /^.\s*else\s*\{\s*$/) {
6082*d68f33bcSAndroid Build Coastguard Worker			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6083*d68f33bcSAndroid Build Coastguard Worker		}
6084*d68f33bcSAndroid Build Coastguard Worker
6085*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary blank lines around braces
6086*d68f33bcSAndroid Build Coastguard Worker		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6087*d68f33bcSAndroid Build Coastguard Worker			if (CHK("BRACES",
6088*d68f33bcSAndroid Build Coastguard Worker				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6089*d68f33bcSAndroid Build Coastguard Worker			    $fix && $prevrawline =~ /^\+/) {
6090*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr - 1, $prevrawline);
6091*d68f33bcSAndroid Build Coastguard Worker			}
6092*d68f33bcSAndroid Build Coastguard Worker		}
6093*d68f33bcSAndroid Build Coastguard Worker		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
6094*d68f33bcSAndroid Build Coastguard Worker			if (CHK("BRACES",
6095*d68f33bcSAndroid Build Coastguard Worker				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6096*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6097*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
6098*d68f33bcSAndroid Build Coastguard Worker			}
6099*d68f33bcSAndroid Build Coastguard Worker		}
6100*d68f33bcSAndroid Build Coastguard Worker
6101*d68f33bcSAndroid Build Coastguard Worker# no volatiles please
6102*d68f33bcSAndroid Build Coastguard Worker		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
6103*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6104*d68f33bcSAndroid Build Coastguard Worker			WARN("VOLATILE",
6105*d68f33bcSAndroid Build Coastguard Worker			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
6106*d68f33bcSAndroid Build Coastguard Worker		}
6107*d68f33bcSAndroid Build Coastguard Worker
6108*d68f33bcSAndroid Build Coastguard Worker# Check for user-visible strings broken across lines, which breaks the ability
6109*d68f33bcSAndroid Build Coastguard Worker# to grep for the string.  Make exceptions when the previous string ends in a
6110*d68f33bcSAndroid Build Coastguard Worker# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
6111*d68f33bcSAndroid Build Coastguard Worker# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
6112*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+\s*$String/ &&
6113*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /"\s*$/ &&
6114*d68f33bcSAndroid Build Coastguard Worker		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
6115*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SPLIT_STRING",
6116*d68f33bcSAndroid Build Coastguard Worker				 "quoted string split across lines\n" . $hereprev) &&
6117*d68f33bcSAndroid Build Coastguard Worker				     $fix &&
6118*d68f33bcSAndroid Build Coastguard Worker				     $prevrawline =~ /^\+.*"\s*$/ &&
6119*d68f33bcSAndroid Build Coastguard Worker				     $last_coalesced_string_linenr != $linenr - 1) {
6120*d68f33bcSAndroid Build Coastguard Worker				my $extracted_string = get_quoted_string($line, $rawline);
6121*d68f33bcSAndroid Build Coastguard Worker				my $comma_close = "";
6122*d68f33bcSAndroid Build Coastguard Worker				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
6123*d68f33bcSAndroid Build Coastguard Worker					$comma_close = $1;
6124*d68f33bcSAndroid Build Coastguard Worker				}
6125*d68f33bcSAndroid Build Coastguard Worker
6126*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr - 1, $prevrawline);
6127*d68f33bcSAndroid Build Coastguard Worker				fix_delete_line($fixlinenr, $rawline);
6128*d68f33bcSAndroid Build Coastguard Worker				my $fixedline = $prevrawline;
6129*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/"\s*$//;
6130*d68f33bcSAndroid Build Coastguard Worker				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
6131*d68f33bcSAndroid Build Coastguard Worker				fix_insert_line($fixlinenr - 1, $fixedline);
6132*d68f33bcSAndroid Build Coastguard Worker				$fixedline = $rawline;
6133*d68f33bcSAndroid Build Coastguard Worker				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
6134*d68f33bcSAndroid Build Coastguard Worker				if ($fixedline !~ /\+\s*$/) {
6135*d68f33bcSAndroid Build Coastguard Worker					fix_insert_line($fixlinenr, $fixedline);
6136*d68f33bcSAndroid Build Coastguard Worker				}
6137*d68f33bcSAndroid Build Coastguard Worker				$last_coalesced_string_linenr = $linenr;
6138*d68f33bcSAndroid Build Coastguard Worker			}
6139*d68f33bcSAndroid Build Coastguard Worker		}
6140*d68f33bcSAndroid Build Coastguard Worker
6141*d68f33bcSAndroid Build Coastguard Worker# check for missing a space in a string concatenation
6142*d68f33bcSAndroid Build Coastguard Worker		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
6143*d68f33bcSAndroid Build Coastguard Worker			WARN('MISSING_SPACE',
6144*d68f33bcSAndroid Build Coastguard Worker			     "break quoted strings at a space character\n" . $hereprev);
6145*d68f33bcSAndroid Build Coastguard Worker		}
6146*d68f33bcSAndroid Build Coastguard Worker
6147*d68f33bcSAndroid Build Coastguard Worker# check for an embedded function name in a string when the function is known
6148*d68f33bcSAndroid Build Coastguard Worker# This does not work very well for -f --file checking as it depends on patch
6149*d68f33bcSAndroid Build Coastguard Worker# context providing the function name or a single line form for in-file
6150*d68f33bcSAndroid Build Coastguard Worker# function declarations
6151*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*$String/ &&
6152*d68f33bcSAndroid Build Coastguard Worker		    defined($context_function) &&
6153*d68f33bcSAndroid Build Coastguard Worker		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6154*d68f33bcSAndroid Build Coastguard Worker		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
6155*d68f33bcSAndroid Build Coastguard Worker			WARN("EMBEDDED_FUNCTION_NAME",
6156*d68f33bcSAndroid Build Coastguard Worker			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
6157*d68f33bcSAndroid Build Coastguard Worker		}
6158*d68f33bcSAndroid Build Coastguard Worker
6159*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary function tracing like uses
6160*d68f33bcSAndroid Build Coastguard Worker# This does not use $logFunctions because there are many instances like
6161*d68f33bcSAndroid Build Coastguard Worker# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6162*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6163*d68f33bcSAndroid Build Coastguard Worker			if (WARN("TRACING_LOGGING",
6164*d68f33bcSAndroid Build Coastguard Worker				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6165*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6166*d68f33bcSAndroid Build Coastguard Worker                                fix_delete_line($fixlinenr, $rawline);
6167*d68f33bcSAndroid Build Coastguard Worker			}
6168*d68f33bcSAndroid Build Coastguard Worker		}
6169*d68f33bcSAndroid Build Coastguard Worker
6170*d68f33bcSAndroid Build Coastguard Worker# check for spaces before a quoted newline
6171*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /^.*\".*\s\\n/) {
6172*d68f33bcSAndroid Build Coastguard Worker			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
6173*d68f33bcSAndroid Build Coastguard Worker				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
6174*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6175*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
6176*d68f33bcSAndroid Build Coastguard Worker			}
6177*d68f33bcSAndroid Build Coastguard Worker
6178*d68f33bcSAndroid Build Coastguard Worker		}
6179*d68f33bcSAndroid Build Coastguard Worker
6180*d68f33bcSAndroid Build Coastguard Worker# concatenated string without spaces between elements
6181*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /$String[A-Z_]/ ||
6182*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
6183*d68f33bcSAndroid Build Coastguard Worker			if (CHK("CONCATENATED_STRING",
6184*d68f33bcSAndroid Build Coastguard Worker				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
6185*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6186*d68f33bcSAndroid Build Coastguard Worker				while ($line =~ /($String)/g) {
6187*d68f33bcSAndroid Build Coastguard Worker					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
6188*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
6189*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
6190*d68f33bcSAndroid Build Coastguard Worker				}
6191*d68f33bcSAndroid Build Coastguard Worker			}
6192*d68f33bcSAndroid Build Coastguard Worker		}
6193*d68f33bcSAndroid Build Coastguard Worker
6194*d68f33bcSAndroid Build Coastguard Worker# uncoalesced string fragments
6195*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /$String\s*[Lu]?"/) {
6196*d68f33bcSAndroid Build Coastguard Worker			if (WARN("STRING_FRAGMENTS",
6197*d68f33bcSAndroid Build Coastguard Worker				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
6198*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6199*d68f33bcSAndroid Build Coastguard Worker				while ($line =~ /($String)(?=\s*")/g) {
6200*d68f33bcSAndroid Build Coastguard Worker					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
6201*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
6202*d68f33bcSAndroid Build Coastguard Worker				}
6203*d68f33bcSAndroid Build Coastguard Worker			}
6204*d68f33bcSAndroid Build Coastguard Worker		}
6205*d68f33bcSAndroid Build Coastguard Worker
6206*d68f33bcSAndroid Build Coastguard Worker# check for non-standard and hex prefixed decimal printf formats
6207*d68f33bcSAndroid Build Coastguard Worker		my $show_L = 1;	#don't show the same defect twice
6208*d68f33bcSAndroid Build Coastguard Worker		my $show_Z = 1;
6209*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6210*d68f33bcSAndroid Build Coastguard Worker			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
6211*d68f33bcSAndroid Build Coastguard Worker			$string =~ s/%%/__/g;
6212*d68f33bcSAndroid Build Coastguard Worker			# check for %L
6213*d68f33bcSAndroid Build Coastguard Worker			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
6214*d68f33bcSAndroid Build Coastguard Worker				WARN("PRINTF_L",
6215*d68f33bcSAndroid Build Coastguard Worker				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6216*d68f33bcSAndroid Build Coastguard Worker				$show_L = 0;
6217*d68f33bcSAndroid Build Coastguard Worker			}
6218*d68f33bcSAndroid Build Coastguard Worker			# check for %Z
6219*d68f33bcSAndroid Build Coastguard Worker			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6220*d68f33bcSAndroid Build Coastguard Worker				WARN("PRINTF_Z",
6221*d68f33bcSAndroid Build Coastguard Worker				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6222*d68f33bcSAndroid Build Coastguard Worker				$show_Z = 0;
6223*d68f33bcSAndroid Build Coastguard Worker			}
6224*d68f33bcSAndroid Build Coastguard Worker			# check for 0x<decimal>
6225*d68f33bcSAndroid Build Coastguard Worker			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6226*d68f33bcSAndroid Build Coastguard Worker				ERROR("PRINTF_0XDECIMAL",
6227*d68f33bcSAndroid Build Coastguard Worker				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
6228*d68f33bcSAndroid Build Coastguard Worker			}
6229*d68f33bcSAndroid Build Coastguard Worker		}
6230*d68f33bcSAndroid Build Coastguard Worker
6231*d68f33bcSAndroid Build Coastguard Worker# check for line continuations in quoted strings with odd counts of "
6232*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
6233*d68f33bcSAndroid Build Coastguard Worker			WARN("LINE_CONTINUATIONS",
6234*d68f33bcSAndroid Build Coastguard Worker			     "Avoid line continuations in quoted strings\n" . $herecurr);
6235*d68f33bcSAndroid Build Coastguard Worker		}
6236*d68f33bcSAndroid Build Coastguard Worker
6237*d68f33bcSAndroid Build Coastguard Worker# warn about #if 0
6238*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
6239*d68f33bcSAndroid Build Coastguard Worker			WARN("IF_0",
6240*d68f33bcSAndroid Build Coastguard Worker			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
6241*d68f33bcSAndroid Build Coastguard Worker		}
6242*d68f33bcSAndroid Build Coastguard Worker
6243*d68f33bcSAndroid Build Coastguard Worker# warn about #if 1
6244*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
6245*d68f33bcSAndroid Build Coastguard Worker			WARN("IF_1",
6246*d68f33bcSAndroid Build Coastguard Worker			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
6247*d68f33bcSAndroid Build Coastguard Worker		}
6248*d68f33bcSAndroid Build Coastguard Worker
6249*d68f33bcSAndroid Build Coastguard Worker# check for needless "if (<foo>) fn(<foo>)" uses
6250*d68f33bcSAndroid Build Coastguard Worker		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6251*d68f33bcSAndroid Build Coastguard Worker			my $tested = quotemeta($1);
6252*d68f33bcSAndroid Build Coastguard Worker			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6253*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6254*d68f33bcSAndroid Build Coastguard Worker				my $func = $1;
6255*d68f33bcSAndroid Build Coastguard Worker				if (WARN('NEEDLESS_IF',
6256*d68f33bcSAndroid Build Coastguard Worker					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6257*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
6258*d68f33bcSAndroid Build Coastguard Worker					my $do_fix = 1;
6259*d68f33bcSAndroid Build Coastguard Worker					my $leading_tabs = "";
6260*d68f33bcSAndroid Build Coastguard Worker					my $new_leading_tabs = "";
6261*d68f33bcSAndroid Build Coastguard Worker					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6262*d68f33bcSAndroid Build Coastguard Worker						$leading_tabs = $1;
6263*d68f33bcSAndroid Build Coastguard Worker					} else {
6264*d68f33bcSAndroid Build Coastguard Worker						$do_fix = 0;
6265*d68f33bcSAndroid Build Coastguard Worker					}
6266*d68f33bcSAndroid Build Coastguard Worker					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6267*d68f33bcSAndroid Build Coastguard Worker						$new_leading_tabs = $1;
6268*d68f33bcSAndroid Build Coastguard Worker						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6269*d68f33bcSAndroid Build Coastguard Worker							$do_fix = 0;
6270*d68f33bcSAndroid Build Coastguard Worker						}
6271*d68f33bcSAndroid Build Coastguard Worker					} else {
6272*d68f33bcSAndroid Build Coastguard Worker						$do_fix = 0;
6273*d68f33bcSAndroid Build Coastguard Worker					}
6274*d68f33bcSAndroid Build Coastguard Worker					if ($do_fix) {
6275*d68f33bcSAndroid Build Coastguard Worker						fix_delete_line($fixlinenr - 1, $prevrawline);
6276*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6277*d68f33bcSAndroid Build Coastguard Worker					}
6278*d68f33bcSAndroid Build Coastguard Worker				}
6279*d68f33bcSAndroid Build Coastguard Worker			}
6280*d68f33bcSAndroid Build Coastguard Worker		}
6281*d68f33bcSAndroid Build Coastguard Worker
6282*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary "Out of Memory" messages
6283*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6284*d68f33bcSAndroid Build Coastguard Worker		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6285*d68f33bcSAndroid Build Coastguard Worker		    (defined $1 || defined $3) &&
6286*d68f33bcSAndroid Build Coastguard Worker		    $linenr > 3) {
6287*d68f33bcSAndroid Build Coastguard Worker			my $testval = $2;
6288*d68f33bcSAndroid Build Coastguard Worker			my $testline = $lines[$linenr - 3];
6289*d68f33bcSAndroid Build Coastguard Worker
6290*d68f33bcSAndroid Build Coastguard Worker			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6291*d68f33bcSAndroid Build Coastguard Worker#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6292*d68f33bcSAndroid Build Coastguard Worker
6293*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6294*d68f33bcSAndroid Build Coastguard Worker			    $s !~ /\b__GFP_NOWARN\b/ ) {
6295*d68f33bcSAndroid Build Coastguard Worker				WARN("OOM_MESSAGE",
6296*d68f33bcSAndroid Build Coastguard Worker				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6297*d68f33bcSAndroid Build Coastguard Worker			}
6298*d68f33bcSAndroid Build Coastguard Worker		}
6299*d68f33bcSAndroid Build Coastguard Worker
6300*d68f33bcSAndroid Build Coastguard Worker# check for logging functions with KERN_<LEVEL>
6301*d68f33bcSAndroid Build Coastguard Worker		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6302*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6303*d68f33bcSAndroid Build Coastguard Worker			my $level = $1;
6304*d68f33bcSAndroid Build Coastguard Worker			if (WARN("UNNECESSARY_KERN_LEVEL",
6305*d68f33bcSAndroid Build Coastguard Worker				 "Possible unnecessary $level\n" . $herecurr) &&
6306*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6307*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6308*d68f33bcSAndroid Build Coastguard Worker			}
6309*d68f33bcSAndroid Build Coastguard Worker		}
6310*d68f33bcSAndroid Build Coastguard Worker
6311*d68f33bcSAndroid Build Coastguard Worker# check for logging continuations
6312*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
6313*d68f33bcSAndroid Build Coastguard Worker			WARN("LOGGING_CONTINUATION",
6314*d68f33bcSAndroid Build Coastguard Worker			     "Avoid logging continuation uses where feasible\n" . $herecurr);
6315*d68f33bcSAndroid Build Coastguard Worker		}
6316*d68f33bcSAndroid Build Coastguard Worker
6317*d68f33bcSAndroid Build Coastguard Worker# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
6318*d68f33bcSAndroid Build Coastguard Worker		if (defined $stat &&
6319*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b$logFunctions\s*\(/ &&
6320*d68f33bcSAndroid Build Coastguard Worker		    index($stat, '"') >= 0) {
6321*d68f33bcSAndroid Build Coastguard Worker			my $lc = $stat =~ tr@\n@@;
6322*d68f33bcSAndroid Build Coastguard Worker			$lc = $lc + $linenr;
6323*d68f33bcSAndroid Build Coastguard Worker			my $stat_real = get_stat_real($linenr, $lc);
6324*d68f33bcSAndroid Build Coastguard Worker			pos($stat_real) = index($stat_real, '"');
6325*d68f33bcSAndroid Build Coastguard Worker			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
6326*d68f33bcSAndroid Build Coastguard Worker				my $pspec = $1;
6327*d68f33bcSAndroid Build Coastguard Worker				my $h = $2;
6328*d68f33bcSAndroid Build Coastguard Worker				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
6329*d68f33bcSAndroid Build Coastguard Worker				if (WARN("UNNECESSARY_MODIFIER",
6330*d68f33bcSAndroid Build Coastguard Worker					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
6331*d68f33bcSAndroid Build Coastguard Worker				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
6332*d68f33bcSAndroid Build Coastguard Worker					my $nspec = $pspec;
6333*d68f33bcSAndroid Build Coastguard Worker					$nspec =~ s/h//g;
6334*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
6335*d68f33bcSAndroid Build Coastguard Worker				}
6336*d68f33bcSAndroid Build Coastguard Worker			}
6337*d68f33bcSAndroid Build Coastguard Worker		}
6338*d68f33bcSAndroid Build Coastguard Worker
6339*d68f33bcSAndroid Build Coastguard Worker# check for mask then right shift without a parentheses
6340*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6341*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6342*d68f33bcSAndroid Build Coastguard Worker		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6343*d68f33bcSAndroid Build Coastguard Worker			WARN("MASK_THEN_SHIFT",
6344*d68f33bcSAndroid Build Coastguard Worker			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6345*d68f33bcSAndroid Build Coastguard Worker		}
6346*d68f33bcSAndroid Build Coastguard Worker
6347*d68f33bcSAndroid Build Coastguard Worker# check for pointer comparisons to NULL
6348*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok) {
6349*d68f33bcSAndroid Build Coastguard Worker			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6350*d68f33bcSAndroid Build Coastguard Worker				my $val = $1;
6351*d68f33bcSAndroid Build Coastguard Worker				my $equal = "!";
6352*d68f33bcSAndroid Build Coastguard Worker				$equal = "" if ($4 eq "!=");
6353*d68f33bcSAndroid Build Coastguard Worker				if (CHK("COMPARISON_TO_NULL",
6354*d68f33bcSAndroid Build Coastguard Worker					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6355*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
6356*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6357*d68f33bcSAndroid Build Coastguard Worker				}
6358*d68f33bcSAndroid Build Coastguard Worker			}
6359*d68f33bcSAndroid Build Coastguard Worker		}
6360*d68f33bcSAndroid Build Coastguard Worker
6361*d68f33bcSAndroid Build Coastguard Worker# check for bad placement of section $InitAttribute (e.g.: __initdata)
6362*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(\b$InitAttribute\b)/) {
6363*d68f33bcSAndroid Build Coastguard Worker			my $attr = $1;
6364*d68f33bcSAndroid Build Coastguard Worker			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
6365*d68f33bcSAndroid Build Coastguard Worker				my $ptr = $1;
6366*d68f33bcSAndroid Build Coastguard Worker				my $var = $2;
6367*d68f33bcSAndroid Build Coastguard Worker				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
6368*d68f33bcSAndroid Build Coastguard Worker				      ERROR("MISPLACED_INIT",
6369*d68f33bcSAndroid Build Coastguard Worker					    "$attr should be placed after $var\n" . $herecurr)) ||
6370*d68f33bcSAndroid Build Coastguard Worker				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
6371*d68f33bcSAndroid Build Coastguard Worker				      WARN("MISPLACED_INIT",
6372*d68f33bcSAndroid Build Coastguard Worker					   "$attr should be placed after $var\n" . $herecurr))) &&
6373*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
6374*d68f33bcSAndroid Build Coastguard Worker					$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;
6375*d68f33bcSAndroid Build Coastguard Worker				}
6376*d68f33bcSAndroid Build Coastguard Worker			}
6377*d68f33bcSAndroid Build Coastguard Worker		}
6378*d68f33bcSAndroid Build Coastguard Worker
6379*d68f33bcSAndroid Build Coastguard Worker# check for $InitAttributeData (ie: __initdata) with const
6380*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6381*d68f33bcSAndroid Build Coastguard Worker			my $attr = $1;
6382*d68f33bcSAndroid Build Coastguard Worker			$attr =~ /($InitAttributePrefix)(.*)/;
6383*d68f33bcSAndroid Build Coastguard Worker			my $attr_prefix = $1;
6384*d68f33bcSAndroid Build Coastguard Worker			my $attr_type = $2;
6385*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("INIT_ATTRIBUTE",
6386*d68f33bcSAndroid Build Coastguard Worker				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6387*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6388*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
6389*d68f33bcSAndroid Build Coastguard Worker				    s/$InitAttributeData/${attr_prefix}initconst/;
6390*d68f33bcSAndroid Build Coastguard Worker			}
6391*d68f33bcSAndroid Build Coastguard Worker		}
6392*d68f33bcSAndroid Build Coastguard Worker
6393*d68f33bcSAndroid Build Coastguard Worker# check for $InitAttributeConst (ie: __initconst) without const
6394*d68f33bcSAndroid Build Coastguard Worker		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6395*d68f33bcSAndroid Build Coastguard Worker			my $attr = $1;
6396*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("INIT_ATTRIBUTE",
6397*d68f33bcSAndroid Build Coastguard Worker				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6398*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6399*d68f33bcSAndroid Build Coastguard Worker				my $lead = $fixed[$fixlinenr] =~
6400*d68f33bcSAndroid Build Coastguard Worker				    /(^\+\s*(?:static\s+))/;
6401*d68f33bcSAndroid Build Coastguard Worker				$lead = rtrim($1);
6402*d68f33bcSAndroid Build Coastguard Worker				$lead = "$lead " if ($lead !~ /^\+$/);
6403*d68f33bcSAndroid Build Coastguard Worker				$lead = "${lead}const ";
6404*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6405*d68f33bcSAndroid Build Coastguard Worker			}
6406*d68f33bcSAndroid Build Coastguard Worker		}
6407*d68f33bcSAndroid Build Coastguard Worker
6408*d68f33bcSAndroid Build Coastguard Worker# check for __read_mostly with const non-pointer (should just be const)
6409*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b__read_mostly\b/ &&
6410*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6411*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("CONST_READ_MOSTLY",
6412*d68f33bcSAndroid Build Coastguard Worker				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6413*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6414*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6415*d68f33bcSAndroid Build Coastguard Worker			}
6416*d68f33bcSAndroid Build Coastguard Worker		}
6417*d68f33bcSAndroid Build Coastguard Worker
6418*d68f33bcSAndroid Build Coastguard Worker# don't use __constant_<foo> functions outside of include/uapi/
6419*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@^include/uapi/@ &&
6420*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6421*d68f33bcSAndroid Build Coastguard Worker			my $constant_func = $1;
6422*d68f33bcSAndroid Build Coastguard Worker			my $func = $constant_func;
6423*d68f33bcSAndroid Build Coastguard Worker			$func =~ s/^__constant_//;
6424*d68f33bcSAndroid Build Coastguard Worker			if (WARN("CONSTANT_CONVERSION",
6425*d68f33bcSAndroid Build Coastguard Worker				 "$constant_func should be $func\n" . $herecurr) &&
6426*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6427*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6428*d68f33bcSAndroid Build Coastguard Worker			}
6429*d68f33bcSAndroid Build Coastguard Worker		}
6430*d68f33bcSAndroid Build Coastguard Worker
6431*d68f33bcSAndroid Build Coastguard Worker# prefer usleep_range over udelay
6432*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
6433*d68f33bcSAndroid Build Coastguard Worker			my $delay = $1;
6434*d68f33bcSAndroid Build Coastguard Worker			# ignore udelay's < 10, however
6435*d68f33bcSAndroid Build Coastguard Worker			if (! ($delay < 10) ) {
6436*d68f33bcSAndroid Build Coastguard Worker				CHK("USLEEP_RANGE",
6437*d68f33bcSAndroid Build Coastguard Worker				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
6438*d68f33bcSAndroid Build Coastguard Worker			}
6439*d68f33bcSAndroid Build Coastguard Worker			if ($delay > 2000) {
6440*d68f33bcSAndroid Build Coastguard Worker				WARN("LONG_UDELAY",
6441*d68f33bcSAndroid Build Coastguard Worker				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
6442*d68f33bcSAndroid Build Coastguard Worker			}
6443*d68f33bcSAndroid Build Coastguard Worker		}
6444*d68f33bcSAndroid Build Coastguard Worker
6445*d68f33bcSAndroid Build Coastguard Worker# warn about unexpectedly long msleep's
6446*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
6447*d68f33bcSAndroid Build Coastguard Worker			if ($1 < 20) {
6448*d68f33bcSAndroid Build Coastguard Worker				WARN("MSLEEP",
6449*d68f33bcSAndroid Build Coastguard Worker				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
6450*d68f33bcSAndroid Build Coastguard Worker			}
6451*d68f33bcSAndroid Build Coastguard Worker		}
6452*d68f33bcSAndroid Build Coastguard Worker
6453*d68f33bcSAndroid Build Coastguard Worker# check for comparisons of jiffies
6454*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
6455*d68f33bcSAndroid Build Coastguard Worker			WARN("JIFFIES_COMPARISON",
6456*d68f33bcSAndroid Build Coastguard Worker			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
6457*d68f33bcSAndroid Build Coastguard Worker		}
6458*d68f33bcSAndroid Build Coastguard Worker
6459*d68f33bcSAndroid Build Coastguard Worker# check for comparisons of get_jiffies_64()
6460*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
6461*d68f33bcSAndroid Build Coastguard Worker			WARN("JIFFIES_COMPARISON",
6462*d68f33bcSAndroid Build Coastguard Worker			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
6463*d68f33bcSAndroid Build Coastguard Worker		}
6464*d68f33bcSAndroid Build Coastguard Worker
6465*d68f33bcSAndroid Build Coastguard Worker# warn about #ifdefs in C files
6466*d68f33bcSAndroid Build Coastguard Worker#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
6467*d68f33bcSAndroid Build Coastguard Worker#			print "#ifdef in C files should be avoided\n";
6468*d68f33bcSAndroid Build Coastguard Worker#			print "$herecurr";
6469*d68f33bcSAndroid Build Coastguard Worker#			$clean = 0;
6470*d68f33bcSAndroid Build Coastguard Worker#		}
6471*d68f33bcSAndroid Build Coastguard Worker
6472*d68f33bcSAndroid Build Coastguard Worker# warn about spacing in #ifdefs
6473*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
6474*d68f33bcSAndroid Build Coastguard Worker			if (ERROR("SPACING",
6475*d68f33bcSAndroid Build Coastguard Worker				  "exactly one space required after that #$1\n" . $herecurr) &&
6476*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6477*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~
6478*d68f33bcSAndroid Build Coastguard Worker				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
6479*d68f33bcSAndroid Build Coastguard Worker			}
6480*d68f33bcSAndroid Build Coastguard Worker
6481*d68f33bcSAndroid Build Coastguard Worker		}
6482*d68f33bcSAndroid Build Coastguard Worker
6483*d68f33bcSAndroid Build Coastguard Worker# check for spinlock_t definitions without a comment.
6484*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6485*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
6486*d68f33bcSAndroid Build Coastguard Worker			my $which = $1;
6487*d68f33bcSAndroid Build Coastguard Worker			if (!ctx_has_comment($first_line, $linenr)) {
6488*d68f33bcSAndroid Build Coastguard Worker				CHK("UNCOMMENTED_DEFINITION",
6489*d68f33bcSAndroid Build Coastguard Worker				    "$1 definition without comment\n" . $herecurr);
6490*d68f33bcSAndroid Build Coastguard Worker			}
6491*d68f33bcSAndroid Build Coastguard Worker		}
6492*d68f33bcSAndroid Build Coastguard Worker# check for memory barriers without a comment.
6493*d68f33bcSAndroid Build Coastguard Worker
6494*d68f33bcSAndroid Build Coastguard Worker		my $barriers = qr{
6495*d68f33bcSAndroid Build Coastguard Worker			mb|
6496*d68f33bcSAndroid Build Coastguard Worker			rmb|
6497*d68f33bcSAndroid Build Coastguard Worker			wmb
6498*d68f33bcSAndroid Build Coastguard Worker		}x;
6499*d68f33bcSAndroid Build Coastguard Worker		my $barrier_stems = qr{
6500*d68f33bcSAndroid Build Coastguard Worker			mb__before_atomic|
6501*d68f33bcSAndroid Build Coastguard Worker			mb__after_atomic|
6502*d68f33bcSAndroid Build Coastguard Worker			store_release|
6503*d68f33bcSAndroid Build Coastguard Worker			load_acquire|
6504*d68f33bcSAndroid Build Coastguard Worker			store_mb|
6505*d68f33bcSAndroid Build Coastguard Worker			(?:$barriers)
6506*d68f33bcSAndroid Build Coastguard Worker		}x;
6507*d68f33bcSAndroid Build Coastguard Worker		my $all_barriers = qr{
6508*d68f33bcSAndroid Build Coastguard Worker			(?:$barriers)|
6509*d68f33bcSAndroid Build Coastguard Worker			smp_(?:$barrier_stems)|
6510*d68f33bcSAndroid Build Coastguard Worker			virt_(?:$barrier_stems)
6511*d68f33bcSAndroid Build Coastguard Worker		}x;
6512*d68f33bcSAndroid Build Coastguard Worker
6513*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
6514*d68f33bcSAndroid Build Coastguard Worker			if (!ctx_has_comment($first_line, $linenr)) {
6515*d68f33bcSAndroid Build Coastguard Worker				WARN("MEMORY_BARRIER",
6516*d68f33bcSAndroid Build Coastguard Worker				     "memory barrier without comment\n" . $herecurr);
6517*d68f33bcSAndroid Build Coastguard Worker			}
6518*d68f33bcSAndroid Build Coastguard Worker		}
6519*d68f33bcSAndroid Build Coastguard Worker
6520*d68f33bcSAndroid Build Coastguard Worker		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6521*d68f33bcSAndroid Build Coastguard Worker
6522*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@^include/asm-generic/@ &&
6523*d68f33bcSAndroid Build Coastguard Worker		    $realfile !~ m@/barrier\.h$@ &&
6524*d68f33bcSAndroid Build Coastguard Worker		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6525*d68f33bcSAndroid Build Coastguard Worker		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6526*d68f33bcSAndroid Build Coastguard Worker			WARN("MEMORY_BARRIER",
6527*d68f33bcSAndroid Build Coastguard Worker			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6528*d68f33bcSAndroid Build Coastguard Worker		}
6529*d68f33bcSAndroid Build Coastguard Worker
6530*d68f33bcSAndroid Build Coastguard Worker# check for waitqueue_active without a comment.
6531*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bwaitqueue_active\s*\(/) {
6532*d68f33bcSAndroid Build Coastguard Worker			if (!ctx_has_comment($first_line, $linenr)) {
6533*d68f33bcSAndroid Build Coastguard Worker				WARN("WAITQUEUE_ACTIVE",
6534*d68f33bcSAndroid Build Coastguard Worker				     "waitqueue_active without comment\n" . $herecurr);
6535*d68f33bcSAndroid Build Coastguard Worker			}
6536*d68f33bcSAndroid Build Coastguard Worker		}
6537*d68f33bcSAndroid Build Coastguard Worker
6538*d68f33bcSAndroid Build Coastguard Worker# check for data_race without a comment.
6539*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bdata_race\s*\(/) {
6540*d68f33bcSAndroid Build Coastguard Worker			if (!ctx_has_comment($first_line, $linenr)) {
6541*d68f33bcSAndroid Build Coastguard Worker				WARN("DATA_RACE",
6542*d68f33bcSAndroid Build Coastguard Worker				     "data_race without comment\n" . $herecurr);
6543*d68f33bcSAndroid Build Coastguard Worker			}
6544*d68f33bcSAndroid Build Coastguard Worker		}
6545*d68f33bcSAndroid Build Coastguard Worker
6546*d68f33bcSAndroid Build Coastguard Worker# check of hardware specific defines
6547*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6548*d68f33bcSAndroid Build Coastguard Worker			CHK("ARCH_DEFINES",
6549*d68f33bcSAndroid Build Coastguard Worker			    "architecture specific defines should be avoided\n" .  $herecurr);
6550*d68f33bcSAndroid Build Coastguard Worker		}
6551*d68f33bcSAndroid Build Coastguard Worker
6552*d68f33bcSAndroid Build Coastguard Worker# check that the storage class is not after a type
6553*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6554*d68f33bcSAndroid Build Coastguard Worker			WARN("STORAGE_CLASS",
6555*d68f33bcSAndroid Build Coastguard Worker			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6556*d68f33bcSAndroid Build Coastguard Worker		}
6557*d68f33bcSAndroid Build Coastguard Worker# Check that the storage class is at the beginning of a declaration
6558*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b$Storage\b/ &&
6559*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^.\s*$Storage/ &&
6560*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6561*d68f33bcSAndroid Build Coastguard Worker		    $1 !~ /[\,\)]\s*$/) {
6562*d68f33bcSAndroid Build Coastguard Worker			WARN("STORAGE_CLASS",
6563*d68f33bcSAndroid Build Coastguard Worker			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6564*d68f33bcSAndroid Build Coastguard Worker		}
6565*d68f33bcSAndroid Build Coastguard Worker
6566*d68f33bcSAndroid Build Coastguard Worker# check the location of the inline attribute, that it is between
6567*d68f33bcSAndroid Build Coastguard Worker# storage class and type.
6568*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b$Type\s+$Inline\b/ ||
6569*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b$Inline\s+$Storage\b/) {
6570*d68f33bcSAndroid Build Coastguard Worker			ERROR("INLINE_LOCATION",
6571*d68f33bcSAndroid Build Coastguard Worker			      "inline keyword should sit between storage class and type\n" . $herecurr);
6572*d68f33bcSAndroid Build Coastguard Worker		}
6573*d68f33bcSAndroid Build Coastguard Worker
6574*d68f33bcSAndroid Build Coastguard Worker# Check for __inline__ and __inline, prefer inline
6575*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@\binclude/uapi/@ &&
6576*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b(__inline__|__inline)\b/) {
6577*d68f33bcSAndroid Build Coastguard Worker			if (WARN("INLINE",
6578*d68f33bcSAndroid Build Coastguard Worker				 "plain inline is preferred over $1\n" . $herecurr) &&
6579*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6580*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6581*d68f33bcSAndroid Build Coastguard Worker
6582*d68f33bcSAndroid Build Coastguard Worker			}
6583*d68f33bcSAndroid Build Coastguard Worker		}
6584*d68f33bcSAndroid Build Coastguard Worker
6585*d68f33bcSAndroid Build Coastguard Worker# Check for compiler attributes
6586*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@\binclude/uapi/@ &&
6587*d68f33bcSAndroid Build Coastguard Worker		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
6588*d68f33bcSAndroid Build Coastguard Worker			my $attr = $1;
6589*d68f33bcSAndroid Build Coastguard Worker			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
6590*d68f33bcSAndroid Build Coastguard Worker
6591*d68f33bcSAndroid Build Coastguard Worker			my %attr_list = (
6592*d68f33bcSAndroid Build Coastguard Worker				"alias"				=> "__alias",
6593*d68f33bcSAndroid Build Coastguard Worker				"aligned"			=> "__aligned",
6594*d68f33bcSAndroid Build Coastguard Worker				"always_inline"			=> "__always_inline",
6595*d68f33bcSAndroid Build Coastguard Worker				"assume_aligned"		=> "__assume_aligned",
6596*d68f33bcSAndroid Build Coastguard Worker				"cold"				=> "__cold",
6597*d68f33bcSAndroid Build Coastguard Worker				"const"				=> "__attribute_const__",
6598*d68f33bcSAndroid Build Coastguard Worker				"copy"				=> "__copy",
6599*d68f33bcSAndroid Build Coastguard Worker				"designated_init"		=> "__designated_init",
6600*d68f33bcSAndroid Build Coastguard Worker				"externally_visible"		=> "__visible",
6601*d68f33bcSAndroid Build Coastguard Worker				"format"			=> "printf|scanf",
6602*d68f33bcSAndroid Build Coastguard Worker				"gnu_inline"			=> "__gnu_inline",
6603*d68f33bcSAndroid Build Coastguard Worker				"malloc"			=> "__malloc",
6604*d68f33bcSAndroid Build Coastguard Worker				"mode"				=> "__mode",
6605*d68f33bcSAndroid Build Coastguard Worker				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
6606*d68f33bcSAndroid Build Coastguard Worker				"noclone"			=> "__noclone",
6607*d68f33bcSAndroid Build Coastguard Worker				"noinline"			=> "noinline",
6608*d68f33bcSAndroid Build Coastguard Worker				"nonstring"			=> "__nonstring",
6609*d68f33bcSAndroid Build Coastguard Worker				"noreturn"			=> "__noreturn",
6610*d68f33bcSAndroid Build Coastguard Worker				"packed"			=> "__packed",
6611*d68f33bcSAndroid Build Coastguard Worker				"pure"				=> "__pure",
6612*d68f33bcSAndroid Build Coastguard Worker				"section"			=> "__section",
6613*d68f33bcSAndroid Build Coastguard Worker				"used"				=> "__used",
6614*d68f33bcSAndroid Build Coastguard Worker				"weak"				=> "__weak"
6615*d68f33bcSAndroid Build Coastguard Worker			);
6616*d68f33bcSAndroid Build Coastguard Worker
6617*d68f33bcSAndroid Build Coastguard Worker			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6618*d68f33bcSAndroid Build Coastguard Worker				my $orig_attr = $1;
6619*d68f33bcSAndroid Build Coastguard Worker				my $params = '';
6620*d68f33bcSAndroid Build Coastguard Worker				$params = $2 if defined($2);
6621*d68f33bcSAndroid Build Coastguard Worker				my $curr_attr = $orig_attr;
6622*d68f33bcSAndroid Build Coastguard Worker				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
6623*d68f33bcSAndroid Build Coastguard Worker				if (exists($attr_list{$curr_attr})) {
6624*d68f33bcSAndroid Build Coastguard Worker					my $new = $attr_list{$curr_attr};
6625*d68f33bcSAndroid Build Coastguard Worker					if ($curr_attr eq "format" && $params) {
6626*d68f33bcSAndroid Build Coastguard Worker						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6627*d68f33bcSAndroid Build Coastguard Worker						$new = "__$1\($2";
6628*d68f33bcSAndroid Build Coastguard Worker					} else {
6629*d68f33bcSAndroid Build Coastguard Worker						$new = "$new$params";
6630*d68f33bcSAndroid Build Coastguard Worker					}
6631*d68f33bcSAndroid Build Coastguard Worker					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6632*d68f33bcSAndroid Build Coastguard Worker						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
6633*d68f33bcSAndroid Build Coastguard Worker					    $fix) {
6634*d68f33bcSAndroid Build Coastguard Worker						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6635*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/$remove//;
6636*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6637*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6638*d68f33bcSAndroid Build Coastguard Worker						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
6639*d68f33bcSAndroid Build Coastguard Worker					}
6640*d68f33bcSAndroid Build Coastguard Worker				}
6641*d68f33bcSAndroid Build Coastguard Worker			}
6642*d68f33bcSAndroid Build Coastguard Worker
6643*d68f33bcSAndroid Build Coastguard Worker			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
6644*d68f33bcSAndroid Build Coastguard Worker			if ($attr =~ /^_*unused/) {
6645*d68f33bcSAndroid Build Coastguard Worker				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6646*d68f33bcSAndroid Build Coastguard Worker				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6647*d68f33bcSAndroid Build Coastguard Worker			}
6648*d68f33bcSAndroid Build Coastguard Worker		}
6649*d68f33bcSAndroid Build Coastguard Worker
6650*d68f33bcSAndroid Build Coastguard Worker# Check for __attribute__ weak, or __weak declarations (may have link issues)
6651*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6652*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6653*d68f33bcSAndroid Build Coastguard Worker		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6654*d68f33bcSAndroid Build Coastguard Worker		     $line =~ /\b__weak\b/)) {
6655*d68f33bcSAndroid Build Coastguard Worker			ERROR("WEAK_DECLARATION",
6656*d68f33bcSAndroid Build Coastguard Worker			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6657*d68f33bcSAndroid Build Coastguard Worker		}
6658*d68f33bcSAndroid Build Coastguard Worker
6659*d68f33bcSAndroid Build Coastguard Worker# check for c99 types like uint8_t used outside of uapi/ and tools/
6660*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@\binclude/uapi/@ &&
6661*d68f33bcSAndroid Build Coastguard Worker		    $realfile !~ m@\btools/@ &&
6662*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6663*d68f33bcSAndroid Build Coastguard Worker			my $type = $1;
6664*d68f33bcSAndroid Build Coastguard Worker			if ($type =~ /\b($typeC99Typedefs)\b/) {
6665*d68f33bcSAndroid Build Coastguard Worker				$type = $1;
6666*d68f33bcSAndroid Build Coastguard Worker				my $kernel_type = 'u';
6667*d68f33bcSAndroid Build Coastguard Worker				$kernel_type = 's' if ($type =~ /^_*[si]/);
6668*d68f33bcSAndroid Build Coastguard Worker				$type =~ /(\d+)/;
6669*d68f33bcSAndroid Build Coastguard Worker				$kernel_type .= $1;
6670*d68f33bcSAndroid Build Coastguard Worker				if (CHK("PREFER_KERNEL_TYPES",
6671*d68f33bcSAndroid Build Coastguard Worker					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6672*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
6673*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6674*d68f33bcSAndroid Build Coastguard Worker				}
6675*d68f33bcSAndroid Build Coastguard Worker			}
6676*d68f33bcSAndroid Build Coastguard Worker		}
6677*d68f33bcSAndroid Build Coastguard Worker
6678*d68f33bcSAndroid Build Coastguard Worker# check for cast of C90 native int or longer types constants
6679*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6680*d68f33bcSAndroid Build Coastguard Worker			my $cast = $1;
6681*d68f33bcSAndroid Build Coastguard Worker			my $const = $2;
6682*d68f33bcSAndroid Build Coastguard Worker			my $suffix = "";
6683*d68f33bcSAndroid Build Coastguard Worker			my $newconst = $const;
6684*d68f33bcSAndroid Build Coastguard Worker			$newconst =~ s/${Int_type}$//;
6685*d68f33bcSAndroid Build Coastguard Worker			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6686*d68f33bcSAndroid Build Coastguard Worker			if ($cast =~ /\blong\s+long\b/) {
6687*d68f33bcSAndroid Build Coastguard Worker			    $suffix .= 'LL';
6688*d68f33bcSAndroid Build Coastguard Worker			} elsif ($cast =~ /\blong\b/) {
6689*d68f33bcSAndroid Build Coastguard Worker			    $suffix .= 'L';
6690*d68f33bcSAndroid Build Coastguard Worker			}
6691*d68f33bcSAndroid Build Coastguard Worker			if (WARN("TYPECAST_INT_CONSTANT",
6692*d68f33bcSAndroid Build Coastguard Worker				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
6693*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6694*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6695*d68f33bcSAndroid Build Coastguard Worker			}
6696*d68f33bcSAndroid Build Coastguard Worker		}
6697*d68f33bcSAndroid Build Coastguard Worker
6698*d68f33bcSAndroid Build Coastguard Worker# check for sizeof(&)
6699*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6700*d68f33bcSAndroid Build Coastguard Worker			WARN("SIZEOF_ADDRESS",
6701*d68f33bcSAndroid Build Coastguard Worker			     "sizeof(& should be avoided\n" . $herecurr);
6702*d68f33bcSAndroid Build Coastguard Worker		}
6703*d68f33bcSAndroid Build Coastguard Worker
6704*d68f33bcSAndroid Build Coastguard Worker# check for sizeof without parenthesis
6705*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6706*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SIZEOF_PARENTHESIS",
6707*d68f33bcSAndroid Build Coastguard Worker				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6708*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6709*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6710*d68f33bcSAndroid Build Coastguard Worker			}
6711*d68f33bcSAndroid Build Coastguard Worker		}
6712*d68f33bcSAndroid Build Coastguard Worker
6713*d68f33bcSAndroid Build Coastguard Worker# check for struct spinlock declarations
6714*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
6715*d68f33bcSAndroid Build Coastguard Worker			WARN("USE_SPINLOCK_T",
6716*d68f33bcSAndroid Build Coastguard Worker			     "struct spinlock should be spinlock_t\n" . $herecurr);
6717*d68f33bcSAndroid Build Coastguard Worker		}
6718*d68f33bcSAndroid Build Coastguard Worker
6719*d68f33bcSAndroid Build Coastguard Worker# check for seq_printf uses that could be seq_puts
6720*d68f33bcSAndroid Build Coastguard Worker		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6721*d68f33bcSAndroid Build Coastguard Worker			my $fmt = get_quoted_string($line, $rawline);
6722*d68f33bcSAndroid Build Coastguard Worker			$fmt =~ s/%%//g;
6723*d68f33bcSAndroid Build Coastguard Worker			if ($fmt !~ /%/) {
6724*d68f33bcSAndroid Build Coastguard Worker				if (WARN("PREFER_SEQ_PUTS",
6725*d68f33bcSAndroid Build Coastguard Worker					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6726*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
6727*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6728*d68f33bcSAndroid Build Coastguard Worker				}
6729*d68f33bcSAndroid Build Coastguard Worker			}
6730*d68f33bcSAndroid Build Coastguard Worker		}
6731*d68f33bcSAndroid Build Coastguard Worker
6732*d68f33bcSAndroid Build Coastguard Worker# check for vsprintf extension %p<foo> misuses
6733*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6734*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6735*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
6736*d68f33bcSAndroid Build Coastguard Worker		    $1 !~ /^_*volatile_*$/) {
6737*d68f33bcSAndroid Build Coastguard Worker			my $stat_real;
6738*d68f33bcSAndroid Build Coastguard Worker
6739*d68f33bcSAndroid Build Coastguard Worker			my $lc = $stat =~ tr@\n@@;
6740*d68f33bcSAndroid Build Coastguard Worker			$lc = $lc + $linenr;
6741*d68f33bcSAndroid Build Coastguard Worker		        for (my $count = $linenr; $count <= $lc; $count++) {
6742*d68f33bcSAndroid Build Coastguard Worker				my $specifier;
6743*d68f33bcSAndroid Build Coastguard Worker				my $extension;
6744*d68f33bcSAndroid Build Coastguard Worker				my $qualifier;
6745*d68f33bcSAndroid Build Coastguard Worker				my $bad_specifier = "";
6746*d68f33bcSAndroid Build Coastguard Worker				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
6747*d68f33bcSAndroid Build Coastguard Worker				$fmt =~ s/%%//g;
6748*d68f33bcSAndroid Build Coastguard Worker
6749*d68f33bcSAndroid Build Coastguard Worker				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6750*d68f33bcSAndroid Build Coastguard Worker					$specifier = $1;
6751*d68f33bcSAndroid Build Coastguard Worker					$extension = $2;
6752*d68f33bcSAndroid Build Coastguard Worker					$qualifier = $3;
6753*d68f33bcSAndroid Build Coastguard Worker					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
6754*d68f33bcSAndroid Build Coastguard Worker					    ($extension eq "f" &&
6755*d68f33bcSAndroid Build Coastguard Worker					     defined $qualifier && $qualifier !~ /^w/) ||
6756*d68f33bcSAndroid Build Coastguard Worker					    ($extension eq "4" &&
6757*d68f33bcSAndroid Build Coastguard Worker					     defined $qualifier && $qualifier !~ /^cc/)) {
6758*d68f33bcSAndroid Build Coastguard Worker						$bad_specifier = $specifier;
6759*d68f33bcSAndroid Build Coastguard Worker						last;
6760*d68f33bcSAndroid Build Coastguard Worker					}
6761*d68f33bcSAndroid Build Coastguard Worker					if ($extension eq "x" && !defined($stat_real)) {
6762*d68f33bcSAndroid Build Coastguard Worker						if (!defined($stat_real)) {
6763*d68f33bcSAndroid Build Coastguard Worker							$stat_real = get_stat_real($linenr, $lc);
6764*d68f33bcSAndroid Build Coastguard Worker						}
6765*d68f33bcSAndroid Build Coastguard Worker						WARN("VSPRINTF_SPECIFIER_PX",
6766*d68f33bcSAndroid Build Coastguard Worker						     "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");
6767*d68f33bcSAndroid Build Coastguard Worker					}
6768*d68f33bcSAndroid Build Coastguard Worker				}
6769*d68f33bcSAndroid Build Coastguard Worker				if ($bad_specifier ne "") {
6770*d68f33bcSAndroid Build Coastguard Worker					my $stat_real = get_stat_real($linenr, $lc);
6771*d68f33bcSAndroid Build Coastguard Worker					my $ext_type = "Invalid";
6772*d68f33bcSAndroid Build Coastguard Worker					my $use = "";
6773*d68f33bcSAndroid Build Coastguard Worker					if ($bad_specifier =~ /p[Ff]/) {
6774*d68f33bcSAndroid Build Coastguard Worker						$use = " - use %pS instead";
6775*d68f33bcSAndroid Build Coastguard Worker						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6776*d68f33bcSAndroid Build Coastguard Worker					}
6777*d68f33bcSAndroid Build Coastguard Worker
6778*d68f33bcSAndroid Build Coastguard Worker					WARN("VSPRINTF_POINTER_EXTENSION",
6779*d68f33bcSAndroid Build Coastguard Worker					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6780*d68f33bcSAndroid Build Coastguard Worker				}
6781*d68f33bcSAndroid Build Coastguard Worker			}
6782*d68f33bcSAndroid Build Coastguard Worker		}
6783*d68f33bcSAndroid Build Coastguard Worker
6784*d68f33bcSAndroid Build Coastguard Worker# Check for misused memsets
6785*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6786*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6787*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6788*d68f33bcSAndroid Build Coastguard Worker
6789*d68f33bcSAndroid Build Coastguard Worker			my $ms_addr = $2;
6790*d68f33bcSAndroid Build Coastguard Worker			my $ms_val = $7;
6791*d68f33bcSAndroid Build Coastguard Worker			my $ms_size = $12;
6792*d68f33bcSAndroid Build Coastguard Worker
6793*d68f33bcSAndroid Build Coastguard Worker			if ($ms_size =~ /^(0x|)0$/i) {
6794*d68f33bcSAndroid Build Coastguard Worker				ERROR("MEMSET",
6795*d68f33bcSAndroid Build Coastguard Worker				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6796*d68f33bcSAndroid Build Coastguard Worker			} elsif ($ms_size =~ /^(0x|)1$/i) {
6797*d68f33bcSAndroid Build Coastguard Worker				WARN("MEMSET",
6798*d68f33bcSAndroid Build Coastguard Worker				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6799*d68f33bcSAndroid Build Coastguard Worker			}
6800*d68f33bcSAndroid Build Coastguard Worker		}
6801*d68f33bcSAndroid Build Coastguard Worker
6802*d68f33bcSAndroid Build Coastguard Worker# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
6803*d68f33bcSAndroid Build Coastguard Worker#		if ($perl_version_ok &&
6804*d68f33bcSAndroid Build Coastguard Worker#		    defined $stat &&
6805*d68f33bcSAndroid Build Coastguard Worker#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6806*d68f33bcSAndroid Build Coastguard Worker#			if (WARN("PREFER_ETHER_ADDR_COPY",
6807*d68f33bcSAndroid Build Coastguard Worker#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6808*d68f33bcSAndroid Build Coastguard Worker#			    $fix) {
6809*d68f33bcSAndroid Build Coastguard Worker#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6810*d68f33bcSAndroid Build Coastguard Worker#			}
6811*d68f33bcSAndroid Build Coastguard Worker#		}
6812*d68f33bcSAndroid Build Coastguard Worker
6813*d68f33bcSAndroid Build Coastguard Worker# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
6814*d68f33bcSAndroid Build Coastguard Worker#		if ($perl_version_ok &&
6815*d68f33bcSAndroid Build Coastguard Worker#		    defined $stat &&
6816*d68f33bcSAndroid Build Coastguard Worker#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6817*d68f33bcSAndroid Build Coastguard Worker#			WARN("PREFER_ETHER_ADDR_EQUAL",
6818*d68f33bcSAndroid Build Coastguard Worker#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6819*d68f33bcSAndroid Build Coastguard Worker#		}
6820*d68f33bcSAndroid Build Coastguard Worker
6821*d68f33bcSAndroid Build Coastguard Worker# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
6822*d68f33bcSAndroid Build Coastguard Worker# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
6823*d68f33bcSAndroid Build Coastguard Worker#		if ($perl_version_ok &&
6824*d68f33bcSAndroid Build Coastguard Worker#		    defined $stat &&
6825*d68f33bcSAndroid Build Coastguard Worker#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6826*d68f33bcSAndroid Build Coastguard Worker#
6827*d68f33bcSAndroid Build Coastguard Worker#			my $ms_val = $7;
6828*d68f33bcSAndroid Build Coastguard Worker#
6829*d68f33bcSAndroid Build Coastguard Worker#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6830*d68f33bcSAndroid Build Coastguard Worker#				if (WARN("PREFER_ETH_ZERO_ADDR",
6831*d68f33bcSAndroid Build Coastguard Worker#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6832*d68f33bcSAndroid Build Coastguard Worker#				    $fix) {
6833*d68f33bcSAndroid Build Coastguard Worker#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6834*d68f33bcSAndroid Build Coastguard Worker#				}
6835*d68f33bcSAndroid Build Coastguard Worker#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6836*d68f33bcSAndroid Build Coastguard Worker#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6837*d68f33bcSAndroid Build Coastguard Worker#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6838*d68f33bcSAndroid Build Coastguard Worker#				    $fix) {
6839*d68f33bcSAndroid Build Coastguard Worker#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6840*d68f33bcSAndroid Build Coastguard Worker#				}
6841*d68f33bcSAndroid Build Coastguard Worker#			}
6842*d68f33bcSAndroid Build Coastguard Worker#		}
6843*d68f33bcSAndroid Build Coastguard Worker
6844*d68f33bcSAndroid Build Coastguard Worker# strlcpy uses that should likely be strscpy
6845*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bstrlcpy\s*\(/) {
6846*d68f33bcSAndroid Build Coastguard Worker			WARN("STRLCPY",
6847*d68f33bcSAndroid Build Coastguard Worker			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
6848*d68f33bcSAndroid Build Coastguard Worker		}
6849*d68f33bcSAndroid Build Coastguard Worker
6850*d68f33bcSAndroid Build Coastguard Worker# typecasts on min/max could be min_t/max_t
6851*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6852*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6853*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6854*d68f33bcSAndroid Build Coastguard Worker			if (defined $2 || defined $7) {
6855*d68f33bcSAndroid Build Coastguard Worker				my $call = $1;
6856*d68f33bcSAndroid Build Coastguard Worker				my $cast1 = deparenthesize($2);
6857*d68f33bcSAndroid Build Coastguard Worker				my $arg1 = $3;
6858*d68f33bcSAndroid Build Coastguard Worker				my $cast2 = deparenthesize($7);
6859*d68f33bcSAndroid Build Coastguard Worker				my $arg2 = $8;
6860*d68f33bcSAndroid Build Coastguard Worker				my $cast;
6861*d68f33bcSAndroid Build Coastguard Worker
6862*d68f33bcSAndroid Build Coastguard Worker				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6863*d68f33bcSAndroid Build Coastguard Worker					$cast = "$cast1 or $cast2";
6864*d68f33bcSAndroid Build Coastguard Worker				} elsif ($cast1 ne "") {
6865*d68f33bcSAndroid Build Coastguard Worker					$cast = $cast1;
6866*d68f33bcSAndroid Build Coastguard Worker				} else {
6867*d68f33bcSAndroid Build Coastguard Worker					$cast = $cast2;
6868*d68f33bcSAndroid Build Coastguard Worker				}
6869*d68f33bcSAndroid Build Coastguard Worker				WARN("MINMAX",
6870*d68f33bcSAndroid Build Coastguard Worker				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6871*d68f33bcSAndroid Build Coastguard Worker			}
6872*d68f33bcSAndroid Build Coastguard Worker		}
6873*d68f33bcSAndroid Build Coastguard Worker
6874*d68f33bcSAndroid Build Coastguard Worker# check usleep_range arguments
6875*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6876*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6877*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
6878*d68f33bcSAndroid Build Coastguard Worker			my $min = $1;
6879*d68f33bcSAndroid Build Coastguard Worker			my $max = $7;
6880*d68f33bcSAndroid Build Coastguard Worker			if ($min eq $max) {
6881*d68f33bcSAndroid Build Coastguard Worker				WARN("USLEEP_RANGE",
6882*d68f33bcSAndroid Build Coastguard Worker				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
6883*d68f33bcSAndroid Build Coastguard Worker			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
6884*d68f33bcSAndroid Build Coastguard Worker				 $min > $max) {
6885*d68f33bcSAndroid Build Coastguard Worker				WARN("USLEEP_RANGE",
6886*d68f33bcSAndroid Build Coastguard Worker				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
6887*d68f33bcSAndroid Build Coastguard Worker			}
6888*d68f33bcSAndroid Build Coastguard Worker		}
6889*d68f33bcSAndroid Build Coastguard Worker
6890*d68f33bcSAndroid Build Coastguard Worker# check for naked sscanf
6891*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6892*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6893*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\bsscanf\b/ &&
6894*d68f33bcSAndroid Build Coastguard Worker		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6895*d68f33bcSAndroid Build Coastguard Worker		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6896*d68f33bcSAndroid Build Coastguard Worker		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6897*d68f33bcSAndroid Build Coastguard Worker			my $lc = $stat =~ tr@\n@@;
6898*d68f33bcSAndroid Build Coastguard Worker			$lc = $lc + $linenr;
6899*d68f33bcSAndroid Build Coastguard Worker			my $stat_real = get_stat_real($linenr, $lc);
6900*d68f33bcSAndroid Build Coastguard Worker			WARN("NAKED_SSCANF",
6901*d68f33bcSAndroid Build Coastguard Worker			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6902*d68f33bcSAndroid Build Coastguard Worker		}
6903*d68f33bcSAndroid Build Coastguard Worker
6904*d68f33bcSAndroid Build Coastguard Worker# check for simple sscanf that should be kstrto<foo>
6905*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6906*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6907*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\bsscanf\b/) {
6908*d68f33bcSAndroid Build Coastguard Worker			my $lc = $stat =~ tr@\n@@;
6909*d68f33bcSAndroid Build Coastguard Worker			$lc = $lc + $linenr;
6910*d68f33bcSAndroid Build Coastguard Worker			my $stat_real = get_stat_real($linenr, $lc);
6911*d68f33bcSAndroid Build Coastguard Worker			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6912*d68f33bcSAndroid Build Coastguard Worker				my $format = $6;
6913*d68f33bcSAndroid Build Coastguard Worker				my $count = $format =~ tr@%@%@;
6914*d68f33bcSAndroid Build Coastguard Worker				if ($count == 1 &&
6915*d68f33bcSAndroid Build Coastguard Worker				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6916*d68f33bcSAndroid Build Coastguard Worker					WARN("SSCANF_TO_KSTRTO",
6917*d68f33bcSAndroid Build Coastguard Worker					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6918*d68f33bcSAndroid Build Coastguard Worker				}
6919*d68f33bcSAndroid Build Coastguard Worker			}
6920*d68f33bcSAndroid Build Coastguard Worker		}
6921*d68f33bcSAndroid Build Coastguard Worker
6922*d68f33bcSAndroid Build Coastguard Worker# check for new externs in .h files.
6923*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ /\.h$/ &&
6924*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6925*d68f33bcSAndroid Build Coastguard Worker			if (CHK("AVOID_EXTERNS",
6926*d68f33bcSAndroid Build Coastguard Worker				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
6927*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
6928*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
6929*d68f33bcSAndroid Build Coastguard Worker			}
6930*d68f33bcSAndroid Build Coastguard Worker		}
6931*d68f33bcSAndroid Build Coastguard Worker
6932*d68f33bcSAndroid Build Coastguard Worker# check for new externs in .c files.
6933*d68f33bcSAndroid Build Coastguard Worker		if ($realfile =~ /\.c$/ && defined $stat &&
6934*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6935*d68f33bcSAndroid Build Coastguard Worker		{
6936*d68f33bcSAndroid Build Coastguard Worker			my $function_name = $1;
6937*d68f33bcSAndroid Build Coastguard Worker			my $paren_space = $2;
6938*d68f33bcSAndroid Build Coastguard Worker
6939*d68f33bcSAndroid Build Coastguard Worker			my $s = $stat;
6940*d68f33bcSAndroid Build Coastguard Worker			if (defined $cond) {
6941*d68f33bcSAndroid Build Coastguard Worker				substr($s, 0, length($cond), '');
6942*d68f33bcSAndroid Build Coastguard Worker			}
6943*d68f33bcSAndroid Build Coastguard Worker			if ($s =~ /^\s*;/)
6944*d68f33bcSAndroid Build Coastguard Worker			{
6945*d68f33bcSAndroid Build Coastguard Worker				WARN("AVOID_EXTERNS",
6946*d68f33bcSAndroid Build Coastguard Worker				     "externs should be avoided in .c files\n" .  $herecurr);
6947*d68f33bcSAndroid Build Coastguard Worker			}
6948*d68f33bcSAndroid Build Coastguard Worker
6949*d68f33bcSAndroid Build Coastguard Worker			if ($paren_space =~ /\n/) {
6950*d68f33bcSAndroid Build Coastguard Worker				WARN("FUNCTION_ARGUMENTS",
6951*d68f33bcSAndroid Build Coastguard Worker				     "arguments for function declarations should follow identifier\n" . $herecurr);
6952*d68f33bcSAndroid Build Coastguard Worker			}
6953*d68f33bcSAndroid Build Coastguard Worker
6954*d68f33bcSAndroid Build Coastguard Worker		} elsif ($realfile =~ /\.c$/ && defined $stat &&
6955*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^.\s*extern\s+/)
6956*d68f33bcSAndroid Build Coastguard Worker		{
6957*d68f33bcSAndroid Build Coastguard Worker			WARN("AVOID_EXTERNS",
6958*d68f33bcSAndroid Build Coastguard Worker			     "externs should be avoided in .c files\n" .  $herecurr);
6959*d68f33bcSAndroid Build Coastguard Worker		}
6960*d68f33bcSAndroid Build Coastguard Worker
6961*d68f33bcSAndroid Build Coastguard Worker# check for function declarations that have arguments without identifier names
6962*d68f33bcSAndroid Build Coastguard Worker		if (defined $stat &&
6963*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6964*d68f33bcSAndroid Build Coastguard Worker		    $1 ne "void") {
6965*d68f33bcSAndroid Build Coastguard Worker			my $args = trim($1);
6966*d68f33bcSAndroid Build Coastguard Worker			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6967*d68f33bcSAndroid Build Coastguard Worker				my $arg = trim($1);
6968*d68f33bcSAndroid Build Coastguard Worker				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6969*d68f33bcSAndroid Build Coastguard Worker					WARN("FUNCTION_ARGUMENTS",
6970*d68f33bcSAndroid Build Coastguard Worker					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6971*d68f33bcSAndroid Build Coastguard Worker				}
6972*d68f33bcSAndroid Build Coastguard Worker			}
6973*d68f33bcSAndroid Build Coastguard Worker		}
6974*d68f33bcSAndroid Build Coastguard Worker
6975*d68f33bcSAndroid Build Coastguard Worker# check for function definitions
6976*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
6977*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
6978*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6979*d68f33bcSAndroid Build Coastguard Worker			$context_function = $1;
6980*d68f33bcSAndroid Build Coastguard Worker
6981*d68f33bcSAndroid Build Coastguard Worker# check for multiline function definition with misplaced open brace
6982*d68f33bcSAndroid Build Coastguard Worker			my $ok = 0;
6983*d68f33bcSAndroid Build Coastguard Worker			my $cnt = statement_rawlines($stat);
6984*d68f33bcSAndroid Build Coastguard Worker			my $herectx = $here . "\n";
6985*d68f33bcSAndroid Build Coastguard Worker			for (my $n = 0; $n < $cnt; $n++) {
6986*d68f33bcSAndroid Build Coastguard Worker				my $rl = raw_line($linenr, $n);
6987*d68f33bcSAndroid Build Coastguard Worker				$herectx .=  $rl . "\n";
6988*d68f33bcSAndroid Build Coastguard Worker				$ok = 1 if ($rl =~ /^[ \+]\{/);
6989*d68f33bcSAndroid Build Coastguard Worker				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6990*d68f33bcSAndroid Build Coastguard Worker				last if $rl =~ /^[ \+].*\{/;
6991*d68f33bcSAndroid Build Coastguard Worker			}
6992*d68f33bcSAndroid Build Coastguard Worker			if (!$ok) {
6993*d68f33bcSAndroid Build Coastguard Worker				ERROR("OPEN_BRACE",
6994*d68f33bcSAndroid Build Coastguard Worker				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6995*d68f33bcSAndroid Build Coastguard Worker			}
6996*d68f33bcSAndroid Build Coastguard Worker		}
6997*d68f33bcSAndroid Build Coastguard Worker
6998*d68f33bcSAndroid Build Coastguard Worker# checks for new __setup's
6999*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /\b__setup\("([^"]*)"/) {
7000*d68f33bcSAndroid Build Coastguard Worker			my $name = $1;
7001*d68f33bcSAndroid Build Coastguard Worker
7002*d68f33bcSAndroid Build Coastguard Worker			if (!grep(/$name/, @setup_docs)) {
7003*d68f33bcSAndroid Build Coastguard Worker				CHK("UNDOCUMENTED_SETUP",
7004*d68f33bcSAndroid Build Coastguard Worker				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
7005*d68f33bcSAndroid Build Coastguard Worker			}
7006*d68f33bcSAndroid Build Coastguard Worker		}
7007*d68f33bcSAndroid Build Coastguard Worker
7008*d68f33bcSAndroid Build Coastguard Worker# check for pointless casting of alloc functions
7009*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
7010*d68f33bcSAndroid Build Coastguard Worker			WARN("UNNECESSARY_CASTS",
7011*d68f33bcSAndroid Build Coastguard Worker			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
7012*d68f33bcSAndroid Build Coastguard Worker		}
7013*d68f33bcSAndroid Build Coastguard Worker
7014*d68f33bcSAndroid Build Coastguard Worker# alloc style
7015*d68f33bcSAndroid Build Coastguard Worker# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
7016*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7017*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
7018*d68f33bcSAndroid Build Coastguard Worker			CHK("ALLOC_SIZEOF_STRUCT",
7019*d68f33bcSAndroid Build Coastguard Worker			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
7020*d68f33bcSAndroid Build Coastguard Worker		}
7021*d68f33bcSAndroid Build Coastguard Worker
7022*d68f33bcSAndroid Build Coastguard Worker# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
7023*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7024*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
7025*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
7026*d68f33bcSAndroid Build Coastguard Worker			my $oldfunc = $3;
7027*d68f33bcSAndroid Build Coastguard Worker			my $a1 = $4;
7028*d68f33bcSAndroid Build Coastguard Worker			my $a2 = $10;
7029*d68f33bcSAndroid Build Coastguard Worker			my $newfunc = "kmalloc_array";
7030*d68f33bcSAndroid Build Coastguard Worker			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
7031*d68f33bcSAndroid Build Coastguard Worker			my $r1 = $a1;
7032*d68f33bcSAndroid Build Coastguard Worker			my $r2 = $a2;
7033*d68f33bcSAndroid Build Coastguard Worker			if ($a1 =~ /^sizeof\s*\S/) {
7034*d68f33bcSAndroid Build Coastguard Worker				$r1 = $a2;
7035*d68f33bcSAndroid Build Coastguard Worker				$r2 = $a1;
7036*d68f33bcSAndroid Build Coastguard Worker			}
7037*d68f33bcSAndroid Build Coastguard Worker			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
7038*d68f33bcSAndroid Build Coastguard Worker			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
7039*d68f33bcSAndroid Build Coastguard Worker				my $cnt = statement_rawlines($stat);
7040*d68f33bcSAndroid Build Coastguard Worker				my $herectx = get_stat_here($linenr, $cnt, $here);
7041*d68f33bcSAndroid Build Coastguard Worker
7042*d68f33bcSAndroid Build Coastguard Worker				if (WARN("ALLOC_WITH_MULTIPLY",
7043*d68f33bcSAndroid Build Coastguard Worker					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
7044*d68f33bcSAndroid Build Coastguard Worker				    $cnt == 1 &&
7045*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
7046*d68f33bcSAndroid Build Coastguard Worker					$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;
7047*d68f33bcSAndroid Build Coastguard Worker				}
7048*d68f33bcSAndroid Build Coastguard Worker			}
7049*d68f33bcSAndroid Build Coastguard Worker		}
7050*d68f33bcSAndroid Build Coastguard Worker
7051*d68f33bcSAndroid Build Coastguard Worker# check for krealloc arg reuse
7052*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7053*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
7054*d68f33bcSAndroid Build Coastguard Worker		    $1 eq $3) {
7055*d68f33bcSAndroid Build Coastguard Worker			WARN("KREALLOC_ARG_REUSE",
7056*d68f33bcSAndroid Build Coastguard Worker			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7057*d68f33bcSAndroid Build Coastguard Worker		}
7058*d68f33bcSAndroid Build Coastguard Worker
7059*d68f33bcSAndroid Build Coastguard Worker# check for alloc argument mismatch
7060*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
7061*d68f33bcSAndroid Build Coastguard Worker			WARN("ALLOC_ARRAY_ARGS",
7062*d68f33bcSAndroid Build Coastguard Worker			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
7063*d68f33bcSAndroid Build Coastguard Worker		}
7064*d68f33bcSAndroid Build Coastguard Worker
7065*d68f33bcSAndroid Build Coastguard Worker# check for multiple semicolons
7066*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /;\s*;\s*$/) {
7067*d68f33bcSAndroid Build Coastguard Worker			if (WARN("ONE_SEMICOLON",
7068*d68f33bcSAndroid Build Coastguard Worker				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7069*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7070*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7071*d68f33bcSAndroid Build Coastguard Worker			}
7072*d68f33bcSAndroid Build Coastguard Worker		}
7073*d68f33bcSAndroid Build Coastguard Worker
7074*d68f33bcSAndroid Build Coastguard Worker# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7075*d68f33bcSAndroid Build Coastguard Worker		if ($realfile !~ m@^include/uapi/@ &&
7076*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
7077*d68f33bcSAndroid Build Coastguard Worker			my $ull = "";
7078*d68f33bcSAndroid Build Coastguard Worker			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
7079*d68f33bcSAndroid Build Coastguard Worker			if (CHK("BIT_MACRO",
7080*d68f33bcSAndroid Build Coastguard Worker				"Prefer using the BIT$ull macro\n" . $herecurr) &&
7081*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7082*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
7083*d68f33bcSAndroid Build Coastguard Worker			}
7084*d68f33bcSAndroid Build Coastguard Worker		}
7085*d68f33bcSAndroid Build Coastguard Worker
7086*d68f33bcSAndroid Build Coastguard Worker# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
7087*d68f33bcSAndroid Build Coastguard Worker		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
7088*d68f33bcSAndroid Build Coastguard Worker			WARN("IS_ENABLED_CONFIG",
7089*d68f33bcSAndroid Build Coastguard Worker			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
7090*d68f33bcSAndroid Build Coastguard Worker		}
7091*d68f33bcSAndroid Build Coastguard Worker
7092*d68f33bcSAndroid Build Coastguard Worker# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
7093*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
7094*d68f33bcSAndroid Build Coastguard Worker			my $config = $1;
7095*d68f33bcSAndroid Build Coastguard Worker			if (WARN("PREFER_IS_ENABLED",
7096*d68f33bcSAndroid Build Coastguard Worker				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
7097*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7098*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
7099*d68f33bcSAndroid Build Coastguard Worker			}
7100*d68f33bcSAndroid Build Coastguard Worker		}
7101*d68f33bcSAndroid Build Coastguard Worker
7102*d68f33bcSAndroid Build Coastguard Worker# check for /* fallthrough */ like comment, prefer fallthrough;
7103*d68f33bcSAndroid Build Coastguard Worker		my @fallthroughs = (
7104*d68f33bcSAndroid Build Coastguard Worker			'fallthrough',
7105*d68f33bcSAndroid Build Coastguard Worker			'@fallthrough@',
7106*d68f33bcSAndroid Build Coastguard Worker			'lint -fallthrough[ \t]*',
7107*d68f33bcSAndroid Build Coastguard Worker			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7108*d68f33bcSAndroid Build Coastguard Worker			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7109*d68f33bcSAndroid Build Coastguard Worker			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7110*d68f33bcSAndroid Build Coastguard Worker			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7111*d68f33bcSAndroid Build Coastguard Worker		    );
7112*d68f33bcSAndroid Build Coastguard Worker		if ($raw_comment ne '') {
7113*d68f33bcSAndroid Build Coastguard Worker			foreach my $ft (@fallthroughs) {
7114*d68f33bcSAndroid Build Coastguard Worker				if ($raw_comment =~ /$ft/) {
7115*d68f33bcSAndroid Build Coastguard Worker					my $msg_level = \&WARN;
7116*d68f33bcSAndroid Build Coastguard Worker					$msg_level = \&CHK if ($file);
7117*d68f33bcSAndroid Build Coastguard Worker					&{$msg_level}("PREFER_FALLTHROUGH",
7118*d68f33bcSAndroid Build Coastguard Worker						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7119*d68f33bcSAndroid Build Coastguard Worker					last;
7120*d68f33bcSAndroid Build Coastguard Worker				}
7121*d68f33bcSAndroid Build Coastguard Worker			}
7122*d68f33bcSAndroid Build Coastguard Worker		}
7123*d68f33bcSAndroid Build Coastguard Worker
7124*d68f33bcSAndroid Build Coastguard Worker# check for switch/default statements without a break;
7125*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7126*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
7127*d68f33bcSAndroid Build Coastguard Worker		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7128*d68f33bcSAndroid Build Coastguard Worker			my $cnt = statement_rawlines($stat);
7129*d68f33bcSAndroid Build Coastguard Worker			my $herectx = get_stat_here($linenr, $cnt, $here);
7130*d68f33bcSAndroid Build Coastguard Worker
7131*d68f33bcSAndroid Build Coastguard Worker			WARN("DEFAULT_NO_BREAK",
7132*d68f33bcSAndroid Build Coastguard Worker			     "switch default: should use break\n" . $herectx);
7133*d68f33bcSAndroid Build Coastguard Worker		}
7134*d68f33bcSAndroid Build Coastguard Worker
7135*d68f33bcSAndroid Build Coastguard Worker# check for gcc specific __FUNCTION__
7136*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b__FUNCTION__\b/) {
7137*d68f33bcSAndroid Build Coastguard Worker			if (WARN("USE_FUNC",
7138*d68f33bcSAndroid Build Coastguard Worker				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
7139*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7140*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7141*d68f33bcSAndroid Build Coastguard Worker			}
7142*d68f33bcSAndroid Build Coastguard Worker		}
7143*d68f33bcSAndroid Build Coastguard Worker
7144*d68f33bcSAndroid Build Coastguard Worker# check for uses of __DATE__, __TIME__, __TIMESTAMP__
7145*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
7146*d68f33bcSAndroid Build Coastguard Worker			ERROR("DATE_TIME",
7147*d68f33bcSAndroid Build Coastguard Worker			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
7148*d68f33bcSAndroid Build Coastguard Worker		}
7149*d68f33bcSAndroid Build Coastguard Worker
7150*d68f33bcSAndroid Build Coastguard Worker# check for use of yield()
7151*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\byield\s*\(\s*\)/) {
7152*d68f33bcSAndroid Build Coastguard Worker			WARN("YIELD",
7153*d68f33bcSAndroid Build Coastguard Worker			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
7154*d68f33bcSAndroid Build Coastguard Worker		}
7155*d68f33bcSAndroid Build Coastguard Worker
7156*d68f33bcSAndroid Build Coastguard Worker# check for comparisons against true and false
7157*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7158*d68f33bcSAndroid Build Coastguard Worker			my $lead = $1;
7159*d68f33bcSAndroid Build Coastguard Worker			my $arg = $2;
7160*d68f33bcSAndroid Build Coastguard Worker			my $test = $3;
7161*d68f33bcSAndroid Build Coastguard Worker			my $otype = $4;
7162*d68f33bcSAndroid Build Coastguard Worker			my $trail = $5;
7163*d68f33bcSAndroid Build Coastguard Worker			my $op = "!";
7164*d68f33bcSAndroid Build Coastguard Worker
7165*d68f33bcSAndroid Build Coastguard Worker			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7166*d68f33bcSAndroid Build Coastguard Worker
7167*d68f33bcSAndroid Build Coastguard Worker			my $type = lc($otype);
7168*d68f33bcSAndroid Build Coastguard Worker			if ($type =~ /^(?:true|false)$/) {
7169*d68f33bcSAndroid Build Coastguard Worker				if (("$test" eq "==" && "$type" eq "true") ||
7170*d68f33bcSAndroid Build Coastguard Worker				    ("$test" eq "!=" && "$type" eq "false")) {
7171*d68f33bcSAndroid Build Coastguard Worker					$op = "";
7172*d68f33bcSAndroid Build Coastguard Worker				}
7173*d68f33bcSAndroid Build Coastguard Worker
7174*d68f33bcSAndroid Build Coastguard Worker				CHK("BOOL_COMPARISON",
7175*d68f33bcSAndroid Build Coastguard Worker				    "Using comparison to $otype is error prone\n" . $herecurr);
7176*d68f33bcSAndroid Build Coastguard Worker
7177*d68f33bcSAndroid Build Coastguard Worker## maybe suggesting a correct construct would better
7178*d68f33bcSAndroid Build Coastguard Worker##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7179*d68f33bcSAndroid Build Coastguard Worker
7180*d68f33bcSAndroid Build Coastguard Worker			}
7181*d68f33bcSAndroid Build Coastguard Worker		}
7182*d68f33bcSAndroid Build Coastguard Worker
7183*d68f33bcSAndroid Build Coastguard Worker# check for semaphores initialized locked
7184*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7185*d68f33bcSAndroid Build Coastguard Worker			WARN("CONSIDER_COMPLETION",
7186*d68f33bcSAndroid Build Coastguard Worker			     "consider using a completion\n" . $herecurr);
7187*d68f33bcSAndroid Build Coastguard Worker		}
7188*d68f33bcSAndroid Build Coastguard Worker
7189*d68f33bcSAndroid Build Coastguard Worker# recommend kstrto* over simple_strto* and strict_strto*
7190*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7191*d68f33bcSAndroid Build Coastguard Worker			WARN("CONSIDER_KSTRTO",
7192*d68f33bcSAndroid Build Coastguard Worker			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7193*d68f33bcSAndroid Build Coastguard Worker		}
7194*d68f33bcSAndroid Build Coastguard Worker
7195*d68f33bcSAndroid Build Coastguard Worker# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7196*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*__initcall\s*\(/) {
7197*d68f33bcSAndroid Build Coastguard Worker			WARN("USE_DEVICE_INITCALL",
7198*d68f33bcSAndroid Build Coastguard Worker			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7199*d68f33bcSAndroid Build Coastguard Worker		}
7200*d68f33bcSAndroid Build Coastguard Worker
7201*d68f33bcSAndroid Build Coastguard Worker# check for spin_is_locked(), suggest lockdep instead
7202*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bspin_is_locked\(/) {
7203*d68f33bcSAndroid Build Coastguard Worker			WARN("USE_LOCKDEP",
7204*d68f33bcSAndroid Build Coastguard Worker			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
7205*d68f33bcSAndroid Build Coastguard Worker		}
7206*d68f33bcSAndroid Build Coastguard Worker
7207*d68f33bcSAndroid Build Coastguard Worker# check for deprecated apis
7208*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
7209*d68f33bcSAndroid Build Coastguard Worker			my $deprecated_api = $1;
7210*d68f33bcSAndroid Build Coastguard Worker			my $new_api = $deprecated_apis{$deprecated_api};
7211*d68f33bcSAndroid Build Coastguard Worker			WARN("DEPRECATED_API",
7212*d68f33bcSAndroid Build Coastguard Worker			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
7213*d68f33bcSAndroid Build Coastguard Worker		}
7214*d68f33bcSAndroid Build Coastguard Worker
7215*d68f33bcSAndroid Build Coastguard Worker# check for various structs that are normally const (ops, kgdb, device_tree)
7216*d68f33bcSAndroid Build Coastguard Worker# and avoid what seem like struct definitions 'struct foo {'
7217*d68f33bcSAndroid Build Coastguard Worker		if (defined($const_structs) &&
7218*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\bconst\b/ &&
7219*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7220*d68f33bcSAndroid Build Coastguard Worker			WARN("CONST_STRUCT",
7221*d68f33bcSAndroid Build Coastguard Worker			     "struct $1 should normally be const\n" . $herecurr);
7222*d68f33bcSAndroid Build Coastguard Worker		}
7223*d68f33bcSAndroid Build Coastguard Worker
7224*d68f33bcSAndroid Build Coastguard Worker# use of NR_CPUS is usually wrong
7225*d68f33bcSAndroid Build Coastguard Worker# ignore definitions of NR_CPUS and usage to define arrays as likely right
7226*d68f33bcSAndroid Build Coastguard Worker# ignore designated initializers using NR_CPUS
7227*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bNR_CPUS\b/ &&
7228*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7229*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7230*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7231*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
7232*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
7233*d68f33bcSAndroid Build Coastguard Worker		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7234*d68f33bcSAndroid Build Coastguard Worker		{
7235*d68f33bcSAndroid Build Coastguard Worker			WARN("NR_CPUS",
7236*d68f33bcSAndroid Build Coastguard Worker			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7237*d68f33bcSAndroid Build Coastguard Worker		}
7238*d68f33bcSAndroid Build Coastguard Worker
7239*d68f33bcSAndroid Build Coastguard Worker# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
7240*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
7241*d68f33bcSAndroid Build Coastguard Worker			ERROR("DEFINE_ARCH_HAS",
7242*d68f33bcSAndroid Build Coastguard Worker			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
7243*d68f33bcSAndroid Build Coastguard Worker		}
7244*d68f33bcSAndroid Build Coastguard Worker
7245*d68f33bcSAndroid Build Coastguard Worker# likely/unlikely comparisons similar to "(likely(foo) > 0)"
7246*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7247*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7248*d68f33bcSAndroid Build Coastguard Worker			WARN("LIKELY_MISUSE",
7249*d68f33bcSAndroid Build Coastguard Worker			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7250*d68f33bcSAndroid Build Coastguard Worker		}
7251*d68f33bcSAndroid Build Coastguard Worker
7252*d68f33bcSAndroid Build Coastguard Worker# return sysfs_emit(foo, fmt, ...) fmt without newline
7253*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7254*d68f33bcSAndroid Build Coastguard Worker		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7255*d68f33bcSAndroid Build Coastguard Worker			my $offset = $+[6] - 1;
7256*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SYSFS_EMIT",
7257*d68f33bcSAndroid Build Coastguard Worker				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7258*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7259*d68f33bcSAndroid Build Coastguard Worker				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7260*d68f33bcSAndroid Build Coastguard Worker			}
7261*d68f33bcSAndroid Build Coastguard Worker		}
7262*d68f33bcSAndroid Build Coastguard Worker
7263*d68f33bcSAndroid Build Coastguard Worker# nested likely/unlikely calls
7264*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7265*d68f33bcSAndroid Build Coastguard Worker			WARN("LIKELY_MISUSE",
7266*d68f33bcSAndroid Build Coastguard Worker			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7267*d68f33bcSAndroid Build Coastguard Worker		}
7268*d68f33bcSAndroid Build Coastguard Worker
7269*d68f33bcSAndroid Build Coastguard Worker# whine mightly about in_atomic
7270*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bin_atomic\s*\(/) {
7271*d68f33bcSAndroid Build Coastguard Worker			if ($realfile =~ m@^drivers/@) {
7272*d68f33bcSAndroid Build Coastguard Worker				ERROR("IN_ATOMIC",
7273*d68f33bcSAndroid Build Coastguard Worker				      "do not use in_atomic in drivers\n" . $herecurr);
7274*d68f33bcSAndroid Build Coastguard Worker			} elsif ($realfile !~ m@^kernel/@) {
7275*d68f33bcSAndroid Build Coastguard Worker				WARN("IN_ATOMIC",
7276*d68f33bcSAndroid Build Coastguard Worker				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7277*d68f33bcSAndroid Build Coastguard Worker			}
7278*d68f33bcSAndroid Build Coastguard Worker		}
7279*d68f33bcSAndroid Build Coastguard Worker
7280*d68f33bcSAndroid Build Coastguard Worker# check for lockdep_set_novalidate_class
7281*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
7282*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
7283*d68f33bcSAndroid Build Coastguard Worker			if ($realfile !~ m@^kernel/lockdep@ &&
7284*d68f33bcSAndroid Build Coastguard Worker			    $realfile !~ m@^include/linux/lockdep@ &&
7285*d68f33bcSAndroid Build Coastguard Worker			    $realfile !~ m@^drivers/base/core@) {
7286*d68f33bcSAndroid Build Coastguard Worker				ERROR("LOCKDEP",
7287*d68f33bcSAndroid Build Coastguard Worker				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
7288*d68f33bcSAndroid Build Coastguard Worker			}
7289*d68f33bcSAndroid Build Coastguard Worker		}
7290*d68f33bcSAndroid Build Coastguard Worker
7291*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7292*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7293*d68f33bcSAndroid Build Coastguard Worker			WARN("EXPORTED_WORLD_WRITABLE",
7294*d68f33bcSAndroid Build Coastguard Worker			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
7295*d68f33bcSAndroid Build Coastguard Worker		}
7296*d68f33bcSAndroid Build Coastguard Worker
7297*d68f33bcSAndroid Build Coastguard Worker# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
7298*d68f33bcSAndroid Build Coastguard Worker# and whether or not function naming is typical and if
7299*d68f33bcSAndroid Build Coastguard Worker# DEVICE_ATTR permissions uses are unusual too
7300*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7301*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
7302*d68f33bcSAndroid Build Coastguard Worker		    $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*\)/) {
7303*d68f33bcSAndroid Build Coastguard Worker			my $var = $1;
7304*d68f33bcSAndroid Build Coastguard Worker			my $perms = $2;
7305*d68f33bcSAndroid Build Coastguard Worker			my $show = $3;
7306*d68f33bcSAndroid Build Coastguard Worker			my $store = $4;
7307*d68f33bcSAndroid Build Coastguard Worker			my $octal_perms = perms_to_octal($perms);
7308*d68f33bcSAndroid Build Coastguard Worker			if ($show =~ /^${var}_show$/ &&
7309*d68f33bcSAndroid Build Coastguard Worker			    $store =~ /^${var}_store$/ &&
7310*d68f33bcSAndroid Build Coastguard Worker			    $octal_perms eq "0644") {
7311*d68f33bcSAndroid Build Coastguard Worker				if (WARN("DEVICE_ATTR_RW",
7312*d68f33bcSAndroid Build Coastguard Worker					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
7313*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
7314*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
7315*d68f33bcSAndroid Build Coastguard Worker				}
7316*d68f33bcSAndroid Build Coastguard Worker			} elsif ($show =~ /^${var}_show$/ &&
7317*d68f33bcSAndroid Build Coastguard Worker				 $store =~ /^NULL$/ &&
7318*d68f33bcSAndroid Build Coastguard Worker				 $octal_perms eq "0444") {
7319*d68f33bcSAndroid Build Coastguard Worker				if (WARN("DEVICE_ATTR_RO",
7320*d68f33bcSAndroid Build Coastguard Worker					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
7321*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
7322*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
7323*d68f33bcSAndroid Build Coastguard Worker				}
7324*d68f33bcSAndroid Build Coastguard Worker			} elsif ($show =~ /^NULL$/ &&
7325*d68f33bcSAndroid Build Coastguard Worker				 $store =~ /^${var}_store$/ &&
7326*d68f33bcSAndroid Build Coastguard Worker				 $octal_perms eq "0200") {
7327*d68f33bcSAndroid Build Coastguard Worker				if (WARN("DEVICE_ATTR_WO",
7328*d68f33bcSAndroid Build Coastguard Worker					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
7329*d68f33bcSAndroid Build Coastguard Worker				    $fix) {
7330*d68f33bcSAndroid Build Coastguard Worker					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
7331*d68f33bcSAndroid Build Coastguard Worker				}
7332*d68f33bcSAndroid Build Coastguard Worker			} elsif ($octal_perms eq "0644" ||
7333*d68f33bcSAndroid Build Coastguard Worker				 $octal_perms eq "0444" ||
7334*d68f33bcSAndroid Build Coastguard Worker				 $octal_perms eq "0200") {
7335*d68f33bcSAndroid Build Coastguard Worker				my $newshow = "$show";
7336*d68f33bcSAndroid Build Coastguard Worker				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
7337*d68f33bcSAndroid Build Coastguard Worker				my $newstore = $store;
7338*d68f33bcSAndroid Build Coastguard Worker				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
7339*d68f33bcSAndroid Build Coastguard Worker				my $rename = "";
7340*d68f33bcSAndroid Build Coastguard Worker				if ($show ne $newshow) {
7341*d68f33bcSAndroid Build Coastguard Worker					$rename .= " '$show' to '$newshow'";
7342*d68f33bcSAndroid Build Coastguard Worker				}
7343*d68f33bcSAndroid Build Coastguard Worker				if ($store ne $newstore) {
7344*d68f33bcSAndroid Build Coastguard Worker					$rename .= " '$store' to '$newstore'";
7345*d68f33bcSAndroid Build Coastguard Worker				}
7346*d68f33bcSAndroid Build Coastguard Worker				WARN("DEVICE_ATTR_FUNCTIONS",
7347*d68f33bcSAndroid Build Coastguard Worker				     "Consider renaming function(s)$rename\n" . $herecurr);
7348*d68f33bcSAndroid Build Coastguard Worker			} else {
7349*d68f33bcSAndroid Build Coastguard Worker				WARN("DEVICE_ATTR_PERMS",
7350*d68f33bcSAndroid Build Coastguard Worker				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
7351*d68f33bcSAndroid Build Coastguard Worker			}
7352*d68f33bcSAndroid Build Coastguard Worker		}
7353*d68f33bcSAndroid Build Coastguard Worker
7354*d68f33bcSAndroid Build Coastguard Worker# Mode permission misuses where it seems decimal should be octal
7355*d68f33bcSAndroid Build Coastguard Worker# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
7356*d68f33bcSAndroid Build Coastguard Worker# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
7357*d68f33bcSAndroid Build Coastguard Worker#   specific definition of not visible in sysfs.
7358*d68f33bcSAndroid Build Coastguard Worker# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
7359*d68f33bcSAndroid Build Coastguard Worker#   use the default permissions
7360*d68f33bcSAndroid Build Coastguard Worker		if ($perl_version_ok &&
7361*d68f33bcSAndroid Build Coastguard Worker		    defined $stat &&
7362*d68f33bcSAndroid Build Coastguard Worker		    $line =~ /$mode_perms_search/) {
7363*d68f33bcSAndroid Build Coastguard Worker			foreach my $entry (@mode_permission_funcs) {
7364*d68f33bcSAndroid Build Coastguard Worker				my $func = $entry->[0];
7365*d68f33bcSAndroid Build Coastguard Worker				my $arg_pos = $entry->[1];
7366*d68f33bcSAndroid Build Coastguard Worker
7367*d68f33bcSAndroid Build Coastguard Worker				my $lc = $stat =~ tr@\n@@;
7368*d68f33bcSAndroid Build Coastguard Worker				$lc = $lc + $linenr;
7369*d68f33bcSAndroid Build Coastguard Worker				my $stat_real = get_stat_real($linenr, $lc);
7370*d68f33bcSAndroid Build Coastguard Worker
7371*d68f33bcSAndroid Build Coastguard Worker				my $skip_args = "";
7372*d68f33bcSAndroid Build Coastguard Worker				if ($arg_pos > 1) {
7373*d68f33bcSAndroid Build Coastguard Worker					$arg_pos--;
7374*d68f33bcSAndroid Build Coastguard Worker					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
7375*d68f33bcSAndroid Build Coastguard Worker				}
7376*d68f33bcSAndroid Build Coastguard Worker				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7377*d68f33bcSAndroid Build Coastguard Worker				if ($stat =~ /$test/) {
7378*d68f33bcSAndroid Build Coastguard Worker					my $val = $1;
7379*d68f33bcSAndroid Build Coastguard Worker					$val = $6 if ($skip_args ne "");
7380*d68f33bcSAndroid Build Coastguard Worker					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
7381*d68f33bcSAndroid Build Coastguard Worker					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
7382*d68f33bcSAndroid Build Coastguard Worker					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
7383*d68f33bcSAndroid Build Coastguard Worker						ERROR("NON_OCTAL_PERMISSIONS",
7384*d68f33bcSAndroid Build Coastguard Worker						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7385*d68f33bcSAndroid Build Coastguard Worker					}
7386*d68f33bcSAndroid Build Coastguard Worker					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7387*d68f33bcSAndroid Build Coastguard Worker						ERROR("EXPORTED_WORLD_WRITABLE",
7388*d68f33bcSAndroid Build Coastguard Worker						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
7389*d68f33bcSAndroid Build Coastguard Worker					}
7390*d68f33bcSAndroid Build Coastguard Worker				}
7391*d68f33bcSAndroid Build Coastguard Worker			}
7392*d68f33bcSAndroid Build Coastguard Worker		}
7393*d68f33bcSAndroid Build Coastguard Worker
7394*d68f33bcSAndroid Build Coastguard Worker# check for uses of S_<PERMS> that could be octal for readability
7395*d68f33bcSAndroid Build Coastguard Worker		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
7396*d68f33bcSAndroid Build Coastguard Worker			my $oval = $1;
7397*d68f33bcSAndroid Build Coastguard Worker			my $octal = perms_to_octal($oval);
7398*d68f33bcSAndroid Build Coastguard Worker			if (WARN("SYMBOLIC_PERMS",
7399*d68f33bcSAndroid Build Coastguard Worker				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7400*d68f33bcSAndroid Build Coastguard Worker			    $fix) {
7401*d68f33bcSAndroid Build Coastguard Worker				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
7402*d68f33bcSAndroid Build Coastguard Worker			}
7403*d68f33bcSAndroid Build Coastguard Worker		}
7404*d68f33bcSAndroid Build Coastguard Worker
7405*d68f33bcSAndroid Build Coastguard Worker# validate content of MODULE_LICENSE against list from include/linux/module.h
7406*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
7407*d68f33bcSAndroid Build Coastguard Worker			my $extracted_string = get_quoted_string($line, $rawline);
7408*d68f33bcSAndroid Build Coastguard Worker			my $valid_licenses = qr{
7409*d68f33bcSAndroid Build Coastguard Worker						GPL|
7410*d68f33bcSAndroid Build Coastguard Worker						GPL\ v2|
7411*d68f33bcSAndroid Build Coastguard Worker						GPL\ and\ additional\ rights|
7412*d68f33bcSAndroid Build Coastguard Worker						Dual\ BSD/GPL|
7413*d68f33bcSAndroid Build Coastguard Worker						Dual\ MIT/GPL|
7414*d68f33bcSAndroid Build Coastguard Worker						Dual\ MPL/GPL|
7415*d68f33bcSAndroid Build Coastguard Worker						Proprietary
7416*d68f33bcSAndroid Build Coastguard Worker					}x;
7417*d68f33bcSAndroid Build Coastguard Worker			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
7418*d68f33bcSAndroid Build Coastguard Worker				WARN("MODULE_LICENSE",
7419*d68f33bcSAndroid Build Coastguard Worker				     "unknown module license " . $extracted_string . "\n" . $herecurr);
7420*d68f33bcSAndroid Build Coastguard Worker			}
7421*d68f33bcSAndroid Build Coastguard Worker		}
7422*d68f33bcSAndroid Build Coastguard Worker
7423*d68f33bcSAndroid Build Coastguard Worker# check for sysctl duplicate constants
7424*d68f33bcSAndroid Build Coastguard Worker		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
7425*d68f33bcSAndroid Build Coastguard Worker			WARN("DUPLICATED_SYSCTL_CONST",
7426*d68f33bcSAndroid Build Coastguard Worker				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
7427*d68f33bcSAndroid Build Coastguard Worker		}
7428*d68f33bcSAndroid Build Coastguard Worker	}
7429*d68f33bcSAndroid Build Coastguard Worker
7430*d68f33bcSAndroid Build Coastguard Worker	# If we have no input at all, then there is nothing to report on
7431*d68f33bcSAndroid Build Coastguard Worker	# so just keep quiet.
7432*d68f33bcSAndroid Build Coastguard Worker	if ($#rawlines == -1) {
7433*d68f33bcSAndroid Build Coastguard Worker		exit(0);
7434*d68f33bcSAndroid Build Coastguard Worker	}
7435*d68f33bcSAndroid Build Coastguard Worker
7436*d68f33bcSAndroid Build Coastguard Worker	# In mailback mode only produce a report in the negative, for
7437*d68f33bcSAndroid Build Coastguard Worker	# things that appear to be patches.
7438*d68f33bcSAndroid Build Coastguard Worker	if ($mailback && ($clean == 1 || !$is_patch)) {
7439*d68f33bcSAndroid Build Coastguard Worker		exit(0);
7440*d68f33bcSAndroid Build Coastguard Worker	}
7441*d68f33bcSAndroid Build Coastguard Worker
7442*d68f33bcSAndroid Build Coastguard Worker	# This is not a patch, and we are in 'no-patch' mode so
7443*d68f33bcSAndroid Build Coastguard Worker	# just keep quiet.
7444*d68f33bcSAndroid Build Coastguard Worker	if (!$chk_patch && !$is_patch) {
7445*d68f33bcSAndroid Build Coastguard Worker		exit(0);
7446*d68f33bcSAndroid Build Coastguard Worker	}
7447*d68f33bcSAndroid Build Coastguard Worker
7448*d68f33bcSAndroid Build Coastguard Worker	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7449*d68f33bcSAndroid Build Coastguard Worker		ERROR("NOT_UNIFIED_DIFF",
7450*d68f33bcSAndroid Build Coastguard Worker		      "Does not appear to be a unified-diff format patch\n");
7451*d68f33bcSAndroid Build Coastguard Worker	}
7452*d68f33bcSAndroid Build Coastguard Worker	if ($is_patch && $has_commit_log && $chk_signoff) {
7453*d68f33bcSAndroid Build Coastguard Worker		if ($signoff == 0) {
7454*d68f33bcSAndroid Build Coastguard Worker			ERROR("MISSING_SIGN_OFF",
7455*d68f33bcSAndroid Build Coastguard Worker			      "Missing Signed-off-by: line(s)\n");
7456*d68f33bcSAndroid Build Coastguard Worker		} elsif ($authorsignoff != 1) {
7457*d68f33bcSAndroid Build Coastguard Worker			# authorsignoff values:
7458*d68f33bcSAndroid Build Coastguard Worker			# 0 -> missing sign off
7459*d68f33bcSAndroid Build Coastguard Worker			# 1 -> sign off identical
7460*d68f33bcSAndroid Build Coastguard Worker			# 2 -> names and addresses match, comments mismatch
7461*d68f33bcSAndroid Build Coastguard Worker			# 3 -> addresses match, names different
7462*d68f33bcSAndroid Build Coastguard Worker			# 4 -> names match, addresses different
7463*d68f33bcSAndroid Build Coastguard Worker			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
7464*d68f33bcSAndroid Build Coastguard Worker
7465*d68f33bcSAndroid Build Coastguard Worker			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
7466*d68f33bcSAndroid Build Coastguard Worker
7467*d68f33bcSAndroid Build Coastguard Worker			if ($authorsignoff == 0) {
7468*d68f33bcSAndroid Build Coastguard Worker				ERROR("NO_AUTHOR_SIGN_OFF",
7469*d68f33bcSAndroid Build Coastguard Worker				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
7470*d68f33bcSAndroid Build Coastguard Worker			} elsif ($authorsignoff == 2) {
7471*d68f33bcSAndroid Build Coastguard Worker				CHK("FROM_SIGN_OFF_MISMATCH",
7472*d68f33bcSAndroid Build Coastguard Worker				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
7473*d68f33bcSAndroid Build Coastguard Worker			} elsif ($authorsignoff == 3) {
7474*d68f33bcSAndroid Build Coastguard Worker				WARN("FROM_SIGN_OFF_MISMATCH",
7475*d68f33bcSAndroid Build Coastguard Worker				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
7476*d68f33bcSAndroid Build Coastguard Worker			} elsif ($authorsignoff == 4) {
7477*d68f33bcSAndroid Build Coastguard Worker				WARN("FROM_SIGN_OFF_MISMATCH",
7478*d68f33bcSAndroid Build Coastguard Worker				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
7479*d68f33bcSAndroid Build Coastguard Worker			} elsif ($authorsignoff == 5) {
7480*d68f33bcSAndroid Build Coastguard Worker				WARN("FROM_SIGN_OFF_MISMATCH",
7481*d68f33bcSAndroid Build Coastguard Worker				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
7482*d68f33bcSAndroid Build Coastguard Worker			}
7483*d68f33bcSAndroid Build Coastguard Worker		}
7484*d68f33bcSAndroid Build Coastguard Worker	}
7485*d68f33bcSAndroid Build Coastguard Worker
7486*d68f33bcSAndroid Build Coastguard Worker	print report_dump();
7487*d68f33bcSAndroid Build Coastguard Worker	if ($summary && !($clean == 1 && $quiet == 1)) {
7488*d68f33bcSAndroid Build Coastguard Worker		print "$filename " if ($summary_file);
7489*d68f33bcSAndroid Build Coastguard Worker		print "total: $cnt_error errors, $cnt_warn warnings, " .
7490*d68f33bcSAndroid Build Coastguard Worker			(($check)? "$cnt_chk checks, " : "") .
7491*d68f33bcSAndroid Build Coastguard Worker			"$cnt_lines lines checked\n";
7492*d68f33bcSAndroid Build Coastguard Worker	}
7493*d68f33bcSAndroid Build Coastguard Worker
7494*d68f33bcSAndroid Build Coastguard Worker	if ($quiet == 0) {
7495*d68f33bcSAndroid Build Coastguard Worker		# If there were any defects found and not already fixing them
7496*d68f33bcSAndroid Build Coastguard Worker		if (!$clean and !$fix) {
7497*d68f33bcSAndroid Build Coastguard Worker			print << "EOM"
7498*d68f33bcSAndroid Build Coastguard Worker
7499*d68f33bcSAndroid Build Coastguard WorkerNOTE: For some of the reported defects, checkpatch may be able to
7500*d68f33bcSAndroid Build Coastguard Worker      mechanically convert to the typical style using --fix or --fix-inplace.
7501*d68f33bcSAndroid Build Coastguard WorkerEOM
7502*d68f33bcSAndroid Build Coastguard Worker		}
7503*d68f33bcSAndroid Build Coastguard Worker		# If there were whitespace errors which cleanpatch can fix
7504*d68f33bcSAndroid Build Coastguard Worker		# then suggest that.
7505*d68f33bcSAndroid Build Coastguard Worker		if ($rpt_cleaners) {
7506*d68f33bcSAndroid Build Coastguard Worker			$rpt_cleaners = 0;
7507*d68f33bcSAndroid Build Coastguard Worker			print << "EOM"
7508*d68f33bcSAndroid Build Coastguard Worker
7509*d68f33bcSAndroid Build Coastguard WorkerNOTE: Whitespace errors detected.
7510*d68f33bcSAndroid Build Coastguard Worker      You may wish to use scripts/cleanpatch or scripts/cleanfile
7511*d68f33bcSAndroid Build Coastguard WorkerEOM
7512*d68f33bcSAndroid Build Coastguard Worker		}
7513*d68f33bcSAndroid Build Coastguard Worker	}
7514*d68f33bcSAndroid Build Coastguard Worker
7515*d68f33bcSAndroid Build Coastguard Worker	if ($clean == 0 && $fix &&
7516*d68f33bcSAndroid Build Coastguard Worker	    ("@rawlines" ne "@fixed" ||
7517*d68f33bcSAndroid Build Coastguard Worker	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
7518*d68f33bcSAndroid Build Coastguard Worker		my $newfile = $filename;
7519*d68f33bcSAndroid Build Coastguard Worker		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
7520*d68f33bcSAndroid Build Coastguard Worker		my $linecount = 0;
7521*d68f33bcSAndroid Build Coastguard Worker		my $f;
7522*d68f33bcSAndroid Build Coastguard Worker
7523*d68f33bcSAndroid Build Coastguard Worker		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7524*d68f33bcSAndroid Build Coastguard Worker
7525*d68f33bcSAndroid Build Coastguard Worker		open($f, '>', $newfile)
7526*d68f33bcSAndroid Build Coastguard Worker		    or die "$P: Can't open $newfile for write\n";
7527*d68f33bcSAndroid Build Coastguard Worker		foreach my $fixed_line (@fixed) {
7528*d68f33bcSAndroid Build Coastguard Worker			$linecount++;
7529*d68f33bcSAndroid Build Coastguard Worker			if ($file) {
7530*d68f33bcSAndroid Build Coastguard Worker				if ($linecount > 3) {
7531*d68f33bcSAndroid Build Coastguard Worker					$fixed_line =~ s/^\+//;
7532*d68f33bcSAndroid Build Coastguard Worker					print $f $fixed_line . "\n";
7533*d68f33bcSAndroid Build Coastguard Worker				}
7534*d68f33bcSAndroid Build Coastguard Worker			} else {
7535*d68f33bcSAndroid Build Coastguard Worker				print $f $fixed_line . "\n";
7536*d68f33bcSAndroid Build Coastguard Worker			}
7537*d68f33bcSAndroid Build Coastguard Worker		}
7538*d68f33bcSAndroid Build Coastguard Worker		close($f);
7539*d68f33bcSAndroid Build Coastguard Worker
7540*d68f33bcSAndroid Build Coastguard Worker		if (!$quiet) {
7541*d68f33bcSAndroid Build Coastguard Worker			print << "EOM";
7542*d68f33bcSAndroid Build Coastguard Worker
7543*d68f33bcSAndroid Build Coastguard WorkerWrote EXPERIMENTAL --fix correction(s) to '$newfile'
7544*d68f33bcSAndroid Build Coastguard Worker
7545*d68f33bcSAndroid Build Coastguard WorkerDo _NOT_ trust the results written to this file.
7546*d68f33bcSAndroid Build Coastguard WorkerDo _NOT_ submit these changes without inspecting them for correctness.
7547*d68f33bcSAndroid Build Coastguard Worker
7548*d68f33bcSAndroid Build Coastguard WorkerThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
7549*d68f33bcSAndroid Build Coastguard WorkerNo warranties, expressed or implied...
7550*d68f33bcSAndroid Build Coastguard WorkerEOM
7551*d68f33bcSAndroid Build Coastguard Worker		}
7552*d68f33bcSAndroid Build Coastguard Worker	}
7553*d68f33bcSAndroid Build Coastguard Worker
7554*d68f33bcSAndroid Build Coastguard Worker	if ($quiet == 0) {
7555*d68f33bcSAndroid Build Coastguard Worker		print "\n";
7556*d68f33bcSAndroid Build Coastguard Worker		if ($clean == 1) {
7557*d68f33bcSAndroid Build Coastguard Worker			print "$vname has no obvious style problems and is ready for submission.\n";
7558*d68f33bcSAndroid Build Coastguard Worker		} else {
7559*d68f33bcSAndroid Build Coastguard Worker			print "$vname has style problems, please review.\n";
7560*d68f33bcSAndroid Build Coastguard Worker		}
7561*d68f33bcSAndroid Build Coastguard Worker	}
7562*d68f33bcSAndroid Build Coastguard Worker	return $clean;
7563*d68f33bcSAndroid Build Coastguard Worker}
7564