17551eb4fSHeinrich Schuchardt#!/usr/bin/env perl 2dd88ab32SMasahiro Yamada# (c) 2001, Dave Jones. (the file handling bit) 3dd88ab32SMasahiro Yamada# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 4dd88ab32SMasahiro Yamada# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 5dd88ab32SMasahiro Yamada# (c) 2008-2010 Andy Whitcroft <apw@canonical.com> 6dd88ab32SMasahiro Yamada# Licensed under the terms of the GNU GPL License version 2 7dd88ab32SMasahiro Yamada 8dd88ab32SMasahiro Yamadause strict; 97551eb4fSHeinrich Schuchardtuse warnings; 106b9709d9STom Riniuse POSIX; 11c10e0f5bSDan Murphyuse File::Basename; 12c10e0f5bSDan Murphyuse Cwd 'abs_path'; 137551eb4fSHeinrich Schuchardtuse Term::ANSIColor qw(:constants); 14dd88ab32SMasahiro Yamada 15dd88ab32SMasahiro Yamadamy $P = $0; 16c10e0f5bSDan Murphymy $D = dirname(abs_path($P)); 17dd88ab32SMasahiro Yamada 18dd88ab32SMasahiro Yamadamy $V = '0.32'; 19dd88ab32SMasahiro Yamada 20dd88ab32SMasahiro Yamadause Getopt::Long qw(:config no_auto_abbrev); 21dd88ab32SMasahiro Yamada 22dd88ab32SMasahiro Yamadamy $quiet = 0; 23dd88ab32SMasahiro Yamadamy $tree = 1; 24dd88ab32SMasahiro Yamadamy $chk_signoff = 1; 25dd88ab32SMasahiro Yamadamy $chk_patch = 1; 26dd88ab32SMasahiro Yamadamy $tst_only; 27dd88ab32SMasahiro Yamadamy $emacs = 0; 28dd88ab32SMasahiro Yamadamy $terse = 0; 297551eb4fSHeinrich Schuchardtmy $showfile = 0; 30dd88ab32SMasahiro Yamadamy $file = 0; 317551eb4fSHeinrich Schuchardtmy $git = 0; 327551eb4fSHeinrich Schuchardtmy %git_commits = (); 33dd88ab32SMasahiro Yamadamy $check = 0; 347551eb4fSHeinrich Schuchardtmy $check_orig = 0; 35dd88ab32SMasahiro Yamadamy $summary = 1; 36dd88ab32SMasahiro Yamadamy $mailback = 0; 37dd88ab32SMasahiro Yamadamy $summary_file = 0; 38dd88ab32SMasahiro Yamadamy $show_types = 0; 397551eb4fSHeinrich Schuchardtmy $list_types = 0; 406b9709d9STom Rinimy $fix = 0; 416b9709d9STom Rinimy $fix_inplace = 0; 42dd88ab32SMasahiro Yamadamy $root; 43dd88ab32SMasahiro Yamadamy %debug; 446b9709d9STom Rinimy %camelcase = (); 456b9709d9STom Rinimy %use_type = (); 466b9709d9STom Rinimy @use = (); 47dd88ab32SMasahiro Yamadamy %ignore_type = (); 48dd88ab32SMasahiro Yamadamy @ignore = (); 49dd88ab32SMasahiro Yamadamy $help = 0; 50dd88ab32SMasahiro Yamadamy $configuration_file = ".checkpatch.conf"; 51dd88ab32SMasahiro Yamadamy $max_line_length = 80; 526b9709d9STom Rinimy $ignore_perl_version = 0; 536b9709d9STom Rinimy $minimum_perl_version = 5.10.0; 547551eb4fSHeinrich Schuchardtmy $min_conf_desc_length = 4; 55c10e0f5bSDan Murphymy $spelling_file = "$D/spelling.txt"; 56c10e0f5bSDan Murphymy $codespell = 0; 57c10e0f5bSDan Murphymy $codespellfile = "/usr/share/codespell/dictionary.txt"; 587551eb4fSHeinrich Schuchardtmy $conststructsfile = "$D/const_structs.checkpatch"; 597551eb4fSHeinrich Schuchardtmy $typedefsfile = ""; 607551eb4fSHeinrich Schuchardtmy $color = "auto"; 617551eb4fSHeinrich Schuchardtmy $allow_c99_comments = 1; 62dd88ab32SMasahiro Yamada 63dd88ab32SMasahiro Yamadasub help { 64dd88ab32SMasahiro Yamada my ($exitcode) = @_; 65dd88ab32SMasahiro Yamada 66dd88ab32SMasahiro Yamada print << "EOM"; 67dd88ab32SMasahiro YamadaUsage: $P [OPTION]... [FILE]... 68dd88ab32SMasahiro YamadaVersion: $V 69dd88ab32SMasahiro Yamada 70dd88ab32SMasahiro YamadaOptions: 71dd88ab32SMasahiro Yamada -q, --quiet quiet 72dd88ab32SMasahiro Yamada --no-tree run without a kernel tree 73dd88ab32SMasahiro Yamada --no-signoff do not check for 'Signed-off-by' line 74dd88ab32SMasahiro Yamada --patch treat FILE as patchfile (default) 75dd88ab32SMasahiro Yamada --emacs emacs compile window format 76dd88ab32SMasahiro Yamada --terse one line per report 777551eb4fSHeinrich Schuchardt --showfile emit diffed file position, not input file position 787551eb4fSHeinrich Schuchardt -g, --git treat FILE as a single commit or git revision range 797551eb4fSHeinrich Schuchardt single git commit with: 807551eb4fSHeinrich Schuchardt <rev> 817551eb4fSHeinrich Schuchardt <rev>^ 827551eb4fSHeinrich Schuchardt <rev>~n 837551eb4fSHeinrich Schuchardt multiple git commits with: 847551eb4fSHeinrich Schuchardt <rev1>..<rev2> 857551eb4fSHeinrich Schuchardt <rev1>...<rev2> 867551eb4fSHeinrich Schuchardt <rev>-<count> 877551eb4fSHeinrich Schuchardt git merges are ignored 88dd88ab32SMasahiro Yamada -f, --file treat FILE as regular source file 89dd88ab32SMasahiro Yamada --subjective, --strict enable more subjective tests 907551eb4fSHeinrich Schuchardt --list-types list the possible message types 916b9709d9STom Rini --types TYPE(,TYPE2...) show only these comma separated message types 92dd88ab32SMasahiro Yamada --ignore TYPE(,TYPE2...) ignore various comma separated message types 937551eb4fSHeinrich Schuchardt --show-types show the specific message type in the output 94dd88ab32SMasahiro Yamada --max-line-length=n set the maximum line length, if exceeded, warn 957551eb4fSHeinrich Schuchardt --min-conf-desc-length=n set the min description length, if shorter, warn 96dd88ab32SMasahiro Yamada --root=PATH PATH to the kernel tree root 97dd88ab32SMasahiro Yamada --no-summary suppress the per-file summary 98dd88ab32SMasahiro Yamada --mailback only produce a report in case of warnings/errors 99dd88ab32SMasahiro Yamada --summary-file include the filename in summary 100dd88ab32SMasahiro Yamada --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 101dd88ab32SMasahiro Yamada 'values', 'possible', 'type', and 'attr' (default 102dd88ab32SMasahiro Yamada is all off) 103dd88ab32SMasahiro Yamada --test-only=WORD report only warnings/errors containing WORD 104dd88ab32SMasahiro Yamada literally 1056b9709d9STom Rini --fix EXPERIMENTAL - may create horrible results 1066b9709d9STom Rini If correctable single-line errors exist, create 1076b9709d9STom Rini "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1086b9709d9STom Rini with potential errors corrected to the preferred 1096b9709d9STom Rini checkpatch style 1106b9709d9STom Rini --fix-inplace EXPERIMENTAL - may create horrible results 1116b9709d9STom Rini Is the same as --fix, but overwrites the input 1126b9709d9STom Rini file. It's your fault if there's no backup or git 1136b9709d9STom Rini --ignore-perl-version override checking of perl version. expect 1146b9709d9STom Rini runtime errors. 115c10e0f5bSDan Murphy --codespell Use the codespell dictionary for spelling/typos 1167551eb4fSHeinrich Schuchardt (default:/usr/share/codespell/dictionary.txt) 117c10e0f5bSDan Murphy --codespellfile Use this codespell dictionary 1187551eb4fSHeinrich Schuchardt --typedefsfile Read additional types from this file 1197551eb4fSHeinrich Schuchardt --color[=WHEN] Use colors 'always', 'never', or only when output 1207551eb4fSHeinrich Schuchardt is a terminal ('auto'). Default is 'auto'. 121dd88ab32SMasahiro Yamada -h, --help, --version display this help and exit 122dd88ab32SMasahiro Yamada 123dd88ab32SMasahiro YamadaWhen FILE is - read standard input. 124dd88ab32SMasahiro YamadaEOM 125dd88ab32SMasahiro Yamada 126dd88ab32SMasahiro Yamada exit($exitcode); 127dd88ab32SMasahiro Yamada} 128dd88ab32SMasahiro Yamada 1297551eb4fSHeinrich Schuchardtsub uniq { 1307551eb4fSHeinrich Schuchardt my %seen; 1317551eb4fSHeinrich Schuchardt return grep { !$seen{$_}++ } @_; 1327551eb4fSHeinrich Schuchardt} 1337551eb4fSHeinrich Schuchardt 1347551eb4fSHeinrich Schuchardtsub list_types { 1357551eb4fSHeinrich Schuchardt my ($exitcode) = @_; 1367551eb4fSHeinrich Schuchardt 1377551eb4fSHeinrich Schuchardt my $count = 0; 1387551eb4fSHeinrich Schuchardt 1397551eb4fSHeinrich Schuchardt local $/ = undef; 1407551eb4fSHeinrich Schuchardt 1417551eb4fSHeinrich Schuchardt open(my $script, '<', abs_path($P)) or 1427551eb4fSHeinrich Schuchardt die "$P: Can't read '$P' $!\n"; 1437551eb4fSHeinrich Schuchardt 1447551eb4fSHeinrich Schuchardt my $text = <$script>; 1457551eb4fSHeinrich Schuchardt close($script); 1467551eb4fSHeinrich Schuchardt 1477551eb4fSHeinrich Schuchardt my @types = (); 1487551eb4fSHeinrich Schuchardt for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { 1497551eb4fSHeinrich Schuchardt push (@types, $_); 1507551eb4fSHeinrich Schuchardt } 1517551eb4fSHeinrich Schuchardt @types = sort(uniq(@types)); 1527551eb4fSHeinrich Schuchardt print("#\tMessage type\n\n"); 1537551eb4fSHeinrich Schuchardt foreach my $type (@types) { 1547551eb4fSHeinrich Schuchardt print(++$count . "\t" . $type . "\n"); 1557551eb4fSHeinrich Schuchardt } 1567551eb4fSHeinrich Schuchardt 1577551eb4fSHeinrich Schuchardt exit($exitcode); 1587551eb4fSHeinrich Schuchardt} 1597551eb4fSHeinrich Schuchardt 160dd88ab32SMasahiro Yamadamy $conf = which_conf($configuration_file); 161dd88ab32SMasahiro Yamadaif (-f $conf) { 162dd88ab32SMasahiro Yamada my @conf_args; 163dd88ab32SMasahiro Yamada open(my $conffile, '<', "$conf") 164dd88ab32SMasahiro Yamada or warn "$P: Can't find a readable $configuration_file file $!\n"; 165dd88ab32SMasahiro Yamada 166dd88ab32SMasahiro Yamada while (<$conffile>) { 167dd88ab32SMasahiro Yamada my $line = $_; 168dd88ab32SMasahiro Yamada 169dd88ab32SMasahiro Yamada $line =~ s/\s*\n?$//g; 170dd88ab32SMasahiro Yamada $line =~ s/^\s*//g; 171dd88ab32SMasahiro Yamada $line =~ s/\s+/ /g; 172dd88ab32SMasahiro Yamada 173dd88ab32SMasahiro Yamada next if ($line =~ m/^\s*#/); 174dd88ab32SMasahiro Yamada next if ($line =~ m/^\s*$/); 175dd88ab32SMasahiro Yamada 176dd88ab32SMasahiro Yamada my @words = split(" ", $line); 177dd88ab32SMasahiro Yamada foreach my $word (@words) { 178dd88ab32SMasahiro Yamada last if ($word =~ m/^#/); 179dd88ab32SMasahiro Yamada push (@conf_args, $word); 180dd88ab32SMasahiro Yamada } 181dd88ab32SMasahiro Yamada } 182dd88ab32SMasahiro Yamada close($conffile); 183dd88ab32SMasahiro Yamada unshift(@ARGV, @conf_args) if @conf_args; 184dd88ab32SMasahiro Yamada} 185dd88ab32SMasahiro Yamada 1867551eb4fSHeinrich Schuchardt# Perl's Getopt::Long allows options to take optional arguments after a space. 1877551eb4fSHeinrich Schuchardt# Prevent --color by itself from consuming other arguments 1887551eb4fSHeinrich Schuchardtforeach (@ARGV) { 1897551eb4fSHeinrich Schuchardt if ($_ eq "--color" || $_ eq "-color") { 1907551eb4fSHeinrich Schuchardt $_ = "--color=$color"; 1917551eb4fSHeinrich Schuchardt } 1927551eb4fSHeinrich Schuchardt} 1937551eb4fSHeinrich Schuchardt 194dd88ab32SMasahiro YamadaGetOptions( 195dd88ab32SMasahiro Yamada 'q|quiet+' => \$quiet, 196dd88ab32SMasahiro Yamada 'tree!' => \$tree, 197dd88ab32SMasahiro Yamada 'signoff!' => \$chk_signoff, 198dd88ab32SMasahiro Yamada 'patch!' => \$chk_patch, 199dd88ab32SMasahiro Yamada 'emacs!' => \$emacs, 200dd88ab32SMasahiro Yamada 'terse!' => \$terse, 2017551eb4fSHeinrich Schuchardt 'showfile!' => \$showfile, 202dd88ab32SMasahiro Yamada 'f|file!' => \$file, 2037551eb4fSHeinrich Schuchardt 'g|git!' => \$git, 204dd88ab32SMasahiro Yamada 'subjective!' => \$check, 205dd88ab32SMasahiro Yamada 'strict!' => \$check, 206dd88ab32SMasahiro Yamada 'ignore=s' => \@ignore, 2076b9709d9STom Rini 'types=s' => \@use, 208dd88ab32SMasahiro Yamada 'show-types!' => \$show_types, 2097551eb4fSHeinrich Schuchardt 'list-types!' => \$list_types, 210dd88ab32SMasahiro Yamada 'max-line-length=i' => \$max_line_length, 2117551eb4fSHeinrich Schuchardt 'min-conf-desc-length=i' => \$min_conf_desc_length, 212dd88ab32SMasahiro Yamada 'root=s' => \$root, 213dd88ab32SMasahiro Yamada 'summary!' => \$summary, 214dd88ab32SMasahiro Yamada 'mailback!' => \$mailback, 215dd88ab32SMasahiro Yamada 'summary-file!' => \$summary_file, 2166b9709d9STom Rini 'fix!' => \$fix, 2176b9709d9STom Rini 'fix-inplace!' => \$fix_inplace, 2186b9709d9STom Rini 'ignore-perl-version!' => \$ignore_perl_version, 219dd88ab32SMasahiro Yamada 'debug=s' => \%debug, 220dd88ab32SMasahiro Yamada 'test-only=s' => \$tst_only, 221c10e0f5bSDan Murphy 'codespell!' => \$codespell, 222c10e0f5bSDan Murphy 'codespellfile=s' => \$codespellfile, 2237551eb4fSHeinrich Schuchardt 'typedefsfile=s' => \$typedefsfile, 2247551eb4fSHeinrich Schuchardt 'color=s' => \$color, 2257551eb4fSHeinrich Schuchardt 'no-color' => \$color, #keep old behaviors of -nocolor 2267551eb4fSHeinrich Schuchardt 'nocolor' => \$color, #keep old behaviors of -nocolor 227dd88ab32SMasahiro Yamada 'h|help' => \$help, 228dd88ab32SMasahiro Yamada 'version' => \$help 229dd88ab32SMasahiro Yamada) or help(1); 230dd88ab32SMasahiro Yamada 231dd88ab32SMasahiro Yamadahelp(0) if ($help); 232dd88ab32SMasahiro Yamada 2337551eb4fSHeinrich Schuchardtlist_types(0) if ($list_types); 2347551eb4fSHeinrich Schuchardt 2356b9709d9STom Rini$fix = 1 if ($fix_inplace); 2367551eb4fSHeinrich Schuchardt$check_orig = $check; 2376b9709d9STom Rini 238dd88ab32SMasahiro Yamadamy $exit = 0; 239dd88ab32SMasahiro Yamada 2406b9709d9STom Riniif ($^V && $^V lt $minimum_perl_version) { 2416b9709d9STom Rini printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 2426b9709d9STom Rini if (!$ignore_perl_version) { 2436b9709d9STom Rini exit(1); 2446b9709d9STom Rini } 2456b9709d9STom Rini} 2466b9709d9STom Rini 2477551eb4fSHeinrich Schuchardt#if no filenames are given, push '-' to read patch from stdin 248dd88ab32SMasahiro Yamadaif ($#ARGV < 0) { 2497551eb4fSHeinrich Schuchardt push(@ARGV, '-'); 2507551eb4fSHeinrich Schuchardt} 2517551eb4fSHeinrich Schuchardt 2527551eb4fSHeinrich Schuchardtif ($color =~ /^[01]$/) { 2537551eb4fSHeinrich Schuchardt $color = !$color; 2547551eb4fSHeinrich Schuchardt} elsif ($color =~ /^always$/i) { 2557551eb4fSHeinrich Schuchardt $color = 1; 2567551eb4fSHeinrich Schuchardt} elsif ($color =~ /^never$/i) { 2577551eb4fSHeinrich Schuchardt $color = 0; 2587551eb4fSHeinrich Schuchardt} elsif ($color =~ /^auto$/i) { 2597551eb4fSHeinrich Schuchardt $color = (-t STDOUT); 2607551eb4fSHeinrich Schuchardt} else { 2617551eb4fSHeinrich Schuchardt die "Invalid color mode: $color\n"; 262dd88ab32SMasahiro Yamada} 263dd88ab32SMasahiro Yamada 2646b9709d9STom Rinisub hash_save_array_words { 2656b9709d9STom Rini my ($hashRef, $arrayRef) = @_; 2666b9709d9STom Rini 2676b9709d9STom Rini my @array = split(/,/, join(',', @$arrayRef)); 2686b9709d9STom Rini foreach my $word (@array) { 269dd88ab32SMasahiro Yamada $word =~ s/\s*\n?$//g; 270dd88ab32SMasahiro Yamada $word =~ s/^\s*//g; 271dd88ab32SMasahiro Yamada $word =~ s/\s+/ /g; 272dd88ab32SMasahiro Yamada $word =~ tr/[a-z]/[A-Z]/; 273dd88ab32SMasahiro Yamada 274dd88ab32SMasahiro Yamada next if ($word =~ m/^\s*#/); 275dd88ab32SMasahiro Yamada next if ($word =~ m/^\s*$/); 276dd88ab32SMasahiro Yamada 2776b9709d9STom Rini $hashRef->{$word}++; 278dd88ab32SMasahiro Yamada } 2796b9709d9STom Rini} 2806b9709d9STom Rini 2816b9709d9STom Rinisub hash_show_words { 2826b9709d9STom Rini my ($hashRef, $prefix) = @_; 2836b9709d9STom Rini 2847551eb4fSHeinrich Schuchardt if (keys %$hashRef) { 2857551eb4fSHeinrich Schuchardt print "\nNOTE: $prefix message types:"; 2866b9709d9STom Rini foreach my $word (sort keys %$hashRef) { 2876b9709d9STom Rini print " $word"; 2886b9709d9STom Rini } 2897551eb4fSHeinrich Schuchardt print "\n"; 2906b9709d9STom Rini } 2916b9709d9STom Rini} 2926b9709d9STom Rini 2936b9709d9STom Rinihash_save_array_words(\%ignore_type, \@ignore); 2946b9709d9STom Rinihash_save_array_words(\%use_type, \@use); 295dd88ab32SMasahiro Yamada 296dd88ab32SMasahiro Yamadamy $dbg_values = 0; 297dd88ab32SMasahiro Yamadamy $dbg_possible = 0; 298dd88ab32SMasahiro Yamadamy $dbg_type = 0; 299dd88ab32SMasahiro Yamadamy $dbg_attr = 0; 300dd88ab32SMasahiro Yamadafor my $key (keys %debug) { 301dd88ab32SMasahiro Yamada ## no critic 302dd88ab32SMasahiro Yamada eval "\${dbg_$key} = '$debug{$key}';"; 303dd88ab32SMasahiro Yamada die "$@" if ($@); 304dd88ab32SMasahiro Yamada} 305dd88ab32SMasahiro Yamada 306dd88ab32SMasahiro Yamadamy $rpt_cleaners = 0; 307dd88ab32SMasahiro Yamada 308dd88ab32SMasahiro Yamadaif ($terse) { 309dd88ab32SMasahiro Yamada $emacs = 1; 310dd88ab32SMasahiro Yamada $quiet++; 311dd88ab32SMasahiro Yamada} 312dd88ab32SMasahiro Yamada 313dd88ab32SMasahiro Yamadaif ($tree) { 314dd88ab32SMasahiro Yamada if (defined $root) { 315dd88ab32SMasahiro Yamada if (!top_of_kernel_tree($root)) { 316dd88ab32SMasahiro Yamada die "$P: $root: --root does not point at a valid tree\n"; 317dd88ab32SMasahiro Yamada } 318dd88ab32SMasahiro Yamada } else { 319dd88ab32SMasahiro Yamada if (top_of_kernel_tree('.')) { 320dd88ab32SMasahiro Yamada $root = '.'; 321dd88ab32SMasahiro Yamada } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 322dd88ab32SMasahiro Yamada top_of_kernel_tree($1)) { 323dd88ab32SMasahiro Yamada $root = $1; 324dd88ab32SMasahiro Yamada } 325dd88ab32SMasahiro Yamada } 326dd88ab32SMasahiro Yamada 327dd88ab32SMasahiro Yamada if (!defined $root) { 328dd88ab32SMasahiro Yamada print "Must be run from the top-level dir. of a kernel tree\n"; 329dd88ab32SMasahiro Yamada exit(2); 330dd88ab32SMasahiro Yamada } 331dd88ab32SMasahiro Yamada} 332dd88ab32SMasahiro Yamada 333dd88ab32SMasahiro Yamadamy $emitted_corrupt = 0; 334dd88ab32SMasahiro Yamada 335dd88ab32SMasahiro Yamadaour $Ident = qr{ 336dd88ab32SMasahiro Yamada [A-Za-z_][A-Za-z\d_]* 337dd88ab32SMasahiro Yamada (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 338dd88ab32SMasahiro Yamada }x; 339dd88ab32SMasahiro Yamadaour $Storage = qr{extern|static|asmlinkage}; 340dd88ab32SMasahiro Yamadaour $Sparse = qr{ 341dd88ab32SMasahiro Yamada __user| 342dd88ab32SMasahiro Yamada __kernel| 343dd88ab32SMasahiro Yamada __force| 344dd88ab32SMasahiro Yamada __iomem| 345dd88ab32SMasahiro Yamada __must_check| 346dd88ab32SMasahiro Yamada __init_refok| 347dd88ab32SMasahiro Yamada __kprobes| 348dd88ab32SMasahiro Yamada __ref| 3497551eb4fSHeinrich Schuchardt __rcu| 3507551eb4fSHeinrich Schuchardt __private 351dd88ab32SMasahiro Yamada }x; 3526b9709d9STom Riniour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 3536b9709d9STom Riniour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 3546b9709d9STom Riniour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 3556b9709d9STom Riniour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 3566b9709d9STom Riniour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 357dd88ab32SMasahiro Yamada 358dd88ab32SMasahiro Yamada# Notes to $Attribute: 359dd88ab32SMasahiro Yamada# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 360dd88ab32SMasahiro Yamadaour $Attribute = qr{ 361dd88ab32SMasahiro Yamada const| 362dd88ab32SMasahiro Yamada __percpu| 363dd88ab32SMasahiro Yamada __nocast| 364dd88ab32SMasahiro Yamada __safe| 3657551eb4fSHeinrich Schuchardt __bitwise| 366dd88ab32SMasahiro Yamada __packed__| 367dd88ab32SMasahiro Yamada __packed2__| 368dd88ab32SMasahiro Yamada __naked| 369dd88ab32SMasahiro Yamada __maybe_unused| 370dd88ab32SMasahiro Yamada __always_unused| 371dd88ab32SMasahiro Yamada __noreturn| 372dd88ab32SMasahiro Yamada __used| 373dd88ab32SMasahiro Yamada __cold| 3747551eb4fSHeinrich Schuchardt __pure| 375dd88ab32SMasahiro Yamada __noclone| 376dd88ab32SMasahiro Yamada __deprecated| 377dd88ab32SMasahiro Yamada __read_mostly| 378dd88ab32SMasahiro Yamada __kprobes| 3796b9709d9STom Rini $InitAttribute| 380dd88ab32SMasahiro Yamada ____cacheline_aligned| 381dd88ab32SMasahiro Yamada ____cacheline_aligned_in_smp| 382dd88ab32SMasahiro Yamada ____cacheline_internodealigned_in_smp| 383dd88ab32SMasahiro Yamada __weak 384dd88ab32SMasahiro Yamada }x; 385dd88ab32SMasahiro Yamadaour $Modifier; 3867551eb4fSHeinrich Schuchardtour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 387dd88ab32SMasahiro Yamadaour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 388dd88ab32SMasahiro Yamadaour $Lval = qr{$Ident(?:$Member)*}; 389dd88ab32SMasahiro Yamada 3906b9709d9STom Riniour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 3916b9709d9STom Riniour $Binary = qr{(?i)0b[01]+$Int_type?}; 3926b9709d9STom Riniour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 3936b9709d9STom Riniour $Int = qr{[0-9]+$Int_type?}; 3947551eb4fSHeinrich Schuchardtour $Octal = qr{0[0-7]+$Int_type?}; 395*722c07ddSHeinrich Schuchardtour $String = qr{(?:\bL)?"[X\t]*"}; 396dd88ab32SMasahiro Yamadaour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 397dd88ab32SMasahiro Yamadaour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 398dd88ab32SMasahiro Yamadaour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 399dd88ab32SMasahiro Yamadaour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 4007551eb4fSHeinrich Schuchardtour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 401dd88ab32SMasahiro Yamadaour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 4027551eb4fSHeinrich Schuchardtour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 4036b9709d9STom Riniour $Arithmetic = qr{\+|-|\*|\/|%}; 404dd88ab32SMasahiro Yamadaour $Operators = qr{ 405dd88ab32SMasahiro Yamada <=|>=|==|!=| 406dd88ab32SMasahiro Yamada =>|->|<<|>>|<|>|!|~| 4076b9709d9STom Rini &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 408dd88ab32SMasahiro Yamada }x; 409dd88ab32SMasahiro Yamada 4107551eb4fSHeinrich Schuchardtour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 4117551eb4fSHeinrich Schuchardt 4127551eb4fSHeinrich Schuchardtour $BasicType; 413dd88ab32SMasahiro Yamadaour $NonptrType; 4147551eb4fSHeinrich Schuchardtour $NonptrTypeMisordered; 4156b9709d9STom Riniour $NonptrTypeWithAttr; 416dd88ab32SMasahiro Yamadaour $Type; 4177551eb4fSHeinrich Schuchardtour $TypeMisordered; 418dd88ab32SMasahiro Yamadaour $Declare; 4197551eb4fSHeinrich Schuchardtour $DeclareMisordered; 420dd88ab32SMasahiro Yamada 421dd88ab32SMasahiro Yamadaour $NON_ASCII_UTF8 = qr{ 422dd88ab32SMasahiro Yamada [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 423dd88ab32SMasahiro Yamada | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 424dd88ab32SMasahiro Yamada | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 425dd88ab32SMasahiro Yamada | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 426dd88ab32SMasahiro Yamada | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 427dd88ab32SMasahiro Yamada | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 428dd88ab32SMasahiro Yamada | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 429dd88ab32SMasahiro Yamada}x; 430dd88ab32SMasahiro Yamada 431dd88ab32SMasahiro Yamadaour $UTF8 = qr{ 432dd88ab32SMasahiro Yamada [\x09\x0A\x0D\x20-\x7E] # ASCII 433dd88ab32SMasahiro Yamada | $NON_ASCII_UTF8 434dd88ab32SMasahiro Yamada}x; 435dd88ab32SMasahiro Yamada 4367551eb4fSHeinrich Schuchardtour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 4377551eb4fSHeinrich Schuchardtour $typeOtherOSTypedefs = qr{(?x: 4387551eb4fSHeinrich Schuchardt u_(?:char|short|int|long) | # bsd 4397551eb4fSHeinrich Schuchardt u(?:nchar|short|int|long) # sysv 4407551eb4fSHeinrich Schuchardt)}; 4417551eb4fSHeinrich Schuchardtour $typeKernelTypedefs = qr{(?x: 442dd88ab32SMasahiro Yamada (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 443dd88ab32SMasahiro Yamada atomic_t 444dd88ab32SMasahiro Yamada)}; 4457551eb4fSHeinrich Schuchardtour $typeTypedefs = qr{(?x: 4467551eb4fSHeinrich Schuchardt $typeC99Typedefs\b| 4477551eb4fSHeinrich Schuchardt $typeOtherOSTypedefs\b| 4487551eb4fSHeinrich Schuchardt $typeKernelTypedefs\b 4497551eb4fSHeinrich Schuchardt)}; 4507551eb4fSHeinrich Schuchardt 4517551eb4fSHeinrich Schuchardtour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 452dd88ab32SMasahiro Yamada 453dd88ab32SMasahiro Yamadaour $logFunctions = qr{(?x: 4547551eb4fSHeinrich Schuchardt printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4556b9709d9STom Rini (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 456dd88ab32SMasahiro Yamada WARN(?:_RATELIMIT|_ONCE|)| 457dd88ab32SMasahiro Yamada panic| 4586b9709d9STom Rini MODULE_[A-Z_]+| 4596b9709d9STom Rini seq_vprintf|seq_printf|seq_puts 460dd88ab32SMasahiro Yamada)}; 461dd88ab32SMasahiro Yamada 462dd88ab32SMasahiro Yamadaour $signature_tags = qr{(?xi: 463dd88ab32SMasahiro Yamada Signed-off-by:| 464dd88ab32SMasahiro Yamada Acked-by:| 465dd88ab32SMasahiro Yamada Tested-by:| 466dd88ab32SMasahiro Yamada Reviewed-by:| 467dd88ab32SMasahiro Yamada Reported-by:| 4686b9709d9STom Rini Suggested-by:| 469dd88ab32SMasahiro Yamada To:| 470dd88ab32SMasahiro Yamada Cc: 471dd88ab32SMasahiro Yamada)}; 472dd88ab32SMasahiro Yamada 4737551eb4fSHeinrich Schuchardtour @typeListMisordered = ( 4747551eb4fSHeinrich Schuchardt qr{char\s+(?:un)?signed}, 4757551eb4fSHeinrich Schuchardt qr{int\s+(?:(?:un)?signed\s+)?short\s}, 4767551eb4fSHeinrich Schuchardt qr{int\s+short(?:\s+(?:un)?signed)}, 4777551eb4fSHeinrich Schuchardt qr{short\s+int(?:\s+(?:un)?signed)}, 4787551eb4fSHeinrich Schuchardt qr{(?:un)?signed\s+int\s+short}, 4797551eb4fSHeinrich Schuchardt qr{short\s+(?:un)?signed}, 4807551eb4fSHeinrich Schuchardt qr{long\s+int\s+(?:un)?signed}, 4817551eb4fSHeinrich Schuchardt qr{int\s+long\s+(?:un)?signed}, 4827551eb4fSHeinrich Schuchardt qr{long\s+(?:un)?signed\s+int}, 4837551eb4fSHeinrich Schuchardt qr{int\s+(?:un)?signed\s+long}, 4847551eb4fSHeinrich Schuchardt qr{int\s+(?:un)?signed}, 4857551eb4fSHeinrich Schuchardt qr{int\s+long\s+long\s+(?:un)?signed}, 4867551eb4fSHeinrich Schuchardt qr{long\s+long\s+int\s+(?:un)?signed}, 4877551eb4fSHeinrich Schuchardt qr{long\s+long\s+(?:un)?signed\s+int}, 4887551eb4fSHeinrich Schuchardt qr{long\s+long\s+(?:un)?signed}, 4897551eb4fSHeinrich Schuchardt qr{long\s+(?:un)?signed}, 4907551eb4fSHeinrich Schuchardt); 4917551eb4fSHeinrich Schuchardt 492dd88ab32SMasahiro Yamadaour @typeList = ( 493dd88ab32SMasahiro Yamada qr{void}, 4947551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?char}, 4957551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?short\s+int}, 4967551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?short}, 4977551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?int}, 4987551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?long\s+int}, 4997551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 5007551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?long\s+long}, 5017551eb4fSHeinrich Schuchardt qr{(?:(?:un)?signed\s+)?long}, 5027551eb4fSHeinrich Schuchardt qr{(?:un)?signed}, 503dd88ab32SMasahiro Yamada qr{float}, 504dd88ab32SMasahiro Yamada qr{double}, 505dd88ab32SMasahiro Yamada qr{bool}, 506dd88ab32SMasahiro Yamada qr{struct\s+$Ident}, 507dd88ab32SMasahiro Yamada qr{union\s+$Ident}, 508dd88ab32SMasahiro Yamada qr{enum\s+$Ident}, 509dd88ab32SMasahiro Yamada qr{${Ident}_t}, 510dd88ab32SMasahiro Yamada qr{${Ident}_handler}, 511dd88ab32SMasahiro Yamada qr{${Ident}_handler_fn}, 5127551eb4fSHeinrich Schuchardt @typeListMisordered, 513dd88ab32SMasahiro Yamada); 5147551eb4fSHeinrich Schuchardt 5157551eb4fSHeinrich Schuchardtour $C90_int_types = qr{(?x: 5167551eb4fSHeinrich Schuchardt long\s+long\s+int\s+(?:un)?signed| 5177551eb4fSHeinrich Schuchardt long\s+long\s+(?:un)?signed\s+int| 5187551eb4fSHeinrich Schuchardt long\s+long\s+(?:un)?signed| 5197551eb4fSHeinrich Schuchardt (?:(?:un)?signed\s+)?long\s+long\s+int| 5207551eb4fSHeinrich Schuchardt (?:(?:un)?signed\s+)?long\s+long| 5217551eb4fSHeinrich Schuchardt int\s+long\s+long\s+(?:un)?signed| 5227551eb4fSHeinrich Schuchardt int\s+(?:(?:un)?signed\s+)?long\s+long| 5237551eb4fSHeinrich Schuchardt 5247551eb4fSHeinrich Schuchardt long\s+int\s+(?:un)?signed| 5257551eb4fSHeinrich Schuchardt long\s+(?:un)?signed\s+int| 5267551eb4fSHeinrich Schuchardt long\s+(?:un)?signed| 5277551eb4fSHeinrich Schuchardt (?:(?:un)?signed\s+)?long\s+int| 5287551eb4fSHeinrich Schuchardt (?:(?:un)?signed\s+)?long| 5297551eb4fSHeinrich Schuchardt int\s+long\s+(?:un)?signed| 5307551eb4fSHeinrich Schuchardt int\s+(?:(?:un)?signed\s+)?long| 5317551eb4fSHeinrich Schuchardt 5327551eb4fSHeinrich Schuchardt int\s+(?:un)?signed| 5337551eb4fSHeinrich Schuchardt (?:(?:un)?signed\s+)?int 5347551eb4fSHeinrich Schuchardt)}; 5357551eb4fSHeinrich Schuchardt 5367551eb4fSHeinrich Schuchardtour @typeListFile = (); 5376b9709d9STom Riniour @typeListWithAttr = ( 5386b9709d9STom Rini @typeList, 5396b9709d9STom Rini qr{struct\s+$InitAttribute\s+$Ident}, 5406b9709d9STom Rini qr{union\s+$InitAttribute\s+$Ident}, 5416b9709d9STom Rini); 5426b9709d9STom Rini 543dd88ab32SMasahiro Yamadaour @modifierList = ( 544dd88ab32SMasahiro Yamada qr{fastcall}, 545dd88ab32SMasahiro Yamada); 5467551eb4fSHeinrich Schuchardtour @modifierListFile = (); 5477551eb4fSHeinrich Schuchardt 5487551eb4fSHeinrich Schuchardtour @mode_permission_funcs = ( 5497551eb4fSHeinrich Schuchardt ["module_param", 3], 5507551eb4fSHeinrich Schuchardt ["module_param_(?:array|named|string)", 4], 5517551eb4fSHeinrich Schuchardt ["module_param_array_named", 5], 5527551eb4fSHeinrich Schuchardt ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 5537551eb4fSHeinrich Schuchardt ["proc_create(?:_data|)", 2], 5547551eb4fSHeinrich Schuchardt ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 5557551eb4fSHeinrich Schuchardt ["IIO_DEV_ATTR_[A-Z_]+", 1], 5567551eb4fSHeinrich Schuchardt ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 5577551eb4fSHeinrich Schuchardt ["SENSOR_TEMPLATE(?:_2|)", 3], 5587551eb4fSHeinrich Schuchardt ["__ATTR", 2], 5597551eb4fSHeinrich Schuchardt); 5607551eb4fSHeinrich Schuchardt 5617551eb4fSHeinrich Schuchardt#Create a search pattern for all these functions to speed up a loop below 5627551eb4fSHeinrich Schuchardtour $mode_perms_search = ""; 5637551eb4fSHeinrich Schuchardtforeach my $entry (@mode_permission_funcs) { 5647551eb4fSHeinrich Schuchardt $mode_perms_search .= '|' if ($mode_perms_search ne ""); 5657551eb4fSHeinrich Schuchardt $mode_perms_search .= $entry->[0]; 5667551eb4fSHeinrich Schuchardt} 5677551eb4fSHeinrich Schuchardt 5687551eb4fSHeinrich Schuchardtour $mode_perms_world_writable = qr{ 5697551eb4fSHeinrich Schuchardt S_IWUGO | 5707551eb4fSHeinrich Schuchardt S_IWOTH | 5717551eb4fSHeinrich Schuchardt S_IRWXUGO | 5727551eb4fSHeinrich Schuchardt S_IALLUGO | 5737551eb4fSHeinrich Schuchardt 0[0-7][0-7][2367] 5747551eb4fSHeinrich Schuchardt}x; 5757551eb4fSHeinrich Schuchardt 5767551eb4fSHeinrich Schuchardtour %mode_permission_string_types = ( 5777551eb4fSHeinrich Schuchardt "S_IRWXU" => 0700, 5787551eb4fSHeinrich Schuchardt "S_IRUSR" => 0400, 5797551eb4fSHeinrich Schuchardt "S_IWUSR" => 0200, 5807551eb4fSHeinrich Schuchardt "S_IXUSR" => 0100, 5817551eb4fSHeinrich Schuchardt "S_IRWXG" => 0070, 5827551eb4fSHeinrich Schuchardt "S_IRGRP" => 0040, 5837551eb4fSHeinrich Schuchardt "S_IWGRP" => 0020, 5847551eb4fSHeinrich Schuchardt "S_IXGRP" => 0010, 5857551eb4fSHeinrich Schuchardt "S_IRWXO" => 0007, 5867551eb4fSHeinrich Schuchardt "S_IROTH" => 0004, 5877551eb4fSHeinrich Schuchardt "S_IWOTH" => 0002, 5887551eb4fSHeinrich Schuchardt "S_IXOTH" => 0001, 5897551eb4fSHeinrich Schuchardt "S_IRWXUGO" => 0777, 5907551eb4fSHeinrich Schuchardt "S_IRUGO" => 0444, 5917551eb4fSHeinrich Schuchardt "S_IWUGO" => 0222, 5927551eb4fSHeinrich Schuchardt "S_IXUGO" => 0111, 5937551eb4fSHeinrich Schuchardt); 5947551eb4fSHeinrich Schuchardt 5957551eb4fSHeinrich Schuchardt#Create a search pattern for all these strings to speed up a loop below 5967551eb4fSHeinrich Schuchardtour $mode_perms_string_search = ""; 5977551eb4fSHeinrich Schuchardtforeach my $entry (keys %mode_permission_string_types) { 5987551eb4fSHeinrich Schuchardt $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 5997551eb4fSHeinrich Schuchardt $mode_perms_string_search .= $entry; 6007551eb4fSHeinrich Schuchardt} 601dd88ab32SMasahiro Yamada 602dd88ab32SMasahiro Yamadaour $allowed_asm_includes = qr{(?x: 603dd88ab32SMasahiro Yamada irq| 6047551eb4fSHeinrich Schuchardt memory| 6057551eb4fSHeinrich Schuchardt time| 6067551eb4fSHeinrich Schuchardt reboot 607dd88ab32SMasahiro Yamada)}; 608dd88ab32SMasahiro Yamada# memory.h: ARM has a custom one 609dd88ab32SMasahiro Yamada 610c10e0f5bSDan Murphy# Load common spelling mistakes and build regular expression list. 611c10e0f5bSDan Murphymy $misspellings; 612c10e0f5bSDan Murphymy %spelling_fix; 613c10e0f5bSDan Murphy 614c10e0f5bSDan Murphyif (open(my $spelling, '<', $spelling_file)) { 615c10e0f5bSDan Murphy while (<$spelling>) { 616c10e0f5bSDan Murphy my $line = $_; 617c10e0f5bSDan Murphy 618c10e0f5bSDan Murphy $line =~ s/\s*\n?$//g; 619c10e0f5bSDan Murphy $line =~ s/^\s*//g; 620c10e0f5bSDan Murphy 621c10e0f5bSDan Murphy next if ($line =~ m/^\s*#/); 622c10e0f5bSDan Murphy next if ($line =~ m/^\s*$/); 623c10e0f5bSDan Murphy 624c10e0f5bSDan Murphy my ($suspect, $fix) = split(/\|\|/, $line); 625c10e0f5bSDan Murphy 626c10e0f5bSDan Murphy $spelling_fix{$suspect} = $fix; 627c10e0f5bSDan Murphy } 628c10e0f5bSDan Murphy close($spelling); 629c10e0f5bSDan Murphy} else { 630c10e0f5bSDan Murphy warn "No typos will be found - file '$spelling_file': $!\n"; 631c10e0f5bSDan Murphy} 632c10e0f5bSDan Murphy 633c10e0f5bSDan Murphyif ($codespell) { 634c10e0f5bSDan Murphy if (open(my $spelling, '<', $codespellfile)) { 635c10e0f5bSDan Murphy while (<$spelling>) { 636c10e0f5bSDan Murphy my $line = $_; 637c10e0f5bSDan Murphy 638c10e0f5bSDan Murphy $line =~ s/\s*\n?$//g; 639c10e0f5bSDan Murphy $line =~ s/^\s*//g; 640c10e0f5bSDan Murphy 641c10e0f5bSDan Murphy next if ($line =~ m/^\s*#/); 642c10e0f5bSDan Murphy next if ($line =~ m/^\s*$/); 643c10e0f5bSDan Murphy next if ($line =~ m/, disabled/i); 644c10e0f5bSDan Murphy 645c10e0f5bSDan Murphy $line =~ s/,.*$//; 646c10e0f5bSDan Murphy 647c10e0f5bSDan Murphy my ($suspect, $fix) = split(/->/, $line); 648c10e0f5bSDan Murphy 649c10e0f5bSDan Murphy $spelling_fix{$suspect} = $fix; 650c10e0f5bSDan Murphy } 651c10e0f5bSDan Murphy close($spelling); 652c10e0f5bSDan Murphy } else { 653c10e0f5bSDan Murphy warn "No codespell typos will be found - file '$codespellfile': $!\n"; 654c10e0f5bSDan Murphy } 655c10e0f5bSDan Murphy} 656c10e0f5bSDan Murphy 657c10e0f5bSDan Murphy$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 658c10e0f5bSDan Murphy 6597551eb4fSHeinrich Schuchardtsub read_words { 6607551eb4fSHeinrich Schuchardt my ($wordsRef, $file) = @_; 6617551eb4fSHeinrich Schuchardt 6627551eb4fSHeinrich Schuchardt if (open(my $words, '<', $file)) { 6637551eb4fSHeinrich Schuchardt while (<$words>) { 6647551eb4fSHeinrich Schuchardt my $line = $_; 6657551eb4fSHeinrich Schuchardt 6667551eb4fSHeinrich Schuchardt $line =~ s/\s*\n?$//g; 6677551eb4fSHeinrich Schuchardt $line =~ s/^\s*//g; 6687551eb4fSHeinrich Schuchardt 6697551eb4fSHeinrich Schuchardt next if ($line =~ m/^\s*#/); 6707551eb4fSHeinrich Schuchardt next if ($line =~ m/^\s*$/); 6717551eb4fSHeinrich Schuchardt if ($line =~ /\s/) { 6727551eb4fSHeinrich Schuchardt print("$file: '$line' invalid - ignored\n"); 6737551eb4fSHeinrich Schuchardt next; 6747551eb4fSHeinrich Schuchardt } 6757551eb4fSHeinrich Schuchardt 6767551eb4fSHeinrich Schuchardt $$wordsRef .= '|' if ($$wordsRef ne ""); 6777551eb4fSHeinrich Schuchardt $$wordsRef .= $line; 6787551eb4fSHeinrich Schuchardt } 6797551eb4fSHeinrich Schuchardt close($file); 6807551eb4fSHeinrich Schuchardt return 1; 6817551eb4fSHeinrich Schuchardt } 6827551eb4fSHeinrich Schuchardt 6837551eb4fSHeinrich Schuchardt return 0; 6847551eb4fSHeinrich Schuchardt} 6857551eb4fSHeinrich Schuchardt 6867551eb4fSHeinrich Schuchardtmy $const_structs = ""; 6877551eb4fSHeinrich Schuchardtread_words(\$const_structs, $conststructsfile) 6887551eb4fSHeinrich Schuchardt or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 6897551eb4fSHeinrich Schuchardt 6907551eb4fSHeinrich Schuchardtmy $typeOtherTypedefs = ""; 6917551eb4fSHeinrich Schuchardtif (length($typedefsfile)) { 6927551eb4fSHeinrich Schuchardt read_words(\$typeOtherTypedefs, $typedefsfile) 6937551eb4fSHeinrich Schuchardt or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 6947551eb4fSHeinrich Schuchardt} 6957551eb4fSHeinrich Schuchardt$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); 696c10e0f5bSDan Murphy 697dd88ab32SMasahiro Yamadasub build_types { 6987551eb4fSHeinrich Schuchardt my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 6997551eb4fSHeinrich Schuchardt my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 7007551eb4fSHeinrich Schuchardt my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 7016b9709d9STom Rini my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 702dd88ab32SMasahiro Yamada $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 7037551eb4fSHeinrich Schuchardt $BasicType = qr{ 7047551eb4fSHeinrich Schuchardt (?:$typeTypedefs\b)| 7057551eb4fSHeinrich Schuchardt (?:${all}\b) 7067551eb4fSHeinrich Schuchardt }x; 707dd88ab32SMasahiro Yamada $NonptrType = qr{ 708dd88ab32SMasahiro Yamada (?:$Modifier\s+|const\s+)* 709dd88ab32SMasahiro Yamada (?: 710dd88ab32SMasahiro Yamada (?:typeof|__typeof__)\s*\([^\)]*\)| 711dd88ab32SMasahiro Yamada (?:$typeTypedefs\b)| 712dd88ab32SMasahiro Yamada (?:${all}\b) 713dd88ab32SMasahiro Yamada ) 714dd88ab32SMasahiro Yamada (?:\s+$Modifier|\s+const)* 715dd88ab32SMasahiro Yamada }x; 7167551eb4fSHeinrich Schuchardt $NonptrTypeMisordered = qr{ 7177551eb4fSHeinrich Schuchardt (?:$Modifier\s+|const\s+)* 7187551eb4fSHeinrich Schuchardt (?: 7197551eb4fSHeinrich Schuchardt (?:${Misordered}\b) 7207551eb4fSHeinrich Schuchardt ) 7217551eb4fSHeinrich Schuchardt (?:\s+$Modifier|\s+const)* 7227551eb4fSHeinrich Schuchardt }x; 7236b9709d9STom Rini $NonptrTypeWithAttr = qr{ 7246b9709d9STom Rini (?:$Modifier\s+|const\s+)* 7256b9709d9STom Rini (?: 7266b9709d9STom Rini (?:typeof|__typeof__)\s*\([^\)]*\)| 7276b9709d9STom Rini (?:$typeTypedefs\b)| 7286b9709d9STom Rini (?:${allWithAttr}\b) 7296b9709d9STom Rini ) 7306b9709d9STom Rini (?:\s+$Modifier|\s+const)* 7316b9709d9STom Rini }x; 732dd88ab32SMasahiro Yamada $Type = qr{ 733dd88ab32SMasahiro Yamada $NonptrType 7347551eb4fSHeinrich Schuchardt (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 735dd88ab32SMasahiro Yamada (?:\s+$Inline|\s+$Modifier)* 736dd88ab32SMasahiro Yamada }x; 7377551eb4fSHeinrich Schuchardt $TypeMisordered = qr{ 7387551eb4fSHeinrich Schuchardt $NonptrTypeMisordered 7397551eb4fSHeinrich Schuchardt (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 7407551eb4fSHeinrich Schuchardt (?:\s+$Inline|\s+$Modifier)* 7417551eb4fSHeinrich Schuchardt }x; 7427551eb4fSHeinrich Schuchardt $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 7437551eb4fSHeinrich Schuchardt $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 744dd88ab32SMasahiro Yamada} 745dd88ab32SMasahiro Yamadabuild_types(); 746dd88ab32SMasahiro Yamada 747dd88ab32SMasahiro Yamadaour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 748dd88ab32SMasahiro Yamada 749dd88ab32SMasahiro Yamada# Using $balanced_parens, $LvalOrFunc, or $FuncArg 750dd88ab32SMasahiro Yamada# requires at least perl version v5.10.0 751dd88ab32SMasahiro Yamada# Any use must be runtime checked with $^V 752dd88ab32SMasahiro Yamada 753dd88ab32SMasahiro Yamadaour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 7547551eb4fSHeinrich Schuchardtour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 7557551eb4fSHeinrich Schuchardtour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 7567551eb4fSHeinrich Schuchardt 7577551eb4fSHeinrich Schuchardtour $declaration_macros = qr{(?x: 7587551eb4fSHeinrich Schuchardt (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 7597551eb4fSHeinrich Schuchardt (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 7607551eb4fSHeinrich Schuchardt (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( 7617551eb4fSHeinrich Schuchardt)}; 762dd88ab32SMasahiro Yamada 763dd88ab32SMasahiro Yamadasub deparenthesize { 764dd88ab32SMasahiro Yamada my ($string) = @_; 765dd88ab32SMasahiro Yamada return "" if (!defined($string)); 7667551eb4fSHeinrich Schuchardt 7677551eb4fSHeinrich Schuchardt while ($string =~ /^\s*\(.*\)\s*$/) { 7687551eb4fSHeinrich Schuchardt $string =~ s@^\s*\(\s*@@; 7697551eb4fSHeinrich Schuchardt $string =~ s@\s*\)\s*$@@; 7707551eb4fSHeinrich Schuchardt } 7717551eb4fSHeinrich Schuchardt 772dd88ab32SMasahiro Yamada $string =~ s@\s+@ @g; 7737551eb4fSHeinrich Schuchardt 774dd88ab32SMasahiro Yamada return $string; 775dd88ab32SMasahiro Yamada} 776dd88ab32SMasahiro Yamada 7776b9709d9STom Rinisub seed_camelcase_file { 7786b9709d9STom Rini my ($file) = @_; 7796b9709d9STom Rini 7806b9709d9STom Rini return if (!(-f $file)); 7816b9709d9STom Rini 7826b9709d9STom Rini local $/; 7836b9709d9STom Rini 7846b9709d9STom Rini open(my $include_file, '<', "$file") 7856b9709d9STom Rini or warn "$P: Can't read '$file' $!\n"; 7866b9709d9STom Rini my $text = <$include_file>; 7876b9709d9STom Rini close($include_file); 7886b9709d9STom Rini 7896b9709d9STom Rini my @lines = split('\n', $text); 7906b9709d9STom Rini 7916b9709d9STom Rini foreach my $line (@lines) { 7926b9709d9STom Rini next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 7936b9709d9STom Rini if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 7946b9709d9STom Rini $camelcase{$1} = 1; 7956b9709d9STom Rini } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 7966b9709d9STom Rini $camelcase{$1} = 1; 7976b9709d9STom Rini } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 7986b9709d9STom Rini $camelcase{$1} = 1; 7996b9709d9STom Rini } 8006b9709d9STom Rini } 8016b9709d9STom Rini} 8026b9709d9STom Rini 8037551eb4fSHeinrich Schuchardtsub is_maintained_obsolete { 8047551eb4fSHeinrich Schuchardt my ($filename) = @_; 8057551eb4fSHeinrich Schuchardt 8067551eb4fSHeinrich Schuchardt return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 8077551eb4fSHeinrich Schuchardt 8087551eb4fSHeinrich Schuchardt my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 8097551eb4fSHeinrich Schuchardt 8107551eb4fSHeinrich Schuchardt return $status =~ /obsolete/i; 8117551eb4fSHeinrich Schuchardt} 8127551eb4fSHeinrich Schuchardt 8136b9709d9STom Rinimy $camelcase_seeded = 0; 8146b9709d9STom Rinisub seed_camelcase_includes { 8156b9709d9STom Rini return if ($camelcase_seeded); 8166b9709d9STom Rini 8176b9709d9STom Rini my $files; 8186b9709d9STom Rini my $camelcase_cache = ""; 8196b9709d9STom Rini my @include_files = (); 8206b9709d9STom Rini 8216b9709d9STom Rini $camelcase_seeded = 1; 8226b9709d9STom Rini 8236b9709d9STom Rini if (-e ".git") { 8246b9709d9STom Rini my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; 8256b9709d9STom Rini chomp $git_last_include_commit; 8266b9709d9STom Rini $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 8276b9709d9STom Rini } else { 8286b9709d9STom Rini my $last_mod_date = 0; 8296b9709d9STom Rini $files = `find $root/include -name "*.h"`; 8306b9709d9STom Rini @include_files = split('\n', $files); 8316b9709d9STom Rini foreach my $file (@include_files) { 8326b9709d9STom Rini my $date = POSIX::strftime("%Y%m%d%H%M", 8336b9709d9STom Rini localtime((stat $file)[9])); 8346b9709d9STom Rini $last_mod_date = $date if ($last_mod_date < $date); 8356b9709d9STom Rini } 8366b9709d9STom Rini $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 8376b9709d9STom Rini } 8386b9709d9STom Rini 8396b9709d9STom Rini if ($camelcase_cache ne "" && -f $camelcase_cache) { 8406b9709d9STom Rini open(my $camelcase_file, '<', "$camelcase_cache") 8416b9709d9STom Rini or warn "$P: Can't read '$camelcase_cache' $!\n"; 8426b9709d9STom Rini while (<$camelcase_file>) { 8436b9709d9STom Rini chomp; 8446b9709d9STom Rini $camelcase{$_} = 1; 8456b9709d9STom Rini } 8466b9709d9STom Rini close($camelcase_file); 8476b9709d9STom Rini 8486b9709d9STom Rini return; 8496b9709d9STom Rini } 8506b9709d9STom Rini 8516b9709d9STom Rini if (-e ".git") { 8526b9709d9STom Rini $files = `git ls-files "include/*.h"`; 8536b9709d9STom Rini @include_files = split('\n', $files); 8546b9709d9STom Rini } 8556b9709d9STom Rini 8566b9709d9STom Rini foreach my $file (@include_files) { 8576b9709d9STom Rini seed_camelcase_file($file); 8586b9709d9STom Rini } 8596b9709d9STom Rini 8606b9709d9STom Rini if ($camelcase_cache ne "") { 8616b9709d9STom Rini unlink glob ".checkpatch-camelcase.*"; 8626b9709d9STom Rini open(my $camelcase_file, '>', "$camelcase_cache") 8636b9709d9STom Rini or warn "$P: Can't write '$camelcase_cache' $!\n"; 8646b9709d9STom Rini foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 8656b9709d9STom Rini print $camelcase_file ("$_\n"); 8666b9709d9STom Rini } 8676b9709d9STom Rini close($camelcase_file); 8686b9709d9STom Rini } 8696b9709d9STom Rini} 8706b9709d9STom Rini 8717551eb4fSHeinrich Schuchardtsub git_commit_info { 8727551eb4fSHeinrich Schuchardt my ($commit, $id, $desc) = @_; 8737551eb4fSHeinrich Schuchardt 8747551eb4fSHeinrich Schuchardt return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 8757551eb4fSHeinrich Schuchardt 8767551eb4fSHeinrich Schuchardt my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; 8777551eb4fSHeinrich Schuchardt $output =~ s/^\s*//gm; 8787551eb4fSHeinrich Schuchardt my @lines = split("\n", $output); 8797551eb4fSHeinrich Schuchardt 8807551eb4fSHeinrich Schuchardt return ($id, $desc) if ($#lines < 0); 8817551eb4fSHeinrich Schuchardt 8827551eb4fSHeinrich Schuchardt if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { 8837551eb4fSHeinrich Schuchardt# Maybe one day convert this block of bash into something that returns 8847551eb4fSHeinrich Schuchardt# all matching commit ids, but it's very slow... 8857551eb4fSHeinrich Schuchardt# 8867551eb4fSHeinrich Schuchardt# echo "checking commits $1..." 8877551eb4fSHeinrich Schuchardt# git rev-list --remotes | grep -i "^$1" | 8887551eb4fSHeinrich Schuchardt# while read line ; do 8897551eb4fSHeinrich Schuchardt# git log --format='%H %s' -1 $line | 8907551eb4fSHeinrich Schuchardt# echo "commit $(cut -c 1-12,41-)" 8917551eb4fSHeinrich Schuchardt# done 8927551eb4fSHeinrich Schuchardt } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 8937551eb4fSHeinrich Schuchardt $id = undef; 8947551eb4fSHeinrich Schuchardt } else { 8957551eb4fSHeinrich Schuchardt $id = substr($lines[0], 0, 12); 8967551eb4fSHeinrich Schuchardt $desc = substr($lines[0], 41); 8977551eb4fSHeinrich Schuchardt } 8987551eb4fSHeinrich Schuchardt 8997551eb4fSHeinrich Schuchardt return ($id, $desc); 9007551eb4fSHeinrich Schuchardt} 9017551eb4fSHeinrich Schuchardt 902dd88ab32SMasahiro Yamada$chk_signoff = 0 if ($file); 903dd88ab32SMasahiro Yamada 904dd88ab32SMasahiro Yamadamy @rawlines = (); 905dd88ab32SMasahiro Yamadamy @lines = (); 9066b9709d9STom Rinimy @fixed = (); 9077551eb4fSHeinrich Schuchardtmy @fixed_inserted = (); 9087551eb4fSHeinrich Schuchardtmy @fixed_deleted = (); 909c10e0f5bSDan Murphymy $fixlinenr = -1; 910c10e0f5bSDan Murphy 9117551eb4fSHeinrich Schuchardt# If input is git commits, extract all commits from the commit expressions. 9127551eb4fSHeinrich Schuchardt# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 9137551eb4fSHeinrich Schuchardtdie "$P: No git repository found\n" if ($git && !-e ".git"); 9147551eb4fSHeinrich Schuchardt 9157551eb4fSHeinrich Schuchardtif ($git) { 9167551eb4fSHeinrich Schuchardt my @commits = (); 9177551eb4fSHeinrich Schuchardt foreach my $commit_expr (@ARGV) { 9187551eb4fSHeinrich Schuchardt my $git_range; 9197551eb4fSHeinrich Schuchardt if ($commit_expr =~ m/^(.*)-(\d+)$/) { 9207551eb4fSHeinrich Schuchardt $git_range = "-$2 $1"; 9217551eb4fSHeinrich Schuchardt } elsif ($commit_expr =~ m/\.\./) { 9227551eb4fSHeinrich Schuchardt $git_range = "$commit_expr"; 9237551eb4fSHeinrich Schuchardt } else { 9247551eb4fSHeinrich Schuchardt $git_range = "-1 $commit_expr"; 9257551eb4fSHeinrich Schuchardt } 9267551eb4fSHeinrich Schuchardt my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 9277551eb4fSHeinrich Schuchardt foreach my $line (split(/\n/, $lines)) { 9287551eb4fSHeinrich Schuchardt $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 9297551eb4fSHeinrich Schuchardt next if (!defined($1) || !defined($2)); 9307551eb4fSHeinrich Schuchardt my $sha1 = $1; 9317551eb4fSHeinrich Schuchardt my $subject = $2; 9327551eb4fSHeinrich Schuchardt unshift(@commits, $sha1); 9337551eb4fSHeinrich Schuchardt $git_commits{$sha1} = $subject; 9347551eb4fSHeinrich Schuchardt } 9357551eb4fSHeinrich Schuchardt } 9367551eb4fSHeinrich Schuchardt die "$P: no git commits after extraction!\n" if (@commits == 0); 9377551eb4fSHeinrich Schuchardt @ARGV = @commits; 9387551eb4fSHeinrich Schuchardt} 9397551eb4fSHeinrich Schuchardt 9407551eb4fSHeinrich Schuchardtmy $vname; 941dd88ab32SMasahiro Yamadafor my $filename (@ARGV) { 942dd88ab32SMasahiro Yamada my $FILE; 9437551eb4fSHeinrich Schuchardt if ($git) { 9447551eb4fSHeinrich Schuchardt open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 9457551eb4fSHeinrich Schuchardt die "$P: $filename: git format-patch failed - $!\n"; 9467551eb4fSHeinrich Schuchardt } elsif ($file) { 947dd88ab32SMasahiro Yamada open($FILE, '-|', "diff -u /dev/null $filename") || 948dd88ab32SMasahiro Yamada die "$P: $filename: diff failed - $!\n"; 949dd88ab32SMasahiro Yamada } elsif ($filename eq '-') { 950dd88ab32SMasahiro Yamada open($FILE, '<&STDIN'); 951dd88ab32SMasahiro Yamada } else { 952dd88ab32SMasahiro Yamada open($FILE, '<', "$filename") || 953dd88ab32SMasahiro Yamada die "$P: $filename: open failed - $!\n"; 954dd88ab32SMasahiro Yamada } 955dd88ab32SMasahiro Yamada if ($filename eq '-') { 956dd88ab32SMasahiro Yamada $vname = 'Your patch'; 9577551eb4fSHeinrich Schuchardt } elsif ($git) { 9587551eb4fSHeinrich Schuchardt $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 959dd88ab32SMasahiro Yamada } else { 960dd88ab32SMasahiro Yamada $vname = $filename; 961dd88ab32SMasahiro Yamada } 962dd88ab32SMasahiro Yamada while (<$FILE>) { 963dd88ab32SMasahiro Yamada chomp; 964dd88ab32SMasahiro Yamada push(@rawlines, $_); 965dd88ab32SMasahiro Yamada } 966dd88ab32SMasahiro Yamada close($FILE); 9677551eb4fSHeinrich Schuchardt 9687551eb4fSHeinrich Schuchardt if ($#ARGV > 0 && $quiet == 0) { 9697551eb4fSHeinrich Schuchardt print '-' x length($vname) . "\n"; 9707551eb4fSHeinrich Schuchardt print "$vname\n"; 9717551eb4fSHeinrich Schuchardt print '-' x length($vname) . "\n"; 9727551eb4fSHeinrich Schuchardt } 9737551eb4fSHeinrich Schuchardt 974dd88ab32SMasahiro Yamada if (!process($filename)) { 975dd88ab32SMasahiro Yamada $exit = 1; 976dd88ab32SMasahiro Yamada } 977dd88ab32SMasahiro Yamada @rawlines = (); 978dd88ab32SMasahiro Yamada @lines = (); 9796b9709d9STom Rini @fixed = (); 9807551eb4fSHeinrich Schuchardt @fixed_inserted = (); 9817551eb4fSHeinrich Schuchardt @fixed_deleted = (); 9827551eb4fSHeinrich Schuchardt $fixlinenr = -1; 9837551eb4fSHeinrich Schuchardt @modifierListFile = (); 9847551eb4fSHeinrich Schuchardt @typeListFile = (); 9857551eb4fSHeinrich Schuchardt build_types(); 9867551eb4fSHeinrich Schuchardt} 9877551eb4fSHeinrich Schuchardt 9887551eb4fSHeinrich Schuchardtif (!$quiet) { 9897551eb4fSHeinrich Schuchardt hash_show_words(\%use_type, "Used"); 9907551eb4fSHeinrich Schuchardt hash_show_words(\%ignore_type, "Ignored"); 9917551eb4fSHeinrich Schuchardt 9927551eb4fSHeinrich Schuchardt if ($^V lt 5.10.0) { 9937551eb4fSHeinrich Schuchardt print << "EOM" 9947551eb4fSHeinrich Schuchardt 9957551eb4fSHeinrich SchuchardtNOTE: perl $^V is not modern enough to detect all possible issues. 9967551eb4fSHeinrich Schuchardt An upgrade to at least perl v5.10.0 is suggested. 9977551eb4fSHeinrich SchuchardtEOM 9987551eb4fSHeinrich Schuchardt } 9997551eb4fSHeinrich Schuchardt if ($exit) { 10007551eb4fSHeinrich Schuchardt print << "EOM" 10017551eb4fSHeinrich Schuchardt 10027551eb4fSHeinrich SchuchardtNOTE: If any of the errors are false positives, please report 10037551eb4fSHeinrich Schuchardt them to the maintainer, see CHECKPATCH in MAINTAINERS. 10047551eb4fSHeinrich SchuchardtEOM 10057551eb4fSHeinrich Schuchardt } 1006dd88ab32SMasahiro Yamada} 1007dd88ab32SMasahiro Yamada 1008dd88ab32SMasahiro Yamadaexit($exit); 1009dd88ab32SMasahiro Yamada 1010dd88ab32SMasahiro Yamadasub top_of_kernel_tree { 1011dd88ab32SMasahiro Yamada my ($root) = @_; 1012dd88ab32SMasahiro Yamada 1013dd88ab32SMasahiro Yamada my @tree_check = ( 10146b9709d9STom Rini "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 1015dd88ab32SMasahiro Yamada "README", "Documentation", "arch", "include", "drivers", 1016dd88ab32SMasahiro Yamada "fs", "init", "ipc", "kernel", "lib", "scripts", 1017dd88ab32SMasahiro Yamada ); 1018dd88ab32SMasahiro Yamada 1019dd88ab32SMasahiro Yamada foreach my $check (@tree_check) { 1020dd88ab32SMasahiro Yamada if (! -e $root . '/' . $check) { 1021dd88ab32SMasahiro Yamada return 0; 1022dd88ab32SMasahiro Yamada } 1023dd88ab32SMasahiro Yamada } 1024dd88ab32SMasahiro Yamada return 1; 1025dd88ab32SMasahiro Yamada} 1026dd88ab32SMasahiro Yamada 1027dd88ab32SMasahiro Yamadasub parse_email { 1028dd88ab32SMasahiro Yamada my ($formatted_email) = @_; 1029dd88ab32SMasahiro Yamada 1030dd88ab32SMasahiro Yamada my $name = ""; 1031dd88ab32SMasahiro Yamada my $address = ""; 1032dd88ab32SMasahiro Yamada my $comment = ""; 1033dd88ab32SMasahiro Yamada 1034dd88ab32SMasahiro Yamada if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 1035dd88ab32SMasahiro Yamada $name = $1; 1036dd88ab32SMasahiro Yamada $address = $2; 1037dd88ab32SMasahiro Yamada $comment = $3 if defined $3; 1038dd88ab32SMasahiro Yamada } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 1039dd88ab32SMasahiro Yamada $address = $1; 1040dd88ab32SMasahiro Yamada $comment = $2 if defined $2; 1041dd88ab32SMasahiro Yamada } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 1042dd88ab32SMasahiro Yamada $address = $1; 1043dd88ab32SMasahiro Yamada $comment = $2 if defined $2; 1044dd88ab32SMasahiro Yamada $formatted_email =~ s/$address.*$//; 1045dd88ab32SMasahiro Yamada $name = $formatted_email; 10466b9709d9STom Rini $name = trim($name); 1047dd88ab32SMasahiro Yamada $name =~ s/^\"|\"$//g; 1048dd88ab32SMasahiro Yamada # If there's a name left after stripping spaces and 1049dd88ab32SMasahiro Yamada # leading quotes, and the address doesn't have both 1050dd88ab32SMasahiro Yamada # leading and trailing angle brackets, the address 1051dd88ab32SMasahiro Yamada # is invalid. ie: 1052dd88ab32SMasahiro Yamada # "joe smith joe@smith.com" bad 1053dd88ab32SMasahiro Yamada # "joe smith <joe@smith.com" bad 1054dd88ab32SMasahiro Yamada if ($name ne "" && $address !~ /^<[^>]+>$/) { 1055dd88ab32SMasahiro Yamada $name = ""; 1056dd88ab32SMasahiro Yamada $address = ""; 1057dd88ab32SMasahiro Yamada $comment = ""; 1058dd88ab32SMasahiro Yamada } 1059dd88ab32SMasahiro Yamada } 1060dd88ab32SMasahiro Yamada 10616b9709d9STom Rini $name = trim($name); 1062dd88ab32SMasahiro Yamada $name =~ s/^\"|\"$//g; 10636b9709d9STom Rini $address = trim($address); 1064dd88ab32SMasahiro Yamada $address =~ s/^\<|\>$//g; 1065dd88ab32SMasahiro Yamada 1066dd88ab32SMasahiro Yamada if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 1067dd88ab32SMasahiro Yamada $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 1068dd88ab32SMasahiro Yamada $name = "\"$name\""; 1069dd88ab32SMasahiro Yamada } 1070dd88ab32SMasahiro Yamada 1071dd88ab32SMasahiro Yamada return ($name, $address, $comment); 1072dd88ab32SMasahiro Yamada} 1073dd88ab32SMasahiro Yamada 1074dd88ab32SMasahiro Yamadasub format_email { 1075dd88ab32SMasahiro Yamada my ($name, $address) = @_; 1076dd88ab32SMasahiro Yamada 1077dd88ab32SMasahiro Yamada my $formatted_email; 1078dd88ab32SMasahiro Yamada 10796b9709d9STom Rini $name = trim($name); 1080dd88ab32SMasahiro Yamada $name =~ s/^\"|\"$//g; 10816b9709d9STom Rini $address = trim($address); 1082dd88ab32SMasahiro Yamada 1083dd88ab32SMasahiro Yamada if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 1084dd88ab32SMasahiro Yamada $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 1085dd88ab32SMasahiro Yamada $name = "\"$name\""; 1086dd88ab32SMasahiro Yamada } 1087dd88ab32SMasahiro Yamada 1088dd88ab32SMasahiro Yamada if ("$name" eq "") { 1089dd88ab32SMasahiro Yamada $formatted_email = "$address"; 1090dd88ab32SMasahiro Yamada } else { 1091dd88ab32SMasahiro Yamada $formatted_email = "$name <$address>"; 1092dd88ab32SMasahiro Yamada } 1093dd88ab32SMasahiro Yamada 1094dd88ab32SMasahiro Yamada return $formatted_email; 1095dd88ab32SMasahiro Yamada} 1096dd88ab32SMasahiro Yamada 10977551eb4fSHeinrich Schuchardtsub which { 10987551eb4fSHeinrich Schuchardt my ($bin) = @_; 10997551eb4fSHeinrich Schuchardt 11007551eb4fSHeinrich Schuchardt foreach my $path (split(/:/, $ENV{PATH})) { 11017551eb4fSHeinrich Schuchardt if (-e "$path/$bin") { 11027551eb4fSHeinrich Schuchardt return "$path/$bin"; 11037551eb4fSHeinrich Schuchardt } 11047551eb4fSHeinrich Schuchardt } 11057551eb4fSHeinrich Schuchardt 11067551eb4fSHeinrich Schuchardt return ""; 11077551eb4fSHeinrich Schuchardt} 11087551eb4fSHeinrich Schuchardt 1109dd88ab32SMasahiro Yamadasub which_conf { 1110dd88ab32SMasahiro Yamada my ($conf) = @_; 1111dd88ab32SMasahiro Yamada 1112dd88ab32SMasahiro Yamada foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1113dd88ab32SMasahiro Yamada if (-e "$path/$conf") { 1114dd88ab32SMasahiro Yamada return "$path/$conf"; 1115dd88ab32SMasahiro Yamada } 1116dd88ab32SMasahiro Yamada } 1117dd88ab32SMasahiro Yamada 1118dd88ab32SMasahiro Yamada return ""; 1119dd88ab32SMasahiro Yamada} 1120dd88ab32SMasahiro Yamada 1121dd88ab32SMasahiro Yamadasub expand_tabs { 1122dd88ab32SMasahiro Yamada my ($str) = @_; 1123dd88ab32SMasahiro Yamada 1124dd88ab32SMasahiro Yamada my $res = ''; 1125dd88ab32SMasahiro Yamada my $n = 0; 1126dd88ab32SMasahiro Yamada for my $c (split(//, $str)) { 1127dd88ab32SMasahiro Yamada if ($c eq "\t") { 1128dd88ab32SMasahiro Yamada $res .= ' '; 1129dd88ab32SMasahiro Yamada $n++; 1130dd88ab32SMasahiro Yamada for (; ($n % 8) != 0; $n++) { 1131dd88ab32SMasahiro Yamada $res .= ' '; 1132dd88ab32SMasahiro Yamada } 1133dd88ab32SMasahiro Yamada next; 1134dd88ab32SMasahiro Yamada } 1135dd88ab32SMasahiro Yamada $res .= $c; 1136dd88ab32SMasahiro Yamada $n++; 1137dd88ab32SMasahiro Yamada } 1138dd88ab32SMasahiro Yamada 1139dd88ab32SMasahiro Yamada return $res; 1140dd88ab32SMasahiro Yamada} 1141dd88ab32SMasahiro Yamadasub copy_spacing { 1142dd88ab32SMasahiro Yamada (my $res = shift) =~ tr/\t/ /c; 1143dd88ab32SMasahiro Yamada return $res; 1144dd88ab32SMasahiro Yamada} 1145dd88ab32SMasahiro Yamada 1146dd88ab32SMasahiro Yamadasub line_stats { 1147dd88ab32SMasahiro Yamada my ($line) = @_; 1148dd88ab32SMasahiro Yamada 1149dd88ab32SMasahiro Yamada # Drop the diff line leader and expand tabs 1150dd88ab32SMasahiro Yamada $line =~ s/^.//; 1151dd88ab32SMasahiro Yamada $line = expand_tabs($line); 1152dd88ab32SMasahiro Yamada 1153dd88ab32SMasahiro Yamada # Pick the indent from the front of the line. 1154dd88ab32SMasahiro Yamada my ($white) = ($line =~ /^(\s*)/); 1155dd88ab32SMasahiro Yamada 1156dd88ab32SMasahiro Yamada return (length($line), length($white)); 1157dd88ab32SMasahiro Yamada} 1158dd88ab32SMasahiro Yamada 1159dd88ab32SMasahiro Yamadamy $sanitise_quote = ''; 1160dd88ab32SMasahiro Yamada 1161dd88ab32SMasahiro Yamadasub sanitise_line_reset { 1162dd88ab32SMasahiro Yamada my ($in_comment) = @_; 1163dd88ab32SMasahiro Yamada 1164dd88ab32SMasahiro Yamada if ($in_comment) { 1165dd88ab32SMasahiro Yamada $sanitise_quote = '*/'; 1166dd88ab32SMasahiro Yamada } else { 1167dd88ab32SMasahiro Yamada $sanitise_quote = ''; 1168dd88ab32SMasahiro Yamada } 1169dd88ab32SMasahiro Yamada} 1170dd88ab32SMasahiro Yamadasub sanitise_line { 1171dd88ab32SMasahiro Yamada my ($line) = @_; 1172dd88ab32SMasahiro Yamada 1173dd88ab32SMasahiro Yamada my $res = ''; 1174dd88ab32SMasahiro Yamada my $l = ''; 1175dd88ab32SMasahiro Yamada 1176dd88ab32SMasahiro Yamada my $qlen = 0; 1177dd88ab32SMasahiro Yamada my $off = 0; 1178dd88ab32SMasahiro Yamada my $c; 1179dd88ab32SMasahiro Yamada 1180dd88ab32SMasahiro Yamada # Always copy over the diff marker. 1181dd88ab32SMasahiro Yamada $res = substr($line, 0, 1); 1182dd88ab32SMasahiro Yamada 1183dd88ab32SMasahiro Yamada for ($off = 1; $off < length($line); $off++) { 1184dd88ab32SMasahiro Yamada $c = substr($line, $off, 1); 1185dd88ab32SMasahiro Yamada 1186dd88ab32SMasahiro Yamada # Comments we are wacking completly including the begin 1187dd88ab32SMasahiro Yamada # and end, all to $;. 1188dd88ab32SMasahiro Yamada if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1189dd88ab32SMasahiro Yamada $sanitise_quote = '*/'; 1190dd88ab32SMasahiro Yamada 1191dd88ab32SMasahiro Yamada substr($res, $off, 2, "$;$;"); 1192dd88ab32SMasahiro Yamada $off++; 1193dd88ab32SMasahiro Yamada next; 1194dd88ab32SMasahiro Yamada } 1195dd88ab32SMasahiro Yamada if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1196dd88ab32SMasahiro Yamada $sanitise_quote = ''; 1197dd88ab32SMasahiro Yamada substr($res, $off, 2, "$;$;"); 1198dd88ab32SMasahiro Yamada $off++; 1199dd88ab32SMasahiro Yamada next; 1200dd88ab32SMasahiro Yamada } 1201dd88ab32SMasahiro Yamada if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1202dd88ab32SMasahiro Yamada $sanitise_quote = '//'; 1203dd88ab32SMasahiro Yamada 1204dd88ab32SMasahiro Yamada substr($res, $off, 2, $sanitise_quote); 1205dd88ab32SMasahiro Yamada $off++; 1206dd88ab32SMasahiro Yamada next; 1207dd88ab32SMasahiro Yamada } 1208dd88ab32SMasahiro Yamada 1209dd88ab32SMasahiro Yamada # A \ in a string means ignore the next character. 1210dd88ab32SMasahiro Yamada if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1211dd88ab32SMasahiro Yamada $c eq "\\") { 1212dd88ab32SMasahiro Yamada substr($res, $off, 2, 'XX'); 1213dd88ab32SMasahiro Yamada $off++; 1214dd88ab32SMasahiro Yamada next; 1215dd88ab32SMasahiro Yamada } 1216dd88ab32SMasahiro Yamada # Regular quotes. 1217dd88ab32SMasahiro Yamada if ($c eq "'" || $c eq '"') { 1218dd88ab32SMasahiro Yamada if ($sanitise_quote eq '') { 1219dd88ab32SMasahiro Yamada $sanitise_quote = $c; 1220dd88ab32SMasahiro Yamada 1221dd88ab32SMasahiro Yamada substr($res, $off, 1, $c); 1222dd88ab32SMasahiro Yamada next; 1223dd88ab32SMasahiro Yamada } elsif ($sanitise_quote eq $c) { 1224dd88ab32SMasahiro Yamada $sanitise_quote = ''; 1225dd88ab32SMasahiro Yamada } 1226dd88ab32SMasahiro Yamada } 1227dd88ab32SMasahiro Yamada 1228dd88ab32SMasahiro Yamada #print "c<$c> SQ<$sanitise_quote>\n"; 1229dd88ab32SMasahiro Yamada if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1230dd88ab32SMasahiro Yamada substr($res, $off, 1, $;); 1231dd88ab32SMasahiro Yamada } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1232dd88ab32SMasahiro Yamada substr($res, $off, 1, $;); 1233dd88ab32SMasahiro Yamada } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1234dd88ab32SMasahiro Yamada substr($res, $off, 1, 'X'); 1235dd88ab32SMasahiro Yamada } else { 1236dd88ab32SMasahiro Yamada substr($res, $off, 1, $c); 1237dd88ab32SMasahiro Yamada } 1238dd88ab32SMasahiro Yamada } 1239dd88ab32SMasahiro Yamada 1240dd88ab32SMasahiro Yamada if ($sanitise_quote eq '//') { 1241dd88ab32SMasahiro Yamada $sanitise_quote = ''; 1242dd88ab32SMasahiro Yamada } 1243dd88ab32SMasahiro Yamada 1244dd88ab32SMasahiro Yamada # The pathname on a #include may be surrounded by '<' and '>'. 1245dd88ab32SMasahiro Yamada if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1246dd88ab32SMasahiro Yamada my $clean = 'X' x length($1); 1247dd88ab32SMasahiro Yamada $res =~ s@\<.*\>@<$clean>@; 1248dd88ab32SMasahiro Yamada 1249dd88ab32SMasahiro Yamada # The whole of a #error is a string. 1250dd88ab32SMasahiro Yamada } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1251dd88ab32SMasahiro Yamada my $clean = 'X' x length($1); 1252dd88ab32SMasahiro Yamada $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1253dd88ab32SMasahiro Yamada } 1254dd88ab32SMasahiro Yamada 12557551eb4fSHeinrich Schuchardt if ($allow_c99_comments && $res =~ m@(//.*$)@) { 12567551eb4fSHeinrich Schuchardt my $match = $1; 12577551eb4fSHeinrich Schuchardt $res =~ s/\Q$match\E/"$;" x length($match)/e; 12587551eb4fSHeinrich Schuchardt } 12597551eb4fSHeinrich Schuchardt 1260dd88ab32SMasahiro Yamada return $res; 1261dd88ab32SMasahiro Yamada} 1262dd88ab32SMasahiro Yamada 12636b9709d9STom Rinisub get_quoted_string { 12646b9709d9STom Rini my ($line, $rawline) = @_; 12656b9709d9STom Rini 12667551eb4fSHeinrich Schuchardt return "" if ($line !~ m/($String)/g); 12676b9709d9STom Rini return substr($rawline, $-[0], $+[0] - $-[0]); 12686b9709d9STom Rini} 12696b9709d9STom Rini 1270dd88ab32SMasahiro Yamadasub ctx_statement_block { 1271dd88ab32SMasahiro Yamada my ($linenr, $remain, $off) = @_; 1272dd88ab32SMasahiro Yamada my $line = $linenr - 1; 1273dd88ab32SMasahiro Yamada my $blk = ''; 1274dd88ab32SMasahiro Yamada my $soff = $off; 1275dd88ab32SMasahiro Yamada my $coff = $off - 1; 1276dd88ab32SMasahiro Yamada my $coff_set = 0; 1277dd88ab32SMasahiro Yamada 1278dd88ab32SMasahiro Yamada my $loff = 0; 1279dd88ab32SMasahiro Yamada 1280dd88ab32SMasahiro Yamada my $type = ''; 1281dd88ab32SMasahiro Yamada my $level = 0; 1282dd88ab32SMasahiro Yamada my @stack = (); 1283dd88ab32SMasahiro Yamada my $p; 1284dd88ab32SMasahiro Yamada my $c; 1285dd88ab32SMasahiro Yamada my $len = 0; 1286dd88ab32SMasahiro Yamada 1287dd88ab32SMasahiro Yamada my $remainder; 1288dd88ab32SMasahiro Yamada while (1) { 1289dd88ab32SMasahiro Yamada @stack = (['', 0]) if ($#stack == -1); 1290dd88ab32SMasahiro Yamada 1291dd88ab32SMasahiro Yamada #warn "CSB: blk<$blk> remain<$remain>\n"; 1292dd88ab32SMasahiro Yamada # If we are about to drop off the end, pull in more 1293dd88ab32SMasahiro Yamada # context. 1294dd88ab32SMasahiro Yamada if ($off >= $len) { 1295dd88ab32SMasahiro Yamada for (; $remain > 0; $line++) { 1296dd88ab32SMasahiro Yamada last if (!defined $lines[$line]); 1297dd88ab32SMasahiro Yamada next if ($lines[$line] =~ /^-/); 1298dd88ab32SMasahiro Yamada $remain--; 1299dd88ab32SMasahiro Yamada $loff = $len; 1300dd88ab32SMasahiro Yamada $blk .= $lines[$line] . "\n"; 1301dd88ab32SMasahiro Yamada $len = length($blk); 1302dd88ab32SMasahiro Yamada $line++; 1303dd88ab32SMasahiro Yamada last; 1304dd88ab32SMasahiro Yamada } 1305dd88ab32SMasahiro Yamada # Bail if there is no further context. 1306dd88ab32SMasahiro Yamada #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 1307dd88ab32SMasahiro Yamada if ($off >= $len) { 1308dd88ab32SMasahiro Yamada last; 1309dd88ab32SMasahiro Yamada } 1310dd88ab32SMasahiro Yamada if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1311dd88ab32SMasahiro Yamada $level++; 1312dd88ab32SMasahiro Yamada $type = '#'; 1313dd88ab32SMasahiro Yamada } 1314dd88ab32SMasahiro Yamada } 1315dd88ab32SMasahiro Yamada $p = $c; 1316dd88ab32SMasahiro Yamada $c = substr($blk, $off, 1); 1317dd88ab32SMasahiro Yamada $remainder = substr($blk, $off); 1318dd88ab32SMasahiro Yamada 1319dd88ab32SMasahiro Yamada #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 1320dd88ab32SMasahiro Yamada 1321dd88ab32SMasahiro Yamada # Handle nested #if/#else. 1322dd88ab32SMasahiro Yamada if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 1323dd88ab32SMasahiro Yamada push(@stack, [ $type, $level ]); 1324dd88ab32SMasahiro Yamada } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 1325dd88ab32SMasahiro Yamada ($type, $level) = @{$stack[$#stack - 1]}; 1326dd88ab32SMasahiro Yamada } elsif ($remainder =~ /^#\s*endif\b/) { 1327dd88ab32SMasahiro Yamada ($type, $level) = @{pop(@stack)}; 1328dd88ab32SMasahiro Yamada } 1329dd88ab32SMasahiro Yamada 1330dd88ab32SMasahiro Yamada # Statement ends at the ';' or a close '}' at the 1331dd88ab32SMasahiro Yamada # outermost level. 1332dd88ab32SMasahiro Yamada if ($level == 0 && $c eq ';') { 1333dd88ab32SMasahiro Yamada last; 1334dd88ab32SMasahiro Yamada } 1335dd88ab32SMasahiro Yamada 1336dd88ab32SMasahiro Yamada # An else is really a conditional as long as its not else if 1337dd88ab32SMasahiro Yamada if ($level == 0 && $coff_set == 0 && 1338dd88ab32SMasahiro Yamada (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1339dd88ab32SMasahiro Yamada $remainder =~ /^(else)(?:\s|{)/ && 1340dd88ab32SMasahiro Yamada $remainder !~ /^else\s+if\b/) { 1341dd88ab32SMasahiro Yamada $coff = $off + length($1) - 1; 1342dd88ab32SMasahiro Yamada $coff_set = 1; 1343dd88ab32SMasahiro Yamada #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1344dd88ab32SMasahiro Yamada #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 1345dd88ab32SMasahiro Yamada } 1346dd88ab32SMasahiro Yamada 1347dd88ab32SMasahiro Yamada if (($type eq '' || $type eq '(') && $c eq '(') { 1348dd88ab32SMasahiro Yamada $level++; 1349dd88ab32SMasahiro Yamada $type = '('; 1350dd88ab32SMasahiro Yamada } 1351dd88ab32SMasahiro Yamada if ($type eq '(' && $c eq ')') { 1352dd88ab32SMasahiro Yamada $level--; 1353dd88ab32SMasahiro Yamada $type = ($level != 0)? '(' : ''; 1354dd88ab32SMasahiro Yamada 1355dd88ab32SMasahiro Yamada if ($level == 0 && $coff < $soff) { 1356dd88ab32SMasahiro Yamada $coff = $off; 1357dd88ab32SMasahiro Yamada $coff_set = 1; 1358dd88ab32SMasahiro Yamada #warn "CSB: mark coff<$coff>\n"; 1359dd88ab32SMasahiro Yamada } 1360dd88ab32SMasahiro Yamada } 1361dd88ab32SMasahiro Yamada if (($type eq '' || $type eq '{') && $c eq '{') { 1362dd88ab32SMasahiro Yamada $level++; 1363dd88ab32SMasahiro Yamada $type = '{'; 1364dd88ab32SMasahiro Yamada } 1365dd88ab32SMasahiro Yamada if ($type eq '{' && $c eq '}') { 1366dd88ab32SMasahiro Yamada $level--; 1367dd88ab32SMasahiro Yamada $type = ($level != 0)? '{' : ''; 1368dd88ab32SMasahiro Yamada 1369dd88ab32SMasahiro Yamada if ($level == 0) { 1370dd88ab32SMasahiro Yamada if (substr($blk, $off + 1, 1) eq ';') { 1371dd88ab32SMasahiro Yamada $off++; 1372dd88ab32SMasahiro Yamada } 1373dd88ab32SMasahiro Yamada last; 1374dd88ab32SMasahiro Yamada } 1375dd88ab32SMasahiro Yamada } 1376dd88ab32SMasahiro Yamada # Preprocessor commands end at the newline unless escaped. 1377dd88ab32SMasahiro Yamada if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1378dd88ab32SMasahiro Yamada $level--; 1379dd88ab32SMasahiro Yamada $type = ''; 1380dd88ab32SMasahiro Yamada $off++; 1381dd88ab32SMasahiro Yamada last; 1382dd88ab32SMasahiro Yamada } 1383dd88ab32SMasahiro Yamada $off++; 1384dd88ab32SMasahiro Yamada } 1385dd88ab32SMasahiro Yamada # We are truly at the end, so shuffle to the next line. 1386dd88ab32SMasahiro Yamada if ($off == $len) { 1387dd88ab32SMasahiro Yamada $loff = $len + 1; 1388dd88ab32SMasahiro Yamada $line++; 1389dd88ab32SMasahiro Yamada $remain--; 1390dd88ab32SMasahiro Yamada } 1391dd88ab32SMasahiro Yamada 1392dd88ab32SMasahiro Yamada my $statement = substr($blk, $soff, $off - $soff + 1); 1393dd88ab32SMasahiro Yamada my $condition = substr($blk, $soff, $coff - $soff + 1); 1394dd88ab32SMasahiro Yamada 1395dd88ab32SMasahiro Yamada #warn "STATEMENT<$statement>\n"; 1396dd88ab32SMasahiro Yamada #warn "CONDITION<$condition>\n"; 1397dd88ab32SMasahiro Yamada 1398dd88ab32SMasahiro Yamada #print "coff<$coff> soff<$off> loff<$loff>\n"; 1399dd88ab32SMasahiro Yamada 1400dd88ab32SMasahiro Yamada return ($statement, $condition, 1401dd88ab32SMasahiro Yamada $line, $remain + 1, $off - $loff + 1, $level); 1402dd88ab32SMasahiro Yamada} 1403dd88ab32SMasahiro Yamada 1404dd88ab32SMasahiro Yamadasub statement_lines { 1405dd88ab32SMasahiro Yamada my ($stmt) = @_; 1406dd88ab32SMasahiro Yamada 1407dd88ab32SMasahiro Yamada # Strip the diff line prefixes and rip blank lines at start and end. 1408dd88ab32SMasahiro Yamada $stmt =~ s/(^|\n)./$1/g; 1409dd88ab32SMasahiro Yamada $stmt =~ s/^\s*//; 1410dd88ab32SMasahiro Yamada $stmt =~ s/\s*$//; 1411dd88ab32SMasahiro Yamada 1412dd88ab32SMasahiro Yamada my @stmt_lines = ($stmt =~ /\n/g); 1413dd88ab32SMasahiro Yamada 1414dd88ab32SMasahiro Yamada return $#stmt_lines + 2; 1415dd88ab32SMasahiro Yamada} 1416dd88ab32SMasahiro Yamada 1417dd88ab32SMasahiro Yamadasub statement_rawlines { 1418dd88ab32SMasahiro Yamada my ($stmt) = @_; 1419dd88ab32SMasahiro Yamada 1420dd88ab32SMasahiro Yamada my @stmt_lines = ($stmt =~ /\n/g); 1421dd88ab32SMasahiro Yamada 1422dd88ab32SMasahiro Yamada return $#stmt_lines + 2; 1423dd88ab32SMasahiro Yamada} 1424dd88ab32SMasahiro Yamada 1425dd88ab32SMasahiro Yamadasub statement_block_size { 1426dd88ab32SMasahiro Yamada my ($stmt) = @_; 1427dd88ab32SMasahiro Yamada 1428dd88ab32SMasahiro Yamada $stmt =~ s/(^|\n)./$1/g; 1429dd88ab32SMasahiro Yamada $stmt =~ s/^\s*{//; 1430dd88ab32SMasahiro Yamada $stmt =~ s/}\s*$//; 1431dd88ab32SMasahiro Yamada $stmt =~ s/^\s*//; 1432dd88ab32SMasahiro Yamada $stmt =~ s/\s*$//; 1433dd88ab32SMasahiro Yamada 1434dd88ab32SMasahiro Yamada my @stmt_lines = ($stmt =~ /\n/g); 1435dd88ab32SMasahiro Yamada my @stmt_statements = ($stmt =~ /;/g); 1436dd88ab32SMasahiro Yamada 1437dd88ab32SMasahiro Yamada my $stmt_lines = $#stmt_lines + 2; 1438dd88ab32SMasahiro Yamada my $stmt_statements = $#stmt_statements + 1; 1439dd88ab32SMasahiro Yamada 1440dd88ab32SMasahiro Yamada if ($stmt_lines > $stmt_statements) { 1441dd88ab32SMasahiro Yamada return $stmt_lines; 1442dd88ab32SMasahiro Yamada } else { 1443dd88ab32SMasahiro Yamada return $stmt_statements; 1444dd88ab32SMasahiro Yamada } 1445dd88ab32SMasahiro Yamada} 1446dd88ab32SMasahiro Yamada 1447dd88ab32SMasahiro Yamadasub ctx_statement_full { 1448dd88ab32SMasahiro Yamada my ($linenr, $remain, $off) = @_; 1449dd88ab32SMasahiro Yamada my ($statement, $condition, $level); 1450dd88ab32SMasahiro Yamada 1451dd88ab32SMasahiro Yamada my (@chunks); 1452dd88ab32SMasahiro Yamada 1453dd88ab32SMasahiro Yamada # Grab the first conditional/block pair. 1454dd88ab32SMasahiro Yamada ($statement, $condition, $linenr, $remain, $off, $level) = 1455dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $remain, $off); 1456dd88ab32SMasahiro Yamada #print "F: c<$condition> s<$statement> remain<$remain>\n"; 1457dd88ab32SMasahiro Yamada push(@chunks, [ $condition, $statement ]); 1458dd88ab32SMasahiro Yamada if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1459dd88ab32SMasahiro Yamada return ($level, $linenr, @chunks); 1460dd88ab32SMasahiro Yamada } 1461dd88ab32SMasahiro Yamada 1462dd88ab32SMasahiro Yamada # Pull in the following conditional/block pairs and see if they 1463dd88ab32SMasahiro Yamada # could continue the statement. 1464dd88ab32SMasahiro Yamada for (;;) { 1465dd88ab32SMasahiro Yamada ($statement, $condition, $linenr, $remain, $off, $level) = 1466dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $remain, $off); 1467dd88ab32SMasahiro Yamada #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1468dd88ab32SMasahiro Yamada last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1469dd88ab32SMasahiro Yamada #print "C: push\n"; 1470dd88ab32SMasahiro Yamada push(@chunks, [ $condition, $statement ]); 1471dd88ab32SMasahiro Yamada } 1472dd88ab32SMasahiro Yamada 1473dd88ab32SMasahiro Yamada return ($level, $linenr, @chunks); 1474dd88ab32SMasahiro Yamada} 1475dd88ab32SMasahiro Yamada 1476dd88ab32SMasahiro Yamadasub ctx_block_get { 1477dd88ab32SMasahiro Yamada my ($linenr, $remain, $outer, $open, $close, $off) = @_; 1478dd88ab32SMasahiro Yamada my $line; 1479dd88ab32SMasahiro Yamada my $start = $linenr - 1; 1480dd88ab32SMasahiro Yamada my $blk = ''; 1481dd88ab32SMasahiro Yamada my @o; 1482dd88ab32SMasahiro Yamada my @c; 1483dd88ab32SMasahiro Yamada my @res = (); 1484dd88ab32SMasahiro Yamada 1485dd88ab32SMasahiro Yamada my $level = 0; 1486dd88ab32SMasahiro Yamada my @stack = ($level); 1487dd88ab32SMasahiro Yamada for ($line = $start; $remain > 0; $line++) { 1488dd88ab32SMasahiro Yamada next if ($rawlines[$line] =~ /^-/); 1489dd88ab32SMasahiro Yamada $remain--; 1490dd88ab32SMasahiro Yamada 1491dd88ab32SMasahiro Yamada $blk .= $rawlines[$line]; 1492dd88ab32SMasahiro Yamada 1493dd88ab32SMasahiro Yamada # Handle nested #if/#else. 1494dd88ab32SMasahiro Yamada if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 1495dd88ab32SMasahiro Yamada push(@stack, $level); 1496dd88ab32SMasahiro Yamada } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 1497dd88ab32SMasahiro Yamada $level = $stack[$#stack - 1]; 1498dd88ab32SMasahiro Yamada } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 1499dd88ab32SMasahiro Yamada $level = pop(@stack); 1500dd88ab32SMasahiro Yamada } 1501dd88ab32SMasahiro Yamada 1502dd88ab32SMasahiro Yamada foreach my $c (split(//, $lines[$line])) { 1503dd88ab32SMasahiro Yamada ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1504dd88ab32SMasahiro Yamada if ($off > 0) { 1505dd88ab32SMasahiro Yamada $off--; 1506dd88ab32SMasahiro Yamada next; 1507dd88ab32SMasahiro Yamada } 1508dd88ab32SMasahiro Yamada 1509dd88ab32SMasahiro Yamada if ($c eq $close && $level > 0) { 1510dd88ab32SMasahiro Yamada $level--; 1511dd88ab32SMasahiro Yamada last if ($level == 0); 1512dd88ab32SMasahiro Yamada } elsif ($c eq $open) { 1513dd88ab32SMasahiro Yamada $level++; 1514dd88ab32SMasahiro Yamada } 1515dd88ab32SMasahiro Yamada } 1516dd88ab32SMasahiro Yamada 1517dd88ab32SMasahiro Yamada if (!$outer || $level <= 1) { 1518dd88ab32SMasahiro Yamada push(@res, $rawlines[$line]); 1519dd88ab32SMasahiro Yamada } 1520dd88ab32SMasahiro Yamada 1521dd88ab32SMasahiro Yamada last if ($level == 0); 1522dd88ab32SMasahiro Yamada } 1523dd88ab32SMasahiro Yamada 1524dd88ab32SMasahiro Yamada return ($level, @res); 1525dd88ab32SMasahiro Yamada} 1526dd88ab32SMasahiro Yamadasub ctx_block_outer { 1527dd88ab32SMasahiro Yamada my ($linenr, $remain) = @_; 1528dd88ab32SMasahiro Yamada 1529dd88ab32SMasahiro Yamada my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1530dd88ab32SMasahiro Yamada return @r; 1531dd88ab32SMasahiro Yamada} 1532dd88ab32SMasahiro Yamadasub ctx_block { 1533dd88ab32SMasahiro Yamada my ($linenr, $remain) = @_; 1534dd88ab32SMasahiro Yamada 1535dd88ab32SMasahiro Yamada my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1536dd88ab32SMasahiro Yamada return @r; 1537dd88ab32SMasahiro Yamada} 1538dd88ab32SMasahiro Yamadasub ctx_statement { 1539dd88ab32SMasahiro Yamada my ($linenr, $remain, $off) = @_; 1540dd88ab32SMasahiro Yamada 1541dd88ab32SMasahiro Yamada my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1542dd88ab32SMasahiro Yamada return @r; 1543dd88ab32SMasahiro Yamada} 1544dd88ab32SMasahiro Yamadasub ctx_block_level { 1545dd88ab32SMasahiro Yamada my ($linenr, $remain) = @_; 1546dd88ab32SMasahiro Yamada 1547dd88ab32SMasahiro Yamada return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1548dd88ab32SMasahiro Yamada} 1549dd88ab32SMasahiro Yamadasub ctx_statement_level { 1550dd88ab32SMasahiro Yamada my ($linenr, $remain, $off) = @_; 1551dd88ab32SMasahiro Yamada 1552dd88ab32SMasahiro Yamada return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1553dd88ab32SMasahiro Yamada} 1554dd88ab32SMasahiro Yamada 1555dd88ab32SMasahiro Yamadasub ctx_locate_comment { 1556dd88ab32SMasahiro Yamada my ($first_line, $end_line) = @_; 1557dd88ab32SMasahiro Yamada 1558dd88ab32SMasahiro Yamada # Catch a comment on the end of the line itself. 1559dd88ab32SMasahiro Yamada my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 1560dd88ab32SMasahiro Yamada return $current_comment if (defined $current_comment); 1561dd88ab32SMasahiro Yamada 1562dd88ab32SMasahiro Yamada # Look through the context and try and figure out if there is a 1563dd88ab32SMasahiro Yamada # comment. 1564dd88ab32SMasahiro Yamada my $in_comment = 0; 1565dd88ab32SMasahiro Yamada $current_comment = ''; 1566dd88ab32SMasahiro Yamada for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 1567dd88ab32SMasahiro Yamada my $line = $rawlines[$linenr - 1]; 1568dd88ab32SMasahiro Yamada #warn " $line\n"; 1569dd88ab32SMasahiro Yamada if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 1570dd88ab32SMasahiro Yamada $in_comment = 1; 1571dd88ab32SMasahiro Yamada } 1572dd88ab32SMasahiro Yamada if ($line =~ m@/\*@) { 1573dd88ab32SMasahiro Yamada $in_comment = 1; 1574dd88ab32SMasahiro Yamada } 1575dd88ab32SMasahiro Yamada if (!$in_comment && $current_comment ne '') { 1576dd88ab32SMasahiro Yamada $current_comment = ''; 1577dd88ab32SMasahiro Yamada } 1578dd88ab32SMasahiro Yamada $current_comment .= $line . "\n" if ($in_comment); 1579dd88ab32SMasahiro Yamada if ($line =~ m@\*/@) { 1580dd88ab32SMasahiro Yamada $in_comment = 0; 1581dd88ab32SMasahiro Yamada } 1582dd88ab32SMasahiro Yamada } 1583dd88ab32SMasahiro Yamada 1584dd88ab32SMasahiro Yamada chomp($current_comment); 1585dd88ab32SMasahiro Yamada return($current_comment); 1586dd88ab32SMasahiro Yamada} 1587dd88ab32SMasahiro Yamadasub ctx_has_comment { 1588dd88ab32SMasahiro Yamada my ($first_line, $end_line) = @_; 1589dd88ab32SMasahiro Yamada my $cmt = ctx_locate_comment($first_line, $end_line); 1590dd88ab32SMasahiro Yamada 1591dd88ab32SMasahiro Yamada ##print "LINE: $rawlines[$end_line - 1 ]\n"; 1592dd88ab32SMasahiro Yamada ##print "CMMT: $cmt\n"; 1593dd88ab32SMasahiro Yamada 1594dd88ab32SMasahiro Yamada return ($cmt ne ''); 1595dd88ab32SMasahiro Yamada} 1596dd88ab32SMasahiro Yamada 1597dd88ab32SMasahiro Yamadasub raw_line { 1598dd88ab32SMasahiro Yamada my ($linenr, $cnt) = @_; 1599dd88ab32SMasahiro Yamada 1600dd88ab32SMasahiro Yamada my $offset = $linenr - 1; 1601dd88ab32SMasahiro Yamada $cnt++; 1602dd88ab32SMasahiro Yamada 1603dd88ab32SMasahiro Yamada my $line; 1604dd88ab32SMasahiro Yamada while ($cnt) { 1605dd88ab32SMasahiro Yamada $line = $rawlines[$offset++]; 1606dd88ab32SMasahiro Yamada next if (defined($line) && $line =~ /^-/); 1607dd88ab32SMasahiro Yamada $cnt--; 1608dd88ab32SMasahiro Yamada } 1609dd88ab32SMasahiro Yamada 1610dd88ab32SMasahiro Yamada return $line; 1611dd88ab32SMasahiro Yamada} 1612dd88ab32SMasahiro Yamada 1613dd88ab32SMasahiro Yamadasub cat_vet { 1614dd88ab32SMasahiro Yamada my ($vet) = @_; 1615dd88ab32SMasahiro Yamada my ($res, $coded); 1616dd88ab32SMasahiro Yamada 1617dd88ab32SMasahiro Yamada $res = ''; 1618dd88ab32SMasahiro Yamada while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 1619dd88ab32SMasahiro Yamada $res .= $1; 1620dd88ab32SMasahiro Yamada if ($2 ne '') { 1621dd88ab32SMasahiro Yamada $coded = sprintf("^%c", unpack('C', $2) + 64); 1622dd88ab32SMasahiro Yamada $res .= $coded; 1623dd88ab32SMasahiro Yamada } 1624dd88ab32SMasahiro Yamada } 1625dd88ab32SMasahiro Yamada $res =~ s/$/\$/; 1626dd88ab32SMasahiro Yamada 1627dd88ab32SMasahiro Yamada return $res; 1628dd88ab32SMasahiro Yamada} 1629dd88ab32SMasahiro Yamada 1630dd88ab32SMasahiro Yamadamy $av_preprocessor = 0; 1631dd88ab32SMasahiro Yamadamy $av_pending; 1632dd88ab32SMasahiro Yamadamy @av_paren_type; 1633dd88ab32SMasahiro Yamadamy $av_pend_colon; 1634dd88ab32SMasahiro Yamada 1635dd88ab32SMasahiro Yamadasub annotate_reset { 1636dd88ab32SMasahiro Yamada $av_preprocessor = 0; 1637dd88ab32SMasahiro Yamada $av_pending = '_'; 1638dd88ab32SMasahiro Yamada @av_paren_type = ('E'); 1639dd88ab32SMasahiro Yamada $av_pend_colon = 'O'; 1640dd88ab32SMasahiro Yamada} 1641dd88ab32SMasahiro Yamada 1642dd88ab32SMasahiro Yamadasub annotate_values { 1643dd88ab32SMasahiro Yamada my ($stream, $type) = @_; 1644dd88ab32SMasahiro Yamada 1645dd88ab32SMasahiro Yamada my $res; 1646dd88ab32SMasahiro Yamada my $var = '_' x length($stream); 1647dd88ab32SMasahiro Yamada my $cur = $stream; 1648dd88ab32SMasahiro Yamada 1649dd88ab32SMasahiro Yamada print "$stream\n" if ($dbg_values > 1); 1650dd88ab32SMasahiro Yamada 1651dd88ab32SMasahiro Yamada while (length($cur)) { 1652dd88ab32SMasahiro Yamada @av_paren_type = ('E') if ($#av_paren_type < 0); 1653dd88ab32SMasahiro Yamada print " <" . join('', @av_paren_type) . 1654dd88ab32SMasahiro Yamada "> <$type> <$av_pending>" if ($dbg_values > 1); 1655dd88ab32SMasahiro Yamada if ($cur =~ /^(\s+)/o) { 1656dd88ab32SMasahiro Yamada print "WS($1)\n" if ($dbg_values > 1); 1657dd88ab32SMasahiro Yamada if ($1 =~ /\n/ && $av_preprocessor) { 1658dd88ab32SMasahiro Yamada $type = pop(@av_paren_type); 1659dd88ab32SMasahiro Yamada $av_preprocessor = 0; 1660dd88ab32SMasahiro Yamada } 1661dd88ab32SMasahiro Yamada 1662dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 1663dd88ab32SMasahiro Yamada print "CAST($1)\n" if ($dbg_values > 1); 1664dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1665dd88ab32SMasahiro Yamada $type = 'c'; 1666dd88ab32SMasahiro Yamada 1667dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1668dd88ab32SMasahiro Yamada print "DECLARE($1)\n" if ($dbg_values > 1); 1669dd88ab32SMasahiro Yamada $type = 'T'; 1670dd88ab32SMasahiro Yamada 1671dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Modifier)\s*/) { 1672dd88ab32SMasahiro Yamada print "MODIFIER($1)\n" if ($dbg_values > 1); 1673dd88ab32SMasahiro Yamada $type = 'T'; 1674dd88ab32SMasahiro Yamada 1675dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1676dd88ab32SMasahiro Yamada print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1677dd88ab32SMasahiro Yamada $av_preprocessor = 1; 1678dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1679dd88ab32SMasahiro Yamada if ($2 ne '') { 1680dd88ab32SMasahiro Yamada $av_pending = 'N'; 1681dd88ab32SMasahiro Yamada } 1682dd88ab32SMasahiro Yamada $type = 'E'; 1683dd88ab32SMasahiro Yamada 1684dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1685dd88ab32SMasahiro Yamada print "UNDEF($1)\n" if ($dbg_values > 1); 1686dd88ab32SMasahiro Yamada $av_preprocessor = 1; 1687dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1688dd88ab32SMasahiro Yamada 1689dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1690dd88ab32SMasahiro Yamada print "PRE_START($1)\n" if ($dbg_values > 1); 1691dd88ab32SMasahiro Yamada $av_preprocessor = 1; 1692dd88ab32SMasahiro Yamada 1693dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1694dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1695dd88ab32SMasahiro Yamada $type = 'E'; 1696dd88ab32SMasahiro Yamada 1697dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1698dd88ab32SMasahiro Yamada print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1699dd88ab32SMasahiro Yamada $av_preprocessor = 1; 1700dd88ab32SMasahiro Yamada 1701dd88ab32SMasahiro Yamada push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1702dd88ab32SMasahiro Yamada 1703dd88ab32SMasahiro Yamada $type = 'E'; 1704dd88ab32SMasahiro Yamada 1705dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1706dd88ab32SMasahiro Yamada print "PRE_END($1)\n" if ($dbg_values > 1); 1707dd88ab32SMasahiro Yamada 1708dd88ab32SMasahiro Yamada $av_preprocessor = 1; 1709dd88ab32SMasahiro Yamada 1710dd88ab32SMasahiro Yamada # Assume all arms of the conditional end as this 1711dd88ab32SMasahiro Yamada # one does, and continue as if the #endif was not here. 1712dd88ab32SMasahiro Yamada pop(@av_paren_type); 1713dd88ab32SMasahiro Yamada push(@av_paren_type, $type); 1714dd88ab32SMasahiro Yamada $type = 'E'; 1715dd88ab32SMasahiro Yamada 1716dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\\\n)/o) { 1717dd88ab32SMasahiro Yamada print "PRECONT($1)\n" if ($dbg_values > 1); 1718dd88ab32SMasahiro Yamada 1719dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1720dd88ab32SMasahiro Yamada print "ATTR($1)\n" if ($dbg_values > 1); 1721dd88ab32SMasahiro Yamada $av_pending = $type; 1722dd88ab32SMasahiro Yamada $type = 'N'; 1723dd88ab32SMasahiro Yamada 1724dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1725dd88ab32SMasahiro Yamada print "SIZEOF($1)\n" if ($dbg_values > 1); 1726dd88ab32SMasahiro Yamada if (defined $2) { 1727dd88ab32SMasahiro Yamada $av_pending = 'V'; 1728dd88ab32SMasahiro Yamada } 1729dd88ab32SMasahiro Yamada $type = 'N'; 1730dd88ab32SMasahiro Yamada 1731dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(if|while|for)\b/o) { 1732dd88ab32SMasahiro Yamada print "COND($1)\n" if ($dbg_values > 1); 1733dd88ab32SMasahiro Yamada $av_pending = 'E'; 1734dd88ab32SMasahiro Yamada $type = 'N'; 1735dd88ab32SMasahiro Yamada 1736dd88ab32SMasahiro Yamada } elsif ($cur =~/^(case)/o) { 1737dd88ab32SMasahiro Yamada print "CASE($1)\n" if ($dbg_values > 1); 1738dd88ab32SMasahiro Yamada $av_pend_colon = 'C'; 1739dd88ab32SMasahiro Yamada $type = 'N'; 1740dd88ab32SMasahiro Yamada 1741dd88ab32SMasahiro Yamada } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1742dd88ab32SMasahiro Yamada print "KEYWORD($1)\n" if ($dbg_values > 1); 1743dd88ab32SMasahiro Yamada $type = 'N'; 1744dd88ab32SMasahiro Yamada 1745dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\()/o) { 1746dd88ab32SMasahiro Yamada print "PAREN('$1')\n" if ($dbg_values > 1); 1747dd88ab32SMasahiro Yamada push(@av_paren_type, $av_pending); 1748dd88ab32SMasahiro Yamada $av_pending = '_'; 1749dd88ab32SMasahiro Yamada $type = 'N'; 1750dd88ab32SMasahiro Yamada 1751dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\))/o) { 1752dd88ab32SMasahiro Yamada my $new_type = pop(@av_paren_type); 1753dd88ab32SMasahiro Yamada if ($new_type ne '_') { 1754dd88ab32SMasahiro Yamada $type = $new_type; 1755dd88ab32SMasahiro Yamada print "PAREN('$1') -> $type\n" 1756dd88ab32SMasahiro Yamada if ($dbg_values > 1); 1757dd88ab32SMasahiro Yamada } else { 1758dd88ab32SMasahiro Yamada print "PAREN('$1')\n" if ($dbg_values > 1); 1759dd88ab32SMasahiro Yamada } 1760dd88ab32SMasahiro Yamada 1761dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Ident)\s*\(/o) { 1762dd88ab32SMasahiro Yamada print "FUNC($1)\n" if ($dbg_values > 1); 1763dd88ab32SMasahiro Yamada $type = 'V'; 1764dd88ab32SMasahiro Yamada $av_pending = 'V'; 1765dd88ab32SMasahiro Yamada 1766dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 1767dd88ab32SMasahiro Yamada if (defined $2 && $type eq 'C' || $type eq 'T') { 1768dd88ab32SMasahiro Yamada $av_pend_colon = 'B'; 1769dd88ab32SMasahiro Yamada } elsif ($type eq 'E') { 1770dd88ab32SMasahiro Yamada $av_pend_colon = 'L'; 1771dd88ab32SMasahiro Yamada } 1772dd88ab32SMasahiro Yamada print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 1773dd88ab32SMasahiro Yamada $type = 'V'; 1774dd88ab32SMasahiro Yamada 1775dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Ident|$Constant)/o) { 1776dd88ab32SMasahiro Yamada print "IDENT($1)\n" if ($dbg_values > 1); 1777dd88ab32SMasahiro Yamada $type = 'V'; 1778dd88ab32SMasahiro Yamada 1779dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Assignment)/o) { 1780dd88ab32SMasahiro Yamada print "ASSIGN($1)\n" if ($dbg_values > 1); 1781dd88ab32SMasahiro Yamada $type = 'N'; 1782dd88ab32SMasahiro Yamada 1783dd88ab32SMasahiro Yamada } elsif ($cur =~/^(;|{|})/) { 1784dd88ab32SMasahiro Yamada print "END($1)\n" if ($dbg_values > 1); 1785dd88ab32SMasahiro Yamada $type = 'E'; 1786dd88ab32SMasahiro Yamada $av_pend_colon = 'O'; 1787dd88ab32SMasahiro Yamada 1788dd88ab32SMasahiro Yamada } elsif ($cur =~/^(,)/) { 1789dd88ab32SMasahiro Yamada print "COMMA($1)\n" if ($dbg_values > 1); 1790dd88ab32SMasahiro Yamada $type = 'C'; 1791dd88ab32SMasahiro Yamada 1792dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\?)/o) { 1793dd88ab32SMasahiro Yamada print "QUESTION($1)\n" if ($dbg_values > 1); 1794dd88ab32SMasahiro Yamada $type = 'N'; 1795dd88ab32SMasahiro Yamada 1796dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(:)/o) { 1797dd88ab32SMasahiro Yamada print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 1798dd88ab32SMasahiro Yamada 1799dd88ab32SMasahiro Yamada substr($var, length($res), 1, $av_pend_colon); 1800dd88ab32SMasahiro Yamada if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 1801dd88ab32SMasahiro Yamada $type = 'E'; 1802dd88ab32SMasahiro Yamada } else { 1803dd88ab32SMasahiro Yamada $type = 'N'; 1804dd88ab32SMasahiro Yamada } 1805dd88ab32SMasahiro Yamada $av_pend_colon = 'O'; 1806dd88ab32SMasahiro Yamada 1807dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(\[)/o) { 1808dd88ab32SMasahiro Yamada print "CLOSE($1)\n" if ($dbg_values > 1); 1809dd88ab32SMasahiro Yamada $type = 'N'; 1810dd88ab32SMasahiro Yamada 1811dd88ab32SMasahiro Yamada } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 1812dd88ab32SMasahiro Yamada my $variant; 1813dd88ab32SMasahiro Yamada 1814dd88ab32SMasahiro Yamada print "OPV($1)\n" if ($dbg_values > 1); 1815dd88ab32SMasahiro Yamada if ($type eq 'V') { 1816dd88ab32SMasahiro Yamada $variant = 'B'; 1817dd88ab32SMasahiro Yamada } else { 1818dd88ab32SMasahiro Yamada $variant = 'U'; 1819dd88ab32SMasahiro Yamada } 1820dd88ab32SMasahiro Yamada 1821dd88ab32SMasahiro Yamada substr($var, length($res), 1, $variant); 1822dd88ab32SMasahiro Yamada $type = 'N'; 1823dd88ab32SMasahiro Yamada 1824dd88ab32SMasahiro Yamada } elsif ($cur =~ /^($Operators)/o) { 1825dd88ab32SMasahiro Yamada print "OP($1)\n" if ($dbg_values > 1); 1826dd88ab32SMasahiro Yamada if ($1 ne '++' && $1 ne '--') { 1827dd88ab32SMasahiro Yamada $type = 'N'; 1828dd88ab32SMasahiro Yamada } 1829dd88ab32SMasahiro Yamada 1830dd88ab32SMasahiro Yamada } elsif ($cur =~ /(^.)/o) { 1831dd88ab32SMasahiro Yamada print "C($1)\n" if ($dbg_values > 1); 1832dd88ab32SMasahiro Yamada } 1833dd88ab32SMasahiro Yamada if (defined $1) { 1834dd88ab32SMasahiro Yamada $cur = substr($cur, length($1)); 1835dd88ab32SMasahiro Yamada $res .= $type x length($1); 1836dd88ab32SMasahiro Yamada } 1837dd88ab32SMasahiro Yamada } 1838dd88ab32SMasahiro Yamada 1839dd88ab32SMasahiro Yamada return ($res, $var); 1840dd88ab32SMasahiro Yamada} 1841dd88ab32SMasahiro Yamada 1842dd88ab32SMasahiro Yamadasub possible { 1843dd88ab32SMasahiro Yamada my ($possible, $line) = @_; 1844dd88ab32SMasahiro Yamada my $notPermitted = qr{(?: 1845dd88ab32SMasahiro Yamada ^(?: 1846dd88ab32SMasahiro Yamada $Modifier| 1847dd88ab32SMasahiro Yamada $Storage| 1848dd88ab32SMasahiro Yamada $Type| 1849dd88ab32SMasahiro Yamada DEFINE_\S+ 1850dd88ab32SMasahiro Yamada )$| 1851dd88ab32SMasahiro Yamada ^(?: 1852dd88ab32SMasahiro Yamada goto| 1853dd88ab32SMasahiro Yamada return| 1854dd88ab32SMasahiro Yamada case| 1855dd88ab32SMasahiro Yamada else| 1856dd88ab32SMasahiro Yamada asm|__asm__| 1857dd88ab32SMasahiro Yamada do| 1858dd88ab32SMasahiro Yamada \#| 1859dd88ab32SMasahiro Yamada \#\#| 1860dd88ab32SMasahiro Yamada )(?:\s|$)| 1861dd88ab32SMasahiro Yamada ^(?:typedef|struct|enum)\b 1862dd88ab32SMasahiro Yamada )}x; 1863dd88ab32SMasahiro Yamada warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 1864dd88ab32SMasahiro Yamada if ($possible !~ $notPermitted) { 1865dd88ab32SMasahiro Yamada # Check for modifiers. 1866dd88ab32SMasahiro Yamada $possible =~ s/\s*$Storage\s*//g; 1867dd88ab32SMasahiro Yamada $possible =~ s/\s*$Sparse\s*//g; 1868dd88ab32SMasahiro Yamada if ($possible =~ /^\s*$/) { 1869dd88ab32SMasahiro Yamada 1870dd88ab32SMasahiro Yamada } elsif ($possible =~ /\s/) { 1871dd88ab32SMasahiro Yamada $possible =~ s/\s*$Type\s*//g; 1872dd88ab32SMasahiro Yamada for my $modifier (split(' ', $possible)) { 1873dd88ab32SMasahiro Yamada if ($modifier !~ $notPermitted) { 1874dd88ab32SMasahiro Yamada warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 18757551eb4fSHeinrich Schuchardt push(@modifierListFile, $modifier); 1876dd88ab32SMasahiro Yamada } 1877dd88ab32SMasahiro Yamada } 1878dd88ab32SMasahiro Yamada 1879dd88ab32SMasahiro Yamada } else { 1880dd88ab32SMasahiro Yamada warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 18817551eb4fSHeinrich Schuchardt push(@typeListFile, $possible); 1882dd88ab32SMasahiro Yamada } 1883dd88ab32SMasahiro Yamada build_types(); 1884dd88ab32SMasahiro Yamada } else { 1885dd88ab32SMasahiro Yamada warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 1886dd88ab32SMasahiro Yamada } 1887dd88ab32SMasahiro Yamada} 1888dd88ab32SMasahiro Yamada 1889dd88ab32SMasahiro Yamadamy $prefix = ''; 1890dd88ab32SMasahiro Yamada 1891dd88ab32SMasahiro Yamadasub show_type { 18927551eb4fSHeinrich Schuchardt my ($type) = @_; 18936b9709d9STom Rini 18947551eb4fSHeinrich Schuchardt $type =~ tr/[a-z]/[A-Z]/; 18957551eb4fSHeinrich Schuchardt 18967551eb4fSHeinrich Schuchardt return defined $use_type{$type} if (scalar keys %use_type > 0); 18977551eb4fSHeinrich Schuchardt 18987551eb4fSHeinrich Schuchardt return !defined $ignore_type{$type}; 1899dd88ab32SMasahiro Yamada} 1900dd88ab32SMasahiro Yamada 1901dd88ab32SMasahiro Yamadasub report { 19027551eb4fSHeinrich Schuchardt my ($level, $type, $msg) = @_; 19037551eb4fSHeinrich Schuchardt 19047551eb4fSHeinrich Schuchardt if (!show_type($type) || 19057551eb4fSHeinrich Schuchardt (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 1906dd88ab32SMasahiro Yamada return 0; 1907dd88ab32SMasahiro Yamada } 19087551eb4fSHeinrich Schuchardt my $output = ''; 19097551eb4fSHeinrich Schuchardt if ($color) { 19107551eb4fSHeinrich Schuchardt if ($level eq 'ERROR') { 19117551eb4fSHeinrich Schuchardt $output .= RED; 19127551eb4fSHeinrich Schuchardt } elsif ($level eq 'WARNING') { 19137551eb4fSHeinrich Schuchardt $output .= YELLOW; 1914dd88ab32SMasahiro Yamada } else { 19157551eb4fSHeinrich Schuchardt $output .= GREEN; 1916dd88ab32SMasahiro Yamada } 19177551eb4fSHeinrich Schuchardt } 19187551eb4fSHeinrich Schuchardt $output .= $prefix . $level . ':'; 19197551eb4fSHeinrich Schuchardt if ($show_types) { 19207551eb4fSHeinrich Schuchardt $output .= BLUE if ($color); 19217551eb4fSHeinrich Schuchardt $output .= "$type:"; 19227551eb4fSHeinrich Schuchardt } 19237551eb4fSHeinrich Schuchardt $output .= RESET if ($color); 19247551eb4fSHeinrich Schuchardt $output .= ' ' . $msg . "\n"; 1925dd88ab32SMasahiro Yamada 19267551eb4fSHeinrich Schuchardt if ($showfile) { 19277551eb4fSHeinrich Schuchardt my @lines = split("\n", $output, -1); 19287551eb4fSHeinrich Schuchardt splice(@lines, 1, 1); 19297551eb4fSHeinrich Schuchardt $output = join("\n", @lines); 19307551eb4fSHeinrich Schuchardt } 19317551eb4fSHeinrich Schuchardt $output = (split('\n', $output))[0] . "\n" if ($terse); 19327551eb4fSHeinrich Schuchardt 19337551eb4fSHeinrich Schuchardt push(our @report, $output); 1934dd88ab32SMasahiro Yamada 1935dd88ab32SMasahiro Yamada return 1; 1936dd88ab32SMasahiro Yamada} 19377551eb4fSHeinrich Schuchardt 1938dd88ab32SMasahiro Yamadasub report_dump { 1939dd88ab32SMasahiro Yamada our @report; 1940dd88ab32SMasahiro Yamada} 1941dd88ab32SMasahiro Yamada 19427551eb4fSHeinrich Schuchardtsub fixup_current_range { 19437551eb4fSHeinrich Schuchardt my ($lineRef, $offset, $length) = @_; 19447551eb4fSHeinrich Schuchardt 19457551eb4fSHeinrich Schuchardt if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 19467551eb4fSHeinrich Schuchardt my $o = $1; 19477551eb4fSHeinrich Schuchardt my $l = $2; 19487551eb4fSHeinrich Schuchardt my $no = $o + $offset; 19497551eb4fSHeinrich Schuchardt my $nl = $l + $length; 19507551eb4fSHeinrich Schuchardt $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 19517551eb4fSHeinrich Schuchardt } 19527551eb4fSHeinrich Schuchardt} 19537551eb4fSHeinrich Schuchardt 19547551eb4fSHeinrich Schuchardtsub fix_inserted_deleted_lines { 19557551eb4fSHeinrich Schuchardt my ($linesRef, $insertedRef, $deletedRef) = @_; 19567551eb4fSHeinrich Schuchardt 19577551eb4fSHeinrich Schuchardt my $range_last_linenr = 0; 19587551eb4fSHeinrich Schuchardt my $delta_offset = 0; 19597551eb4fSHeinrich Schuchardt 19607551eb4fSHeinrich Schuchardt my $old_linenr = 0; 19617551eb4fSHeinrich Schuchardt my $new_linenr = 0; 19627551eb4fSHeinrich Schuchardt 19637551eb4fSHeinrich Schuchardt my $next_insert = 0; 19647551eb4fSHeinrich Schuchardt my $next_delete = 0; 19657551eb4fSHeinrich Schuchardt 19667551eb4fSHeinrich Schuchardt my @lines = (); 19677551eb4fSHeinrich Schuchardt 19687551eb4fSHeinrich Schuchardt my $inserted = @{$insertedRef}[$next_insert++]; 19697551eb4fSHeinrich Schuchardt my $deleted = @{$deletedRef}[$next_delete++]; 19707551eb4fSHeinrich Schuchardt 19717551eb4fSHeinrich Schuchardt foreach my $old_line (@{$linesRef}) { 19727551eb4fSHeinrich Schuchardt my $save_line = 1; 19737551eb4fSHeinrich Schuchardt my $line = $old_line; #don't modify the array 19747551eb4fSHeinrich Schuchardt if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 19757551eb4fSHeinrich Schuchardt $delta_offset = 0; 19767551eb4fSHeinrich Schuchardt } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 19777551eb4fSHeinrich Schuchardt $range_last_linenr = $new_linenr; 19787551eb4fSHeinrich Schuchardt fixup_current_range(\$line, $delta_offset, 0); 19797551eb4fSHeinrich Schuchardt } 19807551eb4fSHeinrich Schuchardt 19817551eb4fSHeinrich Schuchardt while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 19827551eb4fSHeinrich Schuchardt $deleted = @{$deletedRef}[$next_delete++]; 19837551eb4fSHeinrich Schuchardt $save_line = 0; 19847551eb4fSHeinrich Schuchardt fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 19857551eb4fSHeinrich Schuchardt } 19867551eb4fSHeinrich Schuchardt 19877551eb4fSHeinrich Schuchardt while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 19887551eb4fSHeinrich Schuchardt push(@lines, ${$inserted}{'LINE'}); 19897551eb4fSHeinrich Schuchardt $inserted = @{$insertedRef}[$next_insert++]; 19907551eb4fSHeinrich Schuchardt $new_linenr++; 19917551eb4fSHeinrich Schuchardt fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 19927551eb4fSHeinrich Schuchardt } 19937551eb4fSHeinrich Schuchardt 19947551eb4fSHeinrich Schuchardt if ($save_line) { 19957551eb4fSHeinrich Schuchardt push(@lines, $line); 19967551eb4fSHeinrich Schuchardt $new_linenr++; 19977551eb4fSHeinrich Schuchardt } 19987551eb4fSHeinrich Schuchardt 19997551eb4fSHeinrich Schuchardt $old_linenr++; 20007551eb4fSHeinrich Schuchardt } 20017551eb4fSHeinrich Schuchardt 20027551eb4fSHeinrich Schuchardt return @lines; 20037551eb4fSHeinrich Schuchardt} 20047551eb4fSHeinrich Schuchardt 20057551eb4fSHeinrich Schuchardtsub fix_insert_line { 20067551eb4fSHeinrich Schuchardt my ($linenr, $line) = @_; 20077551eb4fSHeinrich Schuchardt 20087551eb4fSHeinrich Schuchardt my $inserted = { 20097551eb4fSHeinrich Schuchardt LINENR => $linenr, 20107551eb4fSHeinrich Schuchardt LINE => $line, 20117551eb4fSHeinrich Schuchardt }; 20127551eb4fSHeinrich Schuchardt push(@fixed_inserted, $inserted); 20137551eb4fSHeinrich Schuchardt} 20147551eb4fSHeinrich Schuchardt 20157551eb4fSHeinrich Schuchardtsub fix_delete_line { 20167551eb4fSHeinrich Schuchardt my ($linenr, $line) = @_; 20177551eb4fSHeinrich Schuchardt 20187551eb4fSHeinrich Schuchardt my $deleted = { 20197551eb4fSHeinrich Schuchardt LINENR => $linenr, 20207551eb4fSHeinrich Schuchardt LINE => $line, 20217551eb4fSHeinrich Schuchardt }; 20227551eb4fSHeinrich Schuchardt 20237551eb4fSHeinrich Schuchardt push(@fixed_deleted, $deleted); 20247551eb4fSHeinrich Schuchardt} 20257551eb4fSHeinrich Schuchardt 2026dd88ab32SMasahiro Yamadasub ERROR { 20277551eb4fSHeinrich Schuchardt my ($type, $msg) = @_; 20287551eb4fSHeinrich Schuchardt 20297551eb4fSHeinrich Schuchardt if (report("ERROR", $type, $msg)) { 2030dd88ab32SMasahiro Yamada our $clean = 0; 2031dd88ab32SMasahiro Yamada our $cnt_error++; 20326b9709d9STom Rini return 1; 2033dd88ab32SMasahiro Yamada } 20346b9709d9STom Rini return 0; 2035dd88ab32SMasahiro Yamada} 2036dd88ab32SMasahiro Yamadasub WARN { 20377551eb4fSHeinrich Schuchardt my ($type, $msg) = @_; 20387551eb4fSHeinrich Schuchardt 20397551eb4fSHeinrich Schuchardt if (report("WARNING", $type, $msg)) { 2040dd88ab32SMasahiro Yamada our $clean = 0; 2041dd88ab32SMasahiro Yamada our $cnt_warn++; 20426b9709d9STom Rini return 1; 2043dd88ab32SMasahiro Yamada } 20446b9709d9STom Rini return 0; 2045dd88ab32SMasahiro Yamada} 2046dd88ab32SMasahiro Yamadasub CHK { 20477551eb4fSHeinrich Schuchardt my ($type, $msg) = @_; 20487551eb4fSHeinrich Schuchardt 20497551eb4fSHeinrich Schuchardt if ($check && report("CHECK", $type, $msg)) { 2050dd88ab32SMasahiro Yamada our $clean = 0; 2051dd88ab32SMasahiro Yamada our $cnt_chk++; 20526b9709d9STom Rini return 1; 2053dd88ab32SMasahiro Yamada } 20546b9709d9STom Rini return 0; 2055dd88ab32SMasahiro Yamada} 2056dd88ab32SMasahiro Yamada 2057dd88ab32SMasahiro Yamadasub check_absolute_file { 2058dd88ab32SMasahiro Yamada my ($absolute, $herecurr) = @_; 2059dd88ab32SMasahiro Yamada my $file = $absolute; 2060dd88ab32SMasahiro Yamada 2061dd88ab32SMasahiro Yamada ##print "absolute<$absolute>\n"; 2062dd88ab32SMasahiro Yamada 2063dd88ab32SMasahiro Yamada # See if any suffix of this path is a path within the tree. 2064dd88ab32SMasahiro Yamada while ($file =~ s@^[^/]*/@@) { 2065dd88ab32SMasahiro Yamada if (-f "$root/$file") { 2066dd88ab32SMasahiro Yamada ##print "file<$file>\n"; 2067dd88ab32SMasahiro Yamada last; 2068dd88ab32SMasahiro Yamada } 2069dd88ab32SMasahiro Yamada } 2070dd88ab32SMasahiro Yamada if (! -f _) { 2071dd88ab32SMasahiro Yamada return 0; 2072dd88ab32SMasahiro Yamada } 2073dd88ab32SMasahiro Yamada 2074dd88ab32SMasahiro Yamada # It is, so see if the prefix is acceptable. 2075dd88ab32SMasahiro Yamada my $prefix = $absolute; 2076dd88ab32SMasahiro Yamada substr($prefix, -length($file)) = ''; 2077dd88ab32SMasahiro Yamada 2078dd88ab32SMasahiro Yamada ##print "prefix<$prefix>\n"; 2079dd88ab32SMasahiro Yamada if ($prefix ne ".../") { 2080dd88ab32SMasahiro Yamada WARN("USE_RELATIVE_PATH", 2081dd88ab32SMasahiro Yamada "use relative pathname instead of absolute in changelog text\n" . $herecurr); 2082dd88ab32SMasahiro Yamada } 2083dd88ab32SMasahiro Yamada} 2084dd88ab32SMasahiro Yamada 20856b9709d9STom Rinisub trim { 20866b9709d9STom Rini my ($string) = @_; 20876b9709d9STom Rini 20886b9709d9STom Rini $string =~ s/^\s+|\s+$//g; 20896b9709d9STom Rini 20906b9709d9STom Rini return $string; 20916b9709d9STom Rini} 20926b9709d9STom Rini 20936b9709d9STom Rinisub ltrim { 20946b9709d9STom Rini my ($string) = @_; 20956b9709d9STom Rini 20966b9709d9STom Rini $string =~ s/^\s+//; 20976b9709d9STom Rini 20986b9709d9STom Rini return $string; 20996b9709d9STom Rini} 21006b9709d9STom Rini 21016b9709d9STom Rinisub rtrim { 21026b9709d9STom Rini my ($string) = @_; 21036b9709d9STom Rini 21046b9709d9STom Rini $string =~ s/\s+$//; 21056b9709d9STom Rini 21066b9709d9STom Rini return $string; 21076b9709d9STom Rini} 21086b9709d9STom Rini 21096b9709d9STom Rinisub string_find_replace { 21106b9709d9STom Rini my ($string, $find, $replace) = @_; 21116b9709d9STom Rini 21126b9709d9STom Rini $string =~ s/$find/$replace/g; 21136b9709d9STom Rini 21146b9709d9STom Rini return $string; 21156b9709d9STom Rini} 21166b9709d9STom Rini 21176b9709d9STom Rinisub tabify { 21186b9709d9STom Rini my ($leading) = @_; 21196b9709d9STom Rini 21206b9709d9STom Rini my $source_indent = 8; 21216b9709d9STom Rini my $max_spaces_before_tab = $source_indent - 1; 21226b9709d9STom Rini my $spaces_to_tab = " " x $source_indent; 21236b9709d9STom Rini 21246b9709d9STom Rini #convert leading spaces to tabs 21256b9709d9STom Rini 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 21266b9709d9STom Rini #Remove spaces before a tab 21276b9709d9STom Rini 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 21286b9709d9STom Rini 21296b9709d9STom Rini return "$leading"; 21306b9709d9STom Rini} 21316b9709d9STom Rini 2132dd88ab32SMasahiro Yamadasub pos_last_openparen { 2133dd88ab32SMasahiro Yamada my ($line) = @_; 2134dd88ab32SMasahiro Yamada 2135dd88ab32SMasahiro Yamada my $pos = 0; 2136dd88ab32SMasahiro Yamada 2137dd88ab32SMasahiro Yamada my $opens = $line =~ tr/\(/\(/; 2138dd88ab32SMasahiro Yamada my $closes = $line =~ tr/\)/\)/; 2139dd88ab32SMasahiro Yamada 2140dd88ab32SMasahiro Yamada my $last_openparen = 0; 2141dd88ab32SMasahiro Yamada 2142dd88ab32SMasahiro Yamada if (($opens == 0) || ($closes >= $opens)) { 2143dd88ab32SMasahiro Yamada return -1; 2144dd88ab32SMasahiro Yamada } 2145dd88ab32SMasahiro Yamada 2146dd88ab32SMasahiro Yamada my $len = length($line); 2147dd88ab32SMasahiro Yamada 2148dd88ab32SMasahiro Yamada for ($pos = 0; $pos < $len; $pos++) { 2149dd88ab32SMasahiro Yamada my $string = substr($line, $pos); 2150dd88ab32SMasahiro Yamada if ($string =~ /^($FuncArg|$balanced_parens)/) { 2151dd88ab32SMasahiro Yamada $pos += length($1) - 1; 2152dd88ab32SMasahiro Yamada } elsif (substr($line, $pos, 1) eq '(') { 2153dd88ab32SMasahiro Yamada $last_openparen = $pos; 2154dd88ab32SMasahiro Yamada } elsif (index($string, '(') == -1) { 2155dd88ab32SMasahiro Yamada last; 2156dd88ab32SMasahiro Yamada } 2157dd88ab32SMasahiro Yamada } 2158dd88ab32SMasahiro Yamada 21597551eb4fSHeinrich Schuchardt return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2160dd88ab32SMasahiro Yamada} 2161dd88ab32SMasahiro Yamada 2162dd88ab32SMasahiro Yamadasub process { 2163dd88ab32SMasahiro Yamada my $filename = shift; 2164dd88ab32SMasahiro Yamada 2165dd88ab32SMasahiro Yamada my $linenr=0; 2166dd88ab32SMasahiro Yamada my $prevline=""; 2167dd88ab32SMasahiro Yamada my $prevrawline=""; 2168dd88ab32SMasahiro Yamada my $stashline=""; 2169dd88ab32SMasahiro Yamada my $stashrawline=""; 2170dd88ab32SMasahiro Yamada 2171dd88ab32SMasahiro Yamada my $length; 2172dd88ab32SMasahiro Yamada my $indent; 2173dd88ab32SMasahiro Yamada my $previndent=0; 2174dd88ab32SMasahiro Yamada my $stashindent=0; 2175dd88ab32SMasahiro Yamada 2176dd88ab32SMasahiro Yamada our $clean = 1; 2177dd88ab32SMasahiro Yamada my $signoff = 0; 2178dd88ab32SMasahiro Yamada my $is_patch = 0; 21797551eb4fSHeinrich Schuchardt my $in_header_lines = $file ? 0 : 1; 2180dd88ab32SMasahiro Yamada my $in_commit_log = 0; #Scanning lines before patch 21817551eb4fSHeinrich Schuchardt my $has_commit_log = 0; #Encountered lines before patch 21827551eb4fSHeinrich Schuchardt my $commit_log_possible_stack_dump = 0; 21837551eb4fSHeinrich Schuchardt my $commit_log_long_line = 0; 21847551eb4fSHeinrich Schuchardt my $commit_log_has_diff = 0; 21857551eb4fSHeinrich Schuchardt my $reported_maintainer_file = 0; 2186dd88ab32SMasahiro Yamada my $non_utf8_charset = 0; 2187dd88ab32SMasahiro Yamada 21887551eb4fSHeinrich Schuchardt my $last_blank_line = 0; 21897551eb4fSHeinrich Schuchardt my $last_coalesced_string_linenr = -1; 21907551eb4fSHeinrich Schuchardt 2191dd88ab32SMasahiro Yamada our @report = (); 2192dd88ab32SMasahiro Yamada our $cnt_lines = 0; 2193dd88ab32SMasahiro Yamada our $cnt_error = 0; 2194dd88ab32SMasahiro Yamada our $cnt_warn = 0; 2195dd88ab32SMasahiro Yamada our $cnt_chk = 0; 2196dd88ab32SMasahiro Yamada 2197dd88ab32SMasahiro Yamada # Trace the real file/line as we go. 2198dd88ab32SMasahiro Yamada my $realfile = ''; 2199dd88ab32SMasahiro Yamada my $realline = 0; 2200dd88ab32SMasahiro Yamada my $realcnt = 0; 2201dd88ab32SMasahiro Yamada my $here = ''; 22027551eb4fSHeinrich Schuchardt my $context_function; #undef'd unless there's a known function 2203dd88ab32SMasahiro Yamada my $in_comment = 0; 2204dd88ab32SMasahiro Yamada my $comment_edge = 0; 2205dd88ab32SMasahiro Yamada my $first_line = 0; 2206dd88ab32SMasahiro Yamada my $p1_prefix = ''; 2207dd88ab32SMasahiro Yamada 2208dd88ab32SMasahiro Yamada my $prev_values = 'E'; 2209dd88ab32SMasahiro Yamada 2210dd88ab32SMasahiro Yamada # suppression flags 2211dd88ab32SMasahiro Yamada my %suppress_ifbraces; 2212dd88ab32SMasahiro Yamada my %suppress_whiletrailers; 2213dd88ab32SMasahiro Yamada my %suppress_export; 2214dd88ab32SMasahiro Yamada my $suppress_statement = 0; 2215dd88ab32SMasahiro Yamada 22166b9709d9STom Rini my %signatures = (); 2217dd88ab32SMasahiro Yamada 2218dd88ab32SMasahiro Yamada # Pre-scan the patch sanitizing the lines. 2219dd88ab32SMasahiro Yamada # Pre-scan the patch looking for any __setup documentation. 2220dd88ab32SMasahiro Yamada # 2221dd88ab32SMasahiro Yamada my @setup_docs = (); 2222dd88ab32SMasahiro Yamada my $setup_docs = 0; 2223dd88ab32SMasahiro Yamada 22246b9709d9STom Rini my $camelcase_file_seeded = 0; 22256b9709d9STom Rini 2226dd88ab32SMasahiro Yamada sanitise_line_reset(); 2227dd88ab32SMasahiro Yamada my $line; 2228dd88ab32SMasahiro Yamada foreach my $rawline (@rawlines) { 2229dd88ab32SMasahiro Yamada $linenr++; 2230dd88ab32SMasahiro Yamada $line = $rawline; 2231dd88ab32SMasahiro Yamada 22326b9709d9STom Rini push(@fixed, $rawline) if ($fix); 22336b9709d9STom Rini 2234dd88ab32SMasahiro Yamada if ($rawline=~/^\+\+\+\s+(\S+)/) { 2235dd88ab32SMasahiro Yamada $setup_docs = 0; 22367551eb4fSHeinrich Schuchardt if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2237dd88ab32SMasahiro Yamada $setup_docs = 1; 2238dd88ab32SMasahiro Yamada } 2239dd88ab32SMasahiro Yamada #next; 2240dd88ab32SMasahiro Yamada } 2241dd88ab32SMasahiro Yamada if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2242dd88ab32SMasahiro Yamada $realline=$1-1; 2243dd88ab32SMasahiro Yamada if (defined $2) { 2244dd88ab32SMasahiro Yamada $realcnt=$3+1; 2245dd88ab32SMasahiro Yamada } else { 2246dd88ab32SMasahiro Yamada $realcnt=1+1; 2247dd88ab32SMasahiro Yamada } 2248dd88ab32SMasahiro Yamada $in_comment = 0; 2249dd88ab32SMasahiro Yamada 2250dd88ab32SMasahiro Yamada # Guestimate if this is a continuing comment. Run 2251dd88ab32SMasahiro Yamada # the context looking for a comment "edge". If this 2252dd88ab32SMasahiro Yamada # edge is a close comment then we must be in a comment 2253dd88ab32SMasahiro Yamada # at context start. 2254dd88ab32SMasahiro Yamada my $edge; 2255dd88ab32SMasahiro Yamada my $cnt = $realcnt; 2256dd88ab32SMasahiro Yamada for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 2257dd88ab32SMasahiro Yamada next if (defined $rawlines[$ln - 1] && 2258dd88ab32SMasahiro Yamada $rawlines[$ln - 1] =~ /^-/); 2259dd88ab32SMasahiro Yamada $cnt--; 2260dd88ab32SMasahiro Yamada #print "RAW<$rawlines[$ln - 1]>\n"; 2261dd88ab32SMasahiro Yamada last if (!defined $rawlines[$ln - 1]); 2262dd88ab32SMasahiro Yamada if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2263dd88ab32SMasahiro Yamada $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2264dd88ab32SMasahiro Yamada ($edge) = $1; 2265dd88ab32SMasahiro Yamada last; 2266dd88ab32SMasahiro Yamada } 2267dd88ab32SMasahiro Yamada } 2268dd88ab32SMasahiro Yamada if (defined $edge && $edge eq '*/') { 2269dd88ab32SMasahiro Yamada $in_comment = 1; 2270dd88ab32SMasahiro Yamada } 2271dd88ab32SMasahiro Yamada 2272dd88ab32SMasahiro Yamada # Guestimate if this is a continuing comment. If this 2273dd88ab32SMasahiro Yamada # is the start of a diff block and this line starts 2274dd88ab32SMasahiro Yamada # ' *' then it is very likely a comment. 2275dd88ab32SMasahiro Yamada if (!defined $edge && 2276dd88ab32SMasahiro Yamada $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2277dd88ab32SMasahiro Yamada { 2278dd88ab32SMasahiro Yamada $in_comment = 1; 2279dd88ab32SMasahiro Yamada } 2280dd88ab32SMasahiro Yamada 2281dd88ab32SMasahiro Yamada ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2282dd88ab32SMasahiro Yamada sanitise_line_reset($in_comment); 2283dd88ab32SMasahiro Yamada 2284dd88ab32SMasahiro Yamada } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2285dd88ab32SMasahiro Yamada # Standardise the strings and chars within the input to 2286dd88ab32SMasahiro Yamada # simplify matching -- only bother with positive lines. 2287dd88ab32SMasahiro Yamada $line = sanitise_line($rawline); 2288dd88ab32SMasahiro Yamada } 2289dd88ab32SMasahiro Yamada push(@lines, $line); 2290dd88ab32SMasahiro Yamada 2291dd88ab32SMasahiro Yamada if ($realcnt > 1) { 2292dd88ab32SMasahiro Yamada $realcnt-- if ($line =~ /^(?:\+| |$)/); 2293dd88ab32SMasahiro Yamada } else { 2294dd88ab32SMasahiro Yamada $realcnt = 0; 2295dd88ab32SMasahiro Yamada } 2296dd88ab32SMasahiro Yamada 2297dd88ab32SMasahiro Yamada #print "==>$rawline\n"; 2298dd88ab32SMasahiro Yamada #print "-->$line\n"; 2299dd88ab32SMasahiro Yamada 2300dd88ab32SMasahiro Yamada if ($setup_docs && $line =~ /^\+/) { 2301dd88ab32SMasahiro Yamada push(@setup_docs, $line); 2302dd88ab32SMasahiro Yamada } 2303dd88ab32SMasahiro Yamada } 2304dd88ab32SMasahiro Yamada 2305dd88ab32SMasahiro Yamada $prefix = ''; 2306dd88ab32SMasahiro Yamada 2307dd88ab32SMasahiro Yamada $realcnt = 0; 2308dd88ab32SMasahiro Yamada $linenr = 0; 23097551eb4fSHeinrich Schuchardt $fixlinenr = -1; 2310dd88ab32SMasahiro Yamada foreach my $line (@lines) { 2311dd88ab32SMasahiro Yamada $linenr++; 23127551eb4fSHeinrich Schuchardt $fixlinenr++; 23136b9709d9STom Rini my $sline = $line; #copy of $line 23146b9709d9STom Rini $sline =~ s/$;/ /g; #with comments as spaces 2315dd88ab32SMasahiro Yamada 2316dd88ab32SMasahiro Yamada my $rawline = $rawlines[$linenr - 1]; 2317dd88ab32SMasahiro Yamada 2318dd88ab32SMasahiro Yamada#extract the line range in the file after the patch is applied 23197551eb4fSHeinrich Schuchardt if (!$in_commit_log && 23207551eb4fSHeinrich Schuchardt $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 23217551eb4fSHeinrich Schuchardt my $context = $4; 2322dd88ab32SMasahiro Yamada $is_patch = 1; 2323dd88ab32SMasahiro Yamada $first_line = $linenr + 1; 2324dd88ab32SMasahiro Yamada $realline=$1-1; 2325dd88ab32SMasahiro Yamada if (defined $2) { 2326dd88ab32SMasahiro Yamada $realcnt=$3+1; 2327dd88ab32SMasahiro Yamada } else { 2328dd88ab32SMasahiro Yamada $realcnt=1+1; 2329dd88ab32SMasahiro Yamada } 2330dd88ab32SMasahiro Yamada annotate_reset(); 2331dd88ab32SMasahiro Yamada $prev_values = 'E'; 2332dd88ab32SMasahiro Yamada 2333dd88ab32SMasahiro Yamada %suppress_ifbraces = (); 2334dd88ab32SMasahiro Yamada %suppress_whiletrailers = (); 2335dd88ab32SMasahiro Yamada %suppress_export = (); 2336dd88ab32SMasahiro Yamada $suppress_statement = 0; 23377551eb4fSHeinrich Schuchardt if ($context =~ /\b(\w+)\s*\(/) { 23387551eb4fSHeinrich Schuchardt $context_function = $1; 23397551eb4fSHeinrich Schuchardt } else { 23407551eb4fSHeinrich Schuchardt undef $context_function; 23417551eb4fSHeinrich Schuchardt } 2342dd88ab32SMasahiro Yamada next; 2343dd88ab32SMasahiro Yamada 2344dd88ab32SMasahiro Yamada# track the line number as we move through the hunk, note that 2345dd88ab32SMasahiro Yamada# new versions of GNU diff omit the leading space on completely 2346dd88ab32SMasahiro Yamada# blank context lines so we need to count that too. 2347dd88ab32SMasahiro Yamada } elsif ($line =~ /^( |\+|$)/) { 2348dd88ab32SMasahiro Yamada $realline++; 2349dd88ab32SMasahiro Yamada $realcnt-- if ($realcnt != 0); 2350dd88ab32SMasahiro Yamada 2351dd88ab32SMasahiro Yamada # Measure the line length and indent. 2352dd88ab32SMasahiro Yamada ($length, $indent) = line_stats($rawline); 2353dd88ab32SMasahiro Yamada 2354dd88ab32SMasahiro Yamada # Track the previous line. 2355dd88ab32SMasahiro Yamada ($prevline, $stashline) = ($stashline, $line); 2356dd88ab32SMasahiro Yamada ($previndent, $stashindent) = ($stashindent, $indent); 2357dd88ab32SMasahiro Yamada ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2358dd88ab32SMasahiro Yamada 2359dd88ab32SMasahiro Yamada #warn "line<$line>\n"; 2360dd88ab32SMasahiro Yamada 2361dd88ab32SMasahiro Yamada } elsif ($realcnt == 1) { 2362dd88ab32SMasahiro Yamada $realcnt--; 2363dd88ab32SMasahiro Yamada } 2364dd88ab32SMasahiro Yamada 2365dd88ab32SMasahiro Yamada my $hunk_line = ($realcnt != 0); 2366dd88ab32SMasahiro Yamada 2367dd88ab32SMasahiro Yamada $here = "#$linenr: " if (!$file); 2368dd88ab32SMasahiro Yamada $here = "#$realline: " if ($file); 2369dd88ab32SMasahiro Yamada 23707551eb4fSHeinrich Schuchardt my $found_file = 0; 2371dd88ab32SMasahiro Yamada # extract the filename as it passes 2372dd88ab32SMasahiro Yamada if ($line =~ /^diff --git.*?(\S+)$/) { 2373dd88ab32SMasahiro Yamada $realfile = $1; 23746b9709d9STom Rini $realfile =~ s@^([^/]*)/@@ if (!$file); 2375dd88ab32SMasahiro Yamada $in_commit_log = 0; 23767551eb4fSHeinrich Schuchardt $found_file = 1; 2377dd88ab32SMasahiro Yamada } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2378dd88ab32SMasahiro Yamada $realfile = $1; 23796b9709d9STom Rini $realfile =~ s@^([^/]*)/@@ if (!$file); 2380dd88ab32SMasahiro Yamada $in_commit_log = 0; 2381dd88ab32SMasahiro Yamada 2382dd88ab32SMasahiro Yamada $p1_prefix = $1; 2383dd88ab32SMasahiro Yamada if (!$file && $tree && $p1_prefix ne '' && 2384dd88ab32SMasahiro Yamada -e "$root/$p1_prefix") { 2385dd88ab32SMasahiro Yamada WARN("PATCH_PREFIX", 2386dd88ab32SMasahiro Yamada "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 2387dd88ab32SMasahiro Yamada } 2388dd88ab32SMasahiro Yamada 2389dd88ab32SMasahiro Yamada if ($realfile =~ m@^include/asm/@) { 2390dd88ab32SMasahiro Yamada ERROR("MODIFIED_INCLUDE_ASM", 2391dd88ab32SMasahiro Yamada "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2392dd88ab32SMasahiro Yamada } 23937551eb4fSHeinrich Schuchardt $found_file = 1; 23947551eb4fSHeinrich Schuchardt } 23957551eb4fSHeinrich Schuchardt 23967551eb4fSHeinrich Schuchardt#make up the handle for any error we report on this line 23977551eb4fSHeinrich Schuchardt if ($showfile) { 23987551eb4fSHeinrich Schuchardt $prefix = "$realfile:$realline: " 23997551eb4fSHeinrich Schuchardt } elsif ($emacs) { 24007551eb4fSHeinrich Schuchardt if ($file) { 24017551eb4fSHeinrich Schuchardt $prefix = "$filename:$realline: "; 24027551eb4fSHeinrich Schuchardt } else { 24037551eb4fSHeinrich Schuchardt $prefix = "$filename:$linenr: "; 24047551eb4fSHeinrich Schuchardt } 24057551eb4fSHeinrich Schuchardt } 24067551eb4fSHeinrich Schuchardt 24077551eb4fSHeinrich Schuchardt if ($found_file) { 24087551eb4fSHeinrich Schuchardt if (is_maintained_obsolete($realfile)) { 24097551eb4fSHeinrich Schuchardt WARN("OBSOLETE", 24107551eb4fSHeinrich Schuchardt "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 24117551eb4fSHeinrich Schuchardt } 24127551eb4fSHeinrich Schuchardt if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 24137551eb4fSHeinrich Schuchardt $check = 1; 24147551eb4fSHeinrich Schuchardt } else { 24157551eb4fSHeinrich Schuchardt $check = $check_orig; 24167551eb4fSHeinrich Schuchardt } 2417dd88ab32SMasahiro Yamada next; 2418dd88ab32SMasahiro Yamada } 2419dd88ab32SMasahiro Yamada 2420dd88ab32SMasahiro Yamada $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 2421dd88ab32SMasahiro Yamada 2422dd88ab32SMasahiro Yamada my $hereline = "$here\n$rawline\n"; 2423dd88ab32SMasahiro Yamada my $herecurr = "$here\n$rawline\n"; 2424dd88ab32SMasahiro Yamada my $hereprev = "$here\n$prevrawline\n$rawline\n"; 2425dd88ab32SMasahiro Yamada 2426dd88ab32SMasahiro Yamada $cnt_lines++ if ($realcnt != 0); 2427dd88ab32SMasahiro Yamada 24287551eb4fSHeinrich Schuchardt# Check if the commit log has what seems like a diff which can confuse patch 24297551eb4fSHeinrich Schuchardt if ($in_commit_log && !$commit_log_has_diff && 24307551eb4fSHeinrich Schuchardt (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 24317551eb4fSHeinrich Schuchardt $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 24327551eb4fSHeinrich Schuchardt $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 24337551eb4fSHeinrich Schuchardt $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 24347551eb4fSHeinrich Schuchardt ERROR("DIFF_IN_COMMIT_MSG", 24357551eb4fSHeinrich Schuchardt "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 24367551eb4fSHeinrich Schuchardt $commit_log_has_diff = 1; 24377551eb4fSHeinrich Schuchardt } 24387551eb4fSHeinrich Schuchardt 2439dd88ab32SMasahiro Yamada# Check for incorrect file permissions 2440dd88ab32SMasahiro Yamada if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 2441dd88ab32SMasahiro Yamada my $permhere = $here . "FILE: $realfile\n"; 24426b9709d9STom Rini if ($realfile !~ m@scripts/@ && 24436b9709d9STom Rini $realfile !~ /\.(py|pl|awk|sh)$/) { 2444dd88ab32SMasahiro Yamada ERROR("EXECUTE_PERMISSIONS", 2445dd88ab32SMasahiro Yamada "do not set execute permissions for source files\n" . $permhere); 2446dd88ab32SMasahiro Yamada } 2447dd88ab32SMasahiro Yamada } 2448dd88ab32SMasahiro Yamada 2449dd88ab32SMasahiro Yamada# Check the patch for a signoff: 2450dd88ab32SMasahiro Yamada if ($line =~ /^\s*signed-off-by:/i) { 2451dd88ab32SMasahiro Yamada $signoff++; 2452dd88ab32SMasahiro Yamada $in_commit_log = 0; 2453dd88ab32SMasahiro Yamada } 2454dd88ab32SMasahiro Yamada 24557551eb4fSHeinrich Schuchardt# Check if MAINTAINERS is being updated. If so, there's probably no need to 24567551eb4fSHeinrich Schuchardt# emit the "does MAINTAINERS need updating?" message on file add/move/delete 24577551eb4fSHeinrich Schuchardt if ($line =~ /^\s*MAINTAINERS\s*\|/) { 24587551eb4fSHeinrich Schuchardt $reported_maintainer_file = 1; 24597551eb4fSHeinrich Schuchardt } 24607551eb4fSHeinrich Schuchardt 2461dd88ab32SMasahiro Yamada# Check signature styles 2462dd88ab32SMasahiro Yamada if (!$in_header_lines && 2463dd88ab32SMasahiro Yamada $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 2464dd88ab32SMasahiro Yamada my $space_before = $1; 2465dd88ab32SMasahiro Yamada my $sign_off = $2; 2466dd88ab32SMasahiro Yamada my $space_after = $3; 2467dd88ab32SMasahiro Yamada my $email = $4; 2468dd88ab32SMasahiro Yamada my $ucfirst_sign_off = ucfirst(lc($sign_off)); 2469dd88ab32SMasahiro Yamada 2470dd88ab32SMasahiro Yamada if ($sign_off !~ /$signature_tags/) { 2471dd88ab32SMasahiro Yamada WARN("BAD_SIGN_OFF", 2472dd88ab32SMasahiro Yamada "Non-standard signature: $sign_off\n" . $herecurr); 2473dd88ab32SMasahiro Yamada } 2474dd88ab32SMasahiro Yamada if (defined $space_before && $space_before ne "") { 24756b9709d9STom Rini if (WARN("BAD_SIGN_OFF", 24766b9709d9STom Rini "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 24776b9709d9STom Rini $fix) { 24787551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] = 24796b9709d9STom Rini "$ucfirst_sign_off $email"; 24806b9709d9STom Rini } 2481dd88ab32SMasahiro Yamada } 2482dd88ab32SMasahiro Yamada if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 24836b9709d9STom Rini if (WARN("BAD_SIGN_OFF", 24846b9709d9STom Rini "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 24856b9709d9STom Rini $fix) { 24867551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] = 24876b9709d9STom Rini "$ucfirst_sign_off $email"; 24886b9709d9STom Rini } 24896b9709d9STom Rini 2490dd88ab32SMasahiro Yamada } 2491dd88ab32SMasahiro Yamada if (!defined $space_after || $space_after ne " ") { 24926b9709d9STom Rini if (WARN("BAD_SIGN_OFF", 24936b9709d9STom Rini "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 24946b9709d9STom Rini $fix) { 24957551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] = 24966b9709d9STom Rini "$ucfirst_sign_off $email"; 24976b9709d9STom Rini } 2498dd88ab32SMasahiro Yamada } 2499dd88ab32SMasahiro Yamada 2500dd88ab32SMasahiro Yamada my ($email_name, $email_address, $comment) = parse_email($email); 2501dd88ab32SMasahiro Yamada my $suggested_email = format_email(($email_name, $email_address)); 2502dd88ab32SMasahiro Yamada if ($suggested_email eq "") { 2503dd88ab32SMasahiro Yamada ERROR("BAD_SIGN_OFF", 2504dd88ab32SMasahiro Yamada "Unrecognized email address: '$email'\n" . $herecurr); 2505dd88ab32SMasahiro Yamada } else { 2506dd88ab32SMasahiro Yamada my $dequoted = $suggested_email; 2507dd88ab32SMasahiro Yamada $dequoted =~ s/^"//; 2508dd88ab32SMasahiro Yamada $dequoted =~ s/" </ </; 2509dd88ab32SMasahiro Yamada # Don't force email to have quotes 2510dd88ab32SMasahiro Yamada # Allow just an angle bracketed address 2511dd88ab32SMasahiro Yamada if ("$dequoted$comment" ne $email && 2512dd88ab32SMasahiro Yamada "<$email_address>$comment" ne $email && 2513dd88ab32SMasahiro Yamada "$suggested_email$comment" ne $email) { 2514dd88ab32SMasahiro Yamada WARN("BAD_SIGN_OFF", 2515dd88ab32SMasahiro Yamada "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 2516dd88ab32SMasahiro Yamada } 2517dd88ab32SMasahiro Yamada } 25186b9709d9STom Rini 25196b9709d9STom Rini# Check for duplicate signatures 25206b9709d9STom Rini my $sig_nospace = $line; 25216b9709d9STom Rini $sig_nospace =~ s/\s//g; 25226b9709d9STom Rini $sig_nospace = lc($sig_nospace); 25236b9709d9STom Rini if (defined $signatures{$sig_nospace}) { 25246b9709d9STom Rini WARN("BAD_SIGN_OFF", 25256b9709d9STom Rini "Duplicate signature\n" . $herecurr); 25266b9709d9STom Rini } else { 25276b9709d9STom Rini $signatures{$sig_nospace} = 1; 25286b9709d9STom Rini } 2529dd88ab32SMasahiro Yamada } 2530dd88ab32SMasahiro Yamada 25317551eb4fSHeinrich Schuchardt# Check email subject for common tools that don't need to be mentioned 25327551eb4fSHeinrich Schuchardt if ($in_header_lines && 25337551eb4fSHeinrich Schuchardt $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 25347551eb4fSHeinrich Schuchardt WARN("EMAIL_SUBJECT", 25357551eb4fSHeinrich Schuchardt "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 25367551eb4fSHeinrich Schuchardt } 25377551eb4fSHeinrich Schuchardt 25387551eb4fSHeinrich Schuchardt# Check for old stable address 25397551eb4fSHeinrich Schuchardt if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { 25407551eb4fSHeinrich Schuchardt ERROR("STABLE_ADDRESS", 25417551eb4fSHeinrich Schuchardt "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); 25427551eb4fSHeinrich Schuchardt } 25437551eb4fSHeinrich Schuchardt 25447551eb4fSHeinrich Schuchardt# Check for unwanted Gerrit info 25457551eb4fSHeinrich Schuchardt if ($in_commit_log && $line =~ /^\s*change-id:/i) { 25467551eb4fSHeinrich Schuchardt ERROR("GERRIT_CHANGE_ID", 25477551eb4fSHeinrich Schuchardt "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 25487551eb4fSHeinrich Schuchardt } 25497551eb4fSHeinrich Schuchardt 25507551eb4fSHeinrich Schuchardt# Check if the commit log is in a possible stack dump 25517551eb4fSHeinrich Schuchardt if ($in_commit_log && !$commit_log_possible_stack_dump && 25527551eb4fSHeinrich Schuchardt ($line =~ /^\s*(?:WARNING:|BUG:)/ || 25537551eb4fSHeinrich Schuchardt $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 25547551eb4fSHeinrich Schuchardt # timestamp 25557551eb4fSHeinrich Schuchardt $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { 25567551eb4fSHeinrich Schuchardt # stack dump address 25577551eb4fSHeinrich Schuchardt $commit_log_possible_stack_dump = 1; 25587551eb4fSHeinrich Schuchardt } 25597551eb4fSHeinrich Schuchardt 25607551eb4fSHeinrich Schuchardt# Check for line lengths > 75 in commit log, warn once 25617551eb4fSHeinrich Schuchardt if ($in_commit_log && !$commit_log_long_line && 25627551eb4fSHeinrich Schuchardt length($line) > 75 && 25637551eb4fSHeinrich Schuchardt !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 25647551eb4fSHeinrich Schuchardt # file delta changes 25657551eb4fSHeinrich Schuchardt $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 25667551eb4fSHeinrich Schuchardt # filename then : 25677551eb4fSHeinrich Schuchardt $line =~ /^\s*(?:Fixes:|Link:)/i || 25687551eb4fSHeinrich Schuchardt # A Fixes: or Link: line 25697551eb4fSHeinrich Schuchardt $commit_log_possible_stack_dump)) { 25707551eb4fSHeinrich Schuchardt WARN("COMMIT_LOG_LONG_LINE", 25717551eb4fSHeinrich Schuchardt "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 25727551eb4fSHeinrich Schuchardt $commit_log_long_line = 1; 25737551eb4fSHeinrich Schuchardt } 25747551eb4fSHeinrich Schuchardt 25757551eb4fSHeinrich Schuchardt# Reset possible stack dump if a blank line is found 25767551eb4fSHeinrich Schuchardt if ($in_commit_log && $commit_log_possible_stack_dump && 25777551eb4fSHeinrich Schuchardt $line =~ /^\s*$/) { 25787551eb4fSHeinrich Schuchardt $commit_log_possible_stack_dump = 0; 25797551eb4fSHeinrich Schuchardt } 25807551eb4fSHeinrich Schuchardt 25817551eb4fSHeinrich Schuchardt# Check for git id commit length and improperly formed commit descriptions 25827551eb4fSHeinrich Schuchardt if ($in_commit_log && !$commit_log_possible_stack_dump && 25837551eb4fSHeinrich Schuchardt $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && 25847551eb4fSHeinrich Schuchardt $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 25857551eb4fSHeinrich Schuchardt ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 25867551eb4fSHeinrich Schuchardt ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 25877551eb4fSHeinrich Schuchardt $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 25887551eb4fSHeinrich Schuchardt $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 25897551eb4fSHeinrich Schuchardt my $init_char = "c"; 25907551eb4fSHeinrich Schuchardt my $orig_commit = ""; 25917551eb4fSHeinrich Schuchardt my $short = 1; 25927551eb4fSHeinrich Schuchardt my $long = 0; 25937551eb4fSHeinrich Schuchardt my $case = 1; 25947551eb4fSHeinrich Schuchardt my $space = 1; 25957551eb4fSHeinrich Schuchardt my $hasdesc = 0; 25967551eb4fSHeinrich Schuchardt my $hasparens = 0; 25977551eb4fSHeinrich Schuchardt my $id = '0123456789ab'; 25987551eb4fSHeinrich Schuchardt my $orig_desc = "commit description"; 25997551eb4fSHeinrich Schuchardt my $description = ""; 26007551eb4fSHeinrich Schuchardt 26017551eb4fSHeinrich Schuchardt if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 26027551eb4fSHeinrich Schuchardt $init_char = $1; 26037551eb4fSHeinrich Schuchardt $orig_commit = lc($2); 26047551eb4fSHeinrich Schuchardt } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 26057551eb4fSHeinrich Schuchardt $orig_commit = lc($1); 26067551eb4fSHeinrich Schuchardt } 26077551eb4fSHeinrich Schuchardt 26087551eb4fSHeinrich Schuchardt $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 26097551eb4fSHeinrich Schuchardt $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 26107551eb4fSHeinrich Schuchardt $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 26117551eb4fSHeinrich Schuchardt $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 26127551eb4fSHeinrich Schuchardt if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 26137551eb4fSHeinrich Schuchardt $orig_desc = $1; 26147551eb4fSHeinrich Schuchardt $hasparens = 1; 26157551eb4fSHeinrich Schuchardt } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 26167551eb4fSHeinrich Schuchardt defined $rawlines[$linenr] && 26177551eb4fSHeinrich Schuchardt $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 26187551eb4fSHeinrich Schuchardt $orig_desc = $1; 26197551eb4fSHeinrich Schuchardt $hasparens = 1; 26207551eb4fSHeinrich Schuchardt } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 26217551eb4fSHeinrich Schuchardt defined $rawlines[$linenr] && 26227551eb4fSHeinrich Schuchardt $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 26237551eb4fSHeinrich Schuchardt $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 26247551eb4fSHeinrich Schuchardt $orig_desc = $1; 26257551eb4fSHeinrich Schuchardt $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 26267551eb4fSHeinrich Schuchardt $orig_desc .= " " . $1; 26277551eb4fSHeinrich Schuchardt $hasparens = 1; 26287551eb4fSHeinrich Schuchardt } 26297551eb4fSHeinrich Schuchardt 26307551eb4fSHeinrich Schuchardt ($id, $description) = git_commit_info($orig_commit, 26317551eb4fSHeinrich Schuchardt $id, $orig_desc); 26327551eb4fSHeinrich Schuchardt 26337551eb4fSHeinrich Schuchardt if (defined($id) && 26347551eb4fSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 26357551eb4fSHeinrich Schuchardt ERROR("GIT_COMMIT_ID", 26367551eb4fSHeinrich Schuchardt "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 26377551eb4fSHeinrich Schuchardt } 26387551eb4fSHeinrich Schuchardt } 26397551eb4fSHeinrich Schuchardt 26407551eb4fSHeinrich Schuchardt# Check for added, moved or deleted files 26417551eb4fSHeinrich Schuchardt if (!$reported_maintainer_file && !$in_commit_log && 26427551eb4fSHeinrich Schuchardt ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 26437551eb4fSHeinrich Schuchardt $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 26447551eb4fSHeinrich Schuchardt ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 26457551eb4fSHeinrich Schuchardt (defined($1) || defined($2))))) { 26467551eb4fSHeinrich Schuchardt $is_patch = 1; 26477551eb4fSHeinrich Schuchardt $reported_maintainer_file = 1; 26487551eb4fSHeinrich Schuchardt WARN("FILE_PATH_CHANGES", 26497551eb4fSHeinrich Schuchardt "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 26507551eb4fSHeinrich Schuchardt } 26517551eb4fSHeinrich Schuchardt 2652dd88ab32SMasahiro Yamada# Check for wrappage within a valid hunk of the file 2653dd88ab32SMasahiro Yamada if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2654dd88ab32SMasahiro Yamada ERROR("CORRUPTED_PATCH", 2655dd88ab32SMasahiro Yamada "patch seems to be corrupt (line wrapped?)\n" . 2656dd88ab32SMasahiro Yamada $herecurr) if (!$emitted_corrupt++); 2657dd88ab32SMasahiro Yamada } 2658dd88ab32SMasahiro Yamada 2659dd88ab32SMasahiro Yamada# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2660dd88ab32SMasahiro Yamada if (($realfile =~ /^$/ || $line =~ /^\+/) && 2661dd88ab32SMasahiro Yamada $rawline !~ m/^$UTF8*$/) { 2662dd88ab32SMasahiro Yamada my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2663dd88ab32SMasahiro Yamada 2664dd88ab32SMasahiro Yamada my $blank = copy_spacing($rawline); 2665dd88ab32SMasahiro Yamada my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2666dd88ab32SMasahiro Yamada my $hereptr = "$hereline$ptr\n"; 2667dd88ab32SMasahiro Yamada 2668dd88ab32SMasahiro Yamada CHK("INVALID_UTF8", 2669dd88ab32SMasahiro Yamada "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 2670dd88ab32SMasahiro Yamada } 2671dd88ab32SMasahiro Yamada 2672dd88ab32SMasahiro Yamada# Check if it's the start of a commit log 2673dd88ab32SMasahiro Yamada# (not a header line and we haven't seen the patch filename) 2674dd88ab32SMasahiro Yamada if ($in_header_lines && $realfile =~ /^$/ && 26757551eb4fSHeinrich Schuchardt !($rawline =~ /^\s+(?:\S|$)/ || 26767551eb4fSHeinrich Schuchardt $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 2677dd88ab32SMasahiro Yamada $in_header_lines = 0; 2678dd88ab32SMasahiro Yamada $in_commit_log = 1; 26797551eb4fSHeinrich Schuchardt $has_commit_log = 1; 2680dd88ab32SMasahiro Yamada } 2681dd88ab32SMasahiro Yamada 2682dd88ab32SMasahiro Yamada# Check if there is UTF-8 in a commit log when a mail header has explicitly 2683dd88ab32SMasahiro Yamada# declined it, i.e defined some charset where it is missing. 2684dd88ab32SMasahiro Yamada if ($in_header_lines && 2685dd88ab32SMasahiro Yamada $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2686dd88ab32SMasahiro Yamada $1 !~ /utf-8/i) { 2687dd88ab32SMasahiro Yamada $non_utf8_charset = 1; 2688dd88ab32SMasahiro Yamada } 2689dd88ab32SMasahiro Yamada 2690dd88ab32SMasahiro Yamada if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 2691dd88ab32SMasahiro Yamada $rawline =~ /$NON_ASCII_UTF8/) { 2692dd88ab32SMasahiro Yamada WARN("UTF8_BEFORE_PATCH", 2693dd88ab32SMasahiro Yamada "8-bit UTF-8 used in possible commit log\n" . $herecurr); 2694dd88ab32SMasahiro Yamada } 2695dd88ab32SMasahiro Yamada 26967551eb4fSHeinrich Schuchardt# Check for absolute kernel paths in commit message 26977551eb4fSHeinrich Schuchardt if ($tree && $in_commit_log) { 26987551eb4fSHeinrich Schuchardt while ($line =~ m{(?:^|\s)(/\S*)}g) { 26997551eb4fSHeinrich Schuchardt my $file = $1; 27007551eb4fSHeinrich Schuchardt 27017551eb4fSHeinrich Schuchardt if ($file =~ m{^(.*?)(?::\d+)+:?$} && 27027551eb4fSHeinrich Schuchardt check_absolute_file($1, $herecurr)) { 27037551eb4fSHeinrich Schuchardt # 27047551eb4fSHeinrich Schuchardt } else { 27057551eb4fSHeinrich Schuchardt check_absolute_file($file, $herecurr); 27067551eb4fSHeinrich Schuchardt } 27077551eb4fSHeinrich Schuchardt } 27087551eb4fSHeinrich Schuchardt } 27097551eb4fSHeinrich Schuchardt 2710c10e0f5bSDan Murphy# Check for various typo / spelling mistakes 2711c10e0f5bSDan Murphy if (defined($misspellings) && 2712c10e0f5bSDan Murphy ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2713c10e0f5bSDan Murphy while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 2714c10e0f5bSDan Murphy my $typo = $1; 2715c10e0f5bSDan Murphy my $typo_fix = $spelling_fix{lc($typo)}; 2716c10e0f5bSDan Murphy $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 2717c10e0f5bSDan Murphy $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 2718c10e0f5bSDan Murphy my $msg_type = \&WARN; 2719c10e0f5bSDan Murphy $msg_type = \&CHK if ($file); 2720c10e0f5bSDan Murphy if (&{$msg_type}("TYPO_SPELLING", 2721c10e0f5bSDan Murphy "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 2722c10e0f5bSDan Murphy $fix) { 2723c10e0f5bSDan Murphy $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 2724c10e0f5bSDan Murphy } 2725c10e0f5bSDan Murphy } 2726c10e0f5bSDan Murphy } 2727c10e0f5bSDan Murphy 2728dd88ab32SMasahiro Yamada# ignore non-hunk lines and lines being removed 2729dd88ab32SMasahiro Yamada next if (!$hunk_line || $line =~ /^-/); 2730dd88ab32SMasahiro Yamada 2731dd88ab32SMasahiro Yamada#trailing whitespace 2732dd88ab32SMasahiro Yamada if ($line =~ /^\+.*\015/) { 2733dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27346b9709d9STom Rini if (ERROR("DOS_LINE_ENDINGS", 27356b9709d9STom Rini "DOS line endings\n" . $herevet) && 27366b9709d9STom Rini $fix) { 27377551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/[\s\015]+$//; 27386b9709d9STom Rini } 2739dd88ab32SMasahiro Yamada } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2740dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27416b9709d9STom Rini if (ERROR("TRAILING_WHITESPACE", 27426b9709d9STom Rini "trailing whitespace\n" . $herevet) && 27436b9709d9STom Rini $fix) { 27447551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\s+$//; 27456b9709d9STom Rini } 27466b9709d9STom Rini 2747dd88ab32SMasahiro Yamada $rpt_cleaners = 1; 2748dd88ab32SMasahiro Yamada } 2749dd88ab32SMasahiro Yamada 27506b9709d9STom Rini# Check for FSF mailing addresses. 27516b9709d9STom Rini if ($rawline =~ /\bwrite to the Free/i || 27527551eb4fSHeinrich Schuchardt $rawline =~ /\b675\s+Mass\s+Ave/i || 27536b9709d9STom Rini $rawline =~ /\b59\s+Temple\s+Pl/i || 27546b9709d9STom Rini $rawline =~ /\b51\s+Franklin\s+St/i) { 27556b9709d9STom Rini my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27566b9709d9STom Rini my $msg_type = \&ERROR; 27576b9709d9STom Rini $msg_type = \&CHK if ($file); 27586b9709d9STom Rini &{$msg_type}("FSF_MAILING_ADDRESS", 27596b9709d9STom Rini "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) 27606b9709d9STom Rini } 27616b9709d9STom Rini 2762dd88ab32SMasahiro Yamada# check for Kconfig help text having a real description 2763dd88ab32SMasahiro Yamada# Only applies when adding the entry originally, after that we do not have 2764dd88ab32SMasahiro Yamada# sufficient context to determine whether it is indeed long enough. 2765dd88ab32SMasahiro Yamada if ($realfile =~ /Kconfig/ && 27667551eb4fSHeinrich Schuchardt $line =~ /^\+\s*config\s+/) { 2767dd88ab32SMasahiro Yamada my $length = 0; 2768dd88ab32SMasahiro Yamada my $cnt = $realcnt; 2769dd88ab32SMasahiro Yamada my $ln = $linenr + 1; 2770dd88ab32SMasahiro Yamada my $f; 2771dd88ab32SMasahiro Yamada my $is_start = 0; 2772dd88ab32SMasahiro Yamada my $is_end = 0; 2773dd88ab32SMasahiro Yamada for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 2774dd88ab32SMasahiro Yamada $f = $lines[$ln - 1]; 2775dd88ab32SMasahiro Yamada $cnt-- if ($lines[$ln - 1] !~ /^-/); 2776dd88ab32SMasahiro Yamada $is_end = $lines[$ln - 1] =~ /^\+/; 2777dd88ab32SMasahiro Yamada 2778dd88ab32SMasahiro Yamada next if ($f =~ /^-/); 27797551eb4fSHeinrich Schuchardt last if (!$file && $f =~ /^\@\@/); 2780dd88ab32SMasahiro Yamada 27817551eb4fSHeinrich Schuchardt if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2782dd88ab32SMasahiro Yamada $is_start = 1; 27837551eb4fSHeinrich Schuchardt } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2784dd88ab32SMasahiro Yamada $length = -1; 2785dd88ab32SMasahiro Yamada } 2786dd88ab32SMasahiro Yamada 2787dd88ab32SMasahiro Yamada $f =~ s/^.//; 2788dd88ab32SMasahiro Yamada $f =~ s/#.*//; 2789dd88ab32SMasahiro Yamada $f =~ s/^\s+//; 2790dd88ab32SMasahiro Yamada next if ($f =~ /^$/); 2791dd88ab32SMasahiro Yamada if ($f =~ /^\s*config\s/) { 2792dd88ab32SMasahiro Yamada $is_end = 1; 2793dd88ab32SMasahiro Yamada last; 2794dd88ab32SMasahiro Yamada } 2795dd88ab32SMasahiro Yamada $length++; 2796dd88ab32SMasahiro Yamada } 27977551eb4fSHeinrich Schuchardt if ($is_start && $is_end && $length < $min_conf_desc_length) { 2798dd88ab32SMasahiro Yamada WARN("CONFIG_DESCRIPTION", 27997551eb4fSHeinrich Schuchardt "please write a paragraph that describes the config symbol fully\n" . $herecurr); 28007551eb4fSHeinrich Schuchardt } 2801dd88ab32SMasahiro Yamada #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 2802dd88ab32SMasahiro Yamada } 2803dd88ab32SMasahiro Yamada 28047551eb4fSHeinrich Schuchardt# check for MAINTAINERS entries that don't have the right form 28057551eb4fSHeinrich Schuchardt if ($realfile =~ /^MAINTAINERS$/ && 28067551eb4fSHeinrich Schuchardt $rawline =~ /^\+[A-Z]:/ && 28077551eb4fSHeinrich Schuchardt $rawline !~ /^\+[A-Z]:\t\S/) { 28087551eb4fSHeinrich Schuchardt if (WARN("MAINTAINERS_STYLE", 28097551eb4fSHeinrich Schuchardt "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 28107551eb4fSHeinrich Schuchardt $fix) { 28117551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 28127551eb4fSHeinrich Schuchardt } 28137551eb4fSHeinrich Schuchardt } 28147551eb4fSHeinrich Schuchardt 28157551eb4fSHeinrich Schuchardt# discourage the use of boolean for type definition attributes of Kconfig options 2816dd88ab32SMasahiro Yamada if ($realfile =~ /Kconfig/ && 28177551eb4fSHeinrich Schuchardt $line =~ /^\+\s*\bboolean\b/) { 28187551eb4fSHeinrich Schuchardt WARN("CONFIG_TYPE_BOOLEAN", 28197551eb4fSHeinrich Schuchardt "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2820dd88ab32SMasahiro Yamada } 2821dd88ab32SMasahiro Yamada 2822dd88ab32SMasahiro Yamada if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2823dd88ab32SMasahiro Yamada ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2824dd88ab32SMasahiro Yamada my $flag = $1; 2825dd88ab32SMasahiro Yamada my $replacement = { 2826dd88ab32SMasahiro Yamada 'EXTRA_AFLAGS' => 'asflags-y', 2827dd88ab32SMasahiro Yamada 'EXTRA_CFLAGS' => 'ccflags-y', 2828dd88ab32SMasahiro Yamada 'EXTRA_CPPFLAGS' => 'cppflags-y', 2829dd88ab32SMasahiro Yamada 'EXTRA_LDFLAGS' => 'ldflags-y', 2830dd88ab32SMasahiro Yamada }; 2831dd88ab32SMasahiro Yamada 2832dd88ab32SMasahiro Yamada WARN("DEPRECATED_VARIABLE", 2833dd88ab32SMasahiro Yamada "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2834dd88ab32SMasahiro Yamada } 2835dd88ab32SMasahiro Yamada 28366b9709d9STom Rini# check for DT compatible documentation 28377551eb4fSHeinrich Schuchardt if (defined $root && 28387551eb4fSHeinrich Schuchardt (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 28397551eb4fSHeinrich Schuchardt ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 28407551eb4fSHeinrich Schuchardt 28416b9709d9STom Rini my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 28426b9709d9STom Rini 28437551eb4fSHeinrich Schuchardt my $dt_path = $root . "/Documentation/devicetree/bindings/"; 28447551eb4fSHeinrich Schuchardt my $vp_file = $dt_path . "vendor-prefixes.txt"; 28457551eb4fSHeinrich Schuchardt 28466b9709d9STom Rini foreach my $compat (@compats) { 28476b9709d9STom Rini my $compat2 = $compat; 28487551eb4fSHeinrich Schuchardt $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 28497551eb4fSHeinrich Schuchardt my $compat3 = $compat; 28507551eb4fSHeinrich Schuchardt $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 28517551eb4fSHeinrich Schuchardt `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 28526b9709d9STom Rini if ( $? >> 8 ) { 28536b9709d9STom Rini WARN("UNDOCUMENTED_DT_STRING", 28546b9709d9STom Rini "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 28556b9709d9STom Rini } 28566b9709d9STom Rini 28577551eb4fSHeinrich Schuchardt next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 28587551eb4fSHeinrich Schuchardt my $vendor = $1; 28597551eb4fSHeinrich Schuchardt `grep -Eq "^$vendor\\b" $vp_file`; 28606b9709d9STom Rini if ( $? >> 8 ) { 28616b9709d9STom Rini WARN("UNDOCUMENTED_DT_STRING", 28627551eb4fSHeinrich Schuchardt "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 28636b9709d9STom Rini } 28646b9709d9STom Rini } 28656b9709d9STom Rini } 28666b9709d9STom Rini 2867dd88ab32SMasahiro Yamada# check we are in a valid source file if not then ignore this hunk 28687551eb4fSHeinrich Schuchardt next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 2869dd88ab32SMasahiro Yamada 28707551eb4fSHeinrich Schuchardt# line length limit (with some exclusions) 28717551eb4fSHeinrich Schuchardt# 28727551eb4fSHeinrich Schuchardt# There are a few types of lines that may extend beyond $max_line_length: 28737551eb4fSHeinrich Schuchardt# logging functions like pr_info that end in a string 28747551eb4fSHeinrich Schuchardt# lines with a single string 28757551eb4fSHeinrich Schuchardt# #defines that are a single string 28767551eb4fSHeinrich Schuchardt# 28777551eb4fSHeinrich Schuchardt# There are 3 different line length message types: 28787551eb4fSHeinrich Schuchardt# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength 28797551eb4fSHeinrich Schuchardt# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 28807551eb4fSHeinrich Schuchardt# LONG_LINE all other lines longer than $max_line_length 28817551eb4fSHeinrich Schuchardt# 28827551eb4fSHeinrich Schuchardt# if LONG_LINE is ignored, the other 2 types are also ignored 28837551eb4fSHeinrich Schuchardt# 28847551eb4fSHeinrich Schuchardt 28857551eb4fSHeinrich Schuchardt if ($line =~ /^\+/ && $length > $max_line_length) { 28867551eb4fSHeinrich Schuchardt my $msg_type = "LONG_LINE"; 28877551eb4fSHeinrich Schuchardt 28887551eb4fSHeinrich Schuchardt # Check the allowed long line types first 28897551eb4fSHeinrich Schuchardt 28907551eb4fSHeinrich Schuchardt # logging functions that end in a string that starts 28917551eb4fSHeinrich Schuchardt # before $max_line_length 28927551eb4fSHeinrich Schuchardt if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 28937551eb4fSHeinrich Schuchardt length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 28947551eb4fSHeinrich Schuchardt $msg_type = ""; 28957551eb4fSHeinrich Schuchardt 28967551eb4fSHeinrich Schuchardt # lines with only strings (w/ possible termination) 28977551eb4fSHeinrich Schuchardt # #defines with only strings 28987551eb4fSHeinrich Schuchardt } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 28997551eb4fSHeinrich Schuchardt $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 29007551eb4fSHeinrich Schuchardt $msg_type = ""; 29017551eb4fSHeinrich Schuchardt 29027551eb4fSHeinrich Schuchardt # EFI_GUID is another special case 29037551eb4fSHeinrich Schuchardt } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { 29047551eb4fSHeinrich Schuchardt $msg_type = ""; 29057551eb4fSHeinrich Schuchardt 29067551eb4fSHeinrich Schuchardt # Otherwise set the alternate message types 29077551eb4fSHeinrich Schuchardt 29087551eb4fSHeinrich Schuchardt # a comment starts before $max_line_length 29097551eb4fSHeinrich Schuchardt } elsif ($line =~ /($;[\s$;]*)$/ && 29107551eb4fSHeinrich Schuchardt length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 29117551eb4fSHeinrich Schuchardt $msg_type = "LONG_LINE_COMMENT" 29127551eb4fSHeinrich Schuchardt 29137551eb4fSHeinrich Schuchardt # a quoted string starts before $max_line_length 29147551eb4fSHeinrich Schuchardt } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 29157551eb4fSHeinrich Schuchardt length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 29167551eb4fSHeinrich Schuchardt $msg_type = "LONG_LINE_STRING" 29177551eb4fSHeinrich Schuchardt } 29187551eb4fSHeinrich Schuchardt 29197551eb4fSHeinrich Schuchardt if ($msg_type ne "" && 29207551eb4fSHeinrich Schuchardt (show_type("LONG_LINE") || show_type($msg_type))) { 29217551eb4fSHeinrich Schuchardt WARN($msg_type, 2922dd88ab32SMasahiro Yamada "line over $max_line_length characters\n" . $herecurr); 2923dd88ab32SMasahiro Yamada } 2924dd88ab32SMasahiro Yamada } 2925dd88ab32SMasahiro Yamada 2926dd88ab32SMasahiro Yamada# check for adding lines without a newline. 2927dd88ab32SMasahiro Yamada if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2928dd88ab32SMasahiro Yamada WARN("MISSING_EOF_NEWLINE", 2929dd88ab32SMasahiro Yamada "adding a line without newline at end of file\n" . $herecurr); 2930dd88ab32SMasahiro Yamada } 2931dd88ab32SMasahiro Yamada 2932dd88ab32SMasahiro Yamada# Blackfin: use hi/lo macros 2933dd88ab32SMasahiro Yamada if ($realfile =~ m@arch/blackfin/.*\.S$@) { 2934dd88ab32SMasahiro Yamada if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 2935dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($line) . "\n"; 2936dd88ab32SMasahiro Yamada ERROR("LO_MACRO", 2937dd88ab32SMasahiro Yamada "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 2938dd88ab32SMasahiro Yamada } 2939dd88ab32SMasahiro Yamada if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 2940dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($line) . "\n"; 2941dd88ab32SMasahiro Yamada ERROR("HI_MACRO", 2942dd88ab32SMasahiro Yamada "use the HI() macro, not (... >> 16)\n" . $herevet); 2943dd88ab32SMasahiro Yamada } 2944dd88ab32SMasahiro Yamada } 2945dd88ab32SMasahiro Yamada 2946dd88ab32SMasahiro Yamada# check we are in a valid source file C or perl if not then ignore this hunk 29477551eb4fSHeinrich Schuchardt next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 2948dd88ab32SMasahiro Yamada 2949dd88ab32SMasahiro Yamada# at the beginning of a line any tabs must come first and anything 2950dd88ab32SMasahiro Yamada# more than 8 must use tabs. 2951dd88ab32SMasahiro Yamada if ($rawline =~ /^\+\s* \t\s*\S/ || 2952dd88ab32SMasahiro Yamada $rawline =~ /^\+\s* \s*/) { 2953dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2954dd88ab32SMasahiro Yamada $rpt_cleaners = 1; 29556b9709d9STom Rini if (ERROR("CODE_INDENT", 29566b9709d9STom Rini "code indent should use tabs where possible\n" . $herevet) && 29576b9709d9STom Rini $fix) { 29587551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 29596b9709d9STom Rini } 2960dd88ab32SMasahiro Yamada } 2961dd88ab32SMasahiro Yamada 2962dd88ab32SMasahiro Yamada# check for space before tabs. 2963dd88ab32SMasahiro Yamada if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 2964dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29656b9709d9STom Rini if (WARN("SPACE_BEFORE_TAB", 29666b9709d9STom Rini "please, no space before tabs\n" . $herevet) && 29676b9709d9STom Rini $fix) { 29687551eb4fSHeinrich Schuchardt while ($fixed[$fixlinenr] =~ 2969e3a4facdSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 29707551eb4fSHeinrich Schuchardt while ($fixed[$fixlinenr] =~ 29716b9709d9STom Rini s/(^\+.*) +\t/$1\t/) {} 29726b9709d9STom Rini } 2973dd88ab32SMasahiro Yamada } 2974dd88ab32SMasahiro Yamada 2975dd88ab32SMasahiro Yamada# check for && or || at the start of a line 2976dd88ab32SMasahiro Yamada if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2977dd88ab32SMasahiro Yamada CHK("LOGICAL_CONTINUATIONS", 2978dd88ab32SMasahiro Yamada "Logical continuations should be on the previous line\n" . $hereprev); 2979dd88ab32SMasahiro Yamada } 2980dd88ab32SMasahiro Yamada 29817551eb4fSHeinrich Schuchardt# check indentation starts on a tab stop 29827551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 29837551eb4fSHeinrich Schuchardt $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { 29847551eb4fSHeinrich Schuchardt my $indent = length($1); 29857551eb4fSHeinrich Schuchardt if ($indent % 8) { 29867551eb4fSHeinrich Schuchardt if (WARN("TABSTOP", 29877551eb4fSHeinrich Schuchardt "Statements should start on a tabstop\n" . $herecurr) && 29887551eb4fSHeinrich Schuchardt $fix) { 29897551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 29907551eb4fSHeinrich Schuchardt } 29917551eb4fSHeinrich Schuchardt } 29927551eb4fSHeinrich Schuchardt } 29937551eb4fSHeinrich Schuchardt 2994dd88ab32SMasahiro Yamada# check multi-line statement indentation matches previous line 2995dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 29967551eb4fSHeinrich Schuchardt $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2997dd88ab32SMasahiro Yamada $prevline =~ /^\+(\t*)(.*)$/; 2998dd88ab32SMasahiro Yamada my $oldindent = $1; 2999dd88ab32SMasahiro Yamada my $rest = $2; 3000dd88ab32SMasahiro Yamada 3001dd88ab32SMasahiro Yamada my $pos = pos_last_openparen($rest); 3002dd88ab32SMasahiro Yamada if ($pos >= 0) { 3003dd88ab32SMasahiro Yamada $line =~ /^(\+| )([ \t]*)/; 3004dd88ab32SMasahiro Yamada my $newindent = $2; 3005dd88ab32SMasahiro Yamada 3006dd88ab32SMasahiro Yamada my $goodtabindent = $oldindent . 3007dd88ab32SMasahiro Yamada "\t" x ($pos / 8) . 3008dd88ab32SMasahiro Yamada " " x ($pos % 8); 3009dd88ab32SMasahiro Yamada my $goodspaceindent = $oldindent . " " x $pos; 3010dd88ab32SMasahiro Yamada 3011dd88ab32SMasahiro Yamada if ($newindent ne $goodtabindent && 3012dd88ab32SMasahiro Yamada $newindent ne $goodspaceindent) { 30136b9709d9STom Rini 30146b9709d9STom Rini if (CHK("PARENTHESIS_ALIGNMENT", 30156b9709d9STom Rini "Alignment should match open parenthesis\n" . $hereprev) && 30166b9709d9STom Rini $fix && $line =~ /^\+/) { 30177551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 30186b9709d9STom Rini s/^\+[ \t]*/\+$goodtabindent/; 30196b9709d9STom Rini } 3020dd88ab32SMasahiro Yamada } 3021dd88ab32SMasahiro Yamada } 3022dd88ab32SMasahiro Yamada } 3023dd88ab32SMasahiro Yamada 30247551eb4fSHeinrich Schuchardt# check for space after cast like "(int) foo" or "(struct foo) bar" 30257551eb4fSHeinrich Schuchardt# avoid checking a few false positives: 30267551eb4fSHeinrich Schuchardt# "sizeof(<type>)" or "__alignof__(<type>)" 30277551eb4fSHeinrich Schuchardt# function pointer declarations like "(*foo)(int) = bar;" 30287551eb4fSHeinrich Schuchardt# structure definitions like "(struct foo) { 0 };" 30297551eb4fSHeinrich Schuchardt# multiline macros that define functions 30307551eb4fSHeinrich Schuchardt# known attributes or the __attribute__ keyword 30317551eb4fSHeinrich Schuchardt if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 30327551eb4fSHeinrich Schuchardt (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 30336b9709d9STom Rini if (CHK("SPACING", 30347551eb4fSHeinrich Schuchardt "No space is necessary after a cast\n" . $herecurr) && 30356b9709d9STom Rini $fix) { 30367551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 30377551eb4fSHeinrich Schuchardt s/(\(\s*$Type\s*\))[ \t]+/$1/; 30386b9709d9STom Rini } 3039dd88ab32SMasahiro Yamada } 3040dd88ab32SMasahiro Yamada 30417551eb4fSHeinrich Schuchardt# Block comment styles 30427551eb4fSHeinrich Schuchardt# Networking with an initial /* 3043dd88ab32SMasahiro Yamada if ($realfile =~ m@^(drivers/net/|net/)@ && 30446b9709d9STom Rini $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 30457551eb4fSHeinrich Schuchardt $rawline =~ /^\+[ \t]*\*/ && 30467551eb4fSHeinrich Schuchardt $realline > 2) { 3047dd88ab32SMasahiro Yamada WARN("NETWORKING_BLOCK_COMMENT_STYLE", 3048dd88ab32SMasahiro Yamada "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 3049dd88ab32SMasahiro Yamada } 3050dd88ab32SMasahiro Yamada 30517551eb4fSHeinrich Schuchardt# Block comments use * on subsequent lines 30527551eb4fSHeinrich Schuchardt if ($prevline =~ /$;[ \t]*$/ && #ends in comment 30537551eb4fSHeinrich Schuchardt $prevrawline =~ /^\+.*?\/\*/ && #starting /* 30546b9709d9STom Rini $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 30556b9709d9STom Rini $rawline =~ /^\+/ && #line is new 30566b9709d9STom Rini $rawline !~ /^\+[ \t]*\*/) { #no leading * 30577551eb4fSHeinrich Schuchardt WARN("BLOCK_COMMENT_STYLE", 30587551eb4fSHeinrich Schuchardt "Block comments use * on subsequent lines\n" . $hereprev); 30596b9709d9STom Rini } 30606b9709d9STom Rini 30617551eb4fSHeinrich Schuchardt# Block comments use */ on trailing lines 30627551eb4fSHeinrich Schuchardt if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3063dd88ab32SMasahiro Yamada $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3064dd88ab32SMasahiro Yamada $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3065dd88ab32SMasahiro Yamada $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 30667551eb4fSHeinrich Schuchardt WARN("BLOCK_COMMENT_STYLE", 30677551eb4fSHeinrich Schuchardt "Block comments use a trailing */ on a separate line\n" . $herecurr); 30687551eb4fSHeinrich Schuchardt } 30697551eb4fSHeinrich Schuchardt 30707551eb4fSHeinrich Schuchardt# Block comment * alignment 30717551eb4fSHeinrich Schuchardt if ($prevline =~ /$;[ \t]*$/ && #ends in comment 30727551eb4fSHeinrich Schuchardt $line =~ /^\+[ \t]*$;/ && #leading comment 30737551eb4fSHeinrich Schuchardt $rawline =~ /^\+[ \t]*\*/ && #leading * 30747551eb4fSHeinrich Schuchardt (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 30757551eb4fSHeinrich Schuchardt $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 30767551eb4fSHeinrich Schuchardt $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 30777551eb4fSHeinrich Schuchardt my $oldindent; 30787551eb4fSHeinrich Schuchardt $prevrawline =~ m@^\+([ \t]*/?)\*@; 30797551eb4fSHeinrich Schuchardt if (defined($1)) { 30807551eb4fSHeinrich Schuchardt $oldindent = expand_tabs($1); 30817551eb4fSHeinrich Schuchardt } else { 30827551eb4fSHeinrich Schuchardt $prevrawline =~ m@^\+(.*/?)\*@; 30837551eb4fSHeinrich Schuchardt $oldindent = expand_tabs($1); 30847551eb4fSHeinrich Schuchardt } 30857551eb4fSHeinrich Schuchardt $rawline =~ m@^\+([ \t]*)\*@; 30867551eb4fSHeinrich Schuchardt my $newindent = $1; 30877551eb4fSHeinrich Schuchardt $newindent = expand_tabs($newindent); 30887551eb4fSHeinrich Schuchardt if (length($oldindent) ne length($newindent)) { 30897551eb4fSHeinrich Schuchardt WARN("BLOCK_COMMENT_STYLE", 30907551eb4fSHeinrich Schuchardt "Block comments should align the * on each line\n" . $hereprev); 30917551eb4fSHeinrich Schuchardt } 30927551eb4fSHeinrich Schuchardt } 30937551eb4fSHeinrich Schuchardt 30947551eb4fSHeinrich Schuchardt# check for missing blank lines after struct/union declarations 30957551eb4fSHeinrich Schuchardt# with exceptions for various attributes and macros 30967551eb4fSHeinrich Schuchardt if ($prevline =~ /^[\+ ]};?\s*$/ && 30977551eb4fSHeinrich Schuchardt $line =~ /^\+/ && 30987551eb4fSHeinrich Schuchardt !($line =~ /^\+\s*$/ || 30997551eb4fSHeinrich Schuchardt $line =~ /^\+\s*EXPORT_SYMBOL/ || 31007551eb4fSHeinrich Schuchardt $line =~ /^\+\s*MODULE_/i || 31017551eb4fSHeinrich Schuchardt $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 31027551eb4fSHeinrich Schuchardt $line =~ /^\+[a-z_]*init/ || 31037551eb4fSHeinrich Schuchardt $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 31047551eb4fSHeinrich Schuchardt $line =~ /^\+\s*DECLARE/ || 31057551eb4fSHeinrich Schuchardt $line =~ /^\+\s*__setup/)) { 31067551eb4fSHeinrich Schuchardt if (CHK("LINE_SPACING", 31077551eb4fSHeinrich Schuchardt "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 31087551eb4fSHeinrich Schuchardt $fix) { 31097551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, "\+"); 31107551eb4fSHeinrich Schuchardt } 31117551eb4fSHeinrich Schuchardt } 31127551eb4fSHeinrich Schuchardt 31137551eb4fSHeinrich Schuchardt# check for multiple consecutive blank lines 31147551eb4fSHeinrich Schuchardt if ($prevline =~ /^[\+ ]\s*$/ && 31157551eb4fSHeinrich Schuchardt $line =~ /^\+\s*$/ && 31167551eb4fSHeinrich Schuchardt $last_blank_line != ($linenr - 1)) { 31177551eb4fSHeinrich Schuchardt if (CHK("LINE_SPACING", 31187551eb4fSHeinrich Schuchardt "Please don't use multiple blank lines\n" . $hereprev) && 31197551eb4fSHeinrich Schuchardt $fix) { 31207551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 31217551eb4fSHeinrich Schuchardt } 31227551eb4fSHeinrich Schuchardt 31237551eb4fSHeinrich Schuchardt $last_blank_line = $linenr; 31247551eb4fSHeinrich Schuchardt } 31257551eb4fSHeinrich Schuchardt 31267551eb4fSHeinrich Schuchardt# check for missing blank lines after declarations 31277551eb4fSHeinrich Schuchardt if ($sline =~ /^\+\s+\S/ && #Not at char 1 31287551eb4fSHeinrich Schuchardt # actual declarations 31297551eb4fSHeinrich Schuchardt ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31307551eb4fSHeinrich Schuchardt # function pointer declarations 31317551eb4fSHeinrich Schuchardt $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31327551eb4fSHeinrich Schuchardt # foo bar; where foo is some local typedef or #define 31337551eb4fSHeinrich Schuchardt $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31347551eb4fSHeinrich Schuchardt # known declaration macros 31357551eb4fSHeinrich Schuchardt $prevline =~ /^\+\s+$declaration_macros/) && 31367551eb4fSHeinrich Schuchardt # for "else if" which can look like "$Ident $Ident" 31377551eb4fSHeinrich Schuchardt !($prevline =~ /^\+\s+$c90_Keywords\b/ || 31387551eb4fSHeinrich Schuchardt # other possible extensions of declaration lines 31397551eb4fSHeinrich Schuchardt $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 31407551eb4fSHeinrich Schuchardt # not starting a section or a macro "\" extended line 31417551eb4fSHeinrich Schuchardt $prevline =~ /(?:\{\s*|\\)$/) && 31427551eb4fSHeinrich Schuchardt # looks like a declaration 31437551eb4fSHeinrich Schuchardt !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31447551eb4fSHeinrich Schuchardt # function pointer declarations 31457551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31467551eb4fSHeinrich Schuchardt # foo bar; where foo is some local typedef or #define 31477551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31487551eb4fSHeinrich Schuchardt # known declaration macros 31497551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+$declaration_macros/ || 31507551eb4fSHeinrich Schuchardt # start of struct or union or enum 31517551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 31527551eb4fSHeinrich Schuchardt # start or end of block or continuation of declaration 31537551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 31547551eb4fSHeinrich Schuchardt # bitfield continuation 31557551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 31567551eb4fSHeinrich Schuchardt # other possible extensions of declaration lines 31577551eb4fSHeinrich Schuchardt $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 31587551eb4fSHeinrich Schuchardt # indentation of previous and current line are the same 31597551eb4fSHeinrich Schuchardt (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 31607551eb4fSHeinrich Schuchardt if (WARN("LINE_SPACING", 31617551eb4fSHeinrich Schuchardt "Missing a blank line after declarations\n" . $hereprev) && 31627551eb4fSHeinrich Schuchardt $fix) { 31637551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, "\+"); 31647551eb4fSHeinrich Schuchardt } 3165dd88ab32SMasahiro Yamada } 3166dd88ab32SMasahiro Yamada 3167dd88ab32SMasahiro Yamada# check for spaces at the beginning of a line. 3168dd88ab32SMasahiro Yamada# Exceptions: 3169dd88ab32SMasahiro Yamada# 1) within comments 3170dd88ab32SMasahiro Yamada# 2) indented preprocessor commands 3171dd88ab32SMasahiro Yamada# 3) hanging labels 31726b9709d9STom Rini if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 3173dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 31746b9709d9STom Rini if (WARN("LEADING_SPACE", 31756b9709d9STom Rini "please, no spaces at the start of a line\n" . $herevet) && 31766b9709d9STom Rini $fix) { 31777551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31786b9709d9STom Rini } 3179dd88ab32SMasahiro Yamada } 3180dd88ab32SMasahiro Yamada 3181dd88ab32SMasahiro Yamada# check we are in a valid C source file if not then ignore this hunk 3182dd88ab32SMasahiro Yamada next if ($realfile !~ /\.(h|c)$/); 3183dd88ab32SMasahiro Yamada 31847551eb4fSHeinrich Schuchardt# check if this appears to be the start function declaration, save the name 31857551eb4fSHeinrich Schuchardt if ($sline =~ /^\+\{\s*$/ && 31867551eb4fSHeinrich Schuchardt $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 31877551eb4fSHeinrich Schuchardt $context_function = $1; 31887551eb4fSHeinrich Schuchardt } 31897551eb4fSHeinrich Schuchardt 31907551eb4fSHeinrich Schuchardt# check if this appears to be the end of function declaration 31917551eb4fSHeinrich Schuchardt if ($sline =~ /^\+\}\s*$/) { 31927551eb4fSHeinrich Schuchardt undef $context_function; 31937551eb4fSHeinrich Schuchardt } 31947551eb4fSHeinrich Schuchardt 31957551eb4fSHeinrich Schuchardt# check indentation of any line with a bare else 31967551eb4fSHeinrich Schuchardt# (but not if it is a multiple line "if (foo) return bar; else return baz;") 31977551eb4fSHeinrich Schuchardt# if the previous line is a break or return and is indented 1 tab more... 31987551eb4fSHeinrich Schuchardt if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 31997551eb4fSHeinrich Schuchardt my $tabs = length($1) + 1; 32007551eb4fSHeinrich Schuchardt if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 32017551eb4fSHeinrich Schuchardt ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 32027551eb4fSHeinrich Schuchardt defined $lines[$linenr] && 32037551eb4fSHeinrich Schuchardt $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 32047551eb4fSHeinrich Schuchardt WARN("UNNECESSARY_ELSE", 32057551eb4fSHeinrich Schuchardt "else is not generally useful after a break or return\n" . $hereprev); 32067551eb4fSHeinrich Schuchardt } 32077551eb4fSHeinrich Schuchardt } 32087551eb4fSHeinrich Schuchardt 32097551eb4fSHeinrich Schuchardt# check indentation of a line with a break; 32107551eb4fSHeinrich Schuchardt# if the previous line is a goto or return and is indented the same # of tabs 32117551eb4fSHeinrich Schuchardt if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 32127551eb4fSHeinrich Schuchardt my $tabs = $1; 32137551eb4fSHeinrich Schuchardt if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 32147551eb4fSHeinrich Schuchardt WARN("UNNECESSARY_BREAK", 32157551eb4fSHeinrich Schuchardt "break is not useful after a goto or return\n" . $hereprev); 32167551eb4fSHeinrich Schuchardt } 3217dd88ab32SMasahiro Yamada } 3218dd88ab32SMasahiro Yamada 3219dd88ab32SMasahiro Yamada# check for RCS/CVS revision markers 3220dd88ab32SMasahiro Yamada if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3221dd88ab32SMasahiro Yamada WARN("CVS_KEYWORD", 3222dd88ab32SMasahiro Yamada "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3223dd88ab32SMasahiro Yamada } 3224dd88ab32SMasahiro Yamada 3225dd88ab32SMasahiro Yamada# Blackfin: don't use __builtin_bfin_[cs]sync 3226dd88ab32SMasahiro Yamada if ($line =~ /__builtin_bfin_csync/) { 3227dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($line) . "\n"; 3228dd88ab32SMasahiro Yamada ERROR("CSYNC", 3229dd88ab32SMasahiro Yamada "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 3230dd88ab32SMasahiro Yamada } 3231dd88ab32SMasahiro Yamada if ($line =~ /__builtin_bfin_ssync/) { 3232dd88ab32SMasahiro Yamada my $herevet = "$here\n" . cat_vet($line) . "\n"; 3233dd88ab32SMasahiro Yamada ERROR("SSYNC", 3234dd88ab32SMasahiro Yamada "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 3235dd88ab32SMasahiro Yamada } 3236dd88ab32SMasahiro Yamada 3237dd88ab32SMasahiro Yamada# check for old HOTPLUG __dev<foo> section markings 3238dd88ab32SMasahiro Yamada if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 3239dd88ab32SMasahiro Yamada WARN("HOTPLUG_SECTION", 3240dd88ab32SMasahiro Yamada "Using $1 is unnecessary\n" . $herecurr); 3241dd88ab32SMasahiro Yamada } 3242dd88ab32SMasahiro Yamada 3243dd88ab32SMasahiro Yamada# Check for potential 'bare' types 3244dd88ab32SMasahiro Yamada my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 3245dd88ab32SMasahiro Yamada $realline_next); 3246dd88ab32SMasahiro Yamada#print "LINE<$line>\n"; 32477551eb4fSHeinrich Schuchardt if ($linenr > $suppress_statement && 32486b9709d9STom Rini $realcnt && $sline =~ /.\s*\S/) { 3249dd88ab32SMasahiro Yamada ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3250dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $realcnt, 0); 3251dd88ab32SMasahiro Yamada $stat =~ s/\n./\n /g; 3252dd88ab32SMasahiro Yamada $cond =~ s/\n./\n /g; 3253dd88ab32SMasahiro Yamada 3254dd88ab32SMasahiro Yamada#print "linenr<$linenr> <$stat>\n"; 3255dd88ab32SMasahiro Yamada # If this statement has no statement boundaries within 3256dd88ab32SMasahiro Yamada # it there is no point in retrying a statement scan 3257dd88ab32SMasahiro Yamada # until we hit end of it. 3258dd88ab32SMasahiro Yamada my $frag = $stat; $frag =~ s/;+\s*$//; 3259dd88ab32SMasahiro Yamada if ($frag !~ /(?:{|;)/) { 3260dd88ab32SMasahiro Yamada#print "skip<$line_nr_next>\n"; 3261dd88ab32SMasahiro Yamada $suppress_statement = $line_nr_next; 3262dd88ab32SMasahiro Yamada } 3263dd88ab32SMasahiro Yamada 3264dd88ab32SMasahiro Yamada # Find the real next line. 3265dd88ab32SMasahiro Yamada $realline_next = $line_nr_next; 3266dd88ab32SMasahiro Yamada if (defined $realline_next && 3267dd88ab32SMasahiro Yamada (!defined $lines[$realline_next - 1] || 3268dd88ab32SMasahiro Yamada substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 3269dd88ab32SMasahiro Yamada $realline_next++; 3270dd88ab32SMasahiro Yamada } 3271dd88ab32SMasahiro Yamada 3272dd88ab32SMasahiro Yamada my $s = $stat; 3273dd88ab32SMasahiro Yamada $s =~ s/{.*$//s; 3274dd88ab32SMasahiro Yamada 3275dd88ab32SMasahiro Yamada # Ignore goto labels. 3276dd88ab32SMasahiro Yamada if ($s =~ /$Ident:\*$/s) { 3277dd88ab32SMasahiro Yamada 3278dd88ab32SMasahiro Yamada # Ignore functions being called 3279dd88ab32SMasahiro Yamada } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3280dd88ab32SMasahiro Yamada 3281dd88ab32SMasahiro Yamada } elsif ($s =~ /^.\s*else\b/s) { 3282dd88ab32SMasahiro Yamada 3283dd88ab32SMasahiro Yamada # declarations always start with types 3284dd88ab32SMasahiro Yamada } 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) { 3285dd88ab32SMasahiro Yamada my $type = $1; 3286dd88ab32SMasahiro Yamada $type =~ s/\s+/ /g; 3287dd88ab32SMasahiro Yamada possible($type, "A:" . $s); 3288dd88ab32SMasahiro Yamada 3289dd88ab32SMasahiro Yamada # definitions in global scope can only start with types 3290dd88ab32SMasahiro Yamada } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3291dd88ab32SMasahiro Yamada possible($1, "B:" . $s); 3292dd88ab32SMasahiro Yamada } 3293dd88ab32SMasahiro Yamada 3294dd88ab32SMasahiro Yamada # any (foo ... *) is a pointer cast, and foo is a type 3295dd88ab32SMasahiro Yamada while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3296dd88ab32SMasahiro Yamada possible($1, "C:" . $s); 3297dd88ab32SMasahiro Yamada } 3298dd88ab32SMasahiro Yamada 3299dd88ab32SMasahiro Yamada # Check for any sort of function declaration. 3300dd88ab32SMasahiro Yamada # int foo(something bar, other baz); 3301dd88ab32SMasahiro Yamada # void (*store_gdt)(x86_descr_ptr *); 3302dd88ab32SMasahiro Yamada if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 3303dd88ab32SMasahiro Yamada my ($name_len) = length($1); 3304dd88ab32SMasahiro Yamada 3305dd88ab32SMasahiro Yamada my $ctx = $s; 3306dd88ab32SMasahiro Yamada substr($ctx, 0, $name_len + 1, ''); 3307dd88ab32SMasahiro Yamada $ctx =~ s/\)[^\)]*$//; 3308dd88ab32SMasahiro Yamada 3309dd88ab32SMasahiro Yamada for my $arg (split(/\s*,\s*/, $ctx)) { 3310dd88ab32SMasahiro Yamada if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 3311dd88ab32SMasahiro Yamada 3312dd88ab32SMasahiro Yamada possible($1, "D:" . $s); 3313dd88ab32SMasahiro Yamada } 3314dd88ab32SMasahiro Yamada } 3315dd88ab32SMasahiro Yamada } 3316dd88ab32SMasahiro Yamada 3317dd88ab32SMasahiro Yamada } 3318dd88ab32SMasahiro Yamada 3319dd88ab32SMasahiro Yamada# 3320dd88ab32SMasahiro Yamada# Checks which may be anchored in the context. 3321dd88ab32SMasahiro Yamada# 3322dd88ab32SMasahiro Yamada 3323dd88ab32SMasahiro Yamada# Check for switch () and associated case and default 3324dd88ab32SMasahiro Yamada# statements should be at the same indent. 3325dd88ab32SMasahiro Yamada if ($line=~/\bswitch\s*\(.*\)/) { 3326dd88ab32SMasahiro Yamada my $err = ''; 3327dd88ab32SMasahiro Yamada my $sep = ''; 3328dd88ab32SMasahiro Yamada my @ctx = ctx_block_outer($linenr, $realcnt); 3329dd88ab32SMasahiro Yamada shift(@ctx); 3330dd88ab32SMasahiro Yamada for my $ctx (@ctx) { 3331dd88ab32SMasahiro Yamada my ($clen, $cindent) = line_stats($ctx); 3332dd88ab32SMasahiro Yamada if ($ctx =~ /^\+\s*(case\s+|default:)/ && 3333dd88ab32SMasahiro Yamada $indent != $cindent) { 3334dd88ab32SMasahiro Yamada $err .= "$sep$ctx\n"; 3335dd88ab32SMasahiro Yamada $sep = ''; 3336dd88ab32SMasahiro Yamada } else { 3337dd88ab32SMasahiro Yamada $sep = "[...]\n"; 3338dd88ab32SMasahiro Yamada } 3339dd88ab32SMasahiro Yamada } 3340dd88ab32SMasahiro Yamada if ($err ne '') { 3341dd88ab32SMasahiro Yamada ERROR("SWITCH_CASE_INDENT_LEVEL", 3342dd88ab32SMasahiro Yamada "switch and case should be at the same indent\n$hereline$err"); 3343dd88ab32SMasahiro Yamada } 3344dd88ab32SMasahiro Yamada } 3345dd88ab32SMasahiro Yamada 3346dd88ab32SMasahiro Yamada# if/while/etc brace do not go on next line, unless defining a do while loop, 3347dd88ab32SMasahiro Yamada# or if that brace on the next line is for something else 33487551eb4fSHeinrich Schuchardt if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3349dd88ab32SMasahiro Yamada my $pre_ctx = "$1$2"; 3350dd88ab32SMasahiro Yamada 3351dd88ab32SMasahiro Yamada my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 3352dd88ab32SMasahiro Yamada 3353dd88ab32SMasahiro Yamada if ($line =~ /^\+\t{6,}/) { 3354dd88ab32SMasahiro Yamada WARN("DEEP_INDENTATION", 3355dd88ab32SMasahiro Yamada "Too many leading tabs - consider code refactoring\n" . $herecurr); 3356dd88ab32SMasahiro Yamada } 3357dd88ab32SMasahiro Yamada 3358dd88ab32SMasahiro Yamada my $ctx_cnt = $realcnt - $#ctx - 1; 3359dd88ab32SMasahiro Yamada my $ctx = join("\n", @ctx); 3360dd88ab32SMasahiro Yamada 3361dd88ab32SMasahiro Yamada my $ctx_ln = $linenr; 3362dd88ab32SMasahiro Yamada my $ctx_skip = $realcnt; 3363dd88ab32SMasahiro Yamada 3364dd88ab32SMasahiro Yamada while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3365dd88ab32SMasahiro Yamada defined $lines[$ctx_ln - 1] && 3366dd88ab32SMasahiro Yamada $lines[$ctx_ln - 1] =~ /^-/)) { 3367dd88ab32SMasahiro Yamada ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3368dd88ab32SMasahiro Yamada $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3369dd88ab32SMasahiro Yamada $ctx_ln++; 3370dd88ab32SMasahiro Yamada } 3371dd88ab32SMasahiro Yamada 3372dd88ab32SMasahiro Yamada #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 3373dd88ab32SMasahiro Yamada #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3374dd88ab32SMasahiro Yamada 3375dd88ab32SMasahiro Yamada if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3376dd88ab32SMasahiro Yamada ERROR("OPEN_BRACE", 3377dd88ab32SMasahiro Yamada "that open brace { should be on the previous line\n" . 3378dd88ab32SMasahiro Yamada "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 3379dd88ab32SMasahiro Yamada } 3380dd88ab32SMasahiro Yamada if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3381dd88ab32SMasahiro Yamada $ctx =~ /\)\s*\;\s*$/ && 3382dd88ab32SMasahiro Yamada defined $lines[$ctx_ln - 1]) 3383dd88ab32SMasahiro Yamada { 3384dd88ab32SMasahiro Yamada my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 3385dd88ab32SMasahiro Yamada if ($nindent > $indent) { 3386dd88ab32SMasahiro Yamada WARN("TRAILING_SEMICOLON", 3387dd88ab32SMasahiro Yamada "trailing semicolon indicates no statements, indent implies otherwise\n" . 3388dd88ab32SMasahiro Yamada "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 3389dd88ab32SMasahiro Yamada } 3390dd88ab32SMasahiro Yamada } 3391dd88ab32SMasahiro Yamada } 3392dd88ab32SMasahiro Yamada 3393dd88ab32SMasahiro Yamada# Check relative indent for conditionals and blocks. 33947551eb4fSHeinrich Schuchardt if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 3395dd88ab32SMasahiro Yamada ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3396dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $realcnt, 0) 3397dd88ab32SMasahiro Yamada if (!defined $stat); 3398dd88ab32SMasahiro Yamada my ($s, $c) = ($stat, $cond); 3399dd88ab32SMasahiro Yamada 3400dd88ab32SMasahiro Yamada substr($s, 0, length($c), ''); 3401dd88ab32SMasahiro Yamada 34027551eb4fSHeinrich Schuchardt # remove inline comments 34037551eb4fSHeinrich Schuchardt $s =~ s/$;/ /g; 34047551eb4fSHeinrich Schuchardt $c =~ s/$;/ /g; 3405dd88ab32SMasahiro Yamada 3406dd88ab32SMasahiro Yamada # Find out how long the conditional actually is. 3407dd88ab32SMasahiro Yamada my @newlines = ($c =~ /\n/gs); 3408dd88ab32SMasahiro Yamada my $cond_lines = 1 + $#newlines; 3409dd88ab32SMasahiro Yamada 34107551eb4fSHeinrich Schuchardt # Make sure we remove the line prefixes as we have 34117551eb4fSHeinrich Schuchardt # none on the first line, and are going to readd them 34127551eb4fSHeinrich Schuchardt # where necessary. 34137551eb4fSHeinrich Schuchardt $s =~ s/\n./\n/gs; 34147551eb4fSHeinrich Schuchardt while ($s =~ /\n\s+\\\n/) { 34157551eb4fSHeinrich Schuchardt $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 34167551eb4fSHeinrich Schuchardt } 34177551eb4fSHeinrich Schuchardt 3418dd88ab32SMasahiro Yamada # We want to check the first line inside the block 3419dd88ab32SMasahiro Yamada # starting at the end of the conditional, so remove: 3420dd88ab32SMasahiro Yamada # 1) any blank line termination 3421dd88ab32SMasahiro Yamada # 2) any opening brace { on end of the line 3422dd88ab32SMasahiro Yamada # 3) any do (...) { 3423dd88ab32SMasahiro Yamada my $continuation = 0; 3424dd88ab32SMasahiro Yamada my $check = 0; 3425dd88ab32SMasahiro Yamada $s =~ s/^.*\bdo\b//; 3426dd88ab32SMasahiro Yamada $s =~ s/^\s*{//; 3427dd88ab32SMasahiro Yamada if ($s =~ s/^\s*\\//) { 3428dd88ab32SMasahiro Yamada $continuation = 1; 3429dd88ab32SMasahiro Yamada } 3430dd88ab32SMasahiro Yamada if ($s =~ s/^\s*?\n//) { 3431dd88ab32SMasahiro Yamada $check = 1; 3432dd88ab32SMasahiro Yamada $cond_lines++; 3433dd88ab32SMasahiro Yamada } 3434dd88ab32SMasahiro Yamada 3435dd88ab32SMasahiro Yamada # Also ignore a loop construct at the end of a 3436dd88ab32SMasahiro Yamada # preprocessor statement. 3437dd88ab32SMasahiro Yamada if (($prevline =~ /^.\s*#\s*define\s/ || 3438dd88ab32SMasahiro Yamada $prevline =~ /\\\s*$/) && $continuation == 0) { 3439dd88ab32SMasahiro Yamada $check = 0; 3440dd88ab32SMasahiro Yamada } 3441dd88ab32SMasahiro Yamada 3442dd88ab32SMasahiro Yamada my $cond_ptr = -1; 3443dd88ab32SMasahiro Yamada $continuation = 0; 3444dd88ab32SMasahiro Yamada while ($cond_ptr != $cond_lines) { 3445dd88ab32SMasahiro Yamada $cond_ptr = $cond_lines; 3446dd88ab32SMasahiro Yamada 3447dd88ab32SMasahiro Yamada # If we see an #else/#elif then the code 3448dd88ab32SMasahiro Yamada # is not linear. 3449dd88ab32SMasahiro Yamada if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3450dd88ab32SMasahiro Yamada $check = 0; 3451dd88ab32SMasahiro Yamada } 3452dd88ab32SMasahiro Yamada 3453dd88ab32SMasahiro Yamada # Ignore: 3454dd88ab32SMasahiro Yamada # 1) blank lines, they should be at 0, 3455dd88ab32SMasahiro Yamada # 2) preprocessor lines, and 3456dd88ab32SMasahiro Yamada # 3) labels. 3457dd88ab32SMasahiro Yamada if ($continuation || 3458dd88ab32SMasahiro Yamada $s =~ /^\s*?\n/ || 3459dd88ab32SMasahiro Yamada $s =~ /^\s*#\s*?/ || 3460dd88ab32SMasahiro Yamada $s =~ /^\s*$Ident\s*:/) { 3461dd88ab32SMasahiro Yamada $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 3462dd88ab32SMasahiro Yamada if ($s =~ s/^.*?\n//) { 3463dd88ab32SMasahiro Yamada $cond_lines++; 3464dd88ab32SMasahiro Yamada } 3465dd88ab32SMasahiro Yamada } 3466dd88ab32SMasahiro Yamada } 3467dd88ab32SMasahiro Yamada 3468dd88ab32SMasahiro Yamada my (undef, $sindent) = line_stats("+" . $s); 3469dd88ab32SMasahiro Yamada my $stat_real = raw_line($linenr, $cond_lines); 3470dd88ab32SMasahiro Yamada 3471dd88ab32SMasahiro Yamada # Check if either of these lines are modified, else 3472dd88ab32SMasahiro Yamada # this is not this patch's fault. 3473dd88ab32SMasahiro Yamada if (!defined($stat_real) || 3474dd88ab32SMasahiro Yamada $stat !~ /^\+/ && $stat_real !~ /^\+/) { 3475dd88ab32SMasahiro Yamada $check = 0; 3476dd88ab32SMasahiro Yamada } 3477dd88ab32SMasahiro Yamada if (defined($stat_real) && $cond_lines > 1) { 3478dd88ab32SMasahiro Yamada $stat_real = "[...]\n$stat_real"; 3479dd88ab32SMasahiro Yamada } 3480dd88ab32SMasahiro Yamada 3481dd88ab32SMasahiro Yamada #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"; 3482dd88ab32SMasahiro Yamada 34837551eb4fSHeinrich Schuchardt if ($check && $s ne '' && 34847551eb4fSHeinrich Schuchardt (($sindent % 8) != 0 || 34857551eb4fSHeinrich Schuchardt ($sindent < $indent) || 34867551eb4fSHeinrich Schuchardt ($sindent == $indent && 34877551eb4fSHeinrich Schuchardt ($s !~ /^\s*(?:\}|\{|else\b)/)) || 34887551eb4fSHeinrich Schuchardt ($sindent > $indent + 8))) { 3489dd88ab32SMasahiro Yamada WARN("SUSPECT_CODE_INDENT", 3490dd88ab32SMasahiro Yamada "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 3491dd88ab32SMasahiro Yamada } 3492dd88ab32SMasahiro Yamada } 3493dd88ab32SMasahiro Yamada 3494dd88ab32SMasahiro Yamada # Track the 'values' across context and added lines. 3495dd88ab32SMasahiro Yamada my $opline = $line; $opline =~ s/^./ /; 3496dd88ab32SMasahiro Yamada my ($curr_values, $curr_vars) = 3497dd88ab32SMasahiro Yamada annotate_values($opline . "\n", $prev_values); 3498dd88ab32SMasahiro Yamada $curr_values = $prev_values . $curr_values; 3499dd88ab32SMasahiro Yamada if ($dbg_values) { 3500dd88ab32SMasahiro Yamada my $outline = $opline; $outline =~ s/\t/ /g; 3501dd88ab32SMasahiro Yamada print "$linenr > .$outline\n"; 3502dd88ab32SMasahiro Yamada print "$linenr > $curr_values\n"; 3503dd88ab32SMasahiro Yamada print "$linenr > $curr_vars\n"; 3504dd88ab32SMasahiro Yamada } 3505dd88ab32SMasahiro Yamada $prev_values = substr($curr_values, -1); 3506dd88ab32SMasahiro Yamada 3507dd88ab32SMasahiro Yamada#ignore lines not being added 35086b9709d9STom Rini next if ($line =~ /^[^\+]/); 3509dd88ab32SMasahiro Yamada 35107551eb4fSHeinrich Schuchardt# check for dereferences that span multiple lines 35117551eb4fSHeinrich Schuchardt if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 35127551eb4fSHeinrich Schuchardt $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 35137551eb4fSHeinrich Schuchardt $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 35147551eb4fSHeinrich Schuchardt my $ref = $1; 35157551eb4fSHeinrich Schuchardt $line =~ /^.\s*($Lval)/; 35167551eb4fSHeinrich Schuchardt $ref .= $1; 35177551eb4fSHeinrich Schuchardt $ref =~ s/\s//g; 35187551eb4fSHeinrich Schuchardt WARN("MULTILINE_DEREFERENCE", 35197551eb4fSHeinrich Schuchardt "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 35207551eb4fSHeinrich Schuchardt } 35217551eb4fSHeinrich Schuchardt 35227551eb4fSHeinrich Schuchardt# check for declarations of signed or unsigned without int 35237551eb4fSHeinrich Schuchardt while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 35247551eb4fSHeinrich Schuchardt my $type = $1; 35257551eb4fSHeinrich Schuchardt my $var = $2; 35267551eb4fSHeinrich Schuchardt $var = "" if (!defined $var); 35277551eb4fSHeinrich Schuchardt if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 35287551eb4fSHeinrich Schuchardt my $sign = $1; 35297551eb4fSHeinrich Schuchardt my $pointer = $2; 35307551eb4fSHeinrich Schuchardt 35317551eb4fSHeinrich Schuchardt $pointer = "" if (!defined $pointer); 35327551eb4fSHeinrich Schuchardt 35337551eb4fSHeinrich Schuchardt if (WARN("UNSPECIFIED_INT", 35347551eb4fSHeinrich Schuchardt "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 35357551eb4fSHeinrich Schuchardt $fix) { 35367551eb4fSHeinrich Schuchardt my $decl = trim($sign) . " int "; 35377551eb4fSHeinrich Schuchardt my $comp_pointer = $pointer; 35387551eb4fSHeinrich Schuchardt $comp_pointer =~ s/\s//g; 35397551eb4fSHeinrich Schuchardt $decl .= $comp_pointer; 35407551eb4fSHeinrich Schuchardt $decl = rtrim($decl) if ($var eq ""); 35417551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 35427551eb4fSHeinrich Schuchardt } 35437551eb4fSHeinrich Schuchardt } 35447551eb4fSHeinrich Schuchardt } 35457551eb4fSHeinrich Schuchardt 3546dd88ab32SMasahiro Yamada# TEST: allow direct testing of the type matcher. 3547dd88ab32SMasahiro Yamada if ($dbg_type) { 3548dd88ab32SMasahiro Yamada if ($line =~ /^.\s*$Declare\s*$/) { 3549dd88ab32SMasahiro Yamada ERROR("TEST_TYPE", 3550dd88ab32SMasahiro Yamada "TEST: is type\n" . $herecurr); 3551dd88ab32SMasahiro Yamada } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3552dd88ab32SMasahiro Yamada ERROR("TEST_NOT_TYPE", 3553dd88ab32SMasahiro Yamada "TEST: is not type ($1 is)\n". $herecurr); 3554dd88ab32SMasahiro Yamada } 3555dd88ab32SMasahiro Yamada next; 3556dd88ab32SMasahiro Yamada } 3557dd88ab32SMasahiro Yamada# TEST: allow direct testing of the attribute matcher. 3558dd88ab32SMasahiro Yamada if ($dbg_attr) { 3559dd88ab32SMasahiro Yamada if ($line =~ /^.\s*$Modifier\s*$/) { 3560dd88ab32SMasahiro Yamada ERROR("TEST_ATTR", 3561dd88ab32SMasahiro Yamada "TEST: is attr\n" . $herecurr); 3562dd88ab32SMasahiro Yamada } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3563dd88ab32SMasahiro Yamada ERROR("TEST_NOT_ATTR", 3564dd88ab32SMasahiro Yamada "TEST: is not attr ($1 is)\n". $herecurr); 3565dd88ab32SMasahiro Yamada } 3566dd88ab32SMasahiro Yamada next; 3567dd88ab32SMasahiro Yamada } 3568dd88ab32SMasahiro Yamada 3569dd88ab32SMasahiro Yamada# check for initialisation to aggregates open brace on the next line 3570dd88ab32SMasahiro Yamada if ($line =~ /^.\s*{/ && 3571dd88ab32SMasahiro Yamada $prevline =~ /(?:^|[^=])=\s*$/) { 35727551eb4fSHeinrich Schuchardt if (ERROR("OPEN_BRACE", 35737551eb4fSHeinrich Schuchardt "that open brace { should be on the previous line\n" . $hereprev) && 35747551eb4fSHeinrich Schuchardt $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 35757551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 35767551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 35777551eb4fSHeinrich Schuchardt my $fixedline = $prevrawline; 35787551eb4fSHeinrich Schuchardt $fixedline =~ s/\s*=\s*$/ = {/; 35797551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 35807551eb4fSHeinrich Schuchardt $fixedline = $line; 35817551eb4fSHeinrich Schuchardt $fixedline =~ s/^(.\s*)\{\s*/$1/; 35827551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 35837551eb4fSHeinrich Schuchardt } 3584dd88ab32SMasahiro Yamada } 3585dd88ab32SMasahiro Yamada 3586dd88ab32SMasahiro Yamada# 3587dd88ab32SMasahiro Yamada# Checks which are anchored on the added line. 3588dd88ab32SMasahiro Yamada# 3589dd88ab32SMasahiro Yamada 3590dd88ab32SMasahiro Yamada# check for malformed paths in #include statements (uses RAW line) 3591dd88ab32SMasahiro Yamada if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3592dd88ab32SMasahiro Yamada my $path = $1; 3593dd88ab32SMasahiro Yamada if ($path =~ m{//}) { 3594dd88ab32SMasahiro Yamada ERROR("MALFORMED_INCLUDE", 3595dd88ab32SMasahiro Yamada "malformed #include filename\n" . $herecurr); 3596dd88ab32SMasahiro Yamada } 3597dd88ab32SMasahiro Yamada if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3598dd88ab32SMasahiro Yamada ERROR("UAPI_INCLUDE", 3599dd88ab32SMasahiro Yamada "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3600dd88ab32SMasahiro Yamada } 3601dd88ab32SMasahiro Yamada } 3602dd88ab32SMasahiro Yamada 3603dd88ab32SMasahiro Yamada# no C99 // comments 3604dd88ab32SMasahiro Yamada if ($line =~ m{//}) { 36056b9709d9STom Rini if (ERROR("C99_COMMENTS", 36066b9709d9STom Rini "do not use C99 // comments\n" . $herecurr) && 36076b9709d9STom Rini $fix) { 36087551eb4fSHeinrich Schuchardt my $line = $fixed[$fixlinenr]; 36096b9709d9STom Rini if ($line =~ /\/\/(.*)$/) { 36106b9709d9STom Rini my $comment = trim($1); 36117551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 36126b9709d9STom Rini } 36136b9709d9STom Rini } 3614dd88ab32SMasahiro Yamada } 3615dd88ab32SMasahiro Yamada # Remove C99 comments. 3616dd88ab32SMasahiro Yamada $line =~ s@//.*@@; 3617dd88ab32SMasahiro Yamada $opline =~ s@//.*@@; 3618dd88ab32SMasahiro Yamada 3619dd88ab32SMasahiro Yamada# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 3620dd88ab32SMasahiro Yamada# the whole statement. 3621dd88ab32SMasahiro Yamada#print "APW <$lines[$realline_next - 1]>\n"; 3622dd88ab32SMasahiro Yamada if (defined $realline_next && 3623dd88ab32SMasahiro Yamada exists $lines[$realline_next - 1] && 3624dd88ab32SMasahiro Yamada !defined $suppress_export{$realline_next} && 3625dd88ab32SMasahiro Yamada ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 3626dd88ab32SMasahiro Yamada $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 3627dd88ab32SMasahiro Yamada # Handle definitions which produce identifiers with 3628dd88ab32SMasahiro Yamada # a prefix: 3629dd88ab32SMasahiro Yamada # XXX(foo); 3630dd88ab32SMasahiro Yamada # EXPORT_SYMBOL(something_foo); 3631dd88ab32SMasahiro Yamada my $name = $1; 3632dd88ab32SMasahiro Yamada if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 3633dd88ab32SMasahiro Yamada $name =~ /^${Ident}_$2/) { 3634dd88ab32SMasahiro Yamada#print "FOO C name<$name>\n"; 3635dd88ab32SMasahiro Yamada $suppress_export{$realline_next} = 1; 3636dd88ab32SMasahiro Yamada 3637dd88ab32SMasahiro Yamada } elsif ($stat !~ /(?: 3638dd88ab32SMasahiro Yamada \n.}\s*$| 3639dd88ab32SMasahiro Yamada ^.DEFINE_$Ident\(\Q$name\E\)| 3640dd88ab32SMasahiro Yamada ^.DECLARE_$Ident\(\Q$name\E\)| 3641dd88ab32SMasahiro Yamada ^.LIST_HEAD\(\Q$name\E\)| 3642dd88ab32SMasahiro Yamada ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 3643dd88ab32SMasahiro Yamada \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 3644dd88ab32SMasahiro Yamada )/x) { 3645dd88ab32SMasahiro Yamada#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 3646dd88ab32SMasahiro Yamada $suppress_export{$realline_next} = 2; 3647dd88ab32SMasahiro Yamada } else { 3648dd88ab32SMasahiro Yamada $suppress_export{$realline_next} = 1; 3649dd88ab32SMasahiro Yamada } 3650dd88ab32SMasahiro Yamada } 3651dd88ab32SMasahiro Yamada if (!defined $suppress_export{$linenr} && 3652dd88ab32SMasahiro Yamada $prevline =~ /^.\s*$/ && 3653dd88ab32SMasahiro Yamada ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 3654dd88ab32SMasahiro Yamada $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 3655dd88ab32SMasahiro Yamada#print "FOO B <$lines[$linenr - 1]>\n"; 3656dd88ab32SMasahiro Yamada $suppress_export{$linenr} = 2; 3657dd88ab32SMasahiro Yamada } 3658dd88ab32SMasahiro Yamada if (defined $suppress_export{$linenr} && 3659dd88ab32SMasahiro Yamada $suppress_export{$linenr} == 2) { 3660dd88ab32SMasahiro Yamada WARN("EXPORT_SYMBOL", 3661dd88ab32SMasahiro Yamada "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 3662dd88ab32SMasahiro Yamada } 3663dd88ab32SMasahiro Yamada 3664dd88ab32SMasahiro Yamada# check for global initialisers. 36657551eb4fSHeinrich Schuchardt if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 36666b9709d9STom Rini if (ERROR("GLOBAL_INITIALISERS", 36677551eb4fSHeinrich Schuchardt "do not initialise globals to $1\n" . $herecurr) && 36686b9709d9STom Rini $fix) { 36697551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 36706b9709d9STom Rini } 3671dd88ab32SMasahiro Yamada } 3672dd88ab32SMasahiro Yamada# check for static initialisers. 36737551eb4fSHeinrich Schuchardt if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 36746b9709d9STom Rini if (ERROR("INITIALISED_STATIC", 36757551eb4fSHeinrich Schuchardt "do not initialise statics to $1\n" . 36766b9709d9STom Rini $herecurr) && 36776b9709d9STom Rini $fix) { 36787551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 36796b9709d9STom Rini } 3680dd88ab32SMasahiro Yamada } 3681dd88ab32SMasahiro Yamada 36827551eb4fSHeinrich Schuchardt# check for misordered declarations of char/short/int/long with signed/unsigned 36837551eb4fSHeinrich Schuchardt while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36847551eb4fSHeinrich Schuchardt my $tmp = trim($1); 36857551eb4fSHeinrich Schuchardt WARN("MISORDERED_TYPE", 36867551eb4fSHeinrich Schuchardt "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36877551eb4fSHeinrich Schuchardt } 36887551eb4fSHeinrich Schuchardt 3689dd88ab32SMasahiro Yamada# check for static const char * arrays. 3690dd88ab32SMasahiro Yamada if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3691dd88ab32SMasahiro Yamada WARN("STATIC_CONST_CHAR_ARRAY", 3692dd88ab32SMasahiro Yamada "static const char * array should probably be static const char * const\n" . 3693dd88ab32SMasahiro Yamada $herecurr); 3694dd88ab32SMasahiro Yamada } 3695dd88ab32SMasahiro Yamada 3696dd88ab32SMasahiro Yamada# check for static char foo[] = "bar" declarations. 3697dd88ab32SMasahiro Yamada if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3698dd88ab32SMasahiro Yamada WARN("STATIC_CONST_CHAR_ARRAY", 3699dd88ab32SMasahiro Yamada "static char array declaration should probably be static const char\n" . 3700dd88ab32SMasahiro Yamada $herecurr); 3701dd88ab32SMasahiro Yamada } 3702dd88ab32SMasahiro Yamada 37037551eb4fSHeinrich Schuchardt# check for const <foo> const where <foo> is not a pointer or array type 37047551eb4fSHeinrich Schuchardt if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 37057551eb4fSHeinrich Schuchardt my $found = $1; 37067551eb4fSHeinrich Schuchardt if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 37077551eb4fSHeinrich Schuchardt WARN("CONST_CONST", 37087551eb4fSHeinrich Schuchardt "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 37097551eb4fSHeinrich Schuchardt } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 37107551eb4fSHeinrich Schuchardt WARN("CONST_CONST", 37117551eb4fSHeinrich Schuchardt "'const $found const' should probably be 'const $found'\n" . $herecurr); 37127551eb4fSHeinrich Schuchardt } 37137551eb4fSHeinrich Schuchardt } 37147551eb4fSHeinrich Schuchardt 37157551eb4fSHeinrich Schuchardt# check for non-global char *foo[] = {"bar", ...} declarations. 37167551eb4fSHeinrich Schuchardt if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 37177551eb4fSHeinrich Schuchardt WARN("STATIC_CONST_CHAR_ARRAY", 37187551eb4fSHeinrich Schuchardt "char * array declaration might be better as static const\n" . 37197551eb4fSHeinrich Schuchardt $herecurr); 37207551eb4fSHeinrich Schuchardt } 37217551eb4fSHeinrich Schuchardt 37227551eb4fSHeinrich Schuchardt# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 37237551eb4fSHeinrich Schuchardt if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 37247551eb4fSHeinrich Schuchardt my $array = $1; 37257551eb4fSHeinrich Schuchardt if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { 37267551eb4fSHeinrich Schuchardt my $array_div = $1; 37277551eb4fSHeinrich Schuchardt if (WARN("ARRAY_SIZE", 37287551eb4fSHeinrich Schuchardt "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 37297551eb4fSHeinrich Schuchardt $fix) { 37307551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 37317551eb4fSHeinrich Schuchardt } 37327551eb4fSHeinrich Schuchardt } 37337551eb4fSHeinrich Schuchardt } 37347551eb4fSHeinrich Schuchardt 37356b9709d9STom Rini# check for function declarations without arguments like "int foo()" 37366b9709d9STom Rini if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 37376b9709d9STom Rini if (ERROR("FUNCTION_WITHOUT_ARGS", 37386b9709d9STom Rini "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 37396b9709d9STom Rini $fix) { 37407551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 37416b9709d9STom Rini } 3742dd88ab32SMasahiro Yamada } 3743dd88ab32SMasahiro Yamada 3744dd88ab32SMasahiro Yamada# check for new typedefs, only function parameters and sparse annotations 3745dd88ab32SMasahiro Yamada# make sense. 3746dd88ab32SMasahiro Yamada if ($line =~ /\btypedef\s/ && 3747dd88ab32SMasahiro Yamada $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3748dd88ab32SMasahiro Yamada $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 3749dd88ab32SMasahiro Yamada $line !~ /\b$typeTypedefs\b/ && 37507551eb4fSHeinrich Schuchardt $line !~ /\b__bitwise\b/) { 3751dd88ab32SMasahiro Yamada WARN("NEW_TYPEDEFS", 3752dd88ab32SMasahiro Yamada "do not add new typedefs\n" . $herecurr); 3753dd88ab32SMasahiro Yamada } 3754dd88ab32SMasahiro Yamada 3755dd88ab32SMasahiro Yamada# * goes on variable not on type 3756dd88ab32SMasahiro Yamada # (char*[ const]) 3757dd88ab32SMasahiro Yamada while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3758dd88ab32SMasahiro Yamada #print "AA<$1>\n"; 37596b9709d9STom Rini my ($ident, $from, $to) = ($1, $2, $2); 3760dd88ab32SMasahiro Yamada 3761dd88ab32SMasahiro Yamada # Should start with a space. 3762dd88ab32SMasahiro Yamada $to =~ s/^(\S)/ $1/; 3763dd88ab32SMasahiro Yamada # Should not end with a space. 3764dd88ab32SMasahiro Yamada $to =~ s/\s+$//; 3765dd88ab32SMasahiro Yamada # '*'s should not have spaces between. 3766dd88ab32SMasahiro Yamada while ($to =~ s/\*\s+\*/\*\*/) { 3767dd88ab32SMasahiro Yamada } 3768dd88ab32SMasahiro Yamada 37696b9709d9STom Rini## print "1: from<$from> to<$to> ident<$ident>\n"; 3770dd88ab32SMasahiro Yamada if ($from ne $to) { 37716b9709d9STom Rini if (ERROR("POINTER_LOCATION", 37726b9709d9STom Rini "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37736b9709d9STom Rini $fix) { 37746b9709d9STom Rini my $sub_from = $ident; 37756b9709d9STom Rini my $sub_to = $ident; 37766b9709d9STom Rini $sub_to =~ s/\Q$from\E/$to/; 37777551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 37786b9709d9STom Rini s@\Q$sub_from\E@$sub_to@; 37796b9709d9STom Rini } 3780dd88ab32SMasahiro Yamada } 3781dd88ab32SMasahiro Yamada } 3782dd88ab32SMasahiro Yamada while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3783dd88ab32SMasahiro Yamada #print "BB<$1>\n"; 37846b9709d9STom Rini my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3785dd88ab32SMasahiro Yamada 3786dd88ab32SMasahiro Yamada # Should start with a space. 3787dd88ab32SMasahiro Yamada $to =~ s/^(\S)/ $1/; 3788dd88ab32SMasahiro Yamada # Should not end with a space. 3789dd88ab32SMasahiro Yamada $to =~ s/\s+$//; 3790dd88ab32SMasahiro Yamada # '*'s should not have spaces between. 3791dd88ab32SMasahiro Yamada while ($to =~ s/\*\s+\*/\*\*/) { 3792dd88ab32SMasahiro Yamada } 3793dd88ab32SMasahiro Yamada # Modifiers should have spaces. 3794dd88ab32SMasahiro Yamada $to =~ s/(\b$Modifier$)/$1 /; 3795dd88ab32SMasahiro Yamada 37966b9709d9STom Rini## print "2: from<$from> to<$to> ident<$ident>\n"; 3797dd88ab32SMasahiro Yamada if ($from ne $to && $ident !~ /^$Modifier$/) { 37986b9709d9STom Rini if (ERROR("POINTER_LOCATION", 37996b9709d9STom Rini "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 38006b9709d9STom Rini $fix) { 38016b9709d9STom Rini 38026b9709d9STom Rini my $sub_from = $match; 38036b9709d9STom Rini my $sub_to = $match; 38046b9709d9STom Rini $sub_to =~ s/\Q$from\E/$to/; 38057551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 38066b9709d9STom Rini s@\Q$sub_from\E@$sub_to@; 38076b9709d9STom Rini } 3808dd88ab32SMasahiro Yamada } 3809dd88ab32SMasahiro Yamada } 3810dd88ab32SMasahiro Yamada 38117551eb4fSHeinrich Schuchardt# avoid BUG() or BUG_ON() 38127551eb4fSHeinrich Schuchardt if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 38137551eb4fSHeinrich Schuchardt my $msg_type = \&WARN; 38147551eb4fSHeinrich Schuchardt $msg_type = \&CHK if ($file); 38157551eb4fSHeinrich Schuchardt &{$msg_type}("AVOID_BUG", 38167551eb4fSHeinrich Schuchardt "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 38177551eb4fSHeinrich Schuchardt } 3818dd88ab32SMasahiro Yamada 38197551eb4fSHeinrich Schuchardt# avoid LINUX_VERSION_CODE 3820dd88ab32SMasahiro Yamada if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3821dd88ab32SMasahiro Yamada WARN("LINUX_VERSION_CODE", 3822dd88ab32SMasahiro Yamada "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 3823dd88ab32SMasahiro Yamada } 3824dd88ab32SMasahiro Yamada 3825dd88ab32SMasahiro Yamada# check for uses of printk_ratelimit 3826dd88ab32SMasahiro Yamada if ($line =~ /\bprintk_ratelimit\s*\(/) { 3827dd88ab32SMasahiro Yamada WARN("PRINTK_RATELIMITED", 3828dd88ab32SMasahiro Yamada "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 3829dd88ab32SMasahiro Yamada } 3830dd88ab32SMasahiro Yamada 3831dd88ab32SMasahiro Yamada# printk should use KERN_* levels. Note that follow on printk's on the 3832dd88ab32SMasahiro Yamada# same line do not need a level, so we use the current block context 3833dd88ab32SMasahiro Yamada# to try and find and validate the current printk. In summary the current 3834dd88ab32SMasahiro Yamada# printk includes all preceding printk's which have no newline on the end. 3835dd88ab32SMasahiro Yamada# we assume the first bad printk is the one to report. 3836dd88ab32SMasahiro Yamada if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 3837dd88ab32SMasahiro Yamada my $ok = 0; 3838dd88ab32SMasahiro Yamada for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 3839dd88ab32SMasahiro Yamada #print "CHECK<$lines[$ln - 1]\n"; 3840dd88ab32SMasahiro Yamada # we have a preceding printk if it ends 3841dd88ab32SMasahiro Yamada # with "\n" ignore it, else it is to blame 3842dd88ab32SMasahiro Yamada if ($lines[$ln - 1] =~ m{\bprintk\(}) { 3843dd88ab32SMasahiro Yamada if ($rawlines[$ln - 1] !~ m{\\n"}) { 3844dd88ab32SMasahiro Yamada $ok = 1; 3845dd88ab32SMasahiro Yamada } 3846dd88ab32SMasahiro Yamada last; 3847dd88ab32SMasahiro Yamada } 3848dd88ab32SMasahiro Yamada } 3849dd88ab32SMasahiro Yamada if ($ok == 0) { 3850dd88ab32SMasahiro Yamada WARN("PRINTK_WITHOUT_KERN_LEVEL", 3851dd88ab32SMasahiro Yamada "printk() should include KERN_ facility level\n" . $herecurr); 3852dd88ab32SMasahiro Yamada } 3853dd88ab32SMasahiro Yamada } 3854dd88ab32SMasahiro Yamada 3855dd88ab32SMasahiro Yamada if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3856dd88ab32SMasahiro Yamada my $orig = $1; 3857dd88ab32SMasahiro Yamada my $level = lc($orig); 3858dd88ab32SMasahiro Yamada $level = "warn" if ($level eq "warning"); 3859dd88ab32SMasahiro Yamada my $level2 = $level; 3860dd88ab32SMasahiro Yamada $level2 = "dbg" if ($level eq "debug"); 3861dd88ab32SMasahiro Yamada WARN("PREFER_PR_LEVEL", 38627551eb4fSHeinrich Schuchardt "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3863dd88ab32SMasahiro Yamada } 3864dd88ab32SMasahiro Yamada 3865dd88ab32SMasahiro Yamada if ($line =~ /\bpr_warning\s*\(/) { 38666b9709d9STom Rini if (WARN("PREFER_PR_LEVEL", 38676b9709d9STom Rini "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 38686b9709d9STom Rini $fix) { 38697551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 38706b9709d9STom Rini s/\bpr_warning\b/pr_warn/; 38716b9709d9STom Rini } 3872dd88ab32SMasahiro Yamada } 3873dd88ab32SMasahiro Yamada 3874dd88ab32SMasahiro Yamada if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3875dd88ab32SMasahiro Yamada my $orig = $1; 3876dd88ab32SMasahiro Yamada my $level = lc($orig); 3877dd88ab32SMasahiro Yamada $level = "warn" if ($level eq "warning"); 3878dd88ab32SMasahiro Yamada $level = "dbg" if ($level eq "debug"); 3879dd88ab32SMasahiro Yamada WARN("PREFER_DEV_LEVEL", 3880dd88ab32SMasahiro Yamada "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3881dd88ab32SMasahiro Yamada } 3882dd88ab32SMasahiro Yamada 38837551eb4fSHeinrich Schuchardt# ENOSYS means "bad syscall nr" and nothing else. This will have a small 38847551eb4fSHeinrich Schuchardt# number of false positives, but assembly files are not checked, so at 38857551eb4fSHeinrich Schuchardt# least the arch entry code will not trigger this warning. 38867551eb4fSHeinrich Schuchardt if ($line =~ /\bENOSYS\b/) { 38877551eb4fSHeinrich Schuchardt WARN("ENOSYS", 38887551eb4fSHeinrich Schuchardt "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 38897551eb4fSHeinrich Schuchardt } 38907551eb4fSHeinrich Schuchardt 3891dd88ab32SMasahiro Yamada# function brace can't be on same line, except for #defines of do while, 3892dd88ab32SMasahiro Yamada# or if closed on same line 38937551eb4fSHeinrich Schuchardt if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 3894d8a1a304SHeiko Schocher !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38957551eb4fSHeinrich Schuchardt if (ERROR("OPEN_BRACE", 38967551eb4fSHeinrich Schuchardt "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38977551eb4fSHeinrich Schuchardt $fix) { 38987551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 38997551eb4fSHeinrich Schuchardt my $fixed_line = $rawline; 39007551eb4fSHeinrich Schuchardt $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 39017551eb4fSHeinrich Schuchardt my $line1 = $1; 39027551eb4fSHeinrich Schuchardt my $line2 = $2; 39037551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, ltrim($line1)); 39047551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, "\+{"); 39057551eb4fSHeinrich Schuchardt if ($line2 !~ /^\s*$/) { 39067551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 39077551eb4fSHeinrich Schuchardt } 39087551eb4fSHeinrich Schuchardt } 3909dd88ab32SMasahiro Yamada } 3910dd88ab32SMasahiro Yamada 3911dd88ab32SMasahiro Yamada# open braces for enum, union and struct go on the same line. 3912dd88ab32SMasahiro Yamada if ($line =~ /^.\s*{/ && 3913dd88ab32SMasahiro Yamada $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 39147551eb4fSHeinrich Schuchardt if (ERROR("OPEN_BRACE", 39157551eb4fSHeinrich Schuchardt "open brace '{' following $1 go on the same line\n" . $hereprev) && 39167551eb4fSHeinrich Schuchardt $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 39177551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 39187551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 39197551eb4fSHeinrich Schuchardt my $fixedline = rtrim($prevrawline) . " {"; 39207551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 39217551eb4fSHeinrich Schuchardt $fixedline = $rawline; 39227551eb4fSHeinrich Schuchardt $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 39237551eb4fSHeinrich Schuchardt if ($fixedline !~ /^\+\s*$/) { 39247551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 39257551eb4fSHeinrich Schuchardt } 39267551eb4fSHeinrich Schuchardt } 3927dd88ab32SMasahiro Yamada } 3928dd88ab32SMasahiro Yamada 3929dd88ab32SMasahiro Yamada# missing space after union, struct or enum definition 39306b9709d9STom Rini if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 39316b9709d9STom Rini if (WARN("SPACING", 39326b9709d9STom Rini "missing space after $1 definition\n" . $herecurr) && 39336b9709d9STom Rini $fix) { 39347551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 39356b9709d9STom Rini s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 39366b9709d9STom Rini } 39376b9709d9STom Rini } 39386b9709d9STom Rini 39396b9709d9STom Rini# Function pointer declarations 39406b9709d9STom Rini# check spacing between type, funcptr, and args 39416b9709d9STom Rini# canonical declaration is "type (*funcptr)(args...)" 39427551eb4fSHeinrich Schuchardt if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 39436b9709d9STom Rini my $declare = $1; 39446b9709d9STom Rini my $pre_pointer_space = $2; 39456b9709d9STom Rini my $post_pointer_space = $3; 39466b9709d9STom Rini my $funcname = $4; 39476b9709d9STom Rini my $post_funcname_space = $5; 39486b9709d9STom Rini my $pre_args_space = $6; 39496b9709d9STom Rini 39507551eb4fSHeinrich Schuchardt# the $Declare variable will capture all spaces after the type 39517551eb4fSHeinrich Schuchardt# so check it for a missing trailing missing space but pointer return types 39527551eb4fSHeinrich Schuchardt# don't need a space so don't warn for those. 39537551eb4fSHeinrich Schuchardt my $post_declare_space = ""; 39547551eb4fSHeinrich Schuchardt if ($declare =~ /(\s+)$/) { 39557551eb4fSHeinrich Schuchardt $post_declare_space = $1; 39567551eb4fSHeinrich Schuchardt $declare = rtrim($declare); 39577551eb4fSHeinrich Schuchardt } 39587551eb4fSHeinrich Schuchardt if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 3959dd88ab32SMasahiro Yamada WARN("SPACING", 39606b9709d9STom Rini "missing space after return type\n" . $herecurr); 39617551eb4fSHeinrich Schuchardt $post_declare_space = " "; 39626b9709d9STom Rini } 39636b9709d9STom Rini 39646b9709d9STom Rini# unnecessary space "type (*funcptr)(args...)" 39657551eb4fSHeinrich Schuchardt# This test is not currently implemented because these declarations are 39667551eb4fSHeinrich Schuchardt# equivalent to 39677551eb4fSHeinrich Schuchardt# int foo(int bar, ...) 39687551eb4fSHeinrich Schuchardt# and this is form shouldn't/doesn't generate a checkpatch warning. 39697551eb4fSHeinrich Schuchardt# 39707551eb4fSHeinrich Schuchardt# elsif ($declare =~ /\s{2,}$/) { 39717551eb4fSHeinrich Schuchardt# WARN("SPACING", 39727551eb4fSHeinrich Schuchardt# "Multiple spaces after return type\n" . $herecurr); 39737551eb4fSHeinrich Schuchardt# } 39746b9709d9STom Rini 39756b9709d9STom Rini# unnecessary space "type ( *funcptr)(args...)" 39766b9709d9STom Rini if (defined $pre_pointer_space && 39776b9709d9STom Rini $pre_pointer_space =~ /^\s/) { 39786b9709d9STom Rini WARN("SPACING", 39796b9709d9STom Rini "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 39806b9709d9STom Rini } 39816b9709d9STom Rini 39826b9709d9STom Rini# unnecessary space "type (* funcptr)(args...)" 39836b9709d9STom Rini if (defined $post_pointer_space && 39846b9709d9STom Rini $post_pointer_space =~ /^\s/) { 39856b9709d9STom Rini WARN("SPACING", 39866b9709d9STom Rini "Unnecessary space before function pointer name\n" . $herecurr); 39876b9709d9STom Rini } 39886b9709d9STom Rini 39896b9709d9STom Rini# unnecessary space "type (*funcptr )(args...)" 39906b9709d9STom Rini if (defined $post_funcname_space && 39916b9709d9STom Rini $post_funcname_space =~ /^\s/) { 39926b9709d9STom Rini WARN("SPACING", 39936b9709d9STom Rini "Unnecessary space after function pointer name\n" . $herecurr); 39946b9709d9STom Rini } 39956b9709d9STom Rini 39966b9709d9STom Rini# unnecessary space "type (*funcptr) (args...)" 39976b9709d9STom Rini if (defined $pre_args_space && 39986b9709d9STom Rini $pre_args_space =~ /^\s/) { 39996b9709d9STom Rini WARN("SPACING", 40006b9709d9STom Rini "Unnecessary space before function pointer arguments\n" . $herecurr); 40016b9709d9STom Rini } 40026b9709d9STom Rini 40036b9709d9STom Rini if (show_type("SPACING") && $fix) { 40047551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 40057551eb4fSHeinrich Schuchardt s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 40066b9709d9STom Rini } 4007dd88ab32SMasahiro Yamada } 4008dd88ab32SMasahiro Yamada 4009dd88ab32SMasahiro Yamada# check for spacing round square brackets; allowed: 4010dd88ab32SMasahiro Yamada# 1. with a type on the left -- int [] a; 4011dd88ab32SMasahiro Yamada# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4012dd88ab32SMasahiro Yamada# 3. inside a curly brace -- = { [0...10] = 5 } 4013dd88ab32SMasahiro Yamada while ($line =~ /(.*?\s)\[/g) { 4014dd88ab32SMasahiro Yamada my ($where, $prefix) = ($-[1], $1); 4015dd88ab32SMasahiro Yamada if ($prefix !~ /$Type\s+$/ && 4016dd88ab32SMasahiro Yamada ($where != 0 || $prefix !~ /^.\s+$/) && 4017dd88ab32SMasahiro Yamada $prefix !~ /[{,]\s+$/) { 40186b9709d9STom Rini if (ERROR("BRACKET_SPACE", 40196b9709d9STom Rini "space prohibited before open square bracket '['\n" . $herecurr) && 40206b9709d9STom Rini $fix) { 40217551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 40226b9709d9STom Rini s/^(\+.*?)\s+\[/$1\[/; 40236b9709d9STom Rini } 4024dd88ab32SMasahiro Yamada } 4025dd88ab32SMasahiro Yamada } 4026dd88ab32SMasahiro Yamada 4027dd88ab32SMasahiro Yamada# check for spaces between functions and their parentheses. 4028dd88ab32SMasahiro Yamada while ($line =~ /($Ident)\s+\(/g) { 4029dd88ab32SMasahiro Yamada my $name = $1; 4030dd88ab32SMasahiro Yamada my $ctx_before = substr($line, 0, $-[1]); 4031dd88ab32SMasahiro Yamada my $ctx = "$ctx_before$name"; 4032dd88ab32SMasahiro Yamada 4033dd88ab32SMasahiro Yamada # Ignore those directives where spaces _are_ permitted. 4034dd88ab32SMasahiro Yamada if ($name =~ /^(?: 4035dd88ab32SMasahiro Yamada if|for|while|switch|return|case| 4036dd88ab32SMasahiro Yamada volatile|__volatile__| 4037dd88ab32SMasahiro Yamada __attribute__|format|__extension__| 4038dd88ab32SMasahiro Yamada asm|__asm__)$/x) 4039dd88ab32SMasahiro Yamada { 4040dd88ab32SMasahiro Yamada # cpp #define statements have non-optional spaces, ie 4041dd88ab32SMasahiro Yamada # if there is a space between the name and the open 4042dd88ab32SMasahiro Yamada # parenthesis it is simply not a parameter group. 4043dd88ab32SMasahiro Yamada } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4044dd88ab32SMasahiro Yamada 4045dd88ab32SMasahiro Yamada # cpp #elif statement condition may start with a ( 4046dd88ab32SMasahiro Yamada } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4047dd88ab32SMasahiro Yamada 4048dd88ab32SMasahiro Yamada # If this whole things ends with a type its most 4049dd88ab32SMasahiro Yamada # likely a typedef for a function. 4050dd88ab32SMasahiro Yamada } elsif ($ctx =~ /$Type$/) { 4051dd88ab32SMasahiro Yamada 4052dd88ab32SMasahiro Yamada } else { 40536b9709d9STom Rini if (WARN("SPACING", 40546b9709d9STom Rini "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40556b9709d9STom Rini $fix) { 40567551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 40576b9709d9STom Rini s/\b$name\s+\(/$name\(/; 4058dd88ab32SMasahiro Yamada } 4059dd88ab32SMasahiro Yamada } 4060dd88ab32SMasahiro Yamada } 4061dd88ab32SMasahiro Yamada 4062dd88ab32SMasahiro Yamada# Check operator spacing. 4063dd88ab32SMasahiro Yamada if (!($line=~/\#\s*include/)) { 40646b9709d9STom Rini my $fixed_line = ""; 40656b9709d9STom Rini my $line_fixed = 0; 40666b9709d9STom Rini 4067dd88ab32SMasahiro Yamada my $ops = qr{ 4068dd88ab32SMasahiro Yamada <<=|>>=|<=|>=|==|!=| 4069dd88ab32SMasahiro Yamada \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 4070dd88ab32SMasahiro Yamada =>|->|<<|>>|<|>|=|!|~| 4071dd88ab32SMasahiro Yamada &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 40726b9709d9STom Rini \?:|\?|: 4073dd88ab32SMasahiro Yamada }x; 4074dd88ab32SMasahiro Yamada my @elements = split(/($ops|;)/, $opline); 40756b9709d9STom Rini 40766b9709d9STom Rini## print("element count: <" . $#elements . ">\n"); 40776b9709d9STom Rini## foreach my $el (@elements) { 40786b9709d9STom Rini## print("el: <$el>\n"); 40796b9709d9STom Rini## } 40806b9709d9STom Rini 40816b9709d9STom Rini my @fix_elements = (); 4082dd88ab32SMasahiro Yamada my $off = 0; 4083dd88ab32SMasahiro Yamada 40846b9709d9STom Rini foreach my $el (@elements) { 40856b9709d9STom Rini push(@fix_elements, substr($rawline, $off, length($el))); 40866b9709d9STom Rini $off += length($el); 40876b9709d9STom Rini } 40886b9709d9STom Rini 40896b9709d9STom Rini $off = 0; 40906b9709d9STom Rini 4091dd88ab32SMasahiro Yamada my $blank = copy_spacing($opline); 40926b9709d9STom Rini my $last_after = -1; 4093dd88ab32SMasahiro Yamada 4094dd88ab32SMasahiro Yamada for (my $n = 0; $n < $#elements; $n += 2) { 40956b9709d9STom Rini 40966b9709d9STom Rini my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40976b9709d9STom Rini 40986b9709d9STom Rini## print("n: <$n> good: <$good>\n"); 40996b9709d9STom Rini 4100dd88ab32SMasahiro Yamada $off += length($elements[$n]); 4101dd88ab32SMasahiro Yamada 4102dd88ab32SMasahiro Yamada # Pick up the preceding and succeeding characters. 4103dd88ab32SMasahiro Yamada my $ca = substr($opline, 0, $off); 4104dd88ab32SMasahiro Yamada my $cc = ''; 4105dd88ab32SMasahiro Yamada if (length($opline) >= ($off + length($elements[$n + 1]))) { 4106dd88ab32SMasahiro Yamada $cc = substr($opline, $off + length($elements[$n + 1])); 4107dd88ab32SMasahiro Yamada } 4108dd88ab32SMasahiro Yamada my $cb = "$ca$;$cc"; 4109dd88ab32SMasahiro Yamada 4110dd88ab32SMasahiro Yamada my $a = ''; 4111dd88ab32SMasahiro Yamada $a = 'V' if ($elements[$n] ne ''); 4112dd88ab32SMasahiro Yamada $a = 'W' if ($elements[$n] =~ /\s$/); 4113dd88ab32SMasahiro Yamada $a = 'C' if ($elements[$n] =~ /$;$/); 4114dd88ab32SMasahiro Yamada $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 4115dd88ab32SMasahiro Yamada $a = 'O' if ($elements[$n] eq ''); 4116dd88ab32SMasahiro Yamada $a = 'E' if ($ca =~ /^\s*$/); 4117dd88ab32SMasahiro Yamada 4118dd88ab32SMasahiro Yamada my $op = $elements[$n + 1]; 4119dd88ab32SMasahiro Yamada 4120dd88ab32SMasahiro Yamada my $c = ''; 4121dd88ab32SMasahiro Yamada if (defined $elements[$n + 2]) { 4122dd88ab32SMasahiro Yamada $c = 'V' if ($elements[$n + 2] ne ''); 4123dd88ab32SMasahiro Yamada $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4124dd88ab32SMasahiro Yamada $c = 'C' if ($elements[$n + 2] =~ /^$;/); 4125dd88ab32SMasahiro Yamada $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 4126dd88ab32SMasahiro Yamada $c = 'O' if ($elements[$n + 2] eq ''); 4127dd88ab32SMasahiro Yamada $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 4128dd88ab32SMasahiro Yamada } else { 4129dd88ab32SMasahiro Yamada $c = 'E'; 4130dd88ab32SMasahiro Yamada } 4131dd88ab32SMasahiro Yamada 4132dd88ab32SMasahiro Yamada my $ctx = "${a}x${c}"; 4133dd88ab32SMasahiro Yamada 4134dd88ab32SMasahiro Yamada my $at = "(ctx:$ctx)"; 4135dd88ab32SMasahiro Yamada 4136dd88ab32SMasahiro Yamada my $ptr = substr($blank, 0, $off) . "^"; 4137dd88ab32SMasahiro Yamada my $hereptr = "$hereline$ptr\n"; 4138dd88ab32SMasahiro Yamada 4139dd88ab32SMasahiro Yamada # Pull out the value of this operator. 4140dd88ab32SMasahiro Yamada my $op_type = substr($curr_values, $off + 1, 1); 4141dd88ab32SMasahiro Yamada 4142dd88ab32SMasahiro Yamada # Get the full operator variant. 4143dd88ab32SMasahiro Yamada my $opv = $op . substr($curr_vars, $off, 1); 4144dd88ab32SMasahiro Yamada 4145dd88ab32SMasahiro Yamada # Ignore operators passed as parameters. 4146dd88ab32SMasahiro Yamada if ($op_type ne 'V' && 41477551eb4fSHeinrich Schuchardt $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 4148dd88ab32SMasahiro Yamada 4149dd88ab32SMasahiro Yamada# # Ignore comments 4150dd88ab32SMasahiro Yamada# } elsif ($op =~ /^$;+$/) { 4151dd88ab32SMasahiro Yamada 4152dd88ab32SMasahiro Yamada # ; should have either the end of line or a space or \ after it 4153dd88ab32SMasahiro Yamada } elsif ($op eq ';') { 4154dd88ab32SMasahiro Yamada if ($ctx !~ /.x[WEBC]/ && 4155dd88ab32SMasahiro Yamada $cc !~ /^\\/ && $cc !~ /^;/) { 41566b9709d9STom Rini if (ERROR("SPACING", 41576b9709d9STom Rini "space required after that '$op' $at\n" . $hereptr)) { 41586b9709d9STom Rini $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41596b9709d9STom Rini $line_fixed = 1; 41606b9709d9STom Rini } 4161dd88ab32SMasahiro Yamada } 4162dd88ab32SMasahiro Yamada 4163dd88ab32SMasahiro Yamada # // is a comment 4164dd88ab32SMasahiro Yamada } elsif ($op eq '//') { 4165dd88ab32SMasahiro Yamada 41667551eb4fSHeinrich Schuchardt # : when part of a bitfield 41677551eb4fSHeinrich Schuchardt } elsif ($opv eq ':B') { 41687551eb4fSHeinrich Schuchardt # skip the bitfield test for now 41697551eb4fSHeinrich Schuchardt 4170dd88ab32SMasahiro Yamada # No spaces for: 4171dd88ab32SMasahiro Yamada # -> 41727551eb4fSHeinrich Schuchardt } elsif ($op eq '->') { 4173dd88ab32SMasahiro Yamada if ($ctx =~ /Wx.|.xW/) { 41746b9709d9STom Rini if (ERROR("SPACING", 41756b9709d9STom Rini "spaces prohibited around that '$op' $at\n" . $hereptr)) { 41766b9709d9STom Rini $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41776b9709d9STom Rini if (defined $fix_elements[$n + 2]) { 41786b9709d9STom Rini $fix_elements[$n + 2] =~ s/^\s+//; 41796b9709d9STom Rini } 41806b9709d9STom Rini $line_fixed = 1; 41816b9709d9STom Rini } 4182dd88ab32SMasahiro Yamada } 4183dd88ab32SMasahiro Yamada 41847551eb4fSHeinrich Schuchardt # , must not have a space before and must have a space on the right. 4185dd88ab32SMasahiro Yamada } elsif ($op eq ',') { 41867551eb4fSHeinrich Schuchardt my $rtrim_before = 0; 41877551eb4fSHeinrich Schuchardt my $space_after = 0; 41887551eb4fSHeinrich Schuchardt if ($ctx =~ /Wx./) { 41897551eb4fSHeinrich Schuchardt if (ERROR("SPACING", 41907551eb4fSHeinrich Schuchardt "space prohibited before that '$op' $at\n" . $hereptr)) { 41917551eb4fSHeinrich Schuchardt $line_fixed = 1; 41927551eb4fSHeinrich Schuchardt $rtrim_before = 1; 41937551eb4fSHeinrich Schuchardt } 41947551eb4fSHeinrich Schuchardt } 4195dd88ab32SMasahiro Yamada if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41966b9709d9STom Rini if (ERROR("SPACING", 41976b9709d9STom Rini "space required after that '$op' $at\n" . $hereptr)) { 41986b9709d9STom Rini $line_fixed = 1; 41996b9709d9STom Rini $last_after = $n; 42007551eb4fSHeinrich Schuchardt $space_after = 1; 42017551eb4fSHeinrich Schuchardt } 42027551eb4fSHeinrich Schuchardt } 42037551eb4fSHeinrich Schuchardt if ($rtrim_before || $space_after) { 42047551eb4fSHeinrich Schuchardt if ($rtrim_before) { 42057551eb4fSHeinrich Schuchardt $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42067551eb4fSHeinrich Schuchardt } else { 42077551eb4fSHeinrich Schuchardt $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42087551eb4fSHeinrich Schuchardt } 42097551eb4fSHeinrich Schuchardt if ($space_after) { 42107551eb4fSHeinrich Schuchardt $good .= " "; 42116b9709d9STom Rini } 4212dd88ab32SMasahiro Yamada } 4213dd88ab32SMasahiro Yamada 4214dd88ab32SMasahiro Yamada # '*' as part of a type definition -- reported already. 4215dd88ab32SMasahiro Yamada } elsif ($opv eq '*_') { 4216dd88ab32SMasahiro Yamada #warn "'*' is part of type\n"; 4217dd88ab32SMasahiro Yamada 4218dd88ab32SMasahiro Yamada # unary operators should have a space before and 4219dd88ab32SMasahiro Yamada # none after. May be left adjacent to another 4220dd88ab32SMasahiro Yamada # unary operator, or a cast 4221dd88ab32SMasahiro Yamada } elsif ($op eq '!' || $op eq '~' || 4222dd88ab32SMasahiro Yamada $opv eq '*U' || $opv eq '-U' || 4223dd88ab32SMasahiro Yamada $opv eq '&U' || $opv eq '&&U') { 4224dd88ab32SMasahiro Yamada if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 42256b9709d9STom Rini if (ERROR("SPACING", 42266b9709d9STom Rini "space required before that '$op' $at\n" . $hereptr)) { 42276b9709d9STom Rini if ($n != $last_after + 2) { 42286b9709d9STom Rini $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 42296b9709d9STom Rini $line_fixed = 1; 42306b9709d9STom Rini } 42316b9709d9STom Rini } 4232dd88ab32SMasahiro Yamada } 4233dd88ab32SMasahiro Yamada if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4234dd88ab32SMasahiro Yamada # A unary '*' may be const 4235dd88ab32SMasahiro Yamada 4236dd88ab32SMasahiro Yamada } elsif ($ctx =~ /.xW/) { 42376b9709d9STom Rini if (ERROR("SPACING", 42386b9709d9STom Rini "space prohibited after that '$op' $at\n" . $hereptr)) { 42396b9709d9STom Rini $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42406b9709d9STom Rini if (defined $fix_elements[$n + 2]) { 42416b9709d9STom Rini $fix_elements[$n + 2] =~ s/^\s+//; 42426b9709d9STom Rini } 42436b9709d9STom Rini $line_fixed = 1; 42446b9709d9STom Rini } 4245dd88ab32SMasahiro Yamada } 4246dd88ab32SMasahiro Yamada 4247dd88ab32SMasahiro Yamada # unary ++ and unary -- are allowed no space on one side. 4248dd88ab32SMasahiro Yamada } elsif ($op eq '++' or $op eq '--') { 4249dd88ab32SMasahiro Yamada if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42506b9709d9STom Rini if (ERROR("SPACING", 42516b9709d9STom Rini "space required one side of that '$op' $at\n" . $hereptr)) { 42526b9709d9STom Rini $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42536b9709d9STom Rini $line_fixed = 1; 42546b9709d9STom Rini } 4255dd88ab32SMasahiro Yamada } 4256dd88ab32SMasahiro Yamada if ($ctx =~ /Wx[BE]/ || 4257dd88ab32SMasahiro Yamada ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42586b9709d9STom Rini if (ERROR("SPACING", 42596b9709d9STom Rini "space prohibited before that '$op' $at\n" . $hereptr)) { 42606b9709d9STom Rini $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42616b9709d9STom Rini $line_fixed = 1; 42626b9709d9STom Rini } 4263dd88ab32SMasahiro Yamada } 4264dd88ab32SMasahiro Yamada if ($ctx =~ /ExW/) { 42656b9709d9STom Rini if (ERROR("SPACING", 42666b9709d9STom Rini "space prohibited after that '$op' $at\n" . $hereptr)) { 42676b9709d9STom Rini $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42686b9709d9STom Rini if (defined $fix_elements[$n + 2]) { 42696b9709d9STom Rini $fix_elements[$n + 2] =~ s/^\s+//; 4270dd88ab32SMasahiro Yamada } 42716b9709d9STom Rini $line_fixed = 1; 42726b9709d9STom Rini } 42736b9709d9STom Rini } 4274dd88ab32SMasahiro Yamada 4275dd88ab32SMasahiro Yamada # << and >> may either have or not have spaces both sides 4276dd88ab32SMasahiro Yamada } elsif ($op eq '<<' or $op eq '>>' or 4277dd88ab32SMasahiro Yamada $op eq '&' or $op eq '^' or $op eq '|' or 4278dd88ab32SMasahiro Yamada $op eq '+' or $op eq '-' or 4279dd88ab32SMasahiro Yamada $op eq '*' or $op eq '/' or 4280dd88ab32SMasahiro Yamada $op eq '%') 4281dd88ab32SMasahiro Yamada { 42827551eb4fSHeinrich Schuchardt if ($check) { 42837551eb4fSHeinrich Schuchardt if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 42847551eb4fSHeinrich Schuchardt if (CHK("SPACING", 42857551eb4fSHeinrich Schuchardt "spaces preferred around that '$op' $at\n" . $hereptr)) { 42867551eb4fSHeinrich Schuchardt $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 42877551eb4fSHeinrich Schuchardt $fix_elements[$n + 2] =~ s/^\s+//; 42887551eb4fSHeinrich Schuchardt $line_fixed = 1; 42897551eb4fSHeinrich Schuchardt } 42907551eb4fSHeinrich Schuchardt } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 42917551eb4fSHeinrich Schuchardt if (CHK("SPACING", 42927551eb4fSHeinrich Schuchardt "space preferred before that '$op' $at\n" . $hereptr)) { 42937551eb4fSHeinrich Schuchardt $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 42947551eb4fSHeinrich Schuchardt $line_fixed = 1; 42957551eb4fSHeinrich Schuchardt } 42967551eb4fSHeinrich Schuchardt } 42977551eb4fSHeinrich Schuchardt } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42986b9709d9STom Rini if (ERROR("SPACING", 42996b9709d9STom Rini "need consistent spacing around '$op' $at\n" . $hereptr)) { 43006b9709d9STom Rini $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 43016b9709d9STom Rini if (defined $fix_elements[$n + 2]) { 43026b9709d9STom Rini $fix_elements[$n + 2] =~ s/^\s+//; 43036b9709d9STom Rini } 43046b9709d9STom Rini $line_fixed = 1; 43056b9709d9STom Rini } 4306dd88ab32SMasahiro Yamada } 4307dd88ab32SMasahiro Yamada 4308dd88ab32SMasahiro Yamada # A colon needs no spaces before when it is 4309dd88ab32SMasahiro Yamada # terminating a case value or a label. 4310dd88ab32SMasahiro Yamada } elsif ($opv eq ':C' || $opv eq ':L') { 4311dd88ab32SMasahiro Yamada if ($ctx =~ /Wx./) { 43126b9709d9STom Rini if (ERROR("SPACING", 43136b9709d9STom Rini "space prohibited before that '$op' $at\n" . $hereptr)) { 43146b9709d9STom Rini $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 43156b9709d9STom Rini $line_fixed = 1; 43166b9709d9STom Rini } 4317dd88ab32SMasahiro Yamada } 4318dd88ab32SMasahiro Yamada 4319dd88ab32SMasahiro Yamada # All the others need spaces both sides. 4320dd88ab32SMasahiro Yamada } elsif ($ctx !~ /[EWC]x[CWE]/) { 4321dd88ab32SMasahiro Yamada my $ok = 0; 4322dd88ab32SMasahiro Yamada 4323dd88ab32SMasahiro Yamada # Ignore email addresses <foo@bar> 4324dd88ab32SMasahiro Yamada if (($op eq '<' && 4325dd88ab32SMasahiro Yamada $cc =~ /^\S+\@\S+>/) || 4326dd88ab32SMasahiro Yamada ($op eq '>' && 4327dd88ab32SMasahiro Yamada $ca =~ /<\S+\@\S+$/)) 4328dd88ab32SMasahiro Yamada { 4329dd88ab32SMasahiro Yamada $ok = 1; 4330dd88ab32SMasahiro Yamada } 4331dd88ab32SMasahiro Yamada 43327551eb4fSHeinrich Schuchardt # for asm volatile statements 43337551eb4fSHeinrich Schuchardt # ignore a colon with another 43347551eb4fSHeinrich Schuchardt # colon immediately before or after 43357551eb4fSHeinrich Schuchardt if (($op eq ':') && 43367551eb4fSHeinrich Schuchardt ($ca =~ /:$/ || $cc =~ /^:/)) { 43377551eb4fSHeinrich Schuchardt $ok = 1; 43387551eb4fSHeinrich Schuchardt } 43397551eb4fSHeinrich Schuchardt 43406b9709d9STom Rini # messages are ERROR, but ?: are CHK 4341dd88ab32SMasahiro Yamada if ($ok == 0) { 43426b9709d9STom Rini my $msg_type = \&ERROR; 43436b9709d9STom Rini $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 43446b9709d9STom Rini 43456b9709d9STom Rini if (&{$msg_type}("SPACING", 43466b9709d9STom Rini "spaces required around that '$op' $at\n" . $hereptr)) { 43476b9709d9STom Rini $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 43486b9709d9STom Rini if (defined $fix_elements[$n + 2]) { 43496b9709d9STom Rini $fix_elements[$n + 2] =~ s/^\s+//; 43506b9709d9STom Rini } 43516b9709d9STom Rini $line_fixed = 1; 43526b9709d9STom Rini } 4353dd88ab32SMasahiro Yamada } 4354dd88ab32SMasahiro Yamada } 4355dd88ab32SMasahiro Yamada $off += length($elements[$n + 1]); 43566b9709d9STom Rini 43576b9709d9STom Rini## print("n: <$n> GOOD: <$good>\n"); 43586b9709d9STom Rini 43596b9709d9STom Rini $fixed_line = $fixed_line . $good; 43606b9709d9STom Rini } 43616b9709d9STom Rini 43626b9709d9STom Rini if (($#elements % 2) == 0) { 43636b9709d9STom Rini $fixed_line = $fixed_line . $fix_elements[$#elements]; 43646b9709d9STom Rini } 43656b9709d9STom Rini 43667551eb4fSHeinrich Schuchardt if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 43677551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] = $fixed_line; 43686b9709d9STom Rini } 43696b9709d9STom Rini 43706b9709d9STom Rini 43716b9709d9STom Rini } 43726b9709d9STom Rini 43736b9709d9STom Rini# check for whitespace before a non-naked semicolon 43746b9709d9STom Rini if ($line =~ /^\+.*\S\s+;\s*$/) { 43756b9709d9STom Rini if (WARN("SPACING", 43766b9709d9STom Rini "space prohibited before semicolon\n" . $herecurr) && 43776b9709d9STom Rini $fix) { 43787551eb4fSHeinrich Schuchardt 1 while $fixed[$fixlinenr] =~ 43796b9709d9STom Rini s/^(\+.*\S)\s+;/$1;/; 4380dd88ab32SMasahiro Yamada } 4381dd88ab32SMasahiro Yamada } 4382dd88ab32SMasahiro Yamada 4383dd88ab32SMasahiro Yamada# check for multiple assignments 4384dd88ab32SMasahiro Yamada if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4385dd88ab32SMasahiro Yamada CHK("MULTIPLE_ASSIGNMENTS", 4386dd88ab32SMasahiro Yamada "multiple assignments should be avoided\n" . $herecurr); 4387dd88ab32SMasahiro Yamada } 4388dd88ab32SMasahiro Yamada 4389dd88ab32SMasahiro Yamada## # check for multiple declarations, allowing for a function declaration 4390dd88ab32SMasahiro Yamada## # continuation. 4391dd88ab32SMasahiro Yamada## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 4392dd88ab32SMasahiro Yamada## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 4393dd88ab32SMasahiro Yamada## 4394dd88ab32SMasahiro Yamada## # Remove any bracketed sections to ensure we do not 4395dd88ab32SMasahiro Yamada## # falsly report the parameters of functions. 4396dd88ab32SMasahiro Yamada## my $ln = $line; 4397dd88ab32SMasahiro Yamada## while ($ln =~ s/\([^\(\)]*\)//g) { 4398dd88ab32SMasahiro Yamada## } 4399dd88ab32SMasahiro Yamada## if ($ln =~ /,/) { 4400dd88ab32SMasahiro Yamada## WARN("MULTIPLE_DECLARATION", 4401dd88ab32SMasahiro Yamada## "declaring multiple variables together should be avoided\n" . $herecurr); 4402dd88ab32SMasahiro Yamada## } 4403dd88ab32SMasahiro Yamada## } 4404dd88ab32SMasahiro Yamada 4405dd88ab32SMasahiro Yamada#need space before brace following if, while, etc 44067551eb4fSHeinrich Schuchardt if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 4407d8a1a304SHeiko Schocher $line =~ /do\{/) { 44086b9709d9STom Rini if (ERROR("SPACING", 44096b9709d9STom Rini "space required before the open brace '{'\n" . $herecurr) && 44106b9709d9STom Rini $fix) { 44117551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; 4412dd88ab32SMasahiro Yamada } 44136b9709d9STom Rini } 44146b9709d9STom Rini 44156b9709d9STom Rini## # check for blank lines before declarations 44166b9709d9STom Rini## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 44176b9709d9STom Rini## $prevrawline =~ /^.\s*$/) { 44186b9709d9STom Rini## WARN("SPACING", 44196b9709d9STom Rini## "No blank lines before declarations\n" . $hereprev); 44206b9709d9STom Rini## } 44216b9709d9STom Rini## 4422dd88ab32SMasahiro Yamada 4423dd88ab32SMasahiro Yamada# closing brace should have a space following it when it has anything 4424dd88ab32SMasahiro Yamada# on the line 4425dd88ab32SMasahiro Yamada if ($line =~ /}(?!(?:,|;|\)))\S/) { 44266b9709d9STom Rini if (ERROR("SPACING", 44276b9709d9STom Rini "space required after that close brace '}'\n" . $herecurr) && 44286b9709d9STom Rini $fix) { 44297551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 44306b9709d9STom Rini s/}((?!(?:,|;|\)))\S)/} $1/; 44316b9709d9STom Rini } 4432dd88ab32SMasahiro Yamada } 4433dd88ab32SMasahiro Yamada 4434dd88ab32SMasahiro Yamada# check spacing on square brackets 4435dd88ab32SMasahiro Yamada if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 44366b9709d9STom Rini if (ERROR("SPACING", 44376b9709d9STom Rini "space prohibited after that open square bracket '['\n" . $herecurr) && 44386b9709d9STom Rini $fix) { 44397551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 44406b9709d9STom Rini s/\[\s+/\[/; 44416b9709d9STom Rini } 4442dd88ab32SMasahiro Yamada } 4443dd88ab32SMasahiro Yamada if ($line =~ /\s\]/) { 44446b9709d9STom Rini if (ERROR("SPACING", 44456b9709d9STom Rini "space prohibited before that close square bracket ']'\n" . $herecurr) && 44466b9709d9STom Rini $fix) { 44477551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 44486b9709d9STom Rini s/\s+\]/\]/; 44496b9709d9STom Rini } 4450dd88ab32SMasahiro Yamada } 4451dd88ab32SMasahiro Yamada 4452dd88ab32SMasahiro Yamada# check spacing on parentheses 4453dd88ab32SMasahiro Yamada if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 4454dd88ab32SMasahiro Yamada $line !~ /for\s*\(\s+;/) { 44556b9709d9STom Rini if (ERROR("SPACING", 44566b9709d9STom Rini "space prohibited after that open parenthesis '('\n" . $herecurr) && 44576b9709d9STom Rini $fix) { 44587551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 44596b9709d9STom Rini s/\(\s+/\(/; 44606b9709d9STom Rini } 4461dd88ab32SMasahiro Yamada } 4462dd88ab32SMasahiro Yamada if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4463dd88ab32SMasahiro Yamada $line !~ /for\s*\(.*;\s+\)/ && 4464dd88ab32SMasahiro Yamada $line !~ /:\s+\)/) { 44656b9709d9STom Rini if (ERROR("SPACING", 44666b9709d9STom Rini "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44676b9709d9STom Rini $fix) { 44687551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 44696b9709d9STom Rini s/\s+\)/\)/; 44706b9709d9STom Rini } 4471dd88ab32SMasahiro Yamada } 4472dd88ab32SMasahiro Yamada 44737551eb4fSHeinrich Schuchardt# check unnecessary parentheses around addressof/dereference single $Lvals 44747551eb4fSHeinrich Schuchardt# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 44757551eb4fSHeinrich Schuchardt 44767551eb4fSHeinrich Schuchardt while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 44777551eb4fSHeinrich Schuchardt my $var = $1; 44787551eb4fSHeinrich Schuchardt if (CHK("UNNECESSARY_PARENTHESES", 44797551eb4fSHeinrich Schuchardt "Unnecessary parentheses around $var\n" . $herecurr) && 44807551eb4fSHeinrich Schuchardt $fix) { 44817551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 44827551eb4fSHeinrich Schuchardt } 44837551eb4fSHeinrich Schuchardt } 44847551eb4fSHeinrich Schuchardt 44857551eb4fSHeinrich Schuchardt# check for unnecessary parentheses around function pointer uses 44867551eb4fSHeinrich Schuchardt# ie: (foo->bar)(); should be foo->bar(); 44877551eb4fSHeinrich Schuchardt# but not "if (foo->bar) (" to avoid some false positives 44887551eb4fSHeinrich Schuchardt if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 44897551eb4fSHeinrich Schuchardt my $var = $2; 44907551eb4fSHeinrich Schuchardt if (CHK("UNNECESSARY_PARENTHESES", 44917551eb4fSHeinrich Schuchardt "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 44927551eb4fSHeinrich Schuchardt $fix) { 44937551eb4fSHeinrich Schuchardt my $var2 = deparenthesize($var); 44947551eb4fSHeinrich Schuchardt $var2 =~ s/\s//g; 44957551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 44967551eb4fSHeinrich Schuchardt } 44977551eb4fSHeinrich Schuchardt } 44987551eb4fSHeinrich Schuchardt 4499dd88ab32SMasahiro Yamada#goto labels aren't indented, allow a single space however 4500dd88ab32SMasahiro Yamada if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 4501dd88ab32SMasahiro Yamada !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 45026b9709d9STom Rini if (WARN("INDENTED_LABEL", 45036b9709d9STom Rini "labels should not be indented\n" . $herecurr) && 45046b9709d9STom Rini $fix) { 45057551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 45066b9709d9STom Rini s/^(.)\s+/$1/; 45076b9709d9STom Rini } 4508dd88ab32SMasahiro Yamada } 4509dd88ab32SMasahiro Yamada 45107551eb4fSHeinrich Schuchardt# return is not a function 45116b9709d9STom Rini if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4512dd88ab32SMasahiro Yamada my $spacing = $1; 45136b9709d9STom Rini if ($^V && $^V ge 5.10.0 && 45147551eb4fSHeinrich Schuchardt $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 45157551eb4fSHeinrich Schuchardt my $value = $1; 45167551eb4fSHeinrich Schuchardt $value = deparenthesize($value); 45177551eb4fSHeinrich Schuchardt if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4518dd88ab32SMasahiro Yamada ERROR("RETURN_PARENTHESES", 4519dd88ab32SMasahiro Yamada "return is not a function, parentheses are not required\n" . $herecurr); 45207551eb4fSHeinrich Schuchardt } 4521dd88ab32SMasahiro Yamada } elsif ($spacing !~ /\s+/) { 4522dd88ab32SMasahiro Yamada ERROR("SPACING", 4523dd88ab32SMasahiro Yamada "space required before the open parenthesis '('\n" . $herecurr); 4524dd88ab32SMasahiro Yamada } 4525dd88ab32SMasahiro Yamada } 45266b9709d9STom Rini 45277551eb4fSHeinrich Schuchardt# unnecessary return in a void function 45287551eb4fSHeinrich Schuchardt# at end-of-function, with the previous line a single leading tab, then return; 45297551eb4fSHeinrich Schuchardt# and the line before that not a goto label target like "out:" 45307551eb4fSHeinrich Schuchardt if ($sline =~ /^[ \+]}\s*$/ && 45317551eb4fSHeinrich Schuchardt $prevline =~ /^\+\treturn\s*;\s*$/ && 45327551eb4fSHeinrich Schuchardt $linenr >= 3 && 45337551eb4fSHeinrich Schuchardt $lines[$linenr - 3] =~ /^[ +]/ && 45347551eb4fSHeinrich Schuchardt $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 45357551eb4fSHeinrich Schuchardt WARN("RETURN_VOID", 45367551eb4fSHeinrich Schuchardt "void function return statements are not generally useful\n" . $hereprev); 45377551eb4fSHeinrich Schuchardt } 45387551eb4fSHeinrich Schuchardt 45396b9709d9STom Rini# if statements using unnecessary parentheses - ie: if ((foo == bar)) 45406b9709d9STom Rini if ($^V && $^V ge 5.10.0 && 45416b9709d9STom Rini $line =~ /\bif\s*((?:\(\s*){2,})/) { 45426b9709d9STom Rini my $openparens = $1; 45436b9709d9STom Rini my $count = $openparens =~ tr@\(@\(@; 45446b9709d9STom Rini my $msg = ""; 45456b9709d9STom Rini if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 45466b9709d9STom Rini my $comp = $4; #Not $1 because of $LvalOrFunc 45476b9709d9STom Rini $msg = " - maybe == should be = ?" if ($comp eq "=="); 45486b9709d9STom Rini WARN("UNNECESSARY_PARENTHESES", 45496b9709d9STom Rini "Unnecessary parentheses$msg\n" . $herecurr); 45506b9709d9STom Rini } 45516b9709d9STom Rini } 45526b9709d9STom Rini 45537551eb4fSHeinrich Schuchardt# comparisons with a constant or upper case identifier on the left 45547551eb4fSHeinrich Schuchardt# avoid cases like "foo + BAR < baz" 45557551eb4fSHeinrich Schuchardt# only fix matches surrounded by parentheses to avoid incorrect 45567551eb4fSHeinrich Schuchardt# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 45577551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 45587551eb4fSHeinrich Schuchardt $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 45597551eb4fSHeinrich Schuchardt my $lead = $1; 45607551eb4fSHeinrich Schuchardt my $const = $2; 45617551eb4fSHeinrich Schuchardt my $comp = $3; 45627551eb4fSHeinrich Schuchardt my $to = $4; 45637551eb4fSHeinrich Schuchardt my $newcomp = $comp; 45647551eb4fSHeinrich Schuchardt if ($lead !~ /(?:$Operators|\.)\s*$/ && 45657551eb4fSHeinrich Schuchardt $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 45667551eb4fSHeinrich Schuchardt WARN("CONSTANT_COMPARISON", 45677551eb4fSHeinrich Schuchardt "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 45687551eb4fSHeinrich Schuchardt $fix) { 45697551eb4fSHeinrich Schuchardt if ($comp eq "<") { 45707551eb4fSHeinrich Schuchardt $newcomp = ">"; 45717551eb4fSHeinrich Schuchardt } elsif ($comp eq "<=") { 45727551eb4fSHeinrich Schuchardt $newcomp = ">="; 45737551eb4fSHeinrich Schuchardt } elsif ($comp eq ">") { 45747551eb4fSHeinrich Schuchardt $newcomp = "<"; 45757551eb4fSHeinrich Schuchardt } elsif ($comp eq ">=") { 45767551eb4fSHeinrich Schuchardt $newcomp = "<="; 45777551eb4fSHeinrich Schuchardt } 45787551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 45797551eb4fSHeinrich Schuchardt } 45807551eb4fSHeinrich Schuchardt } 45817551eb4fSHeinrich Schuchardt 45827551eb4fSHeinrich Schuchardt# Return of what appears to be an errno should normally be negative 45837551eb4fSHeinrich Schuchardt if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 4584dd88ab32SMasahiro Yamada my $name = $1; 4585dd88ab32SMasahiro Yamada if ($name ne 'EOF' && $name ne 'ERROR') { 4586dd88ab32SMasahiro Yamada WARN("USE_NEGATIVE_ERRNO", 45877551eb4fSHeinrich Schuchardt "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 4588dd88ab32SMasahiro Yamada } 4589dd88ab32SMasahiro Yamada } 4590dd88ab32SMasahiro Yamada 4591dd88ab32SMasahiro Yamada# Need a space before open parenthesis after if, while etc 4592dd88ab32SMasahiro Yamada if ($line =~ /\b(if|while|for|switch)\(/) { 45936b9709d9STom Rini if (ERROR("SPACING", 45946b9709d9STom Rini "space required before the open parenthesis '('\n" . $herecurr) && 45956b9709d9STom Rini $fix) { 45967551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 45976b9709d9STom Rini s/\b(if|while|for|switch)\(/$1 \(/; 45986b9709d9STom Rini } 4599dd88ab32SMasahiro Yamada } 4600dd88ab32SMasahiro Yamada 4601dd88ab32SMasahiro Yamada# Check for illegal assignment in if conditional -- and check for trailing 4602dd88ab32SMasahiro Yamada# statements after the conditional. 4603dd88ab32SMasahiro Yamada if ($line =~ /do\s*(?!{)/) { 4604dd88ab32SMasahiro Yamada ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 4605dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $realcnt, 0) 4606dd88ab32SMasahiro Yamada if (!defined $stat); 4607dd88ab32SMasahiro Yamada my ($stat_next) = ctx_statement_block($line_nr_next, 4608dd88ab32SMasahiro Yamada $remain_next, $off_next); 4609dd88ab32SMasahiro Yamada $stat_next =~ s/\n./\n /g; 4610dd88ab32SMasahiro Yamada ##print "stat<$stat> stat_next<$stat_next>\n"; 4611dd88ab32SMasahiro Yamada 4612dd88ab32SMasahiro Yamada if ($stat_next =~ /^\s*while\b/) { 4613dd88ab32SMasahiro Yamada # If the statement carries leading newlines, 4614dd88ab32SMasahiro Yamada # then count those as offsets. 4615dd88ab32SMasahiro Yamada my ($whitespace) = 4616dd88ab32SMasahiro Yamada ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4617dd88ab32SMasahiro Yamada my $offset = 4618dd88ab32SMasahiro Yamada statement_rawlines($whitespace) - 1; 4619dd88ab32SMasahiro Yamada 4620dd88ab32SMasahiro Yamada $suppress_whiletrailers{$line_nr_next + 4621dd88ab32SMasahiro Yamada $offset} = 1; 4622dd88ab32SMasahiro Yamada } 4623dd88ab32SMasahiro Yamada } 4624dd88ab32SMasahiro Yamada if (!defined $suppress_whiletrailers{$linenr} && 46256b9709d9STom Rini defined($stat) && defined($cond) && 4626dd88ab32SMasahiro Yamada $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4627dd88ab32SMasahiro Yamada my ($s, $c) = ($stat, $cond); 4628dd88ab32SMasahiro Yamada 4629dd88ab32SMasahiro Yamada if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4630dd88ab32SMasahiro Yamada ERROR("ASSIGN_IN_IF", 4631dd88ab32SMasahiro Yamada "do not use assignment in if condition\n" . $herecurr); 4632dd88ab32SMasahiro Yamada } 4633dd88ab32SMasahiro Yamada 4634dd88ab32SMasahiro Yamada # Find out what is on the end of the line after the 4635dd88ab32SMasahiro Yamada # conditional. 4636dd88ab32SMasahiro Yamada substr($s, 0, length($c), ''); 4637dd88ab32SMasahiro Yamada $s =~ s/\n.*//g; 4638dd88ab32SMasahiro Yamada $s =~ s/$;//g; # Remove any comments 4639dd88ab32SMasahiro Yamada if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 4640dd88ab32SMasahiro Yamada $c !~ /}\s*while\s*/) 4641dd88ab32SMasahiro Yamada { 4642dd88ab32SMasahiro Yamada # Find out how long the conditional actually is. 4643dd88ab32SMasahiro Yamada my @newlines = ($c =~ /\n/gs); 4644dd88ab32SMasahiro Yamada my $cond_lines = 1 + $#newlines; 4645dd88ab32SMasahiro Yamada my $stat_real = ''; 4646dd88ab32SMasahiro Yamada 4647dd88ab32SMasahiro Yamada $stat_real = raw_line($linenr, $cond_lines) 4648dd88ab32SMasahiro Yamada . "\n" if ($cond_lines); 4649dd88ab32SMasahiro Yamada if (defined($stat_real) && $cond_lines > 1) { 4650dd88ab32SMasahiro Yamada $stat_real = "[...]\n$stat_real"; 4651dd88ab32SMasahiro Yamada } 4652dd88ab32SMasahiro Yamada 4653dd88ab32SMasahiro Yamada ERROR("TRAILING_STATEMENTS", 4654dd88ab32SMasahiro Yamada "trailing statements should be on next line\n" . $herecurr . $stat_real); 4655dd88ab32SMasahiro Yamada } 4656dd88ab32SMasahiro Yamada } 4657dd88ab32SMasahiro Yamada 4658dd88ab32SMasahiro Yamada# Check for bitwise tests written as boolean 4659dd88ab32SMasahiro Yamada if ($line =~ / 4660dd88ab32SMasahiro Yamada (?: 4661dd88ab32SMasahiro Yamada (?:\[|\(|\&\&|\|\|) 4662dd88ab32SMasahiro Yamada \s*0[xX][0-9]+\s* 4663dd88ab32SMasahiro Yamada (?:\&\&|\|\|) 4664dd88ab32SMasahiro Yamada | 4665dd88ab32SMasahiro Yamada (?:\&\&|\|\|) 4666dd88ab32SMasahiro Yamada \s*0[xX][0-9]+\s* 4667dd88ab32SMasahiro Yamada (?:\&\&|\|\||\)|\]) 4668dd88ab32SMasahiro Yamada )/x) 4669dd88ab32SMasahiro Yamada { 4670dd88ab32SMasahiro Yamada WARN("HEXADECIMAL_BOOLEAN_TEST", 4671dd88ab32SMasahiro Yamada "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 4672dd88ab32SMasahiro Yamada } 4673dd88ab32SMasahiro Yamada 4674dd88ab32SMasahiro Yamada# if and else should not have general statements after it 4675dd88ab32SMasahiro Yamada if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 4676dd88ab32SMasahiro Yamada my $s = $1; 4677dd88ab32SMasahiro Yamada $s =~ s/$;//g; # Remove any comments 4678dd88ab32SMasahiro Yamada if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4679dd88ab32SMasahiro Yamada ERROR("TRAILING_STATEMENTS", 4680dd88ab32SMasahiro Yamada "trailing statements should be on next line\n" . $herecurr); 4681dd88ab32SMasahiro Yamada } 4682dd88ab32SMasahiro Yamada } 4683dd88ab32SMasahiro Yamada# if should not continue a brace 4684dd88ab32SMasahiro Yamada if ($line =~ /}\s*if\b/) { 4685dd88ab32SMasahiro Yamada ERROR("TRAILING_STATEMENTS", 46867551eb4fSHeinrich Schuchardt "trailing statements should be on next line (or did you mean 'else if'?)\n" . 4687dd88ab32SMasahiro Yamada $herecurr); 4688dd88ab32SMasahiro Yamada } 4689dd88ab32SMasahiro Yamada# case and default should not have general statements after them 4690dd88ab32SMasahiro Yamada if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4691dd88ab32SMasahiro Yamada $line !~ /\G(?: 4692dd88ab32SMasahiro Yamada (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4693dd88ab32SMasahiro Yamada \s*return\s+ 4694dd88ab32SMasahiro Yamada )/xg) 4695dd88ab32SMasahiro Yamada { 4696dd88ab32SMasahiro Yamada ERROR("TRAILING_STATEMENTS", 4697dd88ab32SMasahiro Yamada "trailing statements should be on next line\n" . $herecurr); 4698dd88ab32SMasahiro Yamada } 4699dd88ab32SMasahiro Yamada 4700dd88ab32SMasahiro Yamada # Check for }<nl>else {, these must be at the same 4701dd88ab32SMasahiro Yamada # indent level to be relevant to each other. 47027551eb4fSHeinrich Schuchardt if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 4703dd88ab32SMasahiro Yamada $previndent == $indent) { 47047551eb4fSHeinrich Schuchardt if (ERROR("ELSE_AFTER_BRACE", 47057551eb4fSHeinrich Schuchardt "else should follow close brace '}'\n" . $hereprev) && 47067551eb4fSHeinrich Schuchardt $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47077551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 47087551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 47097551eb4fSHeinrich Schuchardt my $fixedline = $prevrawline; 47107551eb4fSHeinrich Schuchardt $fixedline =~ s/}\s*$//; 47117551eb4fSHeinrich Schuchardt if ($fixedline !~ /^\+\s*$/) { 47127551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 47137551eb4fSHeinrich Schuchardt } 47147551eb4fSHeinrich Schuchardt $fixedline = $rawline; 47157551eb4fSHeinrich Schuchardt $fixedline =~ s/^(.\s*)else/$1} else/; 47167551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 47177551eb4fSHeinrich Schuchardt } 4718dd88ab32SMasahiro Yamada } 4719dd88ab32SMasahiro Yamada 47207551eb4fSHeinrich Schuchardt if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4721dd88ab32SMasahiro Yamada $previndent == $indent) { 4722dd88ab32SMasahiro Yamada my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4723dd88ab32SMasahiro Yamada 4724dd88ab32SMasahiro Yamada # Find out what is on the end of the line after the 4725dd88ab32SMasahiro Yamada # conditional. 4726dd88ab32SMasahiro Yamada substr($s, 0, length($c), ''); 4727dd88ab32SMasahiro Yamada $s =~ s/\n.*//g; 4728dd88ab32SMasahiro Yamada 4729dd88ab32SMasahiro Yamada if ($s =~ /^\s*;/) { 47307551eb4fSHeinrich Schuchardt if (ERROR("WHILE_AFTER_BRACE", 47317551eb4fSHeinrich Schuchardt "while should follow close brace '}'\n" . $hereprev) && 47327551eb4fSHeinrich Schuchardt $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47337551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 47347551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 47357551eb4fSHeinrich Schuchardt my $fixedline = $prevrawline; 47367551eb4fSHeinrich Schuchardt my $trailing = $rawline; 47377551eb4fSHeinrich Schuchardt $trailing =~ s/^\+//; 47387551eb4fSHeinrich Schuchardt $trailing = trim($trailing); 47397551eb4fSHeinrich Schuchardt $fixedline =~ s/}\s*$/} $trailing/; 47407551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 47417551eb4fSHeinrich Schuchardt } 4742dd88ab32SMasahiro Yamada } 4743dd88ab32SMasahiro Yamada } 4744dd88ab32SMasahiro Yamada 47456b9709d9STom Rini#Specific variable tests 4746dd88ab32SMasahiro Yamada while ($line =~ m{($Constant|$Lval)}g) { 4747dd88ab32SMasahiro Yamada my $var = $1; 47486b9709d9STom Rini 47496b9709d9STom Rini#gcc binary extension 47506b9709d9STom Rini if ($var =~ /^$Binary$/) { 47516b9709d9STom Rini if (WARN("GCC_BINARY_CONSTANT", 47526b9709d9STom Rini "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 47536b9709d9STom Rini $fix) { 47546b9709d9STom Rini my $hexval = sprintf("0x%x", oct($var)); 47557551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 47566b9709d9STom Rini s/\b$var\b/$hexval/; 47576b9709d9STom Rini } 47586b9709d9STom Rini } 47596b9709d9STom Rini 47606b9709d9STom Rini#CamelCase 47616b9709d9STom Rini if ($var !~ /^$Constant$/ && 47626b9709d9STom Rini $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 47636b9709d9STom Rini#Ignore Page<foo> variants 47646b9709d9STom Rini $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 47656b9709d9STom Rini#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 47667551eb4fSHeinrich Schuchardt $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 47677551eb4fSHeinrich Schuchardt#Ignore some three character SI units explicitly, like MiB and KHz 47687551eb4fSHeinrich Schuchardt $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47696b9709d9STom Rini while ($var =~ m{($Ident)}g) { 47706b9709d9STom Rini my $word = $1; 47716b9709d9STom Rini next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 47726b9709d9STom Rini if ($check) { 47736b9709d9STom Rini seed_camelcase_includes(); 47746b9709d9STom Rini if (!$file && !$camelcase_file_seeded) { 47756b9709d9STom Rini seed_camelcase_file($realfile); 47766b9709d9STom Rini $camelcase_file_seeded = 1; 47776b9709d9STom Rini } 47786b9709d9STom Rini } 47796b9709d9STom Rini if (!defined $camelcase{$word}) { 47806b9709d9STom Rini $camelcase{$word} = 1; 47816b9709d9STom Rini CHK("CAMELCASE", 47826b9709d9STom Rini "Avoid CamelCase: <$word>\n" . $herecurr); 47836b9709d9STom Rini } 47846b9709d9STom Rini } 4785dd88ab32SMasahiro Yamada } 4786dd88ab32SMasahiro Yamada } 4787dd88ab32SMasahiro Yamada 4788dd88ab32SMasahiro Yamada#no spaces allowed after \ in define 47896b9709d9STom Rini if ($line =~ /\#\s*define.*\\\s+$/) { 47906b9709d9STom Rini if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 47916b9709d9STom Rini "Whitespace after \\ makes next lines useless\n" . $herecurr) && 47926b9709d9STom Rini $fix) { 47937551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\s+$//; 47946b9709d9STom Rini } 4795dd88ab32SMasahiro Yamada } 4796dd88ab32SMasahiro Yamada 47977551eb4fSHeinrich Schuchardt# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47987551eb4fSHeinrich Schuchardt# itself <asm/foo.h> (uses RAW line) 4799dd88ab32SMasahiro Yamada if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4800dd88ab32SMasahiro Yamada my $file = "$1.h"; 4801dd88ab32SMasahiro Yamada my $checkfile = "include/linux/$file"; 4802dd88ab32SMasahiro Yamada if (-f "$root/$checkfile" && 4803dd88ab32SMasahiro Yamada $realfile ne $checkfile && 4804dd88ab32SMasahiro Yamada $1 !~ /$allowed_asm_includes/) 4805dd88ab32SMasahiro Yamada { 48067551eb4fSHeinrich Schuchardt my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 48077551eb4fSHeinrich Schuchardt if ($asminclude > 0) { 4808dd88ab32SMasahiro Yamada if ($realfile =~ m{^arch/}) { 4809dd88ab32SMasahiro Yamada CHK("ARCH_INCLUDE_LINUX", 4810dd88ab32SMasahiro Yamada "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4811dd88ab32SMasahiro Yamada } else { 4812dd88ab32SMasahiro Yamada WARN("INCLUDE_LINUX", 4813dd88ab32SMasahiro Yamada "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4814dd88ab32SMasahiro Yamada } 4815dd88ab32SMasahiro Yamada } 4816dd88ab32SMasahiro Yamada } 48177551eb4fSHeinrich Schuchardt } 4818dd88ab32SMasahiro Yamada 4819dd88ab32SMasahiro Yamada# multi-statement macros should be enclosed in a do while loop, grab the 4820dd88ab32SMasahiro Yamada# first statement and ensure its the whole macro if its not enclosed 4821dd88ab32SMasahiro Yamada# in a known good container 4822dd88ab32SMasahiro Yamada if ($realfile !~ m@/vmlinux.lds.h$@ && 4823dd88ab32SMasahiro Yamada $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4824dd88ab32SMasahiro Yamada my $ln = $linenr; 4825dd88ab32SMasahiro Yamada my $cnt = $realcnt; 4826dd88ab32SMasahiro Yamada my ($off, $dstat, $dcond, $rest); 4827dd88ab32SMasahiro Yamada my $ctx = ''; 48287551eb4fSHeinrich Schuchardt my $has_flow_statement = 0; 48297551eb4fSHeinrich Schuchardt my $has_arg_concat = 0; 4830dd88ab32SMasahiro Yamada ($dstat, $dcond, $ln, $cnt, $off) = 4831dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $realcnt, 0); 4832dd88ab32SMasahiro Yamada $ctx = $dstat; 4833dd88ab32SMasahiro Yamada #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4834dd88ab32SMasahiro Yamada #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4835dd88ab32SMasahiro Yamada 48367551eb4fSHeinrich Schuchardt $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 48377551eb4fSHeinrich Schuchardt $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 48387551eb4fSHeinrich Schuchardt 48397551eb4fSHeinrich Schuchardt $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 48407551eb4fSHeinrich Schuchardt my $define_args = $1; 48417551eb4fSHeinrich Schuchardt my $define_stmt = $dstat; 48427551eb4fSHeinrich Schuchardt my @def_args = (); 48437551eb4fSHeinrich Schuchardt 48447551eb4fSHeinrich Schuchardt if (defined $define_args && $define_args ne "") { 48457551eb4fSHeinrich Schuchardt $define_args = substr($define_args, 1, length($define_args) - 2); 48467551eb4fSHeinrich Schuchardt $define_args =~ s/\s*//g; 48477551eb4fSHeinrich Schuchardt @def_args = split(",", $define_args); 48487551eb4fSHeinrich Schuchardt } 48497551eb4fSHeinrich Schuchardt 4850dd88ab32SMasahiro Yamada $dstat =~ s/$;//g; 4851dd88ab32SMasahiro Yamada $dstat =~ s/\\\n.//g; 4852dd88ab32SMasahiro Yamada $dstat =~ s/^\s*//s; 4853dd88ab32SMasahiro Yamada $dstat =~ s/\s*$//s; 4854dd88ab32SMasahiro Yamada 4855dd88ab32SMasahiro Yamada # Flatten any parentheses and braces 4856dd88ab32SMasahiro Yamada while ($dstat =~ s/\([^\(\)]*\)/1/ || 4857dd88ab32SMasahiro Yamada $dstat =~ s/\{[^\{\}]*\}/1/ || 48587551eb4fSHeinrich Schuchardt $dstat =~ s/.\[[^\[\]]*\]/1/) 4859dd88ab32SMasahiro Yamada { 4860dd88ab32SMasahiro Yamada } 4861dd88ab32SMasahiro Yamada 4862dd88ab32SMasahiro Yamada # Flatten any obvious string concatentation. 48637551eb4fSHeinrich Schuchardt while ($dstat =~ s/($String)\s*$Ident/$1/ || 48647551eb4fSHeinrich Schuchardt $dstat =~ s/$Ident\s*($String)/$1/) 4865dd88ab32SMasahiro Yamada { 4866dd88ab32SMasahiro Yamada } 4867dd88ab32SMasahiro Yamada 48687551eb4fSHeinrich Schuchardt # Make asm volatile uses seem like a generic function 48697551eb4fSHeinrich Schuchardt $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 48707551eb4fSHeinrich Schuchardt 4871dd88ab32SMasahiro Yamada my $exceptions = qr{ 4872dd88ab32SMasahiro Yamada $Declare| 4873dd88ab32SMasahiro Yamada module_param_named| 4874dd88ab32SMasahiro Yamada MODULE_PARM_DESC| 4875dd88ab32SMasahiro Yamada DECLARE_PER_CPU| 4876dd88ab32SMasahiro Yamada DEFINE_PER_CPU| 4877dd88ab32SMasahiro Yamada __typeof__\(| 4878dd88ab32SMasahiro Yamada union| 4879dd88ab32SMasahiro Yamada struct| 4880dd88ab32SMasahiro Yamada \.$Ident\s*=\s*| 48817551eb4fSHeinrich Schuchardt ^\"|\"$| 48827551eb4fSHeinrich Schuchardt ^\[ 4883dd88ab32SMasahiro Yamada }x; 4884dd88ab32SMasahiro Yamada #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 48857551eb4fSHeinrich Schuchardt 48867551eb4fSHeinrich Schuchardt $ctx =~ s/\n*$//; 48877551eb4fSHeinrich Schuchardt my $herectx = $here . "\n"; 48887551eb4fSHeinrich Schuchardt my $stmt_cnt = statement_rawlines($ctx); 48897551eb4fSHeinrich Schuchardt 48907551eb4fSHeinrich Schuchardt for (my $n = 0; $n < $stmt_cnt; $n++) { 48917551eb4fSHeinrich Schuchardt $herectx .= raw_line($linenr, $n) . "\n"; 48927551eb4fSHeinrich Schuchardt } 48937551eb4fSHeinrich Schuchardt 4894dd88ab32SMasahiro Yamada if ($dstat ne '' && 4895dd88ab32SMasahiro Yamada $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4896dd88ab32SMasahiro Yamada $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48976b9709d9STom Rini $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 48987551eb4fSHeinrich Schuchardt $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4899dd88ab32SMasahiro Yamada $dstat !~ /$exceptions/ && 4900dd88ab32SMasahiro Yamada $dstat !~ /^\.$Ident\s*=/ && # .foo = 49016b9709d9STom Rini $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 4902dd88ab32SMasahiro Yamada $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4903dd88ab32SMasahiro Yamada $dstat !~ /^for\s*$Constant$/ && # for (...) 4904dd88ab32SMasahiro Yamada $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4905dd88ab32SMasahiro Yamada $dstat !~ /^do\s*{/ && # do {... 4906d8a1a304SHeiko Schocher $dstat !~ /^\(\{/ && # ({... 49076b9709d9STom Rini $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4908dd88ab32SMasahiro Yamada { 49097551eb4fSHeinrich Schuchardt if ($dstat =~ /^\s*if\b/) { 49107551eb4fSHeinrich Schuchardt ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 49117551eb4fSHeinrich Schuchardt "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 49127551eb4fSHeinrich Schuchardt } elsif ($dstat =~ /;/) { 49137551eb4fSHeinrich Schuchardt ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 49147551eb4fSHeinrich Schuchardt "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 49157551eb4fSHeinrich Schuchardt } else { 49167551eb4fSHeinrich Schuchardt ERROR("COMPLEX_MACRO", 49177551eb4fSHeinrich Schuchardt "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 49187551eb4fSHeinrich Schuchardt } 49197551eb4fSHeinrich Schuchardt 49207551eb4fSHeinrich Schuchardt } 49217551eb4fSHeinrich Schuchardt 49227551eb4fSHeinrich Schuchardt # Make $define_stmt single line, comment-free, etc 49237551eb4fSHeinrich Schuchardt my @stmt_array = split('\n', $define_stmt); 49247551eb4fSHeinrich Schuchardt my $first = 1; 49257551eb4fSHeinrich Schuchardt $define_stmt = ""; 49267551eb4fSHeinrich Schuchardt foreach my $l (@stmt_array) { 49277551eb4fSHeinrich Schuchardt $l =~ s/\\$//; 49287551eb4fSHeinrich Schuchardt if ($first) { 49297551eb4fSHeinrich Schuchardt $define_stmt = $l; 49307551eb4fSHeinrich Schuchardt $first = 0; 49317551eb4fSHeinrich Schuchardt } elsif ($l =~ /^[\+ ]/) { 49327551eb4fSHeinrich Schuchardt $define_stmt .= substr($l, 1); 49337551eb4fSHeinrich Schuchardt } 49347551eb4fSHeinrich Schuchardt } 49357551eb4fSHeinrich Schuchardt $define_stmt =~ s/$;//g; 49367551eb4fSHeinrich Schuchardt $define_stmt =~ s/\s+/ /g; 49377551eb4fSHeinrich Schuchardt $define_stmt = trim($define_stmt); 49387551eb4fSHeinrich Schuchardt 49397551eb4fSHeinrich Schuchardt# check if any macro arguments are reused (ignore '...' and 'type') 49407551eb4fSHeinrich Schuchardt foreach my $arg (@def_args) { 49417551eb4fSHeinrich Schuchardt next if ($arg =~ /\.\.\./); 49427551eb4fSHeinrich Schuchardt next if ($arg =~ /^type$/i); 49437551eb4fSHeinrich Schuchardt my $tmp_stmt = $define_stmt; 49447551eb4fSHeinrich Schuchardt $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49457551eb4fSHeinrich Schuchardt $tmp_stmt =~ s/\#+\s*$arg\b//g; 49467551eb4fSHeinrich Schuchardt $tmp_stmt =~ s/\b$arg\s*\#\#//g; 49477551eb4fSHeinrich Schuchardt my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; 49487551eb4fSHeinrich Schuchardt if ($use_cnt > 1) { 49497551eb4fSHeinrich Schuchardt CHK("MACRO_ARG_REUSE", 49507551eb4fSHeinrich Schuchardt "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 49517551eb4fSHeinrich Schuchardt } 49527551eb4fSHeinrich Schuchardt# check if any macro arguments may have other precedence issues 49537551eb4fSHeinrich Schuchardt if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49547551eb4fSHeinrich Schuchardt ((defined($1) && $1 ne ',') || 49557551eb4fSHeinrich Schuchardt (defined($2) && $2 ne ','))) { 49567551eb4fSHeinrich Schuchardt CHK("MACRO_ARG_PRECEDENCE", 49577551eb4fSHeinrich Schuchardt "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49587551eb4fSHeinrich Schuchardt } 49597551eb4fSHeinrich Schuchardt } 49607551eb4fSHeinrich Schuchardt 49617551eb4fSHeinrich Schuchardt# check for macros with flow control, but without ## concatenation 49627551eb4fSHeinrich Schuchardt# ## concatenation is commonly a macro that defines a function so ignore those 49637551eb4fSHeinrich Schuchardt if ($has_flow_statement && !$has_arg_concat) { 4964dd88ab32SMasahiro Yamada my $herectx = $here . "\n"; 4965dd88ab32SMasahiro Yamada my $cnt = statement_rawlines($ctx); 4966dd88ab32SMasahiro Yamada 4967dd88ab32SMasahiro Yamada for (my $n = 0; $n < $cnt; $n++) { 4968dd88ab32SMasahiro Yamada $herectx .= raw_line($linenr, $n) . "\n"; 4969dd88ab32SMasahiro Yamada } 49707551eb4fSHeinrich Schuchardt WARN("MACRO_WITH_FLOW_CONTROL", 49717551eb4fSHeinrich Schuchardt "Macros with flow control statements should be avoided\n" . "$herectx"); 4972dd88ab32SMasahiro Yamada } 4973dd88ab32SMasahiro Yamada 4974dd88ab32SMasahiro Yamada# check for line continuations outside of #defines, preprocessor #, and asm 4975dd88ab32SMasahiro Yamada 4976dd88ab32SMasahiro Yamada } else { 4977dd88ab32SMasahiro Yamada if ($prevline !~ /^..*\\$/ && 4978dd88ab32SMasahiro Yamada $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4979dd88ab32SMasahiro Yamada $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 4980dd88ab32SMasahiro Yamada $line =~ /^\+.*\\$/) { 4981dd88ab32SMasahiro Yamada WARN("LINE_CONTINUATIONS", 4982dd88ab32SMasahiro Yamada "Avoid unnecessary line continuations\n" . $herecurr); 4983dd88ab32SMasahiro Yamada } 4984dd88ab32SMasahiro Yamada } 4985dd88ab32SMasahiro Yamada 4986dd88ab32SMasahiro Yamada# do {} while (0) macro tests: 4987dd88ab32SMasahiro Yamada# single-statement macros do not need to be enclosed in do while (0) loop, 4988dd88ab32SMasahiro Yamada# macro should not end with a semicolon 4989dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 4990dd88ab32SMasahiro Yamada $realfile !~ m@/vmlinux.lds.h$@ && 4991dd88ab32SMasahiro Yamada $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4992dd88ab32SMasahiro Yamada my $ln = $linenr; 4993dd88ab32SMasahiro Yamada my $cnt = $realcnt; 4994dd88ab32SMasahiro Yamada my ($off, $dstat, $dcond, $rest); 4995dd88ab32SMasahiro Yamada my $ctx = ''; 4996dd88ab32SMasahiro Yamada ($dstat, $dcond, $ln, $cnt, $off) = 4997dd88ab32SMasahiro Yamada ctx_statement_block($linenr, $realcnt, 0); 4998dd88ab32SMasahiro Yamada $ctx = $dstat; 4999dd88ab32SMasahiro Yamada 5000dd88ab32SMasahiro Yamada $dstat =~ s/\\\n.//g; 50017551eb4fSHeinrich Schuchardt $dstat =~ s/$;/ /g; 5002dd88ab32SMasahiro Yamada 5003dd88ab32SMasahiro Yamada if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5004dd88ab32SMasahiro Yamada my $stmts = $2; 5005dd88ab32SMasahiro Yamada my $semis = $3; 5006dd88ab32SMasahiro Yamada 5007dd88ab32SMasahiro Yamada $ctx =~ s/\n*$//; 5008dd88ab32SMasahiro Yamada my $cnt = statement_rawlines($ctx); 5009dd88ab32SMasahiro Yamada my $herectx = $here . "\n"; 5010dd88ab32SMasahiro Yamada 5011dd88ab32SMasahiro Yamada for (my $n = 0; $n < $cnt; $n++) { 5012dd88ab32SMasahiro Yamada $herectx .= raw_line($linenr, $n) . "\n"; 5013dd88ab32SMasahiro Yamada } 5014dd88ab32SMasahiro Yamada 5015dd88ab32SMasahiro Yamada if (($stmts =~ tr/;/;/) == 1 && 5016dd88ab32SMasahiro Yamada $stmts !~ /^\s*(if|while|for|switch)\b/) { 5017dd88ab32SMasahiro Yamada WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5018dd88ab32SMasahiro Yamada "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5019dd88ab32SMasahiro Yamada } 5020dd88ab32SMasahiro Yamada if (defined $semis && $semis ne "") { 5021dd88ab32SMasahiro Yamada WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5022dd88ab32SMasahiro Yamada "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5023dd88ab32SMasahiro Yamada } 50247551eb4fSHeinrich Schuchardt } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 50257551eb4fSHeinrich Schuchardt $ctx =~ s/\n*$//; 50267551eb4fSHeinrich Schuchardt my $cnt = statement_rawlines($ctx); 50277551eb4fSHeinrich Schuchardt my $herectx = $here . "\n"; 50287551eb4fSHeinrich Schuchardt 50297551eb4fSHeinrich Schuchardt for (my $n = 0; $n < $cnt; $n++) { 50307551eb4fSHeinrich Schuchardt $herectx .= raw_line($linenr, $n) . "\n"; 50317551eb4fSHeinrich Schuchardt } 50327551eb4fSHeinrich Schuchardt 50337551eb4fSHeinrich Schuchardt WARN("TRAILING_SEMICOLON", 50347551eb4fSHeinrich Schuchardt "macros should not use a trailing semicolon\n" . "$herectx"); 5035dd88ab32SMasahiro Yamada } 5036dd88ab32SMasahiro Yamada } 5037dd88ab32SMasahiro Yamada 5038dd88ab32SMasahiro Yamada# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5039dd88ab32SMasahiro Yamada# all assignments may have only one of the following with an assignment: 5040dd88ab32SMasahiro Yamada# . 5041dd88ab32SMasahiro Yamada# ALIGN(...) 5042dd88ab32SMasahiro Yamada# VMLINUX_SYMBOL(...) 5043dd88ab32SMasahiro Yamada if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5044dd88ab32SMasahiro Yamada WARN("MISSING_VMLINUX_SYMBOL", 5045dd88ab32SMasahiro Yamada "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5046dd88ab32SMasahiro Yamada } 5047dd88ab32SMasahiro Yamada 5048dd88ab32SMasahiro Yamada# check for redundant bracing round if etc 5049dd88ab32SMasahiro Yamada if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 5050dd88ab32SMasahiro Yamada my ($level, $endln, @chunks) = 5051dd88ab32SMasahiro Yamada ctx_statement_full($linenr, $realcnt, 1); 5052dd88ab32SMasahiro Yamada #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5053dd88ab32SMasahiro Yamada #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5054dd88ab32SMasahiro Yamada if ($#chunks > 0 && $level == 0) { 5055dd88ab32SMasahiro Yamada my @allowed = (); 5056dd88ab32SMasahiro Yamada my $allow = 0; 5057dd88ab32SMasahiro Yamada my $seen = 0; 5058dd88ab32SMasahiro Yamada my $herectx = $here . "\n"; 5059dd88ab32SMasahiro Yamada my $ln = $linenr - 1; 5060dd88ab32SMasahiro Yamada for my $chunk (@chunks) { 5061dd88ab32SMasahiro Yamada my ($cond, $block) = @{$chunk}; 5062dd88ab32SMasahiro Yamada 5063dd88ab32SMasahiro Yamada # If the condition carries leading newlines, then count those as offsets. 5064dd88ab32SMasahiro Yamada my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5065dd88ab32SMasahiro Yamada my $offset = statement_rawlines($whitespace) - 1; 5066dd88ab32SMasahiro Yamada 5067dd88ab32SMasahiro Yamada $allowed[$allow] = 0; 5068dd88ab32SMasahiro Yamada #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5069dd88ab32SMasahiro Yamada 5070dd88ab32SMasahiro Yamada # We have looked at and allowed this specific line. 5071dd88ab32SMasahiro Yamada $suppress_ifbraces{$ln + $offset} = 1; 5072dd88ab32SMasahiro Yamada 5073dd88ab32SMasahiro Yamada $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5074dd88ab32SMasahiro Yamada $ln += statement_rawlines($block) - 1; 5075dd88ab32SMasahiro Yamada 5076dd88ab32SMasahiro Yamada substr($block, 0, length($cond), ''); 5077dd88ab32SMasahiro Yamada 5078dd88ab32SMasahiro Yamada $seen++ if ($block =~ /^\s*{/); 5079dd88ab32SMasahiro Yamada 5080dd88ab32SMasahiro Yamada #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5081dd88ab32SMasahiro Yamada if (statement_lines($cond) > 1) { 5082dd88ab32SMasahiro Yamada #print "APW: ALLOWED: cond<$cond>\n"; 5083dd88ab32SMasahiro Yamada $allowed[$allow] = 1; 5084dd88ab32SMasahiro Yamada } 5085dd88ab32SMasahiro Yamada if ($block =~/\b(?:if|for|while)\b/) { 5086dd88ab32SMasahiro Yamada #print "APW: ALLOWED: block<$block>\n"; 5087dd88ab32SMasahiro Yamada $allowed[$allow] = 1; 5088dd88ab32SMasahiro Yamada } 5089dd88ab32SMasahiro Yamada if (statement_block_size($block) > 1) { 5090dd88ab32SMasahiro Yamada #print "APW: ALLOWED: lines block<$block>\n"; 5091dd88ab32SMasahiro Yamada $allowed[$allow] = 1; 5092dd88ab32SMasahiro Yamada } 5093dd88ab32SMasahiro Yamada $allow++; 5094dd88ab32SMasahiro Yamada } 5095dd88ab32SMasahiro Yamada if ($seen) { 5096dd88ab32SMasahiro Yamada my $sum_allowed = 0; 5097dd88ab32SMasahiro Yamada foreach (@allowed) { 5098dd88ab32SMasahiro Yamada $sum_allowed += $_; 5099dd88ab32SMasahiro Yamada } 5100dd88ab32SMasahiro Yamada if ($sum_allowed == 0) { 5101dd88ab32SMasahiro Yamada WARN("BRACES", 5102dd88ab32SMasahiro Yamada "braces {} are not necessary for any arm of this statement\n" . $herectx); 5103dd88ab32SMasahiro Yamada } elsif ($sum_allowed != $allow && 5104dd88ab32SMasahiro Yamada $seen != $allow) { 5105dd88ab32SMasahiro Yamada CHK("BRACES", 5106dd88ab32SMasahiro Yamada "braces {} should be used on all arms of this statement\n" . $herectx); 5107dd88ab32SMasahiro Yamada } 5108dd88ab32SMasahiro Yamada } 5109dd88ab32SMasahiro Yamada } 5110dd88ab32SMasahiro Yamada } 5111dd88ab32SMasahiro Yamada if (!defined $suppress_ifbraces{$linenr - 1} && 5112dd88ab32SMasahiro Yamada $line =~ /\b(if|while|for|else)\b/) { 5113dd88ab32SMasahiro Yamada my $allowed = 0; 5114dd88ab32SMasahiro Yamada 5115dd88ab32SMasahiro Yamada # Check the pre-context. 5116dd88ab32SMasahiro Yamada if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5117dd88ab32SMasahiro Yamada #print "APW: ALLOWED: pre<$1>\n"; 5118dd88ab32SMasahiro Yamada $allowed = 1; 5119dd88ab32SMasahiro Yamada } 5120dd88ab32SMasahiro Yamada 5121dd88ab32SMasahiro Yamada my ($level, $endln, @chunks) = 5122dd88ab32SMasahiro Yamada ctx_statement_full($linenr, $realcnt, $-[0]); 5123dd88ab32SMasahiro Yamada 5124dd88ab32SMasahiro Yamada # Check the condition. 5125dd88ab32SMasahiro Yamada my ($cond, $block) = @{$chunks[0]}; 5126dd88ab32SMasahiro Yamada #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5127dd88ab32SMasahiro Yamada if (defined $cond) { 5128dd88ab32SMasahiro Yamada substr($block, 0, length($cond), ''); 5129dd88ab32SMasahiro Yamada } 5130dd88ab32SMasahiro Yamada if (statement_lines($cond) > 1) { 5131dd88ab32SMasahiro Yamada #print "APW: ALLOWED: cond<$cond>\n"; 5132dd88ab32SMasahiro Yamada $allowed = 1; 5133dd88ab32SMasahiro Yamada } 5134dd88ab32SMasahiro Yamada if ($block =~/\b(?:if|for|while)\b/) { 5135dd88ab32SMasahiro Yamada #print "APW: ALLOWED: block<$block>\n"; 5136dd88ab32SMasahiro Yamada $allowed = 1; 5137dd88ab32SMasahiro Yamada } 5138dd88ab32SMasahiro Yamada if (statement_block_size($block) > 1) { 5139dd88ab32SMasahiro Yamada #print "APW: ALLOWED: lines block<$block>\n"; 5140dd88ab32SMasahiro Yamada $allowed = 1; 5141dd88ab32SMasahiro Yamada } 5142dd88ab32SMasahiro Yamada # Check the post-context. 5143dd88ab32SMasahiro Yamada if (defined $chunks[1]) { 5144dd88ab32SMasahiro Yamada my ($cond, $block) = @{$chunks[1]}; 5145dd88ab32SMasahiro Yamada if (defined $cond) { 5146dd88ab32SMasahiro Yamada substr($block, 0, length($cond), ''); 5147dd88ab32SMasahiro Yamada } 5148dd88ab32SMasahiro Yamada if ($block =~ /^\s*\{/) { 5149dd88ab32SMasahiro Yamada #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5150dd88ab32SMasahiro Yamada $allowed = 1; 5151dd88ab32SMasahiro Yamada } 5152dd88ab32SMasahiro Yamada } 5153dd88ab32SMasahiro Yamada if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5154dd88ab32SMasahiro Yamada my $herectx = $here . "\n"; 5155dd88ab32SMasahiro Yamada my $cnt = statement_rawlines($block); 5156dd88ab32SMasahiro Yamada 5157dd88ab32SMasahiro Yamada for (my $n = 0; $n < $cnt; $n++) { 5158dd88ab32SMasahiro Yamada $herectx .= raw_line($linenr, $n) . "\n"; 5159dd88ab32SMasahiro Yamada } 5160dd88ab32SMasahiro Yamada 5161dd88ab32SMasahiro Yamada WARN("BRACES", 5162dd88ab32SMasahiro Yamada "braces {} are not necessary for single statement blocks\n" . $herectx); 5163dd88ab32SMasahiro Yamada } 5164dd88ab32SMasahiro Yamada } 5165dd88ab32SMasahiro Yamada 51667551eb4fSHeinrich Schuchardt# check for single line unbalanced braces 51677551eb4fSHeinrich Schuchardt if ($sline =~ /^.\s*\}\s*else\s*$/ || 51687551eb4fSHeinrich Schuchardt $sline =~ /^.\s*else\s*\{\s*$/) { 51697551eb4fSHeinrich Schuchardt CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 51707551eb4fSHeinrich Schuchardt } 51717551eb4fSHeinrich Schuchardt 5172dd88ab32SMasahiro Yamada# check for unnecessary blank lines around braces 51736b9709d9STom Rini if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 51747551eb4fSHeinrich Schuchardt if (CHK("BRACES", 51757551eb4fSHeinrich Schuchardt "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 51767551eb4fSHeinrich Schuchardt $fix && $prevrawline =~ /^\+/) { 51777551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 51787551eb4fSHeinrich Schuchardt } 5179dd88ab32SMasahiro Yamada } 51806b9709d9STom Rini if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 51817551eb4fSHeinrich Schuchardt if (CHK("BRACES", 51827551eb4fSHeinrich Schuchardt "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 51837551eb4fSHeinrich Schuchardt $fix) { 51847551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 51857551eb4fSHeinrich Schuchardt } 5186dd88ab32SMasahiro Yamada } 5187dd88ab32SMasahiro Yamada 5188dd88ab32SMasahiro Yamada# no volatiles please 5189dd88ab32SMasahiro Yamada my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 5190dd88ab32SMasahiro Yamada if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5191dd88ab32SMasahiro Yamada WARN("VOLATILE", 51927551eb4fSHeinrich Schuchardt "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51937551eb4fSHeinrich Schuchardt } 51947551eb4fSHeinrich Schuchardt 51957551eb4fSHeinrich Schuchardt# Check for user-visible strings broken across lines, which breaks the ability 51967551eb4fSHeinrich Schuchardt# to grep for the string. Make exceptions when the previous string ends in a 51977551eb4fSHeinrich Schuchardt# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51987551eb4fSHeinrich Schuchardt# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 51997551eb4fSHeinrich Schuchardt if ($line =~ /^\+\s*$String/ && 52007551eb4fSHeinrich Schuchardt $prevline =~ /"\s*$/ && 52017551eb4fSHeinrich Schuchardt $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 52027551eb4fSHeinrich Schuchardt if (WARN("SPLIT_STRING", 52037551eb4fSHeinrich Schuchardt "quoted string split across lines\n" . $hereprev) && 52047551eb4fSHeinrich Schuchardt $fix && 52057551eb4fSHeinrich Schuchardt $prevrawline =~ /^\+.*"\s*$/ && 52067551eb4fSHeinrich Schuchardt $last_coalesced_string_linenr != $linenr - 1) { 52077551eb4fSHeinrich Schuchardt my $extracted_string = get_quoted_string($line, $rawline); 52087551eb4fSHeinrich Schuchardt my $comma_close = ""; 52097551eb4fSHeinrich Schuchardt if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 52107551eb4fSHeinrich Schuchardt $comma_close = $1; 52117551eb4fSHeinrich Schuchardt } 52127551eb4fSHeinrich Schuchardt 52137551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 52147551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr, $rawline); 52157551eb4fSHeinrich Schuchardt my $fixedline = $prevrawline; 52167551eb4fSHeinrich Schuchardt $fixedline =~ s/"\s*$//; 52177551eb4fSHeinrich Schuchardt $fixedline .= substr($extracted_string, 1) . trim($comma_close); 52187551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr - 1, $fixedline); 52197551eb4fSHeinrich Schuchardt $fixedline = $rawline; 52207551eb4fSHeinrich Schuchardt $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 52217551eb4fSHeinrich Schuchardt if ($fixedline !~ /\+\s*$/) { 52227551eb4fSHeinrich Schuchardt fix_insert_line($fixlinenr, $fixedline); 52237551eb4fSHeinrich Schuchardt } 52247551eb4fSHeinrich Schuchardt $last_coalesced_string_linenr = $linenr; 52257551eb4fSHeinrich Schuchardt } 52267551eb4fSHeinrich Schuchardt } 52277551eb4fSHeinrich Schuchardt 52287551eb4fSHeinrich Schuchardt# check for missing a space in a string concatenation 52297551eb4fSHeinrich Schuchardt if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 52307551eb4fSHeinrich Schuchardt WARN('MISSING_SPACE', 52317551eb4fSHeinrich Schuchardt "break quoted strings at a space character\n" . $hereprev); 52327551eb4fSHeinrich Schuchardt } 52337551eb4fSHeinrich Schuchardt 52347551eb4fSHeinrich Schuchardt# check for an embedded function name in a string when the function is known 52357551eb4fSHeinrich Schuchardt# This does not work very well for -f --file checking as it depends on patch 52367551eb4fSHeinrich Schuchardt# context providing the function name or a single line form for in-file 52377551eb4fSHeinrich Schuchardt# function declarations 52387551eb4fSHeinrich Schuchardt if ($line =~ /^\+.*$String/ && 52397551eb4fSHeinrich Schuchardt defined($context_function) && 52407551eb4fSHeinrich Schuchardt get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 52417551eb4fSHeinrich Schuchardt length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 52427551eb4fSHeinrich Schuchardt WARN("EMBEDDED_FUNCTION_NAME", 52437551eb4fSHeinrich Schuchardt "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 52447551eb4fSHeinrich Schuchardt } 52457551eb4fSHeinrich Schuchardt 52467551eb4fSHeinrich Schuchardt# check for spaces before a quoted newline 52477551eb4fSHeinrich Schuchardt if ($rawline =~ /^.*\".*\s\\n/) { 52487551eb4fSHeinrich Schuchardt if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52497551eb4fSHeinrich Schuchardt "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52507551eb4fSHeinrich Schuchardt $fix) { 52517551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52527551eb4fSHeinrich Schuchardt } 52537551eb4fSHeinrich Schuchardt 52547551eb4fSHeinrich Schuchardt } 52557551eb4fSHeinrich Schuchardt 52567551eb4fSHeinrich Schuchardt# concatenated string without spaces between elements 5257*722c07ddSHeinrich Schuchardt if ($line =~ /$String[A-Z_]/ || 5258*722c07ddSHeinrich Schuchardt ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^L$/)) { 52597551eb4fSHeinrich Schuchardt CHK("CONCATENATED_STRING", 52607551eb4fSHeinrich Schuchardt "Concatenated strings should use spaces between elements\n" . $herecurr); 52617551eb4fSHeinrich Schuchardt } 52627551eb4fSHeinrich Schuchardt 52637551eb4fSHeinrich Schuchardt# uncoalesced string fragments 5264*722c07ddSHeinrich Schuchardt if ($line =~ /$String\s*L?"/) { 52657551eb4fSHeinrich Schuchardt WARN("STRING_FRAGMENTS", 52667551eb4fSHeinrich Schuchardt "Consecutive strings are generally better as a single string\n" . $herecurr); 52677551eb4fSHeinrich Schuchardt } 52687551eb4fSHeinrich Schuchardt 52697551eb4fSHeinrich Schuchardt# check for non-standard and hex prefixed decimal printf formats 52707551eb4fSHeinrich Schuchardt my $show_L = 1; #don't show the same defect twice 52717551eb4fSHeinrich Schuchardt my $show_Z = 1; 52727551eb4fSHeinrich Schuchardt while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 52737551eb4fSHeinrich Schuchardt my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52747551eb4fSHeinrich Schuchardt $string =~ s/%%/__/g; 52757551eb4fSHeinrich Schuchardt # check for %L 52767551eb4fSHeinrich Schuchardt if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52777551eb4fSHeinrich Schuchardt WARN("PRINTF_L", 52787551eb4fSHeinrich Schuchardt "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 52797551eb4fSHeinrich Schuchardt $show_L = 0; 52807551eb4fSHeinrich Schuchardt } 52817551eb4fSHeinrich Schuchardt # check for %Z 52827551eb4fSHeinrich Schuchardt if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 52837551eb4fSHeinrich Schuchardt WARN("PRINTF_Z", 52847551eb4fSHeinrich Schuchardt "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 52857551eb4fSHeinrich Schuchardt $show_Z = 0; 52867551eb4fSHeinrich Schuchardt } 52877551eb4fSHeinrich Schuchardt # check for 0x<decimal> 52887551eb4fSHeinrich Schuchardt if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 52897551eb4fSHeinrich Schuchardt ERROR("PRINTF_0XDECIMAL", 52907551eb4fSHeinrich Schuchardt "Prefixing 0x with decimal output is defective\n" . $herecurr); 52917551eb4fSHeinrich Schuchardt } 52927551eb4fSHeinrich Schuchardt } 52937551eb4fSHeinrich Schuchardt 52947551eb4fSHeinrich Schuchardt# check for line continuations in quoted strings with odd counts of " 52957551eb4fSHeinrich Schuchardt if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52967551eb4fSHeinrich Schuchardt WARN("LINE_CONTINUATIONS", 52977551eb4fSHeinrich Schuchardt "Avoid line continuations in quoted strings\n" . $herecurr); 5298dd88ab32SMasahiro Yamada } 5299dd88ab32SMasahiro Yamada 5300dd88ab32SMasahiro Yamada# warn about #if 0 5301dd88ab32SMasahiro Yamada if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5302dd88ab32SMasahiro Yamada CHK("REDUNDANT_CODE", 5303dd88ab32SMasahiro Yamada "if this code is redundant consider removing it\n" . 5304dd88ab32SMasahiro Yamada $herecurr); 5305dd88ab32SMasahiro Yamada } 5306dd88ab32SMasahiro Yamada 5307dd88ab32SMasahiro Yamada# check for needless "if (<foo>) fn(<foo>)" uses 5308dd88ab32SMasahiro Yamada if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 53097551eb4fSHeinrich Schuchardt my $tested = quotemeta($1); 53107551eb4fSHeinrich Schuchardt my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 53117551eb4fSHeinrich Schuchardt if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 53127551eb4fSHeinrich Schuchardt my $func = $1; 53137551eb4fSHeinrich Schuchardt if (WARN('NEEDLESS_IF', 53147551eb4fSHeinrich Schuchardt "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 53157551eb4fSHeinrich Schuchardt $fix) { 53167551eb4fSHeinrich Schuchardt my $do_fix = 1; 53177551eb4fSHeinrich Schuchardt my $leading_tabs = ""; 53187551eb4fSHeinrich Schuchardt my $new_leading_tabs = ""; 53197551eb4fSHeinrich Schuchardt if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 53207551eb4fSHeinrich Schuchardt $leading_tabs = $1; 53217551eb4fSHeinrich Schuchardt } else { 53227551eb4fSHeinrich Schuchardt $do_fix = 0; 53237551eb4fSHeinrich Schuchardt } 53247551eb4fSHeinrich Schuchardt if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 53257551eb4fSHeinrich Schuchardt $new_leading_tabs = $1; 53267551eb4fSHeinrich Schuchardt if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 53277551eb4fSHeinrich Schuchardt $do_fix = 0; 53287551eb4fSHeinrich Schuchardt } 53297551eb4fSHeinrich Schuchardt } else { 53307551eb4fSHeinrich Schuchardt $do_fix = 0; 53317551eb4fSHeinrich Schuchardt } 53327551eb4fSHeinrich Schuchardt if ($do_fix) { 53337551eb4fSHeinrich Schuchardt fix_delete_line($fixlinenr - 1, $prevrawline); 53347551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 53357551eb4fSHeinrich Schuchardt } 53367551eb4fSHeinrich Schuchardt } 53377551eb4fSHeinrich Schuchardt } 53387551eb4fSHeinrich Schuchardt } 53397551eb4fSHeinrich Schuchardt 53407551eb4fSHeinrich Schuchardt# check for unnecessary "Out of Memory" messages 53417551eb4fSHeinrich Schuchardt if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 53427551eb4fSHeinrich Schuchardt $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 53437551eb4fSHeinrich Schuchardt (defined $1 || defined $3) && 53447551eb4fSHeinrich Schuchardt $linenr > 3) { 53457551eb4fSHeinrich Schuchardt my $testval = $2; 53467551eb4fSHeinrich Schuchardt my $testline = $lines[$linenr - 3]; 53477551eb4fSHeinrich Schuchardt 53487551eb4fSHeinrich Schuchardt my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 53497551eb4fSHeinrich Schuchardt# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 53507551eb4fSHeinrich Schuchardt 53517551eb4fSHeinrich Schuchardt if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { 53527551eb4fSHeinrich Schuchardt WARN("OOM_MESSAGE", 53537551eb4fSHeinrich Schuchardt "Possible unnecessary 'out of memory' message\n" . $hereprev); 53547551eb4fSHeinrich Schuchardt } 53557551eb4fSHeinrich Schuchardt } 53567551eb4fSHeinrich Schuchardt 53577551eb4fSHeinrich Schuchardt# check for logging functions with KERN_<LEVEL> 53587551eb4fSHeinrich Schuchardt if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 53597551eb4fSHeinrich Schuchardt $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 53607551eb4fSHeinrich Schuchardt my $level = $1; 53617551eb4fSHeinrich Schuchardt if (WARN("UNNECESSARY_KERN_LEVEL", 53627551eb4fSHeinrich Schuchardt "Possible unnecessary $level\n" . $herecurr) && 53637551eb4fSHeinrich Schuchardt $fix) { 53647551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\s*$level\s*//; 53657551eb4fSHeinrich Schuchardt } 53667551eb4fSHeinrich Schuchardt } 53677551eb4fSHeinrich Schuchardt 53687551eb4fSHeinrich Schuchardt# check for logging continuations 53697551eb4fSHeinrich Schuchardt if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 53707551eb4fSHeinrich Schuchardt WARN("LOGGING_CONTINUATION", 53717551eb4fSHeinrich Schuchardt "Avoid logging continuation uses where feasible\n" . $herecurr); 53727551eb4fSHeinrich Schuchardt } 53737551eb4fSHeinrich Schuchardt 53747551eb4fSHeinrich Schuchardt# check for mask then right shift without a parentheses 53757551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 53767551eb4fSHeinrich Schuchardt $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 53777551eb4fSHeinrich Schuchardt $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 53787551eb4fSHeinrich Schuchardt WARN("MASK_THEN_SHIFT", 53797551eb4fSHeinrich Schuchardt "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 53807551eb4fSHeinrich Schuchardt } 53817551eb4fSHeinrich Schuchardt 53827551eb4fSHeinrich Schuchardt# check for pointer comparisons to NULL 53837551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0) { 53847551eb4fSHeinrich Schuchardt while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 53857551eb4fSHeinrich Schuchardt my $val = $1; 53867551eb4fSHeinrich Schuchardt my $equal = "!"; 53877551eb4fSHeinrich Schuchardt $equal = "" if ($4 eq "!="); 53887551eb4fSHeinrich Schuchardt if (CHK("COMPARISON_TO_NULL", 53897551eb4fSHeinrich Schuchardt "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 53907551eb4fSHeinrich Schuchardt $fix) { 53917551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 53927551eb4fSHeinrich Schuchardt } 5393dd88ab32SMasahiro Yamada } 5394dd88ab32SMasahiro Yamada } 5395dd88ab32SMasahiro Yamada 53966b9709d9STom Rini# check for bad placement of section $InitAttribute (e.g.: __initdata) 53976b9709d9STom Rini if ($line =~ /(\b$InitAttribute\b)/) { 53986b9709d9STom Rini my $attr = $1; 53996b9709d9STom Rini if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 54006b9709d9STom Rini my $ptr = $1; 54016b9709d9STom Rini my $var = $2; 54026b9709d9STom Rini if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 54036b9709d9STom Rini ERROR("MISPLACED_INIT", 54046b9709d9STom Rini "$attr should be placed after $var\n" . $herecurr)) || 54056b9709d9STom Rini ($ptr !~ /\b(union|struct)\s+$attr\b/ && 54066b9709d9STom Rini WARN("MISPLACED_INIT", 54076b9709d9STom Rini "$attr should be placed after $var\n" . $herecurr))) && 54086b9709d9STom Rini $fix) { 54097551eb4fSHeinrich Schuchardt $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; 54106b9709d9STom Rini } 54116b9709d9STom Rini } 54126b9709d9STom Rini } 54136b9709d9STom Rini 54146b9709d9STom Rini# check for $InitAttributeData (ie: __initdata) with const 54156b9709d9STom Rini if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 54166b9709d9STom Rini my $attr = $1; 54176b9709d9STom Rini $attr =~ /($InitAttributePrefix)(.*)/; 54186b9709d9STom Rini my $attr_prefix = $1; 54196b9709d9STom Rini my $attr_type = $2; 54206b9709d9STom Rini if (ERROR("INIT_ATTRIBUTE", 54216b9709d9STom Rini "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 54226b9709d9STom Rini $fix) { 54237551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 54246b9709d9STom Rini s/$InitAttributeData/${attr_prefix}initconst/; 54256b9709d9STom Rini } 54266b9709d9STom Rini } 54276b9709d9STom Rini 54286b9709d9STom Rini# check for $InitAttributeConst (ie: __initconst) without const 54296b9709d9STom Rini if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 54306b9709d9STom Rini my $attr = $1; 54316b9709d9STom Rini if (ERROR("INIT_ATTRIBUTE", 54326b9709d9STom Rini "Use of $attr requires a separate use of const\n" . $herecurr) && 54336b9709d9STom Rini $fix) { 54347551eb4fSHeinrich Schuchardt my $lead = $fixed[$fixlinenr] =~ 54356b9709d9STom Rini /(^\+\s*(?:static\s+))/; 54366b9709d9STom Rini $lead = rtrim($1); 54376b9709d9STom Rini $lead = "$lead " if ($lead !~ /^\+$/); 54386b9709d9STom Rini $lead = "${lead}const "; 54397551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 54407551eb4fSHeinrich Schuchardt } 54417551eb4fSHeinrich Schuchardt } 54427551eb4fSHeinrich Schuchardt 54437551eb4fSHeinrich Schuchardt# check for __read_mostly with const non-pointer (should just be const) 54447551eb4fSHeinrich Schuchardt if ($line =~ /\b__read_mostly\b/ && 54457551eb4fSHeinrich Schuchardt $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 54467551eb4fSHeinrich Schuchardt if (ERROR("CONST_READ_MOSTLY", 54477551eb4fSHeinrich Schuchardt "Invalid use of __read_mostly with const type\n" . $herecurr) && 54487551eb4fSHeinrich Schuchardt $fix) { 54497551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 54507551eb4fSHeinrich Schuchardt } 54517551eb4fSHeinrich Schuchardt } 54527551eb4fSHeinrich Schuchardt 54537551eb4fSHeinrich Schuchardt# don't use __constant_<foo> functions outside of include/uapi/ 54547551eb4fSHeinrich Schuchardt if ($realfile !~ m@^include/uapi/@ && 54557551eb4fSHeinrich Schuchardt $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 54567551eb4fSHeinrich Schuchardt my $constant_func = $1; 54577551eb4fSHeinrich Schuchardt my $func = $constant_func; 54587551eb4fSHeinrich Schuchardt $func =~ s/^__constant_//; 54597551eb4fSHeinrich Schuchardt if (WARN("CONSTANT_CONVERSION", 54607551eb4fSHeinrich Schuchardt "$constant_func should be $func\n" . $herecurr) && 54617551eb4fSHeinrich Schuchardt $fix) { 54627551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 54636b9709d9STom Rini } 54646b9709d9STom Rini } 54656b9709d9STom Rini 5466dd88ab32SMasahiro Yamada# prefer usleep_range over udelay 5467dd88ab32SMasahiro Yamada if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 54687551eb4fSHeinrich Schuchardt my $delay = $1; 5469dd88ab32SMasahiro Yamada # ignore udelay's < 10, however 54707551eb4fSHeinrich Schuchardt if (! ($delay < 10) ) { 5471dd88ab32SMasahiro Yamada CHK("USLEEP_RANGE", 54727551eb4fSHeinrich Schuchardt "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 54737551eb4fSHeinrich Schuchardt } 54747551eb4fSHeinrich Schuchardt if ($delay > 2000) { 54757551eb4fSHeinrich Schuchardt WARN("LONG_UDELAY", 54767551eb4fSHeinrich Schuchardt "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 5477dd88ab32SMasahiro Yamada } 5478dd88ab32SMasahiro Yamada } 5479dd88ab32SMasahiro Yamada 5480dd88ab32SMasahiro Yamada# warn about unexpectedly long msleep's 5481dd88ab32SMasahiro Yamada if ($line =~ /\bmsleep\s*\((\d+)\);/) { 5482dd88ab32SMasahiro Yamada if ($1 < 20) { 5483dd88ab32SMasahiro Yamada WARN("MSLEEP", 54847551eb4fSHeinrich Schuchardt "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 5485dd88ab32SMasahiro Yamada } 5486dd88ab32SMasahiro Yamada } 5487dd88ab32SMasahiro Yamada 54886b9709d9STom Rini# check for comparisons of jiffies 54896b9709d9STom Rini if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 54906b9709d9STom Rini WARN("JIFFIES_COMPARISON", 54916b9709d9STom Rini "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 54926b9709d9STom Rini } 54936b9709d9STom Rini 54946b9709d9STom Rini# check for comparisons of get_jiffies_64() 54956b9709d9STom Rini if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54966b9709d9STom Rini WARN("JIFFIES_COMPARISON", 54976b9709d9STom Rini "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54986b9709d9STom Rini } 54996b9709d9STom Rini 5500dd88ab32SMasahiro Yamada# warn about #ifdefs in C files 5501dd88ab32SMasahiro Yamada# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 5502dd88ab32SMasahiro Yamada# print "#ifdef in C files should be avoided\n"; 5503dd88ab32SMasahiro Yamada# print "$herecurr"; 5504dd88ab32SMasahiro Yamada# $clean = 0; 5505dd88ab32SMasahiro Yamada# } 5506dd88ab32SMasahiro Yamada 5507dd88ab32SMasahiro Yamada# warn about spacing in #ifdefs 5508dd88ab32SMasahiro Yamada if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 55096b9709d9STom Rini if (ERROR("SPACING", 55106b9709d9STom Rini "exactly one space required after that #$1\n" . $herecurr) && 55116b9709d9STom Rini $fix) { 55127551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ 55136b9709d9STom Rini s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 55146b9709d9STom Rini } 55156b9709d9STom Rini 5516dd88ab32SMasahiro Yamada } 5517dd88ab32SMasahiro Yamada 5518dd88ab32SMasahiro Yamada# check for spinlock_t definitions without a comment. 5519dd88ab32SMasahiro Yamada if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5520dd88ab32SMasahiro Yamada $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 5521dd88ab32SMasahiro Yamada my $which = $1; 5522dd88ab32SMasahiro Yamada if (!ctx_has_comment($first_line, $linenr)) { 5523dd88ab32SMasahiro Yamada CHK("UNCOMMENTED_DEFINITION", 5524dd88ab32SMasahiro Yamada "$1 definition without comment\n" . $herecurr); 5525dd88ab32SMasahiro Yamada } 5526dd88ab32SMasahiro Yamada } 5527dd88ab32SMasahiro Yamada# check for memory barriers without a comment. 55287551eb4fSHeinrich Schuchardt 55297551eb4fSHeinrich Schuchardt my $barriers = qr{ 55307551eb4fSHeinrich Schuchardt mb| 55317551eb4fSHeinrich Schuchardt rmb| 55327551eb4fSHeinrich Schuchardt wmb| 55337551eb4fSHeinrich Schuchardt read_barrier_depends 55347551eb4fSHeinrich Schuchardt }x; 55357551eb4fSHeinrich Schuchardt my $barrier_stems = qr{ 55367551eb4fSHeinrich Schuchardt mb__before_atomic| 55377551eb4fSHeinrich Schuchardt mb__after_atomic| 55387551eb4fSHeinrich Schuchardt store_release| 55397551eb4fSHeinrich Schuchardt load_acquire| 55407551eb4fSHeinrich Schuchardt store_mb| 55417551eb4fSHeinrich Schuchardt (?:$barriers) 55427551eb4fSHeinrich Schuchardt }x; 55437551eb4fSHeinrich Schuchardt my $all_barriers = qr{ 55447551eb4fSHeinrich Schuchardt (?:$barriers)| 55457551eb4fSHeinrich Schuchardt smp_(?:$barrier_stems)| 55467551eb4fSHeinrich Schuchardt virt_(?:$barrier_stems) 55477551eb4fSHeinrich Schuchardt }x; 55487551eb4fSHeinrich Schuchardt 55497551eb4fSHeinrich Schuchardt if ($line =~ /\b(?:$all_barriers)\s*\(/) { 5550dd88ab32SMasahiro Yamada if (!ctx_has_comment($first_line, $linenr)) { 55516b9709d9STom Rini WARN("MEMORY_BARRIER", 5552dd88ab32SMasahiro Yamada "memory barrier without comment\n" . $herecurr); 5553dd88ab32SMasahiro Yamada } 5554dd88ab32SMasahiro Yamada } 55557551eb4fSHeinrich Schuchardt 55567551eb4fSHeinrich Schuchardt my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 55577551eb4fSHeinrich Schuchardt 55587551eb4fSHeinrich Schuchardt if ($realfile !~ m@^include/asm-generic/@ && 55597551eb4fSHeinrich Schuchardt $realfile !~ m@/barrier\.h$@ && 55607551eb4fSHeinrich Schuchardt $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 55617551eb4fSHeinrich Schuchardt $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 55627551eb4fSHeinrich Schuchardt WARN("MEMORY_BARRIER", 55637551eb4fSHeinrich Schuchardt "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 55647551eb4fSHeinrich Schuchardt } 55657551eb4fSHeinrich Schuchardt 55667551eb4fSHeinrich Schuchardt# check for waitqueue_active without a comment. 55677551eb4fSHeinrich Schuchardt if ($line =~ /\bwaitqueue_active\s*\(/) { 55687551eb4fSHeinrich Schuchardt if (!ctx_has_comment($first_line, $linenr)) { 55697551eb4fSHeinrich Schuchardt WARN("WAITQUEUE_ACTIVE", 55707551eb4fSHeinrich Schuchardt "waitqueue_active without comment\n" . $herecurr); 55717551eb4fSHeinrich Schuchardt } 55727551eb4fSHeinrich Schuchardt } 55737551eb4fSHeinrich Schuchardt 5574dd88ab32SMasahiro Yamada# check of hardware specific defines 5575dd88ab32SMasahiro Yamada if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5576dd88ab32SMasahiro Yamada CHK("ARCH_DEFINES", 5577dd88ab32SMasahiro Yamada "architecture specific defines should be avoided\n" . $herecurr); 5578dd88ab32SMasahiro Yamada } 5579dd88ab32SMasahiro Yamada 55807551eb4fSHeinrich Schuchardt# check that the storage class is not after a type 55817551eb4fSHeinrich Schuchardt if ($line =~ /\b($Type)\s+($Storage)\b/) { 5582dd88ab32SMasahiro Yamada WARN("STORAGE_CLASS", 55837551eb4fSHeinrich Schuchardt "storage class '$2' should be located before type '$1'\n" . $herecurr); 55847551eb4fSHeinrich Schuchardt } 55857551eb4fSHeinrich Schuchardt# Check that the storage class is at the beginning of a declaration 55867551eb4fSHeinrich Schuchardt if ($line =~ /\b$Storage\b/ && 55877551eb4fSHeinrich Schuchardt $line !~ /^.\s*$Storage/ && 55887551eb4fSHeinrich Schuchardt $line =~ /^.\s*(.+?)\$Storage\s/ && 55897551eb4fSHeinrich Schuchardt $1 !~ /[\,\)]\s*$/) { 55907551eb4fSHeinrich Schuchardt WARN("STORAGE_CLASS", 55917551eb4fSHeinrich Schuchardt "storage class should be at the beginning of the declaration\n" . $herecurr); 5592dd88ab32SMasahiro Yamada } 5593dd88ab32SMasahiro Yamada 5594dd88ab32SMasahiro Yamada# check the location of the inline attribute, that it is between 5595dd88ab32SMasahiro Yamada# storage class and type. 5596dd88ab32SMasahiro Yamada if ($line =~ /\b$Type\s+$Inline\b/ || 5597dd88ab32SMasahiro Yamada $line =~ /\b$Inline\s+$Storage\b/) { 5598dd88ab32SMasahiro Yamada ERROR("INLINE_LOCATION", 5599dd88ab32SMasahiro Yamada "inline keyword should sit between storage class and type\n" . $herecurr); 5600dd88ab32SMasahiro Yamada } 5601dd88ab32SMasahiro Yamada 5602dd88ab32SMasahiro Yamada# Check for __inline__ and __inline, prefer inline 56036b9709d9STom Rini if ($realfile !~ m@\binclude/uapi/@ && 56046b9709d9STom Rini $line =~ /\b(__inline__|__inline)\b/) { 56056b9709d9STom Rini if (WARN("INLINE", 56066b9709d9STom Rini "plain inline is preferred over $1\n" . $herecurr) && 56076b9709d9STom Rini $fix) { 56087551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 56096b9709d9STom Rini 56106b9709d9STom Rini } 5611dd88ab32SMasahiro Yamada } 5612dd88ab32SMasahiro Yamada 5613dd88ab32SMasahiro Yamada# Check for __attribute__ packed, prefer __packed 56146b9709d9STom Rini if ($realfile !~ m@\binclude/uapi/@ && 56156b9709d9STom Rini $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5616dd88ab32SMasahiro Yamada WARN("PREFER_PACKED", 5617dd88ab32SMasahiro Yamada "__packed is preferred over __attribute__((packed))\n" . $herecurr); 5618dd88ab32SMasahiro Yamada } 5619dd88ab32SMasahiro Yamada 5620dd10e6c7SHeinrich Schuchardt# Check for new packed members, warn to use care 5621dd10e6c7SHeinrich Schuchardt if ($realfile !~ m@\binclude/uapi/@ && 5622dd10e6c7SHeinrich Schuchardt $line =~ /\b(__attribute__\s*\(\s*\(.*\bpacked|__packed)\b/) { 5623dd10e6c7SHeinrich Schuchardt WARN("NEW_PACKED", 5624dd10e6c7SHeinrich Schuchardt "Adding new packed members is to be done with care\n" . $herecurr); 5625dd10e6c7SHeinrich Schuchardt } 5626dd10e6c7SHeinrich Schuchardt 5627dd88ab32SMasahiro Yamada# Check for __attribute__ aligned, prefer __aligned 56286b9709d9STom Rini if ($realfile !~ m@\binclude/uapi/@ && 56296b9709d9STom Rini $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5630dd88ab32SMasahiro Yamada WARN("PREFER_ALIGNED", 5631dd88ab32SMasahiro Yamada "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 5632dd88ab32SMasahiro Yamada } 5633dd88ab32SMasahiro Yamada 5634dd88ab32SMasahiro Yamada# Check for __attribute__ format(printf, prefer __printf 56356b9709d9STom Rini if ($realfile !~ m@\binclude/uapi/@ && 56366b9709d9STom Rini $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 56376b9709d9STom Rini if (WARN("PREFER_PRINTF", 56386b9709d9STom Rini "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 56396b9709d9STom Rini $fix) { 56407551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 56416b9709d9STom Rini 56426b9709d9STom Rini } 5643dd88ab32SMasahiro Yamada } 5644dd88ab32SMasahiro Yamada 5645dd88ab32SMasahiro Yamada# Check for __attribute__ format(scanf, prefer __scanf 56466b9709d9STom Rini if ($realfile !~ m@\binclude/uapi/@ && 56476b9709d9STom Rini $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 56486b9709d9STom Rini if (WARN("PREFER_SCANF", 56496b9709d9STom Rini "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 56506b9709d9STom Rini $fix) { 56517551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 56527551eb4fSHeinrich Schuchardt } 56537551eb4fSHeinrich Schuchardt } 56547551eb4fSHeinrich Schuchardt 56557551eb4fSHeinrich Schuchardt# Check for __attribute__ weak, or __weak declarations (may have link issues) 56567551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 56577551eb4fSHeinrich Schuchardt $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 56587551eb4fSHeinrich Schuchardt ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 56597551eb4fSHeinrich Schuchardt $line =~ /\b__weak\b/)) { 56607551eb4fSHeinrich Schuchardt ERROR("WEAK_DECLARATION", 56617551eb4fSHeinrich Schuchardt "Using weak declarations can have unintended link defects\n" . $herecurr); 56627551eb4fSHeinrich Schuchardt } 56637551eb4fSHeinrich Schuchardt 56647551eb4fSHeinrich Schuchardt# check for c99 types like uint8_t used outside of uapi/ and tools/ 56657551eb4fSHeinrich Schuchardt if ($realfile !~ m@\binclude/uapi/@ && 56667551eb4fSHeinrich Schuchardt $realfile !~ m@\btools/@ && 56677551eb4fSHeinrich Schuchardt $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 56687551eb4fSHeinrich Schuchardt my $type = $1; 56697551eb4fSHeinrich Schuchardt if ($type =~ /\b($typeC99Typedefs)\b/) { 56707551eb4fSHeinrich Schuchardt $type = $1; 56717551eb4fSHeinrich Schuchardt my $kernel_type = 'u'; 56727551eb4fSHeinrich Schuchardt $kernel_type = 's' if ($type =~ /^_*[si]/); 56737551eb4fSHeinrich Schuchardt $type =~ /(\d+)/; 56747551eb4fSHeinrich Schuchardt $kernel_type .= $1; 56757551eb4fSHeinrich Schuchardt if (CHK("PREFER_KERNEL_TYPES", 56767551eb4fSHeinrich Schuchardt "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 56777551eb4fSHeinrich Schuchardt $fix) { 56787551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 56797551eb4fSHeinrich Schuchardt } 56807551eb4fSHeinrich Schuchardt } 56817551eb4fSHeinrich Schuchardt } 56827551eb4fSHeinrich Schuchardt 56837551eb4fSHeinrich Schuchardt# check for cast of C90 native int or longer types constants 56847551eb4fSHeinrich Schuchardt if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 56857551eb4fSHeinrich Schuchardt my $cast = $1; 56867551eb4fSHeinrich Schuchardt my $const = $2; 56877551eb4fSHeinrich Schuchardt if (WARN("TYPECAST_INT_CONSTANT", 56887551eb4fSHeinrich Schuchardt "Unnecessary typecast of c90 int constant\n" . $herecurr) && 56897551eb4fSHeinrich Schuchardt $fix) { 56907551eb4fSHeinrich Schuchardt my $suffix = ""; 56917551eb4fSHeinrich Schuchardt my $newconst = $const; 56927551eb4fSHeinrich Schuchardt $newconst =~ s/${Int_type}$//; 56937551eb4fSHeinrich Schuchardt $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 56947551eb4fSHeinrich Schuchardt if ($cast =~ /\blong\s+long\b/) { 56957551eb4fSHeinrich Schuchardt $suffix .= 'LL'; 56967551eb4fSHeinrich Schuchardt } elsif ($cast =~ /\blong\b/) { 56977551eb4fSHeinrich Schuchardt $suffix .= 'L'; 56987551eb4fSHeinrich Schuchardt } 56997551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 57006b9709d9STom Rini } 5701dd88ab32SMasahiro Yamada } 5702dd88ab32SMasahiro Yamada 5703dd88ab32SMasahiro Yamada# check for sizeof(&) 5704dd88ab32SMasahiro Yamada if ($line =~ /\bsizeof\s*\(\s*\&/) { 5705dd88ab32SMasahiro Yamada WARN("SIZEOF_ADDRESS", 5706dd88ab32SMasahiro Yamada "sizeof(& should be avoided\n" . $herecurr); 5707dd88ab32SMasahiro Yamada } 5708dd88ab32SMasahiro Yamada 5709dd88ab32SMasahiro Yamada# check for sizeof without parenthesis 5710dd88ab32SMasahiro Yamada if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 57116b9709d9STom Rini if (WARN("SIZEOF_PARENTHESIS", 57126b9709d9STom Rini "sizeof $1 should be sizeof($1)\n" . $herecurr) && 57136b9709d9STom Rini $fix) { 57147551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 57156b9709d9STom Rini } 5716dd88ab32SMasahiro Yamada } 5717dd88ab32SMasahiro Yamada 5718dd88ab32SMasahiro Yamada# check for struct spinlock declarations 5719dd88ab32SMasahiro Yamada if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 5720dd88ab32SMasahiro Yamada WARN("USE_SPINLOCK_T", 5721dd88ab32SMasahiro Yamada "struct spinlock should be spinlock_t\n" . $herecurr); 5722dd88ab32SMasahiro Yamada } 5723dd88ab32SMasahiro Yamada 57246b9709d9STom Rini# check for seq_printf uses that could be seq_puts 57256b9709d9STom Rini if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 57266b9709d9STom Rini my $fmt = get_quoted_string($line, $rawline); 57277551eb4fSHeinrich Schuchardt $fmt =~ s/%%//g; 57287551eb4fSHeinrich Schuchardt if ($fmt !~ /%/) { 57296b9709d9STom Rini if (WARN("PREFER_SEQ_PUTS", 57306b9709d9STom Rini "Prefer seq_puts to seq_printf\n" . $herecurr) && 57316b9709d9STom Rini $fix) { 57327551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 57336b9709d9STom Rini } 57346b9709d9STom Rini } 57356b9709d9STom Rini } 57366b9709d9STom Rini 57377551eb4fSHeinrich Schuchardt # check for vsprintf extension %p<foo> misuses 57387551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 57397551eb4fSHeinrich Schuchardt defined $stat && 57407551eb4fSHeinrich Schuchardt $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 57417551eb4fSHeinrich Schuchardt $1 !~ /^_*volatile_*$/) { 57427551eb4fSHeinrich Schuchardt my $bad_extension = ""; 57437551eb4fSHeinrich Schuchardt my $lc = $stat =~ tr@\n@@; 57447551eb4fSHeinrich Schuchardt $lc = $lc + $linenr; 57457551eb4fSHeinrich Schuchardt for (my $count = $linenr; $count <= $lc; $count++) { 57467551eb4fSHeinrich Schuchardt my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 57477551eb4fSHeinrich Schuchardt $fmt =~ s/%%//g; 57487551eb4fSHeinrich Schuchardt if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 57497551eb4fSHeinrich Schuchardt $bad_extension = $1; 57507551eb4fSHeinrich Schuchardt last; 57517551eb4fSHeinrich Schuchardt } 57527551eb4fSHeinrich Schuchardt } 57537551eb4fSHeinrich Schuchardt if ($bad_extension ne "") { 57547551eb4fSHeinrich Schuchardt my $stat_real = raw_line($linenr, 0); 57557551eb4fSHeinrich Schuchardt for (my $count = $linenr + 1; $count <= $lc; $count++) { 57567551eb4fSHeinrich Schuchardt $stat_real = $stat_real . "\n" . raw_line($count, 0); 57577551eb4fSHeinrich Schuchardt } 57587551eb4fSHeinrich Schuchardt WARN("VSPRINTF_POINTER_EXTENSION", 57597551eb4fSHeinrich Schuchardt "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57607551eb4fSHeinrich Schuchardt } 57617551eb4fSHeinrich Schuchardt } 57627551eb4fSHeinrich Schuchardt 5763dd88ab32SMasahiro Yamada# Check for misused memsets 5764dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 5765dd88ab32SMasahiro Yamada defined $stat && 57667551eb4fSHeinrich Schuchardt $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5767dd88ab32SMasahiro Yamada 5768dd88ab32SMasahiro Yamada my $ms_addr = $2; 5769dd88ab32SMasahiro Yamada my $ms_val = $7; 5770dd88ab32SMasahiro Yamada my $ms_size = $12; 5771dd88ab32SMasahiro Yamada 5772dd88ab32SMasahiro Yamada if ($ms_size =~ /^(0x|)0$/i) { 5773dd88ab32SMasahiro Yamada ERROR("MEMSET", 5774dd88ab32SMasahiro Yamada "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5775dd88ab32SMasahiro Yamada } elsif ($ms_size =~ /^(0x|)1$/i) { 5776dd88ab32SMasahiro Yamada WARN("MEMSET", 5777dd88ab32SMasahiro Yamada "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5778dd88ab32SMasahiro Yamada } 5779dd88ab32SMasahiro Yamada } 5780dd88ab32SMasahiro Yamada 57816b9709d9STom Rini# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 57827551eb4fSHeinrich Schuchardt# if ($^V && $^V ge 5.10.0 && 57837551eb4fSHeinrich Schuchardt# defined $stat && 57847551eb4fSHeinrich Schuchardt# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 57857551eb4fSHeinrich Schuchardt# if (WARN("PREFER_ETHER_ADDR_COPY", 57867551eb4fSHeinrich Schuchardt# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 57877551eb4fSHeinrich Schuchardt# $fix) { 57887551eb4fSHeinrich Schuchardt# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 57897551eb4fSHeinrich Schuchardt# } 57907551eb4fSHeinrich Schuchardt# } 57917551eb4fSHeinrich Schuchardt 57927551eb4fSHeinrich Schuchardt# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 57937551eb4fSHeinrich Schuchardt# if ($^V && $^V ge 5.10.0 && 57947551eb4fSHeinrich Schuchardt# defined $stat && 57957551eb4fSHeinrich Schuchardt# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 57967551eb4fSHeinrich Schuchardt# WARN("PREFER_ETHER_ADDR_EQUAL", 57977551eb4fSHeinrich Schuchardt# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 57987551eb4fSHeinrich Schuchardt# } 57997551eb4fSHeinrich Schuchardt 58007551eb4fSHeinrich Schuchardt# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 58017551eb4fSHeinrich Schuchardt# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 58027551eb4fSHeinrich Schuchardt# if ($^V && $^V ge 5.10.0 && 58037551eb4fSHeinrich Schuchardt# defined $stat && 58047551eb4fSHeinrich Schuchardt# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 58057551eb4fSHeinrich Schuchardt# 58067551eb4fSHeinrich Schuchardt# my $ms_val = $7; 58077551eb4fSHeinrich Schuchardt# 58087551eb4fSHeinrich Schuchardt# if ($ms_val =~ /^(?:0x|)0+$/i) { 58097551eb4fSHeinrich Schuchardt# if (WARN("PREFER_ETH_ZERO_ADDR", 58107551eb4fSHeinrich Schuchardt# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 58117551eb4fSHeinrich Schuchardt# $fix) { 58127551eb4fSHeinrich Schuchardt# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 58137551eb4fSHeinrich Schuchardt# } 58147551eb4fSHeinrich Schuchardt# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 58157551eb4fSHeinrich Schuchardt# if (WARN("PREFER_ETH_BROADCAST_ADDR", 58167551eb4fSHeinrich Schuchardt# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 58177551eb4fSHeinrich Schuchardt# $fix) { 58187551eb4fSHeinrich Schuchardt# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 58197551eb4fSHeinrich Schuchardt# } 58207551eb4fSHeinrich Schuchardt# } 58217551eb4fSHeinrich Schuchardt# } 58226b9709d9STom Rini 5823dd88ab32SMasahiro Yamada# typecasts on min/max could be min_t/max_t 5824dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 5825dd88ab32SMasahiro Yamada defined $stat && 5826dd88ab32SMasahiro Yamada $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5827dd88ab32SMasahiro Yamada if (defined $2 || defined $7) { 5828dd88ab32SMasahiro Yamada my $call = $1; 5829dd88ab32SMasahiro Yamada my $cast1 = deparenthesize($2); 5830dd88ab32SMasahiro Yamada my $arg1 = $3; 5831dd88ab32SMasahiro Yamada my $cast2 = deparenthesize($7); 5832dd88ab32SMasahiro Yamada my $arg2 = $8; 5833dd88ab32SMasahiro Yamada my $cast; 5834dd88ab32SMasahiro Yamada 5835dd88ab32SMasahiro Yamada if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5836dd88ab32SMasahiro Yamada $cast = "$cast1 or $cast2"; 5837dd88ab32SMasahiro Yamada } elsif ($cast1 ne "") { 5838dd88ab32SMasahiro Yamada $cast = $cast1; 5839dd88ab32SMasahiro Yamada } else { 5840dd88ab32SMasahiro Yamada $cast = $cast2; 5841dd88ab32SMasahiro Yamada } 5842dd88ab32SMasahiro Yamada WARN("MINMAX", 5843dd88ab32SMasahiro Yamada "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5844dd88ab32SMasahiro Yamada } 5845dd88ab32SMasahiro Yamada } 5846dd88ab32SMasahiro Yamada 5847dd88ab32SMasahiro Yamada# check usleep_range arguments 5848dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 5849dd88ab32SMasahiro Yamada defined $stat && 5850dd88ab32SMasahiro Yamada $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 5851dd88ab32SMasahiro Yamada my $min = $1; 5852dd88ab32SMasahiro Yamada my $max = $7; 5853dd88ab32SMasahiro Yamada if ($min eq $max) { 5854dd88ab32SMasahiro Yamada WARN("USLEEP_RANGE", 5855dd88ab32SMasahiro Yamada "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 5856dd88ab32SMasahiro Yamada } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 5857dd88ab32SMasahiro Yamada $min > $max) { 5858dd88ab32SMasahiro Yamada WARN("USLEEP_RANGE", 5859dd88ab32SMasahiro Yamada "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 5860dd88ab32SMasahiro Yamada } 5861dd88ab32SMasahiro Yamada } 5862dd88ab32SMasahiro Yamada 58636b9709d9STom Rini# check for naked sscanf 58646b9709d9STom Rini if ($^V && $^V ge 5.10.0 && 58656b9709d9STom Rini defined $stat && 58667551eb4fSHeinrich Schuchardt $line =~ /\bsscanf\b/ && 58676b9709d9STom Rini ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 58686b9709d9STom Rini $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 58696b9709d9STom Rini $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 58706b9709d9STom Rini my $lc = $stat =~ tr@\n@@; 58716b9709d9STom Rini $lc = $lc + $linenr; 58726b9709d9STom Rini my $stat_real = raw_line($linenr, 0); 58736b9709d9STom Rini for (my $count = $linenr + 1; $count <= $lc; $count++) { 58746b9709d9STom Rini $stat_real = $stat_real . "\n" . raw_line($count, 0); 58756b9709d9STom Rini } 58766b9709d9STom Rini WARN("NAKED_SSCANF", 58776b9709d9STom Rini "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 58786b9709d9STom Rini } 58796b9709d9STom Rini 58807551eb4fSHeinrich Schuchardt# check for simple sscanf that should be kstrto<foo> 58817551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 58827551eb4fSHeinrich Schuchardt defined $stat && 58837551eb4fSHeinrich Schuchardt $line =~ /\bsscanf\b/) { 58847551eb4fSHeinrich Schuchardt my $lc = $stat =~ tr@\n@@; 58857551eb4fSHeinrich Schuchardt $lc = $lc + $linenr; 58867551eb4fSHeinrich Schuchardt my $stat_real = raw_line($linenr, 0); 58877551eb4fSHeinrich Schuchardt for (my $count = $linenr + 1; $count <= $lc; $count++) { 58887551eb4fSHeinrich Schuchardt $stat_real = $stat_real . "\n" . raw_line($count, 0); 58897551eb4fSHeinrich Schuchardt } 58907551eb4fSHeinrich Schuchardt if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 58917551eb4fSHeinrich Schuchardt my $format = $6; 58927551eb4fSHeinrich Schuchardt my $count = $format =~ tr@%@%@; 58937551eb4fSHeinrich Schuchardt if ($count == 1 && 58947551eb4fSHeinrich Schuchardt $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 58957551eb4fSHeinrich Schuchardt WARN("SSCANF_TO_KSTRTO", 58967551eb4fSHeinrich Schuchardt "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 58977551eb4fSHeinrich Schuchardt } 58987551eb4fSHeinrich Schuchardt } 58997551eb4fSHeinrich Schuchardt } 59007551eb4fSHeinrich Schuchardt 59016b9709d9STom Rini# check for new externs in .h files. 59026b9709d9STom Rini if ($realfile =~ /\.h$/ && 59036b9709d9STom Rini $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 59046b9709d9STom Rini if (CHK("AVOID_EXTERNS", 59056b9709d9STom Rini "extern prototypes should be avoided in .h files\n" . $herecurr) && 59066b9709d9STom Rini $fix) { 59077551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 59086b9709d9STom Rini } 59096b9709d9STom Rini } 59106b9709d9STom Rini 5911dd88ab32SMasahiro Yamada# check for new externs in .c files. 5912dd88ab32SMasahiro Yamada if ($realfile =~ /\.c$/ && defined $stat && 5913dd88ab32SMasahiro Yamada $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5914dd88ab32SMasahiro Yamada { 5915dd88ab32SMasahiro Yamada my $function_name = $1; 5916dd88ab32SMasahiro Yamada my $paren_space = $2; 5917dd88ab32SMasahiro Yamada 5918dd88ab32SMasahiro Yamada my $s = $stat; 5919dd88ab32SMasahiro Yamada if (defined $cond) { 5920dd88ab32SMasahiro Yamada substr($s, 0, length($cond), ''); 5921dd88ab32SMasahiro Yamada } 5922dd88ab32SMasahiro Yamada if ($s =~ /^\s*;/ && 5923dd88ab32SMasahiro Yamada $function_name ne 'uninitialized_var') 5924dd88ab32SMasahiro Yamada { 5925dd88ab32SMasahiro Yamada WARN("AVOID_EXTERNS", 5926dd88ab32SMasahiro Yamada "externs should be avoided in .c files\n" . $herecurr); 5927dd88ab32SMasahiro Yamada } 5928dd88ab32SMasahiro Yamada 5929dd88ab32SMasahiro Yamada if ($paren_space =~ /\n/) { 5930dd88ab32SMasahiro Yamada WARN("FUNCTION_ARGUMENTS", 5931dd88ab32SMasahiro Yamada "arguments for function declarations should follow identifier\n" . $herecurr); 5932dd88ab32SMasahiro Yamada } 5933dd88ab32SMasahiro Yamada 5934dd88ab32SMasahiro Yamada } elsif ($realfile =~ /\.c$/ && defined $stat && 5935dd88ab32SMasahiro Yamada $stat =~ /^.\s*extern\s+/) 5936dd88ab32SMasahiro Yamada { 5937dd88ab32SMasahiro Yamada WARN("AVOID_EXTERNS", 5938dd88ab32SMasahiro Yamada "externs should be avoided in .c files\n" . $herecurr); 5939dd88ab32SMasahiro Yamada } 5940dd88ab32SMasahiro Yamada 59417551eb4fSHeinrich Schuchardt# check for function declarations that have arguments without identifier names 59427551eb4fSHeinrich Schuchardt if (defined $stat && 59437551eb4fSHeinrich Schuchardt $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 59447551eb4fSHeinrich Schuchardt $1 ne "void") { 59457551eb4fSHeinrich Schuchardt my $args = trim($1); 59467551eb4fSHeinrich Schuchardt while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 59477551eb4fSHeinrich Schuchardt my $arg = trim($1); 59487551eb4fSHeinrich Schuchardt if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 59497551eb4fSHeinrich Schuchardt WARN("FUNCTION_ARGUMENTS", 59507551eb4fSHeinrich Schuchardt "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 59517551eb4fSHeinrich Schuchardt } 59527551eb4fSHeinrich Schuchardt } 59537551eb4fSHeinrich Schuchardt } 59547551eb4fSHeinrich Schuchardt 59557551eb4fSHeinrich Schuchardt# check for function definitions 59567551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 59577551eb4fSHeinrich Schuchardt defined $stat && 59587551eb4fSHeinrich Schuchardt $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 59597551eb4fSHeinrich Schuchardt $context_function = $1; 59607551eb4fSHeinrich Schuchardt 59617551eb4fSHeinrich Schuchardt# check for multiline function definition with misplaced open brace 59627551eb4fSHeinrich Schuchardt my $ok = 0; 59637551eb4fSHeinrich Schuchardt my $cnt = statement_rawlines($stat); 59647551eb4fSHeinrich Schuchardt my $herectx = $here . "\n"; 59657551eb4fSHeinrich Schuchardt for (my $n = 0; $n < $cnt; $n++) { 59667551eb4fSHeinrich Schuchardt my $rl = raw_line($linenr, $n); 59677551eb4fSHeinrich Schuchardt $herectx .= $rl . "\n"; 59687551eb4fSHeinrich Schuchardt $ok = 1 if ($rl =~ /^[ \+]\{/); 59697551eb4fSHeinrich Schuchardt $ok = 1 if ($rl =~ /\{/ && $n == 0); 59707551eb4fSHeinrich Schuchardt last if $rl =~ /^[ \+].*\{/; 59717551eb4fSHeinrich Schuchardt } 59727551eb4fSHeinrich Schuchardt if (!$ok) { 59737551eb4fSHeinrich Schuchardt ERROR("OPEN_BRACE", 59747551eb4fSHeinrich Schuchardt "open brace '{' following function definitions go on the next line\n" . $herectx); 59757551eb4fSHeinrich Schuchardt } 59767551eb4fSHeinrich Schuchardt } 59777551eb4fSHeinrich Schuchardt 5978dd88ab32SMasahiro Yamada# checks for new __setup's 5979dd88ab32SMasahiro Yamada if ($rawline =~ /\b__setup\("([^"]*)"/) { 5980dd88ab32SMasahiro Yamada my $name = $1; 5981dd88ab32SMasahiro Yamada 5982dd88ab32SMasahiro Yamada if (!grep(/$name/, @setup_docs)) { 5983dd88ab32SMasahiro Yamada CHK("UNDOCUMENTED_SETUP", 59847551eb4fSHeinrich Schuchardt "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5985dd88ab32SMasahiro Yamada } 5986dd88ab32SMasahiro Yamada } 5987dd88ab32SMasahiro Yamada 5988dd88ab32SMasahiro Yamada# check for pointless casting of kmalloc return 5989dd88ab32SMasahiro Yamada if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5990dd88ab32SMasahiro Yamada WARN("UNNECESSARY_CASTS", 5991dd88ab32SMasahiro Yamada "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 5992dd88ab32SMasahiro Yamada } 5993dd88ab32SMasahiro Yamada 59946b9709d9STom Rini# alloc style 59956b9709d9STom Rini# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 59966b9709d9STom Rini if ($^V && $^V ge 5.10.0 && 59976b9709d9STom Rini $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 59986b9709d9STom Rini CHK("ALLOC_SIZEOF_STRUCT", 59996b9709d9STom Rini "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 60006b9709d9STom Rini } 60016b9709d9STom Rini 60027551eb4fSHeinrich Schuchardt# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 60037551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 60047551eb4fSHeinrich Schuchardt defined $stat && 60057551eb4fSHeinrich Schuchardt $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 60067551eb4fSHeinrich Schuchardt my $oldfunc = $3; 60077551eb4fSHeinrich Schuchardt my $a1 = $4; 60087551eb4fSHeinrich Schuchardt my $a2 = $10; 60097551eb4fSHeinrich Schuchardt my $newfunc = "kmalloc_array"; 60107551eb4fSHeinrich Schuchardt $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 60117551eb4fSHeinrich Schuchardt my $r1 = $a1; 60127551eb4fSHeinrich Schuchardt my $r2 = $a2; 60137551eb4fSHeinrich Schuchardt if ($a1 =~ /^sizeof\s*\S/) { 60147551eb4fSHeinrich Schuchardt $r1 = $a2; 60157551eb4fSHeinrich Schuchardt $r2 = $a1; 60167551eb4fSHeinrich Schuchardt } 60177551eb4fSHeinrich Schuchardt if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 60187551eb4fSHeinrich Schuchardt !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 60197551eb4fSHeinrich Schuchardt my $ctx = ''; 60207551eb4fSHeinrich Schuchardt my $herectx = $here . "\n"; 60217551eb4fSHeinrich Schuchardt my $cnt = statement_rawlines($stat); 60227551eb4fSHeinrich Schuchardt for (my $n = 0; $n < $cnt; $n++) { 60237551eb4fSHeinrich Schuchardt $herectx .= raw_line($linenr, $n) . "\n"; 60247551eb4fSHeinrich Schuchardt } 60257551eb4fSHeinrich Schuchardt if (WARN("ALLOC_WITH_MULTIPLY", 60267551eb4fSHeinrich Schuchardt "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 60277551eb4fSHeinrich Schuchardt $cnt == 1 && 60287551eb4fSHeinrich Schuchardt $fix) { 60297551eb4fSHeinrich Schuchardt $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; 60307551eb4fSHeinrich Schuchardt } 60317551eb4fSHeinrich Schuchardt } 60327551eb4fSHeinrich Schuchardt } 60337551eb4fSHeinrich Schuchardt 60346b9709d9STom Rini# check for krealloc arg reuse 60356b9709d9STom Rini if ($^V && $^V ge 5.10.0 && 60366b9709d9STom Rini $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 60376b9709d9STom Rini WARN("KREALLOC_ARG_REUSE", 60386b9709d9STom Rini "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 60396b9709d9STom Rini } 60406b9709d9STom Rini 6041dd88ab32SMasahiro Yamada# check for alloc argument mismatch 6042dd88ab32SMasahiro Yamada if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 6043dd88ab32SMasahiro Yamada WARN("ALLOC_ARRAY_ARGS", 6044dd88ab32SMasahiro Yamada "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 6045dd88ab32SMasahiro Yamada } 6046dd88ab32SMasahiro Yamada 6047dd88ab32SMasahiro Yamada# check for multiple semicolons 6048dd88ab32SMasahiro Yamada if ($line =~ /;\s*;\s*$/) { 60496b9709d9STom Rini if (WARN("ONE_SEMICOLON", 60506b9709d9STom Rini "Statements terminations use 1 semicolon\n" . $herecurr) && 60516b9709d9STom Rini $fix) { 60527551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 60537551eb4fSHeinrich Schuchardt } 60547551eb4fSHeinrich Schuchardt } 60557551eb4fSHeinrich Schuchardt 60567551eb4fSHeinrich Schuchardt# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 60577551eb4fSHeinrich Schuchardt if ($realfile !~ m@^include/uapi/@ && 60587551eb4fSHeinrich Schuchardt $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 60597551eb4fSHeinrich Schuchardt my $ull = ""; 60607551eb4fSHeinrich Schuchardt $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 60617551eb4fSHeinrich Schuchardt if (CHK("BIT_MACRO", 60627551eb4fSHeinrich Schuchardt "Prefer using the BIT$ull macro\n" . $herecurr) && 60637551eb4fSHeinrich Schuchardt $fix) { 60647551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 60657551eb4fSHeinrich Schuchardt } 60667551eb4fSHeinrich Schuchardt } 60677551eb4fSHeinrich Schuchardt 60687551eb4fSHeinrich Schuchardt# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 60697551eb4fSHeinrich Schuchardt if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { 60707551eb4fSHeinrich Schuchardt my $config = $1; 60717551eb4fSHeinrich Schuchardt if (WARN("PREFER_IS_ENABLED", 60727551eb4fSHeinrich Schuchardt "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 60737551eb4fSHeinrich Schuchardt $fix) { 60747551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 60756b9709d9STom Rini } 60766b9709d9STom Rini } 60776b9709d9STom Rini 6078fc0b5948SRobert P. J. Day# check for case / default statements not preceded by break/fallthrough/switch 60796b9709d9STom Rini if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 60806b9709d9STom Rini my $has_break = 0; 60816b9709d9STom Rini my $has_statement = 0; 60826b9709d9STom Rini my $count = 0; 60836b9709d9STom Rini my $prevline = $linenr; 60847551eb4fSHeinrich Schuchardt while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 60856b9709d9STom Rini $prevline--; 60866b9709d9STom Rini my $rline = $rawlines[$prevline - 1]; 60876b9709d9STom Rini my $fline = $lines[$prevline - 1]; 60886b9709d9STom Rini last if ($fline =~ /^\@\@/); 60896b9709d9STom Rini next if ($fline =~ /^\-/); 60906b9709d9STom Rini next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 60916b9709d9STom Rini $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 60926b9709d9STom Rini next if ($fline =~ /^.[\s$;]*$/); 60936b9709d9STom Rini $has_statement = 1; 60946b9709d9STom Rini $count++; 60956b9709d9STom Rini $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 60966b9709d9STom Rini } 60976b9709d9STom Rini if (!$has_break && $has_statement) { 60986b9709d9STom Rini WARN("MISSING_BREAK", 6099fc0b5948SRobert P. J. Day "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 61006b9709d9STom Rini } 6101dd88ab32SMasahiro Yamada } 6102dd88ab32SMasahiro Yamada 6103dd88ab32SMasahiro Yamada# check for switch/default statements without a break; 6104dd88ab32SMasahiro Yamada if ($^V && $^V ge 5.10.0 && 6105dd88ab32SMasahiro Yamada defined $stat && 6106dd88ab32SMasahiro Yamada $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6107dd88ab32SMasahiro Yamada my $ctx = ''; 6108dd88ab32SMasahiro Yamada my $herectx = $here . "\n"; 6109dd88ab32SMasahiro Yamada my $cnt = statement_rawlines($stat); 6110dd88ab32SMasahiro Yamada for (my $n = 0; $n < $cnt; $n++) { 6111dd88ab32SMasahiro Yamada $herectx .= raw_line($linenr, $n) . "\n"; 6112dd88ab32SMasahiro Yamada } 6113dd88ab32SMasahiro Yamada WARN("DEFAULT_NO_BREAK", 6114dd88ab32SMasahiro Yamada "switch default: should use break\n" . $herectx); 6115dd88ab32SMasahiro Yamada } 6116dd88ab32SMasahiro Yamada 6117dd88ab32SMasahiro Yamada# check for gcc specific __FUNCTION__ 61186b9709d9STom Rini if ($line =~ /\b__FUNCTION__\b/) { 61196b9709d9STom Rini if (WARN("USE_FUNC", 61206b9709d9STom Rini "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 61216b9709d9STom Rini $fix) { 61227551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 61236b9709d9STom Rini } 6124dd88ab32SMasahiro Yamada } 6125dd88ab32SMasahiro Yamada 61267551eb4fSHeinrich Schuchardt# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 61277551eb4fSHeinrich Schuchardt while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 61287551eb4fSHeinrich Schuchardt ERROR("DATE_TIME", 61297551eb4fSHeinrich Schuchardt "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 61307551eb4fSHeinrich Schuchardt } 61317551eb4fSHeinrich Schuchardt 6132dd88ab32SMasahiro Yamada# check for use of yield() 6133dd88ab32SMasahiro Yamada if ($line =~ /\byield\s*\(\s*\)/) { 6134dd88ab32SMasahiro Yamada WARN("YIELD", 6135dd88ab32SMasahiro Yamada "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 6136dd88ab32SMasahiro Yamada } 6137dd88ab32SMasahiro Yamada 61386b9709d9STom Rini# check for comparisons against true and false 61396b9709d9STom Rini if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 61406b9709d9STom Rini my $lead = $1; 61416b9709d9STom Rini my $arg = $2; 61426b9709d9STom Rini my $test = $3; 61436b9709d9STom Rini my $otype = $4; 61446b9709d9STom Rini my $trail = $5; 61456b9709d9STom Rini my $op = "!"; 61466b9709d9STom Rini 61476b9709d9STom Rini ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 61486b9709d9STom Rini 61496b9709d9STom Rini my $type = lc($otype); 61506b9709d9STom Rini if ($type =~ /^(?:true|false)$/) { 61516b9709d9STom Rini if (("$test" eq "==" && "$type" eq "true") || 61526b9709d9STom Rini ("$test" eq "!=" && "$type" eq "false")) { 61536b9709d9STom Rini $op = ""; 61546b9709d9STom Rini } 61556b9709d9STom Rini 61566b9709d9STom Rini CHK("BOOL_COMPARISON", 61576b9709d9STom Rini "Using comparison to $otype is error prone\n" . $herecurr); 61586b9709d9STom Rini 61596b9709d9STom Rini## maybe suggesting a correct construct would better 61606b9709d9STom Rini## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 61616b9709d9STom Rini 61626b9709d9STom Rini } 61636b9709d9STom Rini } 61646b9709d9STom Rini 6165dd88ab32SMasahiro Yamada# check for semaphores initialized locked 6166dd88ab32SMasahiro Yamada if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6167dd88ab32SMasahiro Yamada WARN("CONSIDER_COMPLETION", 6168dd88ab32SMasahiro Yamada "consider using a completion\n" . $herecurr); 6169dd88ab32SMasahiro Yamada } 6170dd88ab32SMasahiro Yamada 6171dd88ab32SMasahiro Yamada# recommend kstrto* over simple_strto* and strict_strto* 6172dd88ab32SMasahiro Yamada if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6173dd88ab32SMasahiro Yamada WARN("CONSIDER_KSTRTO", 6174dd88ab32SMasahiro Yamada "$1 is obsolete, use k$3 instead\n" . $herecurr); 6175dd88ab32SMasahiro Yamada } 6176dd88ab32SMasahiro Yamada 61777551eb4fSHeinrich Schuchardt# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6178dd88ab32SMasahiro Yamada if ($line =~ /^.\s*__initcall\s*\(/) { 6179dd88ab32SMasahiro Yamada WARN("USE_DEVICE_INITCALL", 61807551eb4fSHeinrich Schuchardt "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6181dd88ab32SMasahiro Yamada } 6182dd88ab32SMasahiro Yamada 61837551eb4fSHeinrich Schuchardt# check for various structs that are normally const (ops, kgdb, device_tree) 61847551eb4fSHeinrich Schuchardt# and avoid what seem like struct definitions 'struct foo {' 6185dd88ab32SMasahiro Yamada if ($line !~ /\bconst\b/ && 61867551eb4fSHeinrich Schuchardt $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6187dd88ab32SMasahiro Yamada WARN("CONST_STRUCT", 61887551eb4fSHeinrich Schuchardt "struct $1 should normally be const\n" . $herecurr); 6189dd88ab32SMasahiro Yamada } 6190dd88ab32SMasahiro Yamada 6191dd88ab32SMasahiro Yamada# use of NR_CPUS is usually wrong 6192dd88ab32SMasahiro Yamada# ignore definitions of NR_CPUS and usage to define arrays as likely right 6193dd88ab32SMasahiro Yamada if ($line =~ /\bNR_CPUS\b/ && 6194dd88ab32SMasahiro Yamada $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6195dd88ab32SMasahiro Yamada $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6196dd88ab32SMasahiro Yamada $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6197dd88ab32SMasahiro Yamada $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6198dd88ab32SMasahiro Yamada $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6199dd88ab32SMasahiro Yamada { 6200dd88ab32SMasahiro Yamada WARN("NR_CPUS", 6201dd88ab32SMasahiro Yamada "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6202dd88ab32SMasahiro Yamada } 6203dd88ab32SMasahiro Yamada 62046b9709d9STom Rini# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 62056b9709d9STom Rini if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 62066b9709d9STom Rini ERROR("DEFINE_ARCH_HAS", 62076b9709d9STom Rini "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 62086b9709d9STom Rini } 62096b9709d9STom Rini 62107551eb4fSHeinrich Schuchardt# likely/unlikely comparisons similar to "(likely(foo) > 0)" 62117551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 62127551eb4fSHeinrich Schuchardt $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 62137551eb4fSHeinrich Schuchardt WARN("LIKELY_MISUSE", 62147551eb4fSHeinrich Schuchardt "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6215dd88ab32SMasahiro Yamada } 6216dd88ab32SMasahiro Yamada 6217dd88ab32SMasahiro Yamada# whine mightly about in_atomic 6218dd88ab32SMasahiro Yamada if ($line =~ /\bin_atomic\s*\(/) { 6219dd88ab32SMasahiro Yamada if ($realfile =~ m@^drivers/@) { 6220dd88ab32SMasahiro Yamada ERROR("IN_ATOMIC", 6221dd88ab32SMasahiro Yamada "do not use in_atomic in drivers\n" . $herecurr); 6222dd88ab32SMasahiro Yamada } elsif ($realfile !~ m@^kernel/@) { 6223dd88ab32SMasahiro Yamada WARN("IN_ATOMIC", 6224dd88ab32SMasahiro Yamada "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6225dd88ab32SMasahiro Yamada } 6226dd88ab32SMasahiro Yamada } 6227dd88ab32SMasahiro Yamada 62287551eb4fSHeinrich Schuchardt# whine about ACCESS_ONCE 62297551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 62307551eb4fSHeinrich Schuchardt $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 62317551eb4fSHeinrich Schuchardt my $par = $1; 62327551eb4fSHeinrich Schuchardt my $eq = $2; 62337551eb4fSHeinrich Schuchardt my $fun = $3; 62347551eb4fSHeinrich Schuchardt $par =~ s/^\(\s*(.*)\s*\)$/$1/; 62357551eb4fSHeinrich Schuchardt if (defined($eq)) { 62367551eb4fSHeinrich Schuchardt if (WARN("PREFER_WRITE_ONCE", 62377551eb4fSHeinrich Schuchardt "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 62387551eb4fSHeinrich Schuchardt $fix) { 62397551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 62407551eb4fSHeinrich Schuchardt } 62417551eb4fSHeinrich Schuchardt } else { 62427551eb4fSHeinrich Schuchardt if (WARN("PREFER_READ_ONCE", 62437551eb4fSHeinrich Schuchardt "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 62447551eb4fSHeinrich Schuchardt $fix) { 62457551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 62467551eb4fSHeinrich Schuchardt } 62477551eb4fSHeinrich Schuchardt } 62487551eb4fSHeinrich Schuchardt } 62497551eb4fSHeinrich Schuchardt 62507551eb4fSHeinrich Schuchardt# check for mutex_trylock_recursive usage 62517551eb4fSHeinrich Schuchardt if ($line =~ /mutex_trylock_recursive/) { 62527551eb4fSHeinrich Schuchardt ERROR("LOCKING", 62537551eb4fSHeinrich Schuchardt "recursive locking is bad, do not use this ever.\n" . $herecurr); 62547551eb4fSHeinrich Schuchardt } 62557551eb4fSHeinrich Schuchardt 6256dd88ab32SMasahiro Yamada# check for lockdep_set_novalidate_class 6257dd88ab32SMasahiro Yamada if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 6258dd88ab32SMasahiro Yamada $line =~ /__lockdep_no_validate__\s*\)/ ) { 6259dd88ab32SMasahiro Yamada if ($realfile !~ m@^kernel/lockdep@ && 6260dd88ab32SMasahiro Yamada $realfile !~ m@^include/linux/lockdep@ && 6261dd88ab32SMasahiro Yamada $realfile !~ m@^drivers/base/core@) { 6262dd88ab32SMasahiro Yamada ERROR("LOCKDEP", 6263dd88ab32SMasahiro Yamada "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 6264dd88ab32SMasahiro Yamada } 6265dd88ab32SMasahiro Yamada } 6266dd88ab32SMasahiro Yamada 62677551eb4fSHeinrich Schuchardt if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 62687551eb4fSHeinrich Schuchardt $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6269dd88ab32SMasahiro Yamada WARN("EXPORTED_WORLD_WRITABLE", 6270dd88ab32SMasahiro Yamada "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 6271dd88ab32SMasahiro Yamada } 62727551eb4fSHeinrich Schuchardt 62737551eb4fSHeinrich Schuchardt# Mode permission misuses where it seems decimal should be octal 62747551eb4fSHeinrich Schuchardt# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 62757551eb4fSHeinrich Schuchardt if ($^V && $^V ge 5.10.0 && 62767551eb4fSHeinrich Schuchardt defined $stat && 62777551eb4fSHeinrich Schuchardt $line =~ /$mode_perms_search/) { 62787551eb4fSHeinrich Schuchardt foreach my $entry (@mode_permission_funcs) { 62797551eb4fSHeinrich Schuchardt my $func = $entry->[0]; 62807551eb4fSHeinrich Schuchardt my $arg_pos = $entry->[1]; 62817551eb4fSHeinrich Schuchardt 62827551eb4fSHeinrich Schuchardt my $lc = $stat =~ tr@\n@@; 62837551eb4fSHeinrich Schuchardt $lc = $lc + $linenr; 62847551eb4fSHeinrich Schuchardt my $stat_real = raw_line($linenr, 0); 62857551eb4fSHeinrich Schuchardt for (my $count = $linenr + 1; $count <= $lc; $count++) { 62867551eb4fSHeinrich Schuchardt $stat_real = $stat_real . "\n" . raw_line($count, 0); 62877551eb4fSHeinrich Schuchardt } 62887551eb4fSHeinrich Schuchardt 62897551eb4fSHeinrich Schuchardt my $skip_args = ""; 62907551eb4fSHeinrich Schuchardt if ($arg_pos > 1) { 62917551eb4fSHeinrich Schuchardt $arg_pos--; 62927551eb4fSHeinrich Schuchardt $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62937551eb4fSHeinrich Schuchardt } 62947551eb4fSHeinrich Schuchardt my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 62957551eb4fSHeinrich Schuchardt if ($stat =~ /$test/) { 62967551eb4fSHeinrich Schuchardt my $val = $1; 62977551eb4fSHeinrich Schuchardt $val = $6 if ($skip_args ne ""); 62987551eb4fSHeinrich Schuchardt if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 62997551eb4fSHeinrich Schuchardt ($val =~ /^$Octal$/ && length($val) ne 4)) { 63007551eb4fSHeinrich Schuchardt ERROR("NON_OCTAL_PERMISSIONS", 63017551eb4fSHeinrich Schuchardt "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 63027551eb4fSHeinrich Schuchardt } 63037551eb4fSHeinrich Schuchardt if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 63047551eb4fSHeinrich Schuchardt ERROR("EXPORTED_WORLD_WRITABLE", 63057551eb4fSHeinrich Schuchardt "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 63067551eb4fSHeinrich Schuchardt } 63077551eb4fSHeinrich Schuchardt } 63087551eb4fSHeinrich Schuchardt } 63097551eb4fSHeinrich Schuchardt } 63107551eb4fSHeinrich Schuchardt 63117551eb4fSHeinrich Schuchardt# check for uses of S_<PERMS> that could be octal for readability 63127551eb4fSHeinrich Schuchardt if ($line =~ /\b$mode_perms_string_search\b/) { 63137551eb4fSHeinrich Schuchardt my $val = ""; 63147551eb4fSHeinrich Schuchardt my $oval = ""; 63157551eb4fSHeinrich Schuchardt my $to = 0; 63167551eb4fSHeinrich Schuchardt my $curpos = 0; 63177551eb4fSHeinrich Schuchardt my $lastpos = 0; 63187551eb4fSHeinrich Schuchardt while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 63197551eb4fSHeinrich Schuchardt $curpos = pos($line); 63207551eb4fSHeinrich Schuchardt my $match = $2; 63217551eb4fSHeinrich Schuchardt my $omatch = $1; 63227551eb4fSHeinrich Schuchardt last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 63237551eb4fSHeinrich Schuchardt $lastpos = $curpos; 63247551eb4fSHeinrich Schuchardt $to |= $mode_permission_string_types{$match}; 63257551eb4fSHeinrich Schuchardt $val .= '\s*\|\s*' if ($val ne ""); 63267551eb4fSHeinrich Schuchardt $val .= $match; 63277551eb4fSHeinrich Schuchardt $oval .= $omatch; 63287551eb4fSHeinrich Schuchardt } 63297551eb4fSHeinrich Schuchardt $oval =~ s/^\s*\|\s*//; 63307551eb4fSHeinrich Schuchardt $oval =~ s/\s*\|\s*$//; 63317551eb4fSHeinrich Schuchardt my $octal = sprintf("%04o", $to); 63327551eb4fSHeinrich Schuchardt if (WARN("SYMBOLIC_PERMS", 63337551eb4fSHeinrich Schuchardt "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 63347551eb4fSHeinrich Schuchardt $fix) { 63357551eb4fSHeinrich Schuchardt $fixed[$fixlinenr] =~ s/$val/$octal/; 63367551eb4fSHeinrich Schuchardt } 63377551eb4fSHeinrich Schuchardt } 63387551eb4fSHeinrich Schuchardt 63397551eb4fSHeinrich Schuchardt# validate content of MODULE_LICENSE against list from include/linux/module.h 63407551eb4fSHeinrich Schuchardt if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 63417551eb4fSHeinrich Schuchardt my $extracted_string = get_quoted_string($line, $rawline); 63427551eb4fSHeinrich Schuchardt my $valid_licenses = qr{ 63437551eb4fSHeinrich Schuchardt GPL| 63447551eb4fSHeinrich Schuchardt GPL\ v2| 63457551eb4fSHeinrich Schuchardt GPL\ and\ additional\ rights| 63467551eb4fSHeinrich Schuchardt Dual\ BSD/GPL| 63477551eb4fSHeinrich Schuchardt Dual\ MIT/GPL| 63487551eb4fSHeinrich Schuchardt Dual\ MPL/GPL| 63497551eb4fSHeinrich Schuchardt Proprietary 63507551eb4fSHeinrich Schuchardt }x; 63517551eb4fSHeinrich Schuchardt if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 63527551eb4fSHeinrich Schuchardt WARN("MODULE_LICENSE", 63537551eb4fSHeinrich Schuchardt "unknown module license " . $extracted_string . "\n" . $herecurr); 63547551eb4fSHeinrich Schuchardt } 63557551eb4fSHeinrich Schuchardt } 6356dd88ab32SMasahiro Yamada } 6357dd88ab32SMasahiro Yamada 6358dd88ab32SMasahiro Yamada # If we have no input at all, then there is nothing to report on 6359dd88ab32SMasahiro Yamada # so just keep quiet. 6360dd88ab32SMasahiro Yamada if ($#rawlines == -1) { 6361dd88ab32SMasahiro Yamada exit(0); 6362dd88ab32SMasahiro Yamada } 6363dd88ab32SMasahiro Yamada 6364dd88ab32SMasahiro Yamada # In mailback mode only produce a report in the negative, for 6365dd88ab32SMasahiro Yamada # things that appear to be patches. 6366dd88ab32SMasahiro Yamada if ($mailback && ($clean == 1 || !$is_patch)) { 6367dd88ab32SMasahiro Yamada exit(0); 6368dd88ab32SMasahiro Yamada } 6369dd88ab32SMasahiro Yamada 6370dd88ab32SMasahiro Yamada # This is not a patch, and we are are in 'no-patch' mode so 6371dd88ab32SMasahiro Yamada # just keep quiet. 6372dd88ab32SMasahiro Yamada if (!$chk_patch && !$is_patch) { 6373dd88ab32SMasahiro Yamada exit(0); 6374dd88ab32SMasahiro Yamada } 6375dd88ab32SMasahiro Yamada 63767551eb4fSHeinrich Schuchardt if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6377dd88ab32SMasahiro Yamada ERROR("NOT_UNIFIED_DIFF", 6378dd88ab32SMasahiro Yamada "Does not appear to be a unified-diff format patch\n"); 6379dd88ab32SMasahiro Yamada } 63807551eb4fSHeinrich Schuchardt if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6381dd88ab32SMasahiro Yamada ERROR("MISSING_SIGN_OFF", 6382dd88ab32SMasahiro Yamada "Missing Signed-off-by: line(s)\n"); 6383dd88ab32SMasahiro Yamada } 6384dd88ab32SMasahiro Yamada 6385dd88ab32SMasahiro Yamada print report_dump(); 6386dd88ab32SMasahiro Yamada if ($summary && !($clean == 1 && $quiet == 1)) { 6387dd88ab32SMasahiro Yamada print "$filename " if ($summary_file); 6388dd88ab32SMasahiro Yamada print "total: $cnt_error errors, $cnt_warn warnings, " . 6389dd88ab32SMasahiro Yamada (($check)? "$cnt_chk checks, " : "") . 6390dd88ab32SMasahiro Yamada "$cnt_lines lines checked\n"; 6391dd88ab32SMasahiro Yamada } 6392dd88ab32SMasahiro Yamada 6393dd88ab32SMasahiro Yamada if ($quiet == 0) { 63947551eb4fSHeinrich Schuchardt # If there were any defects found and not already fixing them 63957551eb4fSHeinrich Schuchardt if (!$clean and !$fix) { 63967551eb4fSHeinrich Schuchardt print << "EOM" 6397dd88ab32SMasahiro Yamada 63987551eb4fSHeinrich SchuchardtNOTE: For some of the reported defects, checkpatch may be able to 63997551eb4fSHeinrich Schuchardt mechanically convert to the typical style using --fix or --fix-inplace. 64007551eb4fSHeinrich SchuchardtEOM 6401dd88ab32SMasahiro Yamada } 6402dd88ab32SMasahiro Yamada # If there were whitespace errors which cleanpatch can fix 6403dd88ab32SMasahiro Yamada # then suggest that. 6404dd88ab32SMasahiro Yamada if ($rpt_cleaners) { 6405dd88ab32SMasahiro Yamada $rpt_cleaners = 0; 64067551eb4fSHeinrich Schuchardt print << "EOM" 64077551eb4fSHeinrich Schuchardt 64087551eb4fSHeinrich SchuchardtNOTE: Whitespace errors detected. 64097551eb4fSHeinrich Schuchardt You may wish to use scripts/cleanpatch or scripts/cleanfile 64107551eb4fSHeinrich SchuchardtEOM 6411dd88ab32SMasahiro Yamada } 6412dd88ab32SMasahiro Yamada } 6413dd88ab32SMasahiro Yamada 64147551eb4fSHeinrich Schuchardt if ($clean == 0 && $fix && 64157551eb4fSHeinrich Schuchardt ("@rawlines" ne "@fixed" || 64167551eb4fSHeinrich Schuchardt $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 64176b9709d9STom Rini my $newfile = $filename; 64186b9709d9STom Rini $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 64196b9709d9STom Rini my $linecount = 0; 64206b9709d9STom Rini my $f; 64216b9709d9STom Rini 64227551eb4fSHeinrich Schuchardt @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 64237551eb4fSHeinrich Schuchardt 64246b9709d9STom Rini open($f, '>', $newfile) 64256b9709d9STom Rini or die "$P: Can't open $newfile for write\n"; 64266b9709d9STom Rini foreach my $fixed_line (@fixed) { 64276b9709d9STom Rini $linecount++; 64286b9709d9STom Rini if ($file) { 64296b9709d9STom Rini if ($linecount > 3) { 64306b9709d9STom Rini $fixed_line =~ s/^\+//; 64316b9709d9STom Rini print $f $fixed_line . "\n"; 6432dd88ab32SMasahiro Yamada } 64336b9709d9STom Rini } else { 64346b9709d9STom Rini print $f $fixed_line . "\n"; 64356b9709d9STom Rini } 64366b9709d9STom Rini } 64376b9709d9STom Rini close($f); 64386b9709d9STom Rini 64396b9709d9STom Rini if (!$quiet) { 64406b9709d9STom Rini print << "EOM"; 64417551eb4fSHeinrich Schuchardt 64426b9709d9STom RiniWrote EXPERIMENTAL --fix correction(s) to '$newfile' 64436b9709d9STom Rini 64446b9709d9STom RiniDo _NOT_ trust the results written to this file. 64456b9709d9STom RiniDo _NOT_ submit these changes without inspecting them for correctness. 64466b9709d9STom Rini 64476b9709d9STom RiniThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 64486b9709d9STom RiniNo warranties, expressed or implied... 64496b9709d9STom RiniEOM 64506b9709d9STom Rini } 6451dd88ab32SMasahiro Yamada } 6452dd88ab32SMasahiro Yamada 64537551eb4fSHeinrich Schuchardt if ($quiet == 0) { 64547551eb4fSHeinrich Schuchardt print "\n"; 64557551eb4fSHeinrich Schuchardt if ($clean == 1) { 64567551eb4fSHeinrich Schuchardt print "$vname has no obvious style problems and is ready for submission.\n"; 64577551eb4fSHeinrich Schuchardt } else { 64587551eb4fSHeinrich Schuchardt print "$vname has style problems, please review.\n"; 6459dd88ab32SMasahiro Yamada } 6460dd88ab32SMasahiro Yamada } 6461dd88ab32SMasahiro Yamada return $clean; 6462dd88ab32SMasahiro Yamada} 6463