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