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