10a920b5bSAndy Whitcroft#!/usr/bin/perl -w 2dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 42a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 5015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 60a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2 70a920b5bSAndy Whitcroft 80a920b5bSAndy Whitcroftuse strict; 9c707a81dSJoe Perchesuse POSIX; 1036061e38SJoe Perchesuse File::Basename; 1136061e38SJoe Perchesuse Cwd 'abs_path'; 120a920b5bSAndy Whitcroft 130a920b5bSAndy Whitcroftmy $P = $0; 1436061e38SJoe Perchesmy $D = dirname(abs_path($P)); 150a920b5bSAndy Whitcroft 16000d1cc1SJoe Perchesmy $V = '0.32'; 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 190a920b5bSAndy Whitcroft 200a920b5bSAndy Whitcroftmy $quiet = 0; 210a920b5bSAndy Whitcroftmy $tree = 1; 220a920b5bSAndy Whitcroftmy $chk_signoff = 1; 230a920b5bSAndy Whitcroftmy $chk_patch = 1; 24773647a0SAndy Whitcroftmy $tst_only; 256c72ffaaSAndy Whitcroftmy $emacs = 0; 268905a67cSAndy Whitcroftmy $terse = 0; 276c72ffaaSAndy Whitcroftmy $file = 0; 286c72ffaaSAndy Whitcroftmy $check = 0; 292ac73b4fSJoe Perchesmy $check_orig = 0; 308905a67cSAndy Whitcroftmy $summary = 1; 318905a67cSAndy Whitcroftmy $mailback = 0; 3213214adfSAndy Whitcroftmy $summary_file = 0; 33000d1cc1SJoe Perchesmy $show_types = 0; 343705ce5bSJoe Perchesmy $fix = 0; 359624b8d6SJoe Perchesmy $fix_inplace = 0; 366c72ffaaSAndy Whitcroftmy $root; 37c2fdda0dSAndy Whitcroftmy %debug; 383445686aSJoe Perchesmy %camelcase = (); 3991bfe484SJoe Perchesmy %use_type = (); 4091bfe484SJoe Perchesmy @use = (); 4191bfe484SJoe Perchesmy %ignore_type = (); 42000d1cc1SJoe Perchesmy @ignore = (); 4377f5b10aSHannes Edermy $help = 0; 44000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 456cd7f386SJoe Perchesmy $max_line_length = 80; 46d62a201fSDave Hansenmy $ignore_perl_version = 0; 47d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 4856193274SVadim Bendeburymy $min_conf_desc_length = 4; 4966b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 50ebfd7d62SJoe Perchesmy $codespell = 0; 51ebfd7d62SJoe Perchesmy $codespellfile = "/usr/local/share/codespell/dictionary.txt"; 5277f5b10aSHannes Eder 5377f5b10aSHannes Edersub help { 5477f5b10aSHannes Eder my ($exitcode) = @_; 5577f5b10aSHannes Eder 5677f5b10aSHannes Eder print << "EOM"; 5777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 5877f5b10aSHannes EderVersion: $V 5977f5b10aSHannes Eder 6077f5b10aSHannes EderOptions: 6177f5b10aSHannes Eder -q, --quiet quiet 6277f5b10aSHannes Eder --no-tree run without a kernel tree 6377f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 6477f5b10aSHannes Eder --patch treat FILE as patchfile (default) 6577f5b10aSHannes Eder --emacs emacs compile window format 6677f5b10aSHannes Eder --terse one line per report 6777f5b10aSHannes Eder -f, --file treat FILE as regular source file 6877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 6991bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 70000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 716cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 7256193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 73000d1cc1SJoe Perches --show-types show the message "types" in the output 7477f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 7577f5b10aSHannes Eder --no-summary suppress the per-file summary 7677f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 7777f5b10aSHannes Eder --summary-file include the filename in summary 7877f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 7977f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 8077f5b10aSHannes Eder is all off) 8177f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 8277f5b10aSHannes Eder literally 833705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 843705ce5bSJoe Perches If correctable single-line errors exist, create 853705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 863705ce5bSJoe Perches with potential errors corrected to the preferred 873705ce5bSJoe Perches checkpatch style 889624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 899624b8d6SJoe Perches Is the same as --fix, but overwrites the input 909624b8d6SJoe Perches file. It's your fault if there's no backup or git 91d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 92d62a201fSDave Hansen runtime errors. 93ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 94ebfd7d62SJoe Perches (default:/usr/local/share/codespell/dictionary.txt) 95ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 9677f5b10aSHannes Eder -h, --help, --version display this help and exit 9777f5b10aSHannes Eder 9877f5b10aSHannes EderWhen FILE is - read standard input. 9977f5b10aSHannes EderEOM 10077f5b10aSHannes Eder 10177f5b10aSHannes Eder exit($exitcode); 10277f5b10aSHannes Eder} 10377f5b10aSHannes Eder 104000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 105000d1cc1SJoe Perchesif (-f $conf) { 106000d1cc1SJoe Perches my @conf_args; 107000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 108000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 109000d1cc1SJoe Perches 110000d1cc1SJoe Perches while (<$conffile>) { 111000d1cc1SJoe Perches my $line = $_; 112000d1cc1SJoe Perches 113000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 114000d1cc1SJoe Perches $line =~ s/^\s*//g; 115000d1cc1SJoe Perches $line =~ s/\s+/ /g; 116000d1cc1SJoe Perches 117000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 118000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 119000d1cc1SJoe Perches 120000d1cc1SJoe Perches my @words = split(" ", $line); 121000d1cc1SJoe Perches foreach my $word (@words) { 122000d1cc1SJoe Perches last if ($word =~ m/^#/); 123000d1cc1SJoe Perches push (@conf_args, $word); 124000d1cc1SJoe Perches } 125000d1cc1SJoe Perches } 126000d1cc1SJoe Perches close($conffile); 127000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 128000d1cc1SJoe Perches} 129000d1cc1SJoe Perches 1300a920b5bSAndy WhitcroftGetOptions( 1316c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 1320a920b5bSAndy Whitcroft 'tree!' => \$tree, 1330a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 1340a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 1356c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 1368905a67cSAndy Whitcroft 'terse!' => \$terse, 13777f5b10aSHannes Eder 'f|file!' => \$file, 1386c72ffaaSAndy Whitcroft 'subjective!' => \$check, 1396c72ffaaSAndy Whitcroft 'strict!' => \$check, 140000d1cc1SJoe Perches 'ignore=s' => \@ignore, 14191bfe484SJoe Perches 'types=s' => \@use, 142000d1cc1SJoe Perches 'show-types!' => \$show_types, 1436cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 14456193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 1456c72ffaaSAndy Whitcroft 'root=s' => \$root, 1468905a67cSAndy Whitcroft 'summary!' => \$summary, 1478905a67cSAndy Whitcroft 'mailback!' => \$mailback, 14813214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 1493705ce5bSJoe Perches 'fix!' => \$fix, 1509624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 151d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 152c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 153773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 154ebfd7d62SJoe Perches 'codespell!' => \$codespell, 155ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 15677f5b10aSHannes Eder 'h|help' => \$help, 15777f5b10aSHannes Eder 'version' => \$help 15877f5b10aSHannes Eder) or help(1); 15977f5b10aSHannes Eder 16077f5b10aSHannes Ederhelp(0) if ($help); 1610a920b5bSAndy Whitcroft 1629624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 1632ac73b4fSJoe Perches$check_orig = $check; 1649624b8d6SJoe Perches 1650a920b5bSAndy Whitcroftmy $exit = 0; 1660a920b5bSAndy Whitcroft 167d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 168d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 169d62a201fSDave Hansen if (!$ignore_perl_version) { 170d62a201fSDave Hansen exit(1); 171d62a201fSDave Hansen } 172d62a201fSDave Hansen} 173d62a201fSDave Hansen 1740a920b5bSAndy Whitcroftif ($#ARGV < 0) { 17577f5b10aSHannes Eder print "$P: no input files\n"; 1760a920b5bSAndy Whitcroft exit(1); 1770a920b5bSAndy Whitcroft} 1780a920b5bSAndy Whitcroft 17991bfe484SJoe Perchessub hash_save_array_words { 18091bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 18191bfe484SJoe Perches 18291bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 18391bfe484SJoe Perches foreach my $word (@array) { 184000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 185000d1cc1SJoe Perches $word =~ s/^\s*//g; 186000d1cc1SJoe Perches $word =~ s/\s+/ /g; 187000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 188000d1cc1SJoe Perches 189000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 190000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 191000d1cc1SJoe Perches 19291bfe484SJoe Perches $hashRef->{$word}++; 193000d1cc1SJoe Perches } 19491bfe484SJoe Perches} 19591bfe484SJoe Perches 19691bfe484SJoe Perchessub hash_show_words { 19791bfe484SJoe Perches my ($hashRef, $prefix) = @_; 19891bfe484SJoe Perches 19958cb3cf6SJoe Perches if ($quiet == 0 && keys %$hashRef) { 20091bfe484SJoe Perches print "NOTE: $prefix message types:"; 20158cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 20291bfe484SJoe Perches print " $word"; 20391bfe484SJoe Perches } 20491bfe484SJoe Perches print "\n\n"; 20591bfe484SJoe Perches } 20691bfe484SJoe Perches} 20791bfe484SJoe Perches 20891bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 20991bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 210000d1cc1SJoe Perches 211c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 212c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 2137429c690SAndy Whitcroftmy $dbg_type = 0; 214a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 215c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 21621caa13cSAndy Whitcroft ## no critic 21721caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 21821caa13cSAndy Whitcroft die "$@" if ($@); 219c2fdda0dSAndy Whitcroft} 220c2fdda0dSAndy Whitcroft 221d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 222d2c0a235SAndy Whitcroft 2238905a67cSAndy Whitcroftif ($terse) { 2248905a67cSAndy Whitcroft $emacs = 1; 2258905a67cSAndy Whitcroft $quiet++; 2268905a67cSAndy Whitcroft} 2278905a67cSAndy Whitcroft 2286c72ffaaSAndy Whitcroftif ($tree) { 2296c72ffaaSAndy Whitcroft if (defined $root) { 2306c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 2316c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 2326c72ffaaSAndy Whitcroft } 2336c72ffaaSAndy Whitcroft } else { 2346c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 2356c72ffaaSAndy Whitcroft $root = '.'; 2366c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 2376c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 2386c72ffaaSAndy Whitcroft $root = $1; 2396c72ffaaSAndy Whitcroft } 2406c72ffaaSAndy Whitcroft } 2416c72ffaaSAndy Whitcroft 2426c72ffaaSAndy Whitcroft if (!defined $root) { 2430a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 2440a920b5bSAndy Whitcroft exit(2); 2450a920b5bSAndy Whitcroft } 2466c72ffaaSAndy Whitcroft} 2476c72ffaaSAndy Whitcroft 2486c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 2496c72ffaaSAndy Whitcroft 2502ceb532bSAndy Whitcroftour $Ident = qr{ 2512ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 2522ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 2532ceb532bSAndy Whitcroft }x; 2546c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 2556c72ffaaSAndy Whitcroftour $Sparse = qr{ 2566c72ffaaSAndy Whitcroft __user| 2576c72ffaaSAndy Whitcroft __kernel| 2586c72ffaaSAndy Whitcroft __force| 2596c72ffaaSAndy Whitcroft __iomem| 2606c72ffaaSAndy Whitcroft __must_check| 2616c72ffaaSAndy Whitcroft __init_refok| 262417495edSAndy Whitcroft __kprobes| 263165e72a6SSven Eckelmann __ref| 264165e72a6SSven Eckelmann __rcu 2656c72ffaaSAndy Whitcroft }x; 266e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 267e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 268e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 269e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 270e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 2718716de38SJoe Perches 27252131292SWolfram Sang# Notes to $Attribute: 27352131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 2746c72ffaaSAndy Whitcroftour $Attribute = qr{ 2756c72ffaaSAndy Whitcroft const| 27603f1df7dSJoe Perches __percpu| 27703f1df7dSJoe Perches __nocast| 27803f1df7dSJoe Perches __safe| 27903f1df7dSJoe Perches __bitwise__| 28003f1df7dSJoe Perches __packed__| 28103f1df7dSJoe Perches __packed2__| 28203f1df7dSJoe Perches __naked| 28303f1df7dSJoe Perches __maybe_unused| 28403f1df7dSJoe Perches __always_unused| 28503f1df7dSJoe Perches __noreturn| 28603f1df7dSJoe Perches __used| 28703f1df7dSJoe Perches __cold| 288e23ef1f3SJoe Perches __pure| 28903f1df7dSJoe Perches __noclone| 29003f1df7dSJoe Perches __deprecated| 2916c72ffaaSAndy Whitcroft __read_mostly| 2926c72ffaaSAndy Whitcroft __kprobes| 2938716de38SJoe Perches $InitAttribute| 29424e1d81aSAndy Whitcroft ____cacheline_aligned| 29524e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 2965fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 2975fe3af11SAndy Whitcroft __weak 2986c72ffaaSAndy Whitcroft }x; 299c45dcabdSAndy Whitcroftour $Modifier; 30091cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 3016c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 3026c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 3036c72ffaaSAndy Whitcroft 30495e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 30595e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 30695e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 30795e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 3082435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 309c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 310326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 311326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 312326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 31374349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 3142435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 315326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 316447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 31723f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 3186c72ffaaSAndy Whitcroftour $Operators = qr{ 3196c72ffaaSAndy Whitcroft <=|>=|==|!=| 3206c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 32123f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 3226c72ffaaSAndy Whitcroft }x; 3236c72ffaaSAndy Whitcroft 32491cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 32591cb5195SJoe Perches 326ab7e23f3SJoe Perchesour $BasicType; 3278905a67cSAndy Whitcroftour $NonptrType; 3281813087dSJoe Perchesour $NonptrTypeMisordered; 3298716de38SJoe Perchesour $NonptrTypeWithAttr; 3308905a67cSAndy Whitcroftour $Type; 3311813087dSJoe Perchesour $TypeMisordered; 3328905a67cSAndy Whitcroftour $Declare; 3331813087dSJoe Perchesour $DeclareMisordered; 3348905a67cSAndy Whitcroft 33515662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 33615662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 337171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 338171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 339171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 340171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 341171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 342171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 343171ae1a4SAndy Whitcroft}x; 344171ae1a4SAndy Whitcroft 34515662b3eSJoe Perchesour $UTF8 = qr{ 34615662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 34715662b3eSJoe Perches | $NON_ASCII_UTF8 34815662b3eSJoe Perches}x; 34915662b3eSJoe Perches 350e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 351021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 352021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 353021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 354021158b4SJoe Perches)}; 355e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 356fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 3578ed22cadSAndy Whitcroft atomic_t 3588ed22cadSAndy Whitcroft)}; 359e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 360e6176fa4SJoe Perches $typeC99Typedefs\b| 361e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 362e6176fa4SJoe Perches $typeKernelTypedefs\b 363e6176fa4SJoe Perches)}; 3648ed22cadSAndy Whitcroft 365691e669bSJoe Perchesour $logFunctions = qr{(?x: 3666e60c02eSJoe Perches printk(?:_ratelimited|_once|)| 3677d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 3686e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 369b0531722SJoe Perches panic| 37006668727SJoe Perches MODULE_[A-Z_]+| 37106668727SJoe Perches seq_vprintf|seq_printf|seq_puts 372691e669bSJoe Perches)}; 373691e669bSJoe Perches 37420112475SJoe Perchesour $signature_tags = qr{(?xi: 37520112475SJoe Perches Signed-off-by:| 37620112475SJoe Perches Acked-by:| 37720112475SJoe Perches Tested-by:| 37820112475SJoe Perches Reviewed-by:| 37920112475SJoe Perches Reported-by:| 3808543ae12SMugunthan V N Suggested-by:| 38120112475SJoe Perches To:| 38220112475SJoe Perches Cc: 38320112475SJoe Perches)}; 38420112475SJoe Perches 3851813087dSJoe Perchesour @typeListMisordered = ( 3861813087dSJoe Perches qr{char\s+(?:un)?signed}, 3871813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 3881813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 3891813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 3901813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 3911813087dSJoe Perches qr{short\s+(?:un)?signed}, 3921813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 3931813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 3941813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 3951813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 3961813087dSJoe Perches qr{int\s+(?:un)?signed}, 3971813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 3981813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 3991813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 4001813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 4011813087dSJoe Perches qr{long\s+(?:un)?signed}, 4021813087dSJoe Perches); 4031813087dSJoe Perches 4048905a67cSAndy Whitcroftour @typeList = ( 4058905a67cSAndy Whitcroft qr{void}, 4060c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 4070c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 4080c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 4090c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 4100c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 4110c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 4120c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 4130c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 4140c773d9dSJoe Perches qr{(?:un)?signed}, 4158905a67cSAndy Whitcroft qr{float}, 4168905a67cSAndy Whitcroft qr{double}, 4178905a67cSAndy Whitcroft qr{bool}, 4188905a67cSAndy Whitcroft qr{struct\s+$Ident}, 4198905a67cSAndy Whitcroft qr{union\s+$Ident}, 4208905a67cSAndy Whitcroft qr{enum\s+$Ident}, 4218905a67cSAndy Whitcroft qr{${Ident}_t}, 4228905a67cSAndy Whitcroft qr{${Ident}_handler}, 4238905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 4241813087dSJoe Perches @typeListMisordered, 4258905a67cSAndy Whitcroft); 426*485ff23eSAlex Dowadour @typeListFile = (); 4278716de38SJoe Perchesour @typeListWithAttr = ( 4288716de38SJoe Perches @typeList, 4298716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 4308716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 4318716de38SJoe Perches); 4328716de38SJoe Perches 433c45dcabdSAndy Whitcroftour @modifierList = ( 434c45dcabdSAndy Whitcroft qr{fastcall}, 435c45dcabdSAndy Whitcroft); 436*485ff23eSAlex Dowadour @modifierListFile = (); 4378905a67cSAndy Whitcroft 4382435880fSJoe Perchesour @mode_permission_funcs = ( 4392435880fSJoe Perches ["module_param", 3], 4402435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 4412435880fSJoe Perches ["module_param_array_named", 5], 4422435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 4432435880fSJoe Perches ["proc_create(?:_data|)", 2], 4442435880fSJoe Perches ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2], 4452435880fSJoe Perches); 4462435880fSJoe Perches 447515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 448515a235eSJoe Perchesour $mode_perms_search = ""; 449515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 450515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 451515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 452515a235eSJoe Perches} 453515a235eSJoe Perches 454b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 455b392c64fSJoe Perches S_IWUGO | 456b392c64fSJoe Perches S_IWOTH | 457b392c64fSJoe Perches S_IRWXUGO | 458b392c64fSJoe Perches S_IALLUGO | 459b392c64fSJoe Perches 0[0-7][0-7][2367] 460b392c64fSJoe Perches}x; 461b392c64fSJoe Perches 4627840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 4637840a94cSWolfram Sang irq| 464cdcee686SSergey Ryazanov memory| 465cdcee686SSergey Ryazanov time| 466cdcee686SSergey Ryazanov reboot 4677840a94cSWolfram Sang)}; 4687840a94cSWolfram Sang# memory.h: ARM has a custom one 4697840a94cSWolfram Sang 47066b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 47166b47b4aSKees Cookmy $misspellings; 47266b47b4aSKees Cookmy %spelling_fix; 47336061e38SJoe Perches 47436061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 47566b47b4aSKees Cook while (<$spelling>) { 47666b47b4aSKees Cook my $line = $_; 47766b47b4aSKees Cook 47866b47b4aSKees Cook $line =~ s/\s*\n?$//g; 47966b47b4aSKees Cook $line =~ s/^\s*//g; 48066b47b4aSKees Cook 48166b47b4aSKees Cook next if ($line =~ m/^\s*#/); 48266b47b4aSKees Cook next if ($line =~ m/^\s*$/); 48366b47b4aSKees Cook 48466b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 48566b47b4aSKees Cook 48666b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 48766b47b4aSKees Cook } 48866b47b4aSKees Cook close($spelling); 48936061e38SJoe Perches} else { 49036061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 49136061e38SJoe Perches} 49266b47b4aSKees Cook 493ebfd7d62SJoe Perchesif ($codespell) { 494ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 495ebfd7d62SJoe Perches while (<$spelling>) { 496ebfd7d62SJoe Perches my $line = $_; 497ebfd7d62SJoe Perches 498ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 499ebfd7d62SJoe Perches $line =~ s/^\s*//g; 500ebfd7d62SJoe Perches 501ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 502ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 503ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 504ebfd7d62SJoe Perches 505ebfd7d62SJoe Perches $line =~ s/,.*$//; 506ebfd7d62SJoe Perches 507ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 508ebfd7d62SJoe Perches 509ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 510ebfd7d62SJoe Perches } 511ebfd7d62SJoe Perches close($spelling); 512ebfd7d62SJoe Perches } else { 513ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 514ebfd7d62SJoe Perches } 515ebfd7d62SJoe Perches} 516ebfd7d62SJoe Perches 517ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 518ebfd7d62SJoe Perches 5198905a67cSAndy Whitcroftsub build_types { 520*485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 521*485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 5221813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 5238716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 524c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 525ab7e23f3SJoe Perches $BasicType = qr{ 526ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 527ab7e23f3SJoe Perches (?:${all}\b) 528ab7e23f3SJoe Perches }x; 5298905a67cSAndy Whitcroft $NonptrType = qr{ 530d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 531cf655043SAndy Whitcroft (?: 5326b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 5338ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 534c45dcabdSAndy Whitcroft (?:${all}\b) 535cf655043SAndy Whitcroft ) 536c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 5378905a67cSAndy Whitcroft }x; 5381813087dSJoe Perches $NonptrTypeMisordered = qr{ 5391813087dSJoe Perches (?:$Modifier\s+|const\s+)* 5401813087dSJoe Perches (?: 5411813087dSJoe Perches (?:${Misordered}\b) 5421813087dSJoe Perches ) 5431813087dSJoe Perches (?:\s+$Modifier|\s+const)* 5441813087dSJoe Perches }x; 5458716de38SJoe Perches $NonptrTypeWithAttr = qr{ 5468716de38SJoe Perches (?:$Modifier\s+|const\s+)* 5478716de38SJoe Perches (?: 5488716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 5498716de38SJoe Perches (?:$typeTypedefs\b)| 5508716de38SJoe Perches (?:${allWithAttr}\b) 5518716de38SJoe Perches ) 5528716de38SJoe Perches (?:\s+$Modifier|\s+const)* 5538716de38SJoe Perches }x; 5548905a67cSAndy Whitcroft $Type = qr{ 555c45dcabdSAndy Whitcroft $NonptrType 5561574a29fSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 557c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 5588905a67cSAndy Whitcroft }x; 5591813087dSJoe Perches $TypeMisordered = qr{ 5601813087dSJoe Perches $NonptrTypeMisordered 5611813087dSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 5621813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 5631813087dSJoe Perches }x; 56491cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 5651813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 5668905a67cSAndy Whitcroft} 5678905a67cSAndy Whitcroftbuild_types(); 5686c72ffaaSAndy Whitcroft 5697d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 570d1fe9c09SJoe Perches 571d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 572d1fe9c09SJoe Perches# requires at least perl version v5.10.0 573d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 574d1fe9c09SJoe Perches 575d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 5762435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 577c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 5787d2367afSJoe Perches 579f8422308SJoe Perchesour $declaration_macros = qr{(?x: 580f8422308SJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,2}\s*\(| 581f8422308SJoe Perches (?:$Storage\s+)?LIST_HEAD\s*\(| 582f8422308SJoe Perches (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( 583f8422308SJoe Perches)}; 584f8422308SJoe Perches 5857d2367afSJoe Perchessub deparenthesize { 5867d2367afSJoe Perches my ($string) = @_; 5877d2367afSJoe Perches return "" if (!defined($string)); 5885b9553abSJoe Perches 5895b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 5905b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 5915b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 5925b9553abSJoe Perches } 5935b9553abSJoe Perches 5947d2367afSJoe Perches $string =~ s@\s+@ @g; 5955b9553abSJoe Perches 5967d2367afSJoe Perches return $string; 5977d2367afSJoe Perches} 5987d2367afSJoe Perches 5993445686aSJoe Perchessub seed_camelcase_file { 6003445686aSJoe Perches my ($file) = @_; 6013445686aSJoe Perches 6023445686aSJoe Perches return if (!(-f $file)); 6033445686aSJoe Perches 6043445686aSJoe Perches local $/; 6053445686aSJoe Perches 6063445686aSJoe Perches open(my $include_file, '<', "$file") 6073445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 6083445686aSJoe Perches my $text = <$include_file>; 6093445686aSJoe Perches close($include_file); 6103445686aSJoe Perches 6113445686aSJoe Perches my @lines = split('\n', $text); 6123445686aSJoe Perches 6133445686aSJoe Perches foreach my $line (@lines) { 6143445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 6153445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 6163445686aSJoe Perches $camelcase{$1} = 1; 61711ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 61811ea516aSJoe Perches $camelcase{$1} = 1; 61911ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 6203445686aSJoe Perches $camelcase{$1} = 1; 6213445686aSJoe Perches } 6223445686aSJoe Perches } 6233445686aSJoe Perches} 6243445686aSJoe Perches 6253445686aSJoe Perchesmy $camelcase_seeded = 0; 6263445686aSJoe Perchessub seed_camelcase_includes { 6273445686aSJoe Perches return if ($camelcase_seeded); 6283445686aSJoe Perches 6293445686aSJoe Perches my $files; 630c707a81dSJoe Perches my $camelcase_cache = ""; 631c707a81dSJoe Perches my @include_files = (); 632c707a81dSJoe Perches 633c707a81dSJoe Perches $camelcase_seeded = 1; 634351b2a1fSJoe Perches 6353645e328SRichard Genoud if (-e ".git") { 636351b2a1fSJoe Perches my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; 637351b2a1fSJoe Perches chomp $git_last_include_commit; 638c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 639c707a81dSJoe Perches } else { 640c707a81dSJoe Perches my $last_mod_date = 0; 641c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 642c707a81dSJoe Perches @include_files = split('\n', $files); 643c707a81dSJoe Perches foreach my $file (@include_files) { 644c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 645c707a81dSJoe Perches localtime((stat $file)[9])); 646c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 647c707a81dSJoe Perches } 648c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 649c707a81dSJoe Perches } 650c707a81dSJoe Perches 651c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 652c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 653c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 654351b2a1fSJoe Perches while (<$camelcase_file>) { 655351b2a1fSJoe Perches chomp; 656351b2a1fSJoe Perches $camelcase{$_} = 1; 657351b2a1fSJoe Perches } 658351b2a1fSJoe Perches close($camelcase_file); 659351b2a1fSJoe Perches 660351b2a1fSJoe Perches return; 661351b2a1fSJoe Perches } 662c707a81dSJoe Perches 6633645e328SRichard Genoud if (-e ".git") { 664c707a81dSJoe Perches $files = `git ls-files "include/*.h"`; 665c707a81dSJoe Perches @include_files = split('\n', $files); 6663445686aSJoe Perches } 667c707a81dSJoe Perches 6683445686aSJoe Perches foreach my $file (@include_files) { 6693445686aSJoe Perches seed_camelcase_file($file); 6703445686aSJoe Perches } 671351b2a1fSJoe Perches 672c707a81dSJoe Perches if ($camelcase_cache ne "") { 673351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 674c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 675c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 676351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 677351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 678351b2a1fSJoe Perches } 679351b2a1fSJoe Perches close($camelcase_file); 680351b2a1fSJoe Perches } 6813445686aSJoe Perches} 6823445686aSJoe Perches 683d311cd44SJoe Perchessub git_commit_info { 684d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 685d311cd44SJoe Perches 686d311cd44SJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 687d311cd44SJoe Perches 688d311cd44SJoe Perches my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; 689d311cd44SJoe Perches $output =~ s/^\s*//gm; 690d311cd44SJoe Perches my @lines = split("\n", $output); 691d311cd44SJoe Perches 6920d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 6930d7835fcSJoe Perches 694d311cd44SJoe Perches if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { 695d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 696d311cd44SJoe Perches# all matching commit ids, but it's very slow... 697d311cd44SJoe Perches# 698d311cd44SJoe Perches# echo "checking commits $1..." 699d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 700d311cd44SJoe Perches# while read line ; do 701d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 702d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 703d311cd44SJoe Perches# done 704d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 705d311cd44SJoe Perches } else { 706d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 707d311cd44SJoe Perches $desc = substr($lines[0], 41); 708d311cd44SJoe Perches } 709d311cd44SJoe Perches 710d311cd44SJoe Perches return ($id, $desc); 711d311cd44SJoe Perches} 712d311cd44SJoe Perches 7136c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 7140a920b5bSAndy Whitcroft 71500df344fSAndy Whitcroftmy @rawlines = (); 716c2fdda0dSAndy Whitcroftmy @lines = (); 7173705ce5bSJoe Perchesmy @fixed = (); 718d752fcc8SJoe Perchesmy @fixed_inserted = (); 719d752fcc8SJoe Perchesmy @fixed_deleted = (); 720194f66fcSJoe Perchesmy $fixlinenr = -1; 721194f66fcSJoe Perches 722c2fdda0dSAndy Whitcroftmy $vname; 7236c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 72421caa13cSAndy Whitcroft my $FILE; 7256c72ffaaSAndy Whitcroft if ($file) { 72621caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 7276c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 72821caa13cSAndy Whitcroft } elsif ($filename eq '-') { 72921caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 7306c72ffaaSAndy Whitcroft } else { 73121caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 7326c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 7336c72ffaaSAndy Whitcroft } 734c2fdda0dSAndy Whitcroft if ($filename eq '-') { 735c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 736c2fdda0dSAndy Whitcroft } else { 737c2fdda0dSAndy Whitcroft $vname = $filename; 738c2fdda0dSAndy Whitcroft } 73921caa13cSAndy Whitcroft while (<$FILE>) { 7400a920b5bSAndy Whitcroft chomp; 74100df344fSAndy Whitcroft push(@rawlines, $_); 7426c72ffaaSAndy Whitcroft } 74321caa13cSAndy Whitcroft close($FILE); 744c2fdda0dSAndy Whitcroft if (!process($filename)) { 7450a920b5bSAndy Whitcroft $exit = 1; 7460a920b5bSAndy Whitcroft } 74700df344fSAndy Whitcroft @rawlines = (); 74813214adfSAndy Whitcroft @lines = (); 7493705ce5bSJoe Perches @fixed = (); 750d752fcc8SJoe Perches @fixed_inserted = (); 751d752fcc8SJoe Perches @fixed_deleted = (); 752194f66fcSJoe Perches $fixlinenr = -1; 753*485ff23eSAlex Dowad @modifierListFile = (); 754*485ff23eSAlex Dowad @typeListFile = (); 755*485ff23eSAlex Dowad build_types(); 7560a920b5bSAndy Whitcroft} 7570a920b5bSAndy Whitcroft 7580a920b5bSAndy Whitcroftexit($exit); 7590a920b5bSAndy Whitcroft 7600a920b5bSAndy Whitcroftsub top_of_kernel_tree { 7616c72ffaaSAndy Whitcroft my ($root) = @_; 7626c72ffaaSAndy Whitcroft 7636c72ffaaSAndy Whitcroft my @tree_check = ( 7646c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 7656c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 7666c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 7676c72ffaaSAndy Whitcroft ); 7686c72ffaaSAndy Whitcroft 7696c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 7706c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 7710a920b5bSAndy Whitcroft return 0; 7720a920b5bSAndy Whitcroft } 7736c72ffaaSAndy Whitcroft } 7746c72ffaaSAndy Whitcroft return 1; 7756c72ffaaSAndy Whitcroft} 7760a920b5bSAndy Whitcroft 77720112475SJoe Perchessub parse_email { 77820112475SJoe Perches my ($formatted_email) = @_; 77920112475SJoe Perches 78020112475SJoe Perches my $name = ""; 78120112475SJoe Perches my $address = ""; 78220112475SJoe Perches my $comment = ""; 78320112475SJoe Perches 78420112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 78520112475SJoe Perches $name = $1; 78620112475SJoe Perches $address = $2; 78720112475SJoe Perches $comment = $3 if defined $3; 78820112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 78920112475SJoe Perches $address = $1; 79020112475SJoe Perches $comment = $2 if defined $2; 79120112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 79220112475SJoe Perches $address = $1; 79320112475SJoe Perches $comment = $2 if defined $2; 79420112475SJoe Perches $formatted_email =~ s/$address.*$//; 79520112475SJoe Perches $name = $formatted_email; 7963705ce5bSJoe Perches $name = trim($name); 79720112475SJoe Perches $name =~ s/^\"|\"$//g; 79820112475SJoe Perches # If there's a name left after stripping spaces and 79920112475SJoe Perches # leading quotes, and the address doesn't have both 80020112475SJoe Perches # leading and trailing angle brackets, the address 80120112475SJoe Perches # is invalid. ie: 80220112475SJoe Perches # "joe smith [email protected]" bad 80320112475SJoe Perches # "joe smith <[email protected]" bad 80420112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 80520112475SJoe Perches $name = ""; 80620112475SJoe Perches $address = ""; 80720112475SJoe Perches $comment = ""; 80820112475SJoe Perches } 80920112475SJoe Perches } 81020112475SJoe Perches 8113705ce5bSJoe Perches $name = trim($name); 81220112475SJoe Perches $name =~ s/^\"|\"$//g; 8133705ce5bSJoe Perches $address = trim($address); 81420112475SJoe Perches $address =~ s/^\<|\>$//g; 81520112475SJoe Perches 81620112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 81720112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 81820112475SJoe Perches $name = "\"$name\""; 81920112475SJoe Perches } 82020112475SJoe Perches 82120112475SJoe Perches return ($name, $address, $comment); 82220112475SJoe Perches} 82320112475SJoe Perches 82420112475SJoe Perchessub format_email { 82520112475SJoe Perches my ($name, $address) = @_; 82620112475SJoe Perches 82720112475SJoe Perches my $formatted_email; 82820112475SJoe Perches 8293705ce5bSJoe Perches $name = trim($name); 83020112475SJoe Perches $name =~ s/^\"|\"$//g; 8313705ce5bSJoe Perches $address = trim($address); 83220112475SJoe Perches 83320112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 83420112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 83520112475SJoe Perches $name = "\"$name\""; 83620112475SJoe Perches } 83720112475SJoe Perches 83820112475SJoe Perches if ("$name" eq "") { 83920112475SJoe Perches $formatted_email = "$address"; 84020112475SJoe Perches } else { 84120112475SJoe Perches $formatted_email = "$name <$address>"; 84220112475SJoe Perches } 84320112475SJoe Perches 84420112475SJoe Perches return $formatted_email; 84520112475SJoe Perches} 84620112475SJoe Perches 847d311cd44SJoe Perchessub which { 848d311cd44SJoe Perches my ($bin) = @_; 849d311cd44SJoe Perches 850d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 851d311cd44SJoe Perches if (-e "$path/$bin") { 852d311cd44SJoe Perches return "$path/$bin"; 853d311cd44SJoe Perches } 854d311cd44SJoe Perches } 855d311cd44SJoe Perches 856d311cd44SJoe Perches return ""; 857d311cd44SJoe Perches} 858d311cd44SJoe Perches 859000d1cc1SJoe Perchessub which_conf { 860000d1cc1SJoe Perches my ($conf) = @_; 861000d1cc1SJoe Perches 862000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 863000d1cc1SJoe Perches if (-e "$path/$conf") { 864000d1cc1SJoe Perches return "$path/$conf"; 865000d1cc1SJoe Perches } 866000d1cc1SJoe Perches } 867000d1cc1SJoe Perches 868000d1cc1SJoe Perches return ""; 869000d1cc1SJoe Perches} 870000d1cc1SJoe Perches 8710a920b5bSAndy Whitcroftsub expand_tabs { 8720a920b5bSAndy Whitcroft my ($str) = @_; 8730a920b5bSAndy Whitcroft 8740a920b5bSAndy Whitcroft my $res = ''; 8750a920b5bSAndy Whitcroft my $n = 0; 8760a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 8770a920b5bSAndy Whitcroft if ($c eq "\t") { 8780a920b5bSAndy Whitcroft $res .= ' '; 8790a920b5bSAndy Whitcroft $n++; 8800a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 8810a920b5bSAndy Whitcroft $res .= ' '; 8820a920b5bSAndy Whitcroft } 8830a920b5bSAndy Whitcroft next; 8840a920b5bSAndy Whitcroft } 8850a920b5bSAndy Whitcroft $res .= $c; 8860a920b5bSAndy Whitcroft $n++; 8870a920b5bSAndy Whitcroft } 8880a920b5bSAndy Whitcroft 8890a920b5bSAndy Whitcroft return $res; 8900a920b5bSAndy Whitcroft} 8916c72ffaaSAndy Whitcroftsub copy_spacing { 892773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 8936c72ffaaSAndy Whitcroft return $res; 8946c72ffaaSAndy Whitcroft} 8950a920b5bSAndy Whitcroft 8964a0df2efSAndy Whitcroftsub line_stats { 8974a0df2efSAndy Whitcroft my ($line) = @_; 8984a0df2efSAndy Whitcroft 8994a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 9004a0df2efSAndy Whitcroft $line =~ s/^.//; 9014a0df2efSAndy Whitcroft $line = expand_tabs($line); 9024a0df2efSAndy Whitcroft 9034a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 9044a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 9054a0df2efSAndy Whitcroft 9064a0df2efSAndy Whitcroft return (length($line), length($white)); 9074a0df2efSAndy Whitcroft} 9084a0df2efSAndy Whitcroft 909773647a0SAndy Whitcroftmy $sanitise_quote = ''; 910773647a0SAndy Whitcroft 911773647a0SAndy Whitcroftsub sanitise_line_reset { 912773647a0SAndy Whitcroft my ($in_comment) = @_; 913773647a0SAndy Whitcroft 914773647a0SAndy Whitcroft if ($in_comment) { 915773647a0SAndy Whitcroft $sanitise_quote = '*/'; 916773647a0SAndy Whitcroft } else { 917773647a0SAndy Whitcroft $sanitise_quote = ''; 918773647a0SAndy Whitcroft } 919773647a0SAndy Whitcroft} 92000df344fSAndy Whitcroftsub sanitise_line { 92100df344fSAndy Whitcroft my ($line) = @_; 92200df344fSAndy Whitcroft 92300df344fSAndy Whitcroft my $res = ''; 92400df344fSAndy Whitcroft my $l = ''; 92500df344fSAndy Whitcroft 926c2fdda0dSAndy Whitcroft my $qlen = 0; 927773647a0SAndy Whitcroft my $off = 0; 928773647a0SAndy Whitcroft my $c; 92900df344fSAndy Whitcroft 930773647a0SAndy Whitcroft # Always copy over the diff marker. 931773647a0SAndy Whitcroft $res = substr($line, 0, 1); 932773647a0SAndy Whitcroft 933773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 934773647a0SAndy Whitcroft $c = substr($line, $off, 1); 935773647a0SAndy Whitcroft 936773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 937773647a0SAndy Whitcroft # and end, all to $;. 938773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 939773647a0SAndy Whitcroft $sanitise_quote = '*/'; 940773647a0SAndy Whitcroft 941773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 942773647a0SAndy Whitcroft $off++; 94300df344fSAndy Whitcroft next; 944773647a0SAndy Whitcroft } 94581bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 946773647a0SAndy Whitcroft $sanitise_quote = ''; 947773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 948773647a0SAndy Whitcroft $off++; 949773647a0SAndy Whitcroft next; 950773647a0SAndy Whitcroft } 951113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 952113f04a8SDaniel Walker $sanitise_quote = '//'; 953113f04a8SDaniel Walker 954113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 955113f04a8SDaniel Walker $off++; 956113f04a8SDaniel Walker next; 957113f04a8SDaniel Walker } 958773647a0SAndy Whitcroft 959773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 960773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 961773647a0SAndy Whitcroft $c eq "\\") { 962773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 963773647a0SAndy Whitcroft $off++; 964773647a0SAndy Whitcroft next; 965773647a0SAndy Whitcroft } 966773647a0SAndy Whitcroft # Regular quotes. 967773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 968773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 969773647a0SAndy Whitcroft $sanitise_quote = $c; 970773647a0SAndy Whitcroft 971773647a0SAndy Whitcroft substr($res, $off, 1, $c); 972773647a0SAndy Whitcroft next; 973773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 974773647a0SAndy Whitcroft $sanitise_quote = ''; 97500df344fSAndy Whitcroft } 97600df344fSAndy Whitcroft } 977773647a0SAndy Whitcroft 978fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 979773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 980773647a0SAndy Whitcroft substr($res, $off, 1, $;); 981113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 982113f04a8SDaniel Walker substr($res, $off, 1, $;); 983773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 984773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 98500df344fSAndy Whitcroft } else { 986773647a0SAndy Whitcroft substr($res, $off, 1, $c); 98700df344fSAndy Whitcroft } 988c2fdda0dSAndy Whitcroft } 989c2fdda0dSAndy Whitcroft 990113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 991113f04a8SDaniel Walker $sanitise_quote = ''; 992113f04a8SDaniel Walker } 993113f04a8SDaniel Walker 994c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 995c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 996c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 997c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 998c2fdda0dSAndy Whitcroft 999c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1000c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1001c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1002c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1003c2fdda0dSAndy Whitcroft } 1004c2fdda0dSAndy Whitcroft 100500df344fSAndy Whitcroft return $res; 100600df344fSAndy Whitcroft} 100700df344fSAndy Whitcroft 1008a6962d72SJoe Perchessub get_quoted_string { 1009a6962d72SJoe Perches my ($line, $rawline) = @_; 1010a6962d72SJoe Perches 10115e4f6ba5SJoe Perches return "" if ($line !~ m/(\"[X\t]+\")/g); 1012a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1013a6962d72SJoe Perches} 1014a6962d72SJoe Perches 10158905a67cSAndy Whitcroftsub ctx_statement_block { 10168905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 10178905a67cSAndy Whitcroft my $line = $linenr - 1; 10188905a67cSAndy Whitcroft my $blk = ''; 10198905a67cSAndy Whitcroft my $soff = $off; 10208905a67cSAndy Whitcroft my $coff = $off - 1; 1021773647a0SAndy Whitcroft my $coff_set = 0; 10228905a67cSAndy Whitcroft 102313214adfSAndy Whitcroft my $loff = 0; 102413214adfSAndy Whitcroft 10258905a67cSAndy Whitcroft my $type = ''; 10268905a67cSAndy Whitcroft my $level = 0; 1027a2750645SAndy Whitcroft my @stack = (); 1028cf655043SAndy Whitcroft my $p; 10298905a67cSAndy Whitcroft my $c; 10308905a67cSAndy Whitcroft my $len = 0; 103113214adfSAndy Whitcroft 103213214adfSAndy Whitcroft my $remainder; 10338905a67cSAndy Whitcroft while (1) { 1034a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1035a2750645SAndy Whitcroft 1036773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 10378905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 10388905a67cSAndy Whitcroft # context. 10398905a67cSAndy Whitcroft if ($off >= $len) { 10408905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1041dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1042c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 10438905a67cSAndy Whitcroft $remain--; 104413214adfSAndy Whitcroft $loff = $len; 1045c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 10468905a67cSAndy Whitcroft $len = length($blk); 10478905a67cSAndy Whitcroft $line++; 10488905a67cSAndy Whitcroft last; 10498905a67cSAndy Whitcroft } 10508905a67cSAndy Whitcroft # Bail if there is no further context. 10518905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 105213214adfSAndy Whitcroft if ($off >= $len) { 10538905a67cSAndy Whitcroft last; 10548905a67cSAndy Whitcroft } 1055f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1056f74bd194SAndy Whitcroft $level++; 1057f74bd194SAndy Whitcroft $type = '#'; 1058f74bd194SAndy Whitcroft } 10598905a67cSAndy Whitcroft } 1060cf655043SAndy Whitcroft $p = $c; 10618905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 106213214adfSAndy Whitcroft $remainder = substr($blk, $off); 10638905a67cSAndy Whitcroft 1064773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 10654635f4fbSAndy Whitcroft 10664635f4fbSAndy Whitcroft # Handle nested #if/#else. 10674635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 10684635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 10694635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 10704635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 10714635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 10724635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 10734635f4fbSAndy Whitcroft } 10744635f4fbSAndy Whitcroft 10758905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 10768905a67cSAndy Whitcroft # outermost level. 10778905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 10788905a67cSAndy Whitcroft last; 10798905a67cSAndy Whitcroft } 10808905a67cSAndy Whitcroft 108113214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1082773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1083773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1084773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1085773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1086773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1087773647a0SAndy Whitcroft $coff_set = 1; 1088773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1089773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 109013214adfSAndy Whitcroft } 109113214adfSAndy Whitcroft 10928905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 10938905a67cSAndy Whitcroft $level++; 10948905a67cSAndy Whitcroft $type = '('; 10958905a67cSAndy Whitcroft } 10968905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 10978905a67cSAndy Whitcroft $level--; 10988905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 10998905a67cSAndy Whitcroft 11008905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 11018905a67cSAndy Whitcroft $coff = $off; 1102773647a0SAndy Whitcroft $coff_set = 1; 1103773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 11048905a67cSAndy Whitcroft } 11058905a67cSAndy Whitcroft } 11068905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 11078905a67cSAndy Whitcroft $level++; 11088905a67cSAndy Whitcroft $type = '{'; 11098905a67cSAndy Whitcroft } 11108905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 11118905a67cSAndy Whitcroft $level--; 11128905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 11138905a67cSAndy Whitcroft 11148905a67cSAndy Whitcroft if ($level == 0) { 1115b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1116b998e001SPatrick Pannuto $off++; 1117b998e001SPatrick Pannuto } 11188905a67cSAndy Whitcroft last; 11198905a67cSAndy Whitcroft } 11208905a67cSAndy Whitcroft } 1121f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1122f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1123f74bd194SAndy Whitcroft $level--; 1124f74bd194SAndy Whitcroft $type = ''; 1125f74bd194SAndy Whitcroft $off++; 1126f74bd194SAndy Whitcroft last; 1127f74bd194SAndy Whitcroft } 11288905a67cSAndy Whitcroft $off++; 11298905a67cSAndy Whitcroft } 1130a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 113113214adfSAndy Whitcroft if ($off == $len) { 1132a3bb97a7SAndy Whitcroft $loff = $len + 1; 113313214adfSAndy Whitcroft $line++; 113413214adfSAndy Whitcroft $remain--; 113513214adfSAndy Whitcroft } 11368905a67cSAndy Whitcroft 11378905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 11388905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 11398905a67cSAndy Whitcroft 11408905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 11418905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 11428905a67cSAndy Whitcroft 1143773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 114413214adfSAndy Whitcroft 114513214adfSAndy Whitcroft return ($statement, $condition, 114613214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 114713214adfSAndy Whitcroft} 114813214adfSAndy Whitcroft 1149cf655043SAndy Whitcroftsub statement_lines { 1150cf655043SAndy Whitcroft my ($stmt) = @_; 1151cf655043SAndy Whitcroft 1152cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1153cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1154cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1155cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1156cf655043SAndy Whitcroft 1157cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1158cf655043SAndy Whitcroft 1159cf655043SAndy Whitcroft return $#stmt_lines + 2; 1160cf655043SAndy Whitcroft} 1161cf655043SAndy Whitcroft 1162cf655043SAndy Whitcroftsub statement_rawlines { 1163cf655043SAndy Whitcroft my ($stmt) = @_; 1164cf655043SAndy Whitcroft 1165cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1166cf655043SAndy Whitcroft 1167cf655043SAndy Whitcroft return $#stmt_lines + 2; 1168cf655043SAndy Whitcroft} 1169cf655043SAndy Whitcroft 1170cf655043SAndy Whitcroftsub statement_block_size { 1171cf655043SAndy Whitcroft my ($stmt) = @_; 1172cf655043SAndy Whitcroft 1173cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1174cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1175cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1176cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1177cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1178cf655043SAndy Whitcroft 1179cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1180cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1181cf655043SAndy Whitcroft 1182cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1183cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1184cf655043SAndy Whitcroft 1185cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1186cf655043SAndy Whitcroft return $stmt_lines; 1187cf655043SAndy Whitcroft } else { 1188cf655043SAndy Whitcroft return $stmt_statements; 1189cf655043SAndy Whitcroft } 1190cf655043SAndy Whitcroft} 1191cf655043SAndy Whitcroft 119213214adfSAndy Whitcroftsub ctx_statement_full { 119313214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 119413214adfSAndy Whitcroft my ($statement, $condition, $level); 119513214adfSAndy Whitcroft 119613214adfSAndy Whitcroft my (@chunks); 119713214adfSAndy Whitcroft 1198cf655043SAndy Whitcroft # Grab the first conditional/block pair. 119913214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 120013214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1201773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 120213214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1203cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1204cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1205cf655043SAndy Whitcroft } 1206cf655043SAndy Whitcroft 1207cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1208cf655043SAndy Whitcroft # could continue the statement. 1209cf655043SAndy Whitcroft for (;;) { 121013214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 121113214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1212cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1213773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1214cf655043SAndy Whitcroft #print "C: push\n"; 1215cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 121613214adfSAndy Whitcroft } 121713214adfSAndy Whitcroft 121813214adfSAndy Whitcroft return ($level, $linenr, @chunks); 12198905a67cSAndy Whitcroft} 12208905a67cSAndy Whitcroft 12214a0df2efSAndy Whitcroftsub ctx_block_get { 1222f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 12234a0df2efSAndy Whitcroft my $line; 12244a0df2efSAndy Whitcroft my $start = $linenr - 1; 12254a0df2efSAndy Whitcroft my $blk = ''; 12264a0df2efSAndy Whitcroft my @o; 12274a0df2efSAndy Whitcroft my @c; 12284a0df2efSAndy Whitcroft my @res = (); 12294a0df2efSAndy Whitcroft 1230f0a594c1SAndy Whitcroft my $level = 0; 12314635f4fbSAndy Whitcroft my @stack = ($level); 123200df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 123300df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 123400df344fSAndy Whitcroft $remain--; 123500df344fSAndy Whitcroft 123600df344fSAndy Whitcroft $blk .= $rawlines[$line]; 12374635f4fbSAndy Whitcroft 12384635f4fbSAndy Whitcroft # Handle nested #if/#else. 123901464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 12404635f4fbSAndy Whitcroft push(@stack, $level); 124101464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 12424635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 124301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 12444635f4fbSAndy Whitcroft $level = pop(@stack); 12454635f4fbSAndy Whitcroft } 12464635f4fbSAndy Whitcroft 124701464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1248f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1249f0a594c1SAndy Whitcroft if ($off > 0) { 1250f0a594c1SAndy Whitcroft $off--; 1251f0a594c1SAndy Whitcroft next; 1252f0a594c1SAndy Whitcroft } 12534a0df2efSAndy Whitcroft 1254f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1255f0a594c1SAndy Whitcroft $level--; 1256f0a594c1SAndy Whitcroft last if ($level == 0); 1257f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1258f0a594c1SAndy Whitcroft $level++; 1259f0a594c1SAndy Whitcroft } 1260f0a594c1SAndy Whitcroft } 12614a0df2efSAndy Whitcroft 1262f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 126300df344fSAndy Whitcroft push(@res, $rawlines[$line]); 12644a0df2efSAndy Whitcroft } 12654a0df2efSAndy Whitcroft 1266f0a594c1SAndy Whitcroft last if ($level == 0); 12674a0df2efSAndy Whitcroft } 12684a0df2efSAndy Whitcroft 1269f0a594c1SAndy Whitcroft return ($level, @res); 12704a0df2efSAndy Whitcroft} 12714a0df2efSAndy Whitcroftsub ctx_block_outer { 12724a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 12734a0df2efSAndy Whitcroft 1274f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1275f0a594c1SAndy Whitcroft return @r; 12764a0df2efSAndy Whitcroft} 12774a0df2efSAndy Whitcroftsub ctx_block { 12784a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 12794a0df2efSAndy Whitcroft 1280f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1281f0a594c1SAndy Whitcroft return @r; 1282653d4876SAndy Whitcroft} 1283653d4876SAndy Whitcroftsub ctx_statement { 1284f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1285f0a594c1SAndy Whitcroft 1286f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1287f0a594c1SAndy Whitcroft return @r; 1288f0a594c1SAndy Whitcroft} 1289f0a594c1SAndy Whitcroftsub ctx_block_level { 1290653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1291653d4876SAndy Whitcroft 1292f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 12934a0df2efSAndy Whitcroft} 12949c0ca6f9SAndy Whitcroftsub ctx_statement_level { 12959c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 12969c0ca6f9SAndy Whitcroft 12979c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 12989c0ca6f9SAndy Whitcroft} 12994a0df2efSAndy Whitcroft 13004a0df2efSAndy Whitcroftsub ctx_locate_comment { 13014a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 13024a0df2efSAndy Whitcroft 13034a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1304beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 13054a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 13064a0df2efSAndy Whitcroft 13074a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 13084a0df2efSAndy Whitcroft # comment. 13094a0df2efSAndy Whitcroft my $in_comment = 0; 13104a0df2efSAndy Whitcroft $current_comment = ''; 13114a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 131200df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 131300df344fSAndy Whitcroft #warn " $line\n"; 13144a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 13154a0df2efSAndy Whitcroft $in_comment = 1; 13164a0df2efSAndy Whitcroft } 13174a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 13184a0df2efSAndy Whitcroft $in_comment = 1; 13194a0df2efSAndy Whitcroft } 13204a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 13214a0df2efSAndy Whitcroft $current_comment = ''; 13224a0df2efSAndy Whitcroft } 13234a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 13244a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 13254a0df2efSAndy Whitcroft $in_comment = 0; 13264a0df2efSAndy Whitcroft } 13274a0df2efSAndy Whitcroft } 13284a0df2efSAndy Whitcroft 13294a0df2efSAndy Whitcroft chomp($current_comment); 13304a0df2efSAndy Whitcroft return($current_comment); 13314a0df2efSAndy Whitcroft} 13324a0df2efSAndy Whitcroftsub ctx_has_comment { 13334a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 13344a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 13354a0df2efSAndy Whitcroft 133600df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 13374a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 13384a0df2efSAndy Whitcroft 13394a0df2efSAndy Whitcroft return ($cmt ne ''); 13404a0df2efSAndy Whitcroft} 13414a0df2efSAndy Whitcroft 13424d001e4dSAndy Whitcroftsub raw_line { 13434d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 13444d001e4dSAndy Whitcroft 13454d001e4dSAndy Whitcroft my $offset = $linenr - 1; 13464d001e4dSAndy Whitcroft $cnt++; 13474d001e4dSAndy Whitcroft 13484d001e4dSAndy Whitcroft my $line; 13494d001e4dSAndy Whitcroft while ($cnt) { 13504d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 13514d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 13524d001e4dSAndy Whitcroft $cnt--; 13534d001e4dSAndy Whitcroft } 13544d001e4dSAndy Whitcroft 13554d001e4dSAndy Whitcroft return $line; 13564d001e4dSAndy Whitcroft} 13574d001e4dSAndy Whitcroft 13580a920b5bSAndy Whitcroftsub cat_vet { 13590a920b5bSAndy Whitcroft my ($vet) = @_; 13609c0ca6f9SAndy Whitcroft my ($res, $coded); 13610a920b5bSAndy Whitcroft 13629c0ca6f9SAndy Whitcroft $res = ''; 13636c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 13646c72ffaaSAndy Whitcroft $res .= $1; 13656c72ffaaSAndy Whitcroft if ($2 ne '') { 13669c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 13676c72ffaaSAndy Whitcroft $res .= $coded; 13686c72ffaaSAndy Whitcroft } 13699c0ca6f9SAndy Whitcroft } 13709c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 13710a920b5bSAndy Whitcroft 13729c0ca6f9SAndy Whitcroft return $res; 13730a920b5bSAndy Whitcroft} 13740a920b5bSAndy Whitcroft 1375c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1376cf655043SAndy Whitcroftmy $av_pending; 1377c2fdda0dSAndy Whitcroftmy @av_paren_type; 13781f65f947SAndy Whitcroftmy $av_pend_colon; 1379c2fdda0dSAndy Whitcroft 1380c2fdda0dSAndy Whitcroftsub annotate_reset { 1381c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1382cf655043SAndy Whitcroft $av_pending = '_'; 1383cf655043SAndy Whitcroft @av_paren_type = ('E'); 13841f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1385c2fdda0dSAndy Whitcroft} 1386c2fdda0dSAndy Whitcroft 13876c72ffaaSAndy Whitcroftsub annotate_values { 13886c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 13896c72ffaaSAndy Whitcroft 13906c72ffaaSAndy Whitcroft my $res; 13911f65f947SAndy Whitcroft my $var = '_' x length($stream); 13926c72ffaaSAndy Whitcroft my $cur = $stream; 13936c72ffaaSAndy Whitcroft 1394c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 13956c72ffaaSAndy Whitcroft 13966c72ffaaSAndy Whitcroft while (length($cur)) { 1397773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1398cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1399171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 14006c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1401c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1402c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1403cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1404c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 14056c72ffaaSAndy Whitcroft } 14066c72ffaaSAndy Whitcroft 1407c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 14089446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 14099446ef56SAndy Whitcroft push(@av_paren_type, $type); 1410addcdceaSAndy Whitcroft $type = 'c'; 14119446ef56SAndy Whitcroft 1412e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1413c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 14146c72ffaaSAndy Whitcroft $type = 'T'; 14156c72ffaaSAndy Whitcroft 1416389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1417389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1418389a2fe5SAndy Whitcroft $type = 'T'; 1419389a2fe5SAndy Whitcroft 1420c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1421171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1422c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1423171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1424171ae1a4SAndy Whitcroft if ($2 ne '') { 1425cf655043SAndy Whitcroft $av_pending = 'N'; 1426171ae1a4SAndy Whitcroft } 1427171ae1a4SAndy Whitcroft $type = 'E'; 1428171ae1a4SAndy Whitcroft 1429c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1430171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1431171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1432171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 14336c72ffaaSAndy Whitcroft 1434c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1435cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1436c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1437cf655043SAndy Whitcroft 1438cf655043SAndy Whitcroft push(@av_paren_type, $type); 1439cf655043SAndy Whitcroft push(@av_paren_type, $type); 1440171ae1a4SAndy Whitcroft $type = 'E'; 1441cf655043SAndy Whitcroft 1442c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1443cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1444cf655043SAndy Whitcroft $av_preprocessor = 1; 1445cf655043SAndy Whitcroft 1446cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1447cf655043SAndy Whitcroft 1448171ae1a4SAndy Whitcroft $type = 'E'; 1449cf655043SAndy Whitcroft 1450c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1451cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1452cf655043SAndy Whitcroft 1453cf655043SAndy Whitcroft $av_preprocessor = 1; 1454cf655043SAndy Whitcroft 1455cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1456cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1457cf655043SAndy Whitcroft pop(@av_paren_type); 1458cf655043SAndy Whitcroft push(@av_paren_type, $type); 1459171ae1a4SAndy Whitcroft $type = 'E'; 14606c72ffaaSAndy Whitcroft 14616c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1462c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 14636c72ffaaSAndy Whitcroft 1464171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1465171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1466171ae1a4SAndy Whitcroft $av_pending = $type; 1467171ae1a4SAndy Whitcroft $type = 'N'; 1468171ae1a4SAndy Whitcroft 14696c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1470c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 14716c72ffaaSAndy Whitcroft if (defined $2) { 1472cf655043SAndy Whitcroft $av_pending = 'V'; 14736c72ffaaSAndy Whitcroft } 14746c72ffaaSAndy Whitcroft $type = 'N'; 14756c72ffaaSAndy Whitcroft 147614b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1477c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 147814b111c1SAndy Whitcroft $av_pending = 'E'; 14796c72ffaaSAndy Whitcroft $type = 'N'; 14806c72ffaaSAndy Whitcroft 14811f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 14821f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 14831f65f947SAndy Whitcroft $av_pend_colon = 'C'; 14841f65f947SAndy Whitcroft $type = 'N'; 14851f65f947SAndy Whitcroft 148614b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1487c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 14886c72ffaaSAndy Whitcroft $type = 'N'; 14896c72ffaaSAndy Whitcroft 14906c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1491c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1492cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1493cf655043SAndy Whitcroft $av_pending = '_'; 14946c72ffaaSAndy Whitcroft $type = 'N'; 14956c72ffaaSAndy Whitcroft 14966c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1497cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1498cf655043SAndy Whitcroft if ($new_type ne '_') { 1499cf655043SAndy Whitcroft $type = $new_type; 1500c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1501c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 15026c72ffaaSAndy Whitcroft } else { 1503c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 15046c72ffaaSAndy Whitcroft } 15056c72ffaaSAndy Whitcroft 1506c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1507c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1508c8cb2ca3SAndy Whitcroft $type = 'V'; 1509cf655043SAndy Whitcroft $av_pending = 'V'; 15106c72ffaaSAndy Whitcroft 15118e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 15128e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 15131f65f947SAndy Whitcroft $av_pend_colon = 'B'; 15148e761b04SAndy Whitcroft } elsif ($type eq 'E') { 15158e761b04SAndy Whitcroft $av_pend_colon = 'L'; 15161f65f947SAndy Whitcroft } 15171f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 15181f65f947SAndy Whitcroft $type = 'V'; 15191f65f947SAndy Whitcroft 15206c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1521c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 15226c72ffaaSAndy Whitcroft $type = 'V'; 15236c72ffaaSAndy Whitcroft 15246c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1525c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 15266c72ffaaSAndy Whitcroft $type = 'N'; 15276c72ffaaSAndy Whitcroft 1528cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1529c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 153013214adfSAndy Whitcroft $type = 'E'; 15311f65f947SAndy Whitcroft $av_pend_colon = 'O'; 153213214adfSAndy Whitcroft 15338e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 15348e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 15358e761b04SAndy Whitcroft $type = 'C'; 15368e761b04SAndy Whitcroft 15371f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 15381f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 15391f65f947SAndy Whitcroft $type = 'N'; 15401f65f947SAndy Whitcroft 15411f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 15421f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 15431f65f947SAndy Whitcroft 15441f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 15451f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 15461f65f947SAndy Whitcroft $type = 'E'; 15471f65f947SAndy Whitcroft } else { 15481f65f947SAndy Whitcroft $type = 'N'; 15491f65f947SAndy Whitcroft } 15501f65f947SAndy Whitcroft $av_pend_colon = 'O'; 15511f65f947SAndy Whitcroft 15528e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 155313214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 15546c72ffaaSAndy Whitcroft $type = 'N'; 15556c72ffaaSAndy Whitcroft 15560d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 155774048ed8SAndy Whitcroft my $variant; 155874048ed8SAndy Whitcroft 155974048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 156074048ed8SAndy Whitcroft if ($type eq 'V') { 156174048ed8SAndy Whitcroft $variant = 'B'; 156274048ed8SAndy Whitcroft } else { 156374048ed8SAndy Whitcroft $variant = 'U'; 156474048ed8SAndy Whitcroft } 156574048ed8SAndy Whitcroft 156674048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 156774048ed8SAndy Whitcroft $type = 'N'; 156874048ed8SAndy Whitcroft 15696c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1570c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 15716c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 15726c72ffaaSAndy Whitcroft $type = 'N'; 15736c72ffaaSAndy Whitcroft } 15746c72ffaaSAndy Whitcroft 15756c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1576c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 15776c72ffaaSAndy Whitcroft } 15786c72ffaaSAndy Whitcroft if (defined $1) { 15796c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 15806c72ffaaSAndy Whitcroft $res .= $type x length($1); 15816c72ffaaSAndy Whitcroft } 15826c72ffaaSAndy Whitcroft } 15836c72ffaaSAndy Whitcroft 15841f65f947SAndy Whitcroft return ($res, $var); 15856c72ffaaSAndy Whitcroft} 15866c72ffaaSAndy Whitcroft 15878905a67cSAndy Whitcroftsub possible { 158813214adfSAndy Whitcroft my ($possible, $line) = @_; 15899a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 15900776e594SAndy Whitcroft ^(?: 15910776e594SAndy Whitcroft $Modifier| 15920776e594SAndy Whitcroft $Storage| 15930776e594SAndy Whitcroft $Type| 15949a974fdbSAndy Whitcroft DEFINE_\S+ 15959a974fdbSAndy Whitcroft )$| 15969a974fdbSAndy Whitcroft ^(?: 15970776e594SAndy Whitcroft goto| 15980776e594SAndy Whitcroft return| 15990776e594SAndy Whitcroft case| 16000776e594SAndy Whitcroft else| 16010776e594SAndy Whitcroft asm|__asm__| 160289a88353SAndy Whitcroft do| 160389a88353SAndy Whitcroft \#| 160489a88353SAndy Whitcroft \#\#| 16059a974fdbSAndy Whitcroft )(?:\s|$)| 16060776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 16079a974fdbSAndy Whitcroft )}x; 16089a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 16099a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1610c45dcabdSAndy Whitcroft # Check for modifiers. 1611c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1612c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1613c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1614c45dcabdSAndy Whitcroft 1615c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1616c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1617d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 16189a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1619d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1620*485ff23eSAlex Dowad push(@modifierListFile, $modifier); 1621d2506586SAndy Whitcroft } 16229a974fdbSAndy Whitcroft } 1623c45dcabdSAndy Whitcroft 1624c45dcabdSAndy Whitcroft } else { 162513214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1626*485ff23eSAlex Dowad push(@typeListFile, $possible); 1627c45dcabdSAndy Whitcroft } 16288905a67cSAndy Whitcroft build_types(); 16290776e594SAndy Whitcroft } else { 16300776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 16318905a67cSAndy Whitcroft } 16328905a67cSAndy Whitcroft} 16338905a67cSAndy Whitcroft 16346c72ffaaSAndy Whitcroftmy $prefix = ''; 16356c72ffaaSAndy Whitcroft 1636000d1cc1SJoe Perchessub show_type { 1637cbec18afSJoe Perches my ($type) = @_; 163891bfe484SJoe Perches 1639cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 1640cbec18afSJoe Perches 1641cbec18afSJoe Perches return !defined $ignore_type{$type}; 1642000d1cc1SJoe Perches} 1643000d1cc1SJoe Perches 1644f0a594c1SAndy Whitcroftsub report { 1645cbec18afSJoe Perches my ($level, $type, $msg) = @_; 1646cbec18afSJoe Perches 1647cbec18afSJoe Perches if (!show_type($type) || 1648cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 1649773647a0SAndy Whitcroft return 0; 1650773647a0SAndy Whitcroft } 1651000d1cc1SJoe Perches my $line; 1652000d1cc1SJoe Perches if ($show_types) { 1653cbec18afSJoe Perches $line = "$prefix$level:$type: $msg\n"; 1654000d1cc1SJoe Perches } else { 1655cbec18afSJoe Perches $line = "$prefix$level: $msg\n"; 1656000d1cc1SJoe Perches } 16578905a67cSAndy Whitcroft $line = (split('\n', $line))[0] . "\n" if ($terse); 16588905a67cSAndy Whitcroft 165913214adfSAndy Whitcroft push(our @report, $line); 1660773647a0SAndy Whitcroft 1661773647a0SAndy Whitcroft return 1; 1662f0a594c1SAndy Whitcroft} 1663cbec18afSJoe Perches 1664f0a594c1SAndy Whitcroftsub report_dump { 166513214adfSAndy Whitcroft our @report; 1666f0a594c1SAndy Whitcroft} 1667000d1cc1SJoe Perches 1668d752fcc8SJoe Perchessub fixup_current_range { 1669d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 1670d752fcc8SJoe Perches 1671d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 1672d752fcc8SJoe Perches my $o = $1; 1673d752fcc8SJoe Perches my $l = $2; 1674d752fcc8SJoe Perches my $no = $o + $offset; 1675d752fcc8SJoe Perches my $nl = $l + $length; 1676d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 1677d752fcc8SJoe Perches } 1678d752fcc8SJoe Perches} 1679d752fcc8SJoe Perches 1680d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 1681d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 1682d752fcc8SJoe Perches 1683d752fcc8SJoe Perches my $range_last_linenr = 0; 1684d752fcc8SJoe Perches my $delta_offset = 0; 1685d752fcc8SJoe Perches 1686d752fcc8SJoe Perches my $old_linenr = 0; 1687d752fcc8SJoe Perches my $new_linenr = 0; 1688d752fcc8SJoe Perches 1689d752fcc8SJoe Perches my $next_insert = 0; 1690d752fcc8SJoe Perches my $next_delete = 0; 1691d752fcc8SJoe Perches 1692d752fcc8SJoe Perches my @lines = (); 1693d752fcc8SJoe Perches 1694d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 1695d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 1696d752fcc8SJoe Perches 1697d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 1698d752fcc8SJoe Perches my $save_line = 1; 1699d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 1700323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 1701d752fcc8SJoe Perches $delta_offset = 0; 1702d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 1703d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 1704d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 1705d752fcc8SJoe Perches } 1706d752fcc8SJoe Perches 1707d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 1708d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 1709d752fcc8SJoe Perches $save_line = 0; 1710d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 1711d752fcc8SJoe Perches } 1712d752fcc8SJoe Perches 1713d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 1714d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 1715d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 1716d752fcc8SJoe Perches $new_linenr++; 1717d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 1718d752fcc8SJoe Perches } 1719d752fcc8SJoe Perches 1720d752fcc8SJoe Perches if ($save_line) { 1721d752fcc8SJoe Perches push(@lines, $line); 1722d752fcc8SJoe Perches $new_linenr++; 1723d752fcc8SJoe Perches } 1724d752fcc8SJoe Perches 1725d752fcc8SJoe Perches $old_linenr++; 1726d752fcc8SJoe Perches } 1727d752fcc8SJoe Perches 1728d752fcc8SJoe Perches return @lines; 1729d752fcc8SJoe Perches} 1730d752fcc8SJoe Perches 1731f2d7e4d4SJoe Perchessub fix_insert_line { 1732f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1733f2d7e4d4SJoe Perches 1734f2d7e4d4SJoe Perches my $inserted = { 1735f2d7e4d4SJoe Perches LINENR => $linenr, 1736f2d7e4d4SJoe Perches LINE => $line, 1737f2d7e4d4SJoe Perches }; 1738f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 1739f2d7e4d4SJoe Perches} 1740f2d7e4d4SJoe Perches 1741f2d7e4d4SJoe Perchessub fix_delete_line { 1742f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1743f2d7e4d4SJoe Perches 1744f2d7e4d4SJoe Perches my $deleted = { 1745f2d7e4d4SJoe Perches LINENR => $linenr, 1746f2d7e4d4SJoe Perches LINE => $line, 1747f2d7e4d4SJoe Perches }; 1748f2d7e4d4SJoe Perches 1749f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 1750f2d7e4d4SJoe Perches} 1751f2d7e4d4SJoe Perches 1752de7d4f0eSAndy Whitcroftsub ERROR { 1753cbec18afSJoe Perches my ($type, $msg) = @_; 1754cbec18afSJoe Perches 1755cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 1756de7d4f0eSAndy Whitcroft our $clean = 0; 17576c72ffaaSAndy Whitcroft our $cnt_error++; 17583705ce5bSJoe Perches return 1; 1759de7d4f0eSAndy Whitcroft } 17603705ce5bSJoe Perches return 0; 1761773647a0SAndy Whitcroft} 1762de7d4f0eSAndy Whitcroftsub WARN { 1763cbec18afSJoe Perches my ($type, $msg) = @_; 1764cbec18afSJoe Perches 1765cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 1766de7d4f0eSAndy Whitcroft our $clean = 0; 17676c72ffaaSAndy Whitcroft our $cnt_warn++; 17683705ce5bSJoe Perches return 1; 1769de7d4f0eSAndy Whitcroft } 17703705ce5bSJoe Perches return 0; 1771773647a0SAndy Whitcroft} 1772de7d4f0eSAndy Whitcroftsub CHK { 1773cbec18afSJoe Perches my ($type, $msg) = @_; 1774cbec18afSJoe Perches 1775cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 1776de7d4f0eSAndy Whitcroft our $clean = 0; 17776c72ffaaSAndy Whitcroft our $cnt_chk++; 17783705ce5bSJoe Perches return 1; 17796c72ffaaSAndy Whitcroft } 17803705ce5bSJoe Perches return 0; 1781de7d4f0eSAndy Whitcroft} 1782de7d4f0eSAndy Whitcroft 17836ecd9674SAndy Whitcroftsub check_absolute_file { 17846ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 17856ecd9674SAndy Whitcroft my $file = $absolute; 17866ecd9674SAndy Whitcroft 17876ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 17886ecd9674SAndy Whitcroft 17896ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 17906ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 17916ecd9674SAndy Whitcroft if (-f "$root/$file") { 17926ecd9674SAndy Whitcroft ##print "file<$file>\n"; 17936ecd9674SAndy Whitcroft last; 17946ecd9674SAndy Whitcroft } 17956ecd9674SAndy Whitcroft } 17966ecd9674SAndy Whitcroft if (! -f _) { 17976ecd9674SAndy Whitcroft return 0; 17986ecd9674SAndy Whitcroft } 17996ecd9674SAndy Whitcroft 18006ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 18016ecd9674SAndy Whitcroft my $prefix = $absolute; 18026ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 18036ecd9674SAndy Whitcroft 18046ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 18056ecd9674SAndy Whitcroft if ($prefix ne ".../") { 1806000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 1807000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 18086ecd9674SAndy Whitcroft } 18096ecd9674SAndy Whitcroft} 18106ecd9674SAndy Whitcroft 18113705ce5bSJoe Perchessub trim { 18123705ce5bSJoe Perches my ($string) = @_; 18133705ce5bSJoe Perches 1814b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 1815b34c648bSJoe Perches 1816b34c648bSJoe Perches return $string; 1817b34c648bSJoe Perches} 1818b34c648bSJoe Perches 1819b34c648bSJoe Perchessub ltrim { 1820b34c648bSJoe Perches my ($string) = @_; 1821b34c648bSJoe Perches 1822b34c648bSJoe Perches $string =~ s/^\s+//; 1823b34c648bSJoe Perches 1824b34c648bSJoe Perches return $string; 1825b34c648bSJoe Perches} 1826b34c648bSJoe Perches 1827b34c648bSJoe Perchessub rtrim { 1828b34c648bSJoe Perches my ($string) = @_; 1829b34c648bSJoe Perches 1830b34c648bSJoe Perches $string =~ s/\s+$//; 18313705ce5bSJoe Perches 18323705ce5bSJoe Perches return $string; 18333705ce5bSJoe Perches} 18343705ce5bSJoe Perches 183552ea8506SJoe Perchessub string_find_replace { 183652ea8506SJoe Perches my ($string, $find, $replace) = @_; 183752ea8506SJoe Perches 183852ea8506SJoe Perches $string =~ s/$find/$replace/g; 183952ea8506SJoe Perches 184052ea8506SJoe Perches return $string; 184152ea8506SJoe Perches} 184252ea8506SJoe Perches 18433705ce5bSJoe Perchessub tabify { 18443705ce5bSJoe Perches my ($leading) = @_; 18453705ce5bSJoe Perches 18463705ce5bSJoe Perches my $source_indent = 8; 18473705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 18483705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 18493705ce5bSJoe Perches 18503705ce5bSJoe Perches #convert leading spaces to tabs 18513705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 18523705ce5bSJoe Perches #Remove spaces before a tab 18533705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 18543705ce5bSJoe Perches 18553705ce5bSJoe Perches return "$leading"; 18563705ce5bSJoe Perches} 18573705ce5bSJoe Perches 1858d1fe9c09SJoe Perchessub pos_last_openparen { 1859d1fe9c09SJoe Perches my ($line) = @_; 1860d1fe9c09SJoe Perches 1861d1fe9c09SJoe Perches my $pos = 0; 1862d1fe9c09SJoe Perches 1863d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 1864d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 1865d1fe9c09SJoe Perches 1866d1fe9c09SJoe Perches my $last_openparen = 0; 1867d1fe9c09SJoe Perches 1868d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 1869d1fe9c09SJoe Perches return -1; 1870d1fe9c09SJoe Perches } 1871d1fe9c09SJoe Perches 1872d1fe9c09SJoe Perches my $len = length($line); 1873d1fe9c09SJoe Perches 1874d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 1875d1fe9c09SJoe Perches my $string = substr($line, $pos); 1876d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 1877d1fe9c09SJoe Perches $pos += length($1) - 1; 1878d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 1879d1fe9c09SJoe Perches $last_openparen = $pos; 1880d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 1881d1fe9c09SJoe Perches last; 1882d1fe9c09SJoe Perches } 1883d1fe9c09SJoe Perches } 1884d1fe9c09SJoe Perches 188591cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 1886d1fe9c09SJoe Perches} 1887d1fe9c09SJoe Perches 18880a920b5bSAndy Whitcroftsub process { 18890a920b5bSAndy Whitcroft my $filename = shift; 18900a920b5bSAndy Whitcroft 18910a920b5bSAndy Whitcroft my $linenr=0; 18920a920b5bSAndy Whitcroft my $prevline=""; 1893c2fdda0dSAndy Whitcroft my $prevrawline=""; 18940a920b5bSAndy Whitcroft my $stashline=""; 1895c2fdda0dSAndy Whitcroft my $stashrawline=""; 18960a920b5bSAndy Whitcroft 18974a0df2efSAndy Whitcroft my $length; 18980a920b5bSAndy Whitcroft my $indent; 18990a920b5bSAndy Whitcroft my $previndent=0; 19000a920b5bSAndy Whitcroft my $stashindent=0; 19010a920b5bSAndy Whitcroft 1902de7d4f0eSAndy Whitcroft our $clean = 1; 19030a920b5bSAndy Whitcroft my $signoff = 0; 19040a920b5bSAndy Whitcroft my $is_patch = 0; 19050a920b5bSAndy Whitcroft 190629ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 190715662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 19082a076f40SJoe Perches my $commit_log_long_line = 0; 190913f1937eSJoe Perches my $reported_maintainer_file = 0; 1910fa64205dSPasi Savanainen my $non_utf8_charset = 0; 1911fa64205dSPasi Savanainen 1912365dd4eaSJoe Perches my $last_blank_line = 0; 19135e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 1914365dd4eaSJoe Perches 191513214adfSAndy Whitcroft our @report = (); 19166c72ffaaSAndy Whitcroft our $cnt_lines = 0; 19176c72ffaaSAndy Whitcroft our $cnt_error = 0; 19186c72ffaaSAndy Whitcroft our $cnt_warn = 0; 19196c72ffaaSAndy Whitcroft our $cnt_chk = 0; 19206c72ffaaSAndy Whitcroft 19210a920b5bSAndy Whitcroft # Trace the real file/line as we go. 19220a920b5bSAndy Whitcroft my $realfile = ''; 19230a920b5bSAndy Whitcroft my $realline = 0; 19240a920b5bSAndy Whitcroft my $realcnt = 0; 19250a920b5bSAndy Whitcroft my $here = ''; 19260a920b5bSAndy Whitcroft my $in_comment = 0; 1927c2fdda0dSAndy Whitcroft my $comment_edge = 0; 19280a920b5bSAndy Whitcroft my $first_line = 0; 19291e855726SWolfram Sang my $p1_prefix = ''; 19300a920b5bSAndy Whitcroft 193113214adfSAndy Whitcroft my $prev_values = 'E'; 193213214adfSAndy Whitcroft 193313214adfSAndy Whitcroft # suppression flags 1934773647a0SAndy Whitcroft my %suppress_ifbraces; 1935170d3a22SAndy Whitcroft my %suppress_whiletrailers; 19362b474a1aSAndy Whitcroft my %suppress_export; 19373e469cdcSAndy Whitcroft my $suppress_statement = 0; 1938653d4876SAndy Whitcroft 19397e51f197SJoe Perches my %signatures = (); 1940323c1260SJoe Perches 1941c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 1942de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 1943c2fdda0dSAndy Whitcroft # 1944de7d4f0eSAndy Whitcroft my @setup_docs = (); 1945de7d4f0eSAndy Whitcroft my $setup_docs = 0; 1946773647a0SAndy Whitcroft 1947d8b07710SJoe Perches my $camelcase_file_seeded = 0; 1948d8b07710SJoe Perches 1949773647a0SAndy Whitcroft sanitise_line_reset(); 1950c2fdda0dSAndy Whitcroft my $line; 1951c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 1952773647a0SAndy Whitcroft $linenr++; 1953773647a0SAndy Whitcroft $line = $rawline; 1954c2fdda0dSAndy Whitcroft 19553705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 19563705ce5bSJoe Perches 1957773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 1958de7d4f0eSAndy Whitcroft $setup_docs = 0; 1959de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 1960de7d4f0eSAndy Whitcroft $setup_docs = 1; 1961de7d4f0eSAndy Whitcroft } 1962773647a0SAndy Whitcroft #next; 1963de7d4f0eSAndy Whitcroft } 1964773647a0SAndy Whitcroft if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1965773647a0SAndy Whitcroft $realline=$1-1; 1966773647a0SAndy Whitcroft if (defined $2) { 1967773647a0SAndy Whitcroft $realcnt=$3+1; 1968773647a0SAndy Whitcroft } else { 1969773647a0SAndy Whitcroft $realcnt=1+1; 1970773647a0SAndy Whitcroft } 1971c45dcabdSAndy Whitcroft $in_comment = 0; 1972773647a0SAndy Whitcroft 1973773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 1974773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 1975773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 1976773647a0SAndy Whitcroft # at context start. 1977773647a0SAndy Whitcroft my $edge; 197801fa9147SAndy Whitcroft my $cnt = $realcnt; 197901fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 198001fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 198101fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 198201fa9147SAndy Whitcroft $cnt--; 198301fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 1984721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 1985fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1986fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1987fae17daeSAndy Whitcroft ($edge) = $1; 1988fae17daeSAndy Whitcroft last; 1989fae17daeSAndy Whitcroft } 1990773647a0SAndy Whitcroft } 1991773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 1992773647a0SAndy Whitcroft $in_comment = 1; 1993773647a0SAndy Whitcroft } 1994773647a0SAndy Whitcroft 1995773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 1996773647a0SAndy Whitcroft # is the start of a diff block and this line starts 1997773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 1998773647a0SAndy Whitcroft if (!defined $edge && 199983242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2000773647a0SAndy Whitcroft { 2001773647a0SAndy Whitcroft $in_comment = 1; 2002773647a0SAndy Whitcroft } 2003773647a0SAndy Whitcroft 2004773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2005773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2006773647a0SAndy Whitcroft 2007171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2008773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2009171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2010773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2011773647a0SAndy Whitcroft } 2012773647a0SAndy Whitcroft push(@lines, $line); 2013773647a0SAndy Whitcroft 2014773647a0SAndy Whitcroft if ($realcnt > 1) { 2015773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2016773647a0SAndy Whitcroft } else { 2017773647a0SAndy Whitcroft $realcnt = 0; 2018773647a0SAndy Whitcroft } 2019773647a0SAndy Whitcroft 2020773647a0SAndy Whitcroft #print "==>$rawline\n"; 2021773647a0SAndy Whitcroft #print "-->$line\n"; 2022de7d4f0eSAndy Whitcroft 2023de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2024de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2025de7d4f0eSAndy Whitcroft } 2026de7d4f0eSAndy Whitcroft } 2027de7d4f0eSAndy Whitcroft 20286c72ffaaSAndy Whitcroft $prefix = ''; 20296c72ffaaSAndy Whitcroft 2030773647a0SAndy Whitcroft $realcnt = 0; 2031773647a0SAndy Whitcroft $linenr = 0; 2032194f66fcSJoe Perches $fixlinenr = -1; 20330a920b5bSAndy Whitcroft foreach my $line (@lines) { 20340a920b5bSAndy Whitcroft $linenr++; 2035194f66fcSJoe Perches $fixlinenr++; 20361b5539b1SJoe Perches my $sline = $line; #copy of $line 20371b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 20380a920b5bSAndy Whitcroft 2039c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 20406c72ffaaSAndy Whitcroft 20410a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 20426c72ffaaSAndy Whitcroft if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 20430a920b5bSAndy Whitcroft $is_patch = 1; 20444a0df2efSAndy Whitcroft $first_line = $linenr + 1; 20450a920b5bSAndy Whitcroft $realline=$1-1; 20460a920b5bSAndy Whitcroft if (defined $2) { 20470a920b5bSAndy Whitcroft $realcnt=$3+1; 20480a920b5bSAndy Whitcroft } else { 20490a920b5bSAndy Whitcroft $realcnt=1+1; 20500a920b5bSAndy Whitcroft } 2051c2fdda0dSAndy Whitcroft annotate_reset(); 205213214adfSAndy Whitcroft $prev_values = 'E'; 205313214adfSAndy Whitcroft 2054773647a0SAndy Whitcroft %suppress_ifbraces = (); 2055170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 20562b474a1aSAndy Whitcroft %suppress_export = (); 20573e469cdcSAndy Whitcroft $suppress_statement = 0; 20580a920b5bSAndy Whitcroft next; 20590a920b5bSAndy Whitcroft 20604a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 20614a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 20624a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2063773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 20640a920b5bSAndy Whitcroft $realline++; 2065d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 20660a920b5bSAndy Whitcroft 20674a0df2efSAndy Whitcroft # Measure the line length and indent. 2068c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 20690a920b5bSAndy Whitcroft 20700a920b5bSAndy Whitcroft # Track the previous line. 20710a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 20720a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2073c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2074c2fdda0dSAndy Whitcroft 2075773647a0SAndy Whitcroft #warn "line<$line>\n"; 20766c72ffaaSAndy Whitcroft 2077d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2078d8aaf121SAndy Whitcroft $realcnt--; 20790a920b5bSAndy Whitcroft } 20800a920b5bSAndy Whitcroft 2081cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2082cc77cdcaSAndy Whitcroft 20830a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 2084773647a0SAndy Whitcroft $prefix = "$filename:$realline: " if ($emacs && $file); 2085773647a0SAndy Whitcroft $prefix = "$filename:$linenr: " if ($emacs && !$file); 2086773647a0SAndy Whitcroft 20876c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 20886c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2089773647a0SAndy Whitcroft 20902ac73b4fSJoe Perches my $found_file = 0; 2091773647a0SAndy Whitcroft # extract the filename as it passes 20923bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 20933bf9a009SRabin Vincent $realfile = $1; 20942b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2095270c49a0SJoe Perches $in_commit_log = 0; 20962ac73b4fSJoe Perches $found_file = 1; 20973bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2098773647a0SAndy Whitcroft $realfile = $1; 20992b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2100270c49a0SJoe Perches $in_commit_log = 0; 21011e855726SWolfram Sang 21021e855726SWolfram Sang $p1_prefix = $1; 2103e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2104e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2105000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2106000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 21071e855726SWolfram Sang } 2108773647a0SAndy Whitcroft 2109c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2110000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2111000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2112773647a0SAndy Whitcroft } 21132ac73b4fSJoe Perches $found_file = 1; 21142ac73b4fSJoe Perches } 21152ac73b4fSJoe Perches 21162ac73b4fSJoe Perches if ($found_file) { 21172ac73b4fSJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@) { 21182ac73b4fSJoe Perches $check = 1; 21192ac73b4fSJoe Perches } else { 21202ac73b4fSJoe Perches $check = $check_orig; 21212ac73b4fSJoe Perches } 2122773647a0SAndy Whitcroft next; 2123773647a0SAndy Whitcroft } 2124773647a0SAndy Whitcroft 2125389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 21260a920b5bSAndy Whitcroft 2127c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2128c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2129c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 21300a920b5bSAndy Whitcroft 21316c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 21326c72ffaaSAndy Whitcroft 21333bf9a009SRabin Vincent# Check for incorrect file permissions 21343bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 21353bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 213604db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 213704db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2138000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2139000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 21403bf9a009SRabin Vincent } 21413bf9a009SRabin Vincent } 21423bf9a009SRabin Vincent 214320112475SJoe Perches# Check the patch for a signoff: 2144d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 21454a0df2efSAndy Whitcroft $signoff++; 214615662b3eSJoe Perches $in_commit_log = 0; 21470a920b5bSAndy Whitcroft } 214820112475SJoe Perches 2149e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2150e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2151e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2152e0d975b1SJoe Perches $reported_maintainer_file = 1; 2153e0d975b1SJoe Perches } 2154e0d975b1SJoe Perches 215520112475SJoe Perches# Check signature styles 2156270c49a0SJoe Perches if (!$in_header_lines && 2157ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 215820112475SJoe Perches my $space_before = $1; 215920112475SJoe Perches my $sign_off = $2; 216020112475SJoe Perches my $space_after = $3; 216120112475SJoe Perches my $email = $4; 216220112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 216320112475SJoe Perches 2164ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2165ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2166ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2167ce0338dfSJoe Perches } 216820112475SJoe Perches if (defined $space_before && $space_before ne "") { 21693705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 21703705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 21713705ce5bSJoe Perches $fix) { 2172194f66fcSJoe Perches $fixed[$fixlinenr] = 21733705ce5bSJoe Perches "$ucfirst_sign_off $email"; 21743705ce5bSJoe Perches } 217520112475SJoe Perches } 217620112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 21773705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 21783705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 21793705ce5bSJoe Perches $fix) { 2180194f66fcSJoe Perches $fixed[$fixlinenr] = 21813705ce5bSJoe Perches "$ucfirst_sign_off $email"; 21823705ce5bSJoe Perches } 21833705ce5bSJoe Perches 218420112475SJoe Perches } 218520112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 21863705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 21873705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 21883705ce5bSJoe Perches $fix) { 2189194f66fcSJoe Perches $fixed[$fixlinenr] = 21903705ce5bSJoe Perches "$ucfirst_sign_off $email"; 21913705ce5bSJoe Perches } 219220112475SJoe Perches } 219320112475SJoe Perches 219420112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 219520112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 219620112475SJoe Perches if ($suggested_email eq "") { 2197000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2198000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 219920112475SJoe Perches } else { 220020112475SJoe Perches my $dequoted = $suggested_email; 220120112475SJoe Perches $dequoted =~ s/^"//; 220220112475SJoe Perches $dequoted =~ s/" </ </; 220320112475SJoe Perches # Don't force email to have quotes 220420112475SJoe Perches # Allow just an angle bracketed address 220520112475SJoe Perches if ("$dequoted$comment" ne $email && 220620112475SJoe Perches "<$email_address>$comment" ne $email && 220720112475SJoe Perches "$suggested_email$comment" ne $email) { 2208000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2209000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 221020112475SJoe Perches } 22110a920b5bSAndy Whitcroft } 22127e51f197SJoe Perches 22137e51f197SJoe Perches# Check for duplicate signatures 22147e51f197SJoe Perches my $sig_nospace = $line; 22157e51f197SJoe Perches $sig_nospace =~ s/\s//g; 22167e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 22177e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 22187e51f197SJoe Perches WARN("BAD_SIGN_OFF", 22197e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 22207e51f197SJoe Perches } else { 22217e51f197SJoe Perches $signatures{$sig_nospace} = 1; 22227e51f197SJoe Perches } 22230a920b5bSAndy Whitcroft } 22240a920b5bSAndy Whitcroft 2225a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2226a2fe16b9SJoe Perches if ($in_header_lines && 2227a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2228a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2229a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2230a2fe16b9SJoe Perches } 2231a2fe16b9SJoe Perches 22329b3189ebSJoe Perches# Check for old stable address 22339b3189ebSJoe Perches if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { 22349b3189ebSJoe Perches ERROR("STABLE_ADDRESS", 22359b3189ebSJoe Perches "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); 22369b3189ebSJoe Perches } 22379b3189ebSJoe Perches 22387ebd05efSChristopher Covington# Check for unwanted Gerrit info 22397ebd05efSChristopher Covington if ($in_commit_log && $line =~ /^\s*change-id:/i) { 22407ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 22417ebd05efSChristopher Covington "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 22427ebd05efSChristopher Covington } 22437ebd05efSChristopher Covington 22442a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 22452a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 22462a076f40SJoe Perches length($line) > 75) { 22472a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 22482a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 22492a076f40SJoe Perches $commit_log_long_line = 1; 22502a076f40SJoe Perches } 22512a076f40SJoe Perches 22520d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 22530d7835fcSJoe Perches if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) { 2254d311cd44SJoe Perches my $init_char = $1; 2255d311cd44SJoe Perches my $orig_commit = lc($2); 22560d7835fcSJoe Perches my $short = 1; 22570d7835fcSJoe Perches my $long = 0; 22580d7835fcSJoe Perches my $case = 1; 22590d7835fcSJoe Perches my $space = 1; 22600d7835fcSJoe Perches my $hasdesc = 0; 226119c146a6SJoe Perches my $hasparens = 0; 22620d7835fcSJoe Perches my $id = '0123456789ab'; 22630d7835fcSJoe Perches my $orig_desc = "commit description"; 22640d7835fcSJoe Perches my $description = ""; 22650d7835fcSJoe Perches 22660d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 22670d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 22680d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 22690d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 22700d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 22710d7835fcSJoe Perches $orig_desc = $1; 227219c146a6SJoe Perches $hasparens = 1; 22730d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 22740d7835fcSJoe Perches defined $rawlines[$linenr] && 22750d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 22760d7835fcSJoe Perches $orig_desc = $1; 227719c146a6SJoe Perches $hasparens = 1; 2278b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2279b671fde0SJoe Perches defined $rawlines[$linenr] && 2280b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2281b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2282b671fde0SJoe Perches $orig_desc = $1; 2283b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2284b671fde0SJoe Perches $orig_desc .= " " . $1; 228519c146a6SJoe Perches $hasparens = 1; 22860d7835fcSJoe Perches } 22870d7835fcSJoe Perches 22880d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 22890d7835fcSJoe Perches $id, $orig_desc); 22900d7835fcSJoe Perches 229119c146a6SJoe Perches if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { 2292d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 22930d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 22940d7835fcSJoe Perches } 2295d311cd44SJoe Perches } 2296d311cd44SJoe Perches 229713f1937eSJoe Perches# Check for added, moved or deleted files 229813f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 229913f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 230013f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 230113f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 230213f1937eSJoe Perches (defined($1) || defined($2))))) { 230313f1937eSJoe Perches $reported_maintainer_file = 1; 230413f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 230513f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 230613f1937eSJoe Perches } 230713f1937eSJoe Perches 230800df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 23098905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2310000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2311000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 23126c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2313de7d4f0eSAndy Whitcroft } 2314de7d4f0eSAndy Whitcroft 23156ecd9674SAndy Whitcroft# Check for absolute kernel paths. 23166ecd9674SAndy Whitcroft if ($tree) { 23176ecd9674SAndy Whitcroft while ($line =~ m{(?:^|\s)(/\S*)}g) { 23186ecd9674SAndy Whitcroft my $file = $1; 23196ecd9674SAndy Whitcroft 23206ecd9674SAndy Whitcroft if ($file =~ m{^(.*?)(?::\d+)+:?$} && 23216ecd9674SAndy Whitcroft check_absolute_file($1, $herecurr)) { 23226ecd9674SAndy Whitcroft # 23236ecd9674SAndy Whitcroft } else { 23246ecd9674SAndy Whitcroft check_absolute_file($file, $herecurr); 23256ecd9674SAndy Whitcroft } 23266ecd9674SAndy Whitcroft } 23276ecd9674SAndy Whitcroft } 23286ecd9674SAndy Whitcroft 2329de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2330de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2331171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2332171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2333171ae1a4SAndy Whitcroft 2334171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2335171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2336171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2337171ae1a4SAndy Whitcroft 233834d99219SJoe Perches CHK("INVALID_UTF8", 2339000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 234000df344fSAndy Whitcroft } 23410a920b5bSAndy Whitcroft 234215662b3eSJoe Perches# Check if it's the start of a commit log 234315662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 234415662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 234529ee1b0cSJoe Perches !($rawline =~ /^\s+\S/ || 234629ee1b0cSJoe Perches $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) { 234715662b3eSJoe Perches $in_header_lines = 0; 234815662b3eSJoe Perches $in_commit_log = 1; 234915662b3eSJoe Perches } 235015662b3eSJoe Perches 2351fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2352fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2353fa64205dSPasi Savanainen if ($in_header_lines && 2354fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2355fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2356fa64205dSPasi Savanainen $non_utf8_charset = 1; 2357fa64205dSPasi Savanainen } 2358fa64205dSPasi Savanainen 2359fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 236015662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2361fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 236215662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 236315662b3eSJoe Perches } 236415662b3eSJoe Perches 236566b47b4aSKees Cook# Check for various typo / spelling mistakes 236666d7a382SJoe Perches if (defined($misspellings) && 236766d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2368ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 236966b47b4aSKees Cook my $typo = $1; 237066b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 237166b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 237266b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 237366b47b4aSKees Cook my $msg_type = \&WARN; 237466b47b4aSKees Cook $msg_type = \&CHK if ($file); 237566b47b4aSKees Cook if (&{$msg_type}("TYPO_SPELLING", 237666b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 237766b47b4aSKees Cook $fix) { 237866b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 237966b47b4aSKees Cook } 238066b47b4aSKees Cook } 238166b47b4aSKees Cook } 238266b47b4aSKees Cook 238330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 238430670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 238500df344fSAndy Whitcroft 23860a920b5bSAndy Whitcroft#trailing whitespace 23879c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2388c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2389d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2390d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2391d5e616fcSJoe Perches $fix) { 2392194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2393d5e616fcSJoe Perches } 2394c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2395c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 23963705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 23973705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 23983705ce5bSJoe Perches $fix) { 2399194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 24003705ce5bSJoe Perches } 24013705ce5bSJoe Perches 2402d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 24030a920b5bSAndy Whitcroft } 24045368df20SAndy Whitcroft 24054783f894SJosh Triplett# Check for FSF mailing addresses. 2406109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 24073e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 24083e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 24094783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 24104783f894SJosh Triplett my $msg_type = \&ERROR; 24114783f894SJosh Triplett $msg_type = \&CHK if ($file); 24124783f894SJosh Triplett &{$msg_type}("FSF_MAILING_ADDRESS", 24134783f894SJosh Triplett "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) 24144783f894SJosh Triplett } 24154783f894SJosh Triplett 24163354957aSAndi Kleen# check for Kconfig help text having a real description 24179fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 24189fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 24193354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 24208d73e0e7SJoe Perches $line =~ /^\+\s*config\s+/) { 24213354957aSAndi Kleen my $length = 0; 24229fe287d7SAndy Whitcroft my $cnt = $realcnt; 24239fe287d7SAndy Whitcroft my $ln = $linenr + 1; 24249fe287d7SAndy Whitcroft my $f; 2425a1385803SAndy Whitcroft my $is_start = 0; 24269fe287d7SAndy Whitcroft my $is_end = 0; 2427a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 24289fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 24299fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 24309fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 24319fe287d7SAndy Whitcroft 24329fe287d7SAndy Whitcroft next if ($f =~ /^-/); 24338d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 2434a1385803SAndy Whitcroft 24358d73e0e7SJoe Perches if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2436a1385803SAndy Whitcroft $is_start = 1; 24378d73e0e7SJoe Perches } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2438a1385803SAndy Whitcroft $length = -1; 2439a1385803SAndy Whitcroft } 2440a1385803SAndy Whitcroft 24419fe287d7SAndy Whitcroft $f =~ s/^.//; 24423354957aSAndi Kleen $f =~ s/#.*//; 24433354957aSAndi Kleen $f =~ s/^\s+//; 24443354957aSAndi Kleen next if ($f =~ /^$/); 24459fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 24469fe287d7SAndy Whitcroft $is_end = 1; 24479fe287d7SAndy Whitcroft last; 24489fe287d7SAndy Whitcroft } 24493354957aSAndi Kleen $length++; 24503354957aSAndi Kleen } 245156193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 2452000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 245356193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 245456193274SVadim Bendebury } 2455a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 24563354957aSAndi Kleen } 24573354957aSAndi Kleen 24581ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. 24591ba8dfd1SKees Cook if ($realfile =~ /Kconfig/ && 24601ba8dfd1SKees Cook $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { 24611ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 24621ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 24631ba8dfd1SKees Cook } 24641ba8dfd1SKees Cook 2465327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 2466327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 2467327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 2468327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 2469327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2470327953e9SChristoph Jaeger } 2471327953e9SChristoph Jaeger 2472c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2473c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2474c68e5878SArnaud Lacombe my $flag = $1; 2475c68e5878SArnaud Lacombe my $replacement = { 2476c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 2477c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 2478c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 2479c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 2480c68e5878SArnaud Lacombe }; 2481c68e5878SArnaud Lacombe 2482c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 2483c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2484c68e5878SArnaud Lacombe } 2485c68e5878SArnaud Lacombe 2486bff5da43SRob Herring# check for DT compatible documentation 24877dd05b38SFlorian Vaussard if (defined $root && 24887dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 24897dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 24907dd05b38SFlorian Vaussard 2491bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 2492bff5da43SRob Herring 2493cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 2494cc93319bSFlorian Vaussard my $vp_file = $dt_path . "vendor-prefixes.txt"; 2495cc93319bSFlorian Vaussard 2496bff5da43SRob Herring foreach my $compat (@compats) { 2497bff5da43SRob Herring my $compat2 = $compat; 2498185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 2499185d566bSRob Herring my $compat3 = $compat; 2500185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 2501185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 2502bff5da43SRob Herring if ( $? >> 8 ) { 2503bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2504bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 2505bff5da43SRob Herring } 2506bff5da43SRob Herring 25074fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 25084fbf32a6SFlorian Vaussard my $vendor = $1; 2509cc93319bSFlorian Vaussard `grep -Eq "^$vendor\\b" $vp_file`; 2510bff5da43SRob Herring if ( $? >> 8 ) { 2511bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2512cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 2513bff5da43SRob Herring } 2514bff5da43SRob Herring } 2515bff5da43SRob Herring } 2516bff5da43SRob Herring 25175368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 2518de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/); 25195368df20SAndy Whitcroft 25206cd7f386SJoe Perches#line length limit 2521c45dcabdSAndy Whitcroft if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 2522f4c014c0SAndy Whitcroft $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 252329a3c466SJoe Perches !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ || 252429a3c466SJoe Perches $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 252529a3c466SJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) && 25266cd7f386SJoe Perches $length > $max_line_length) 2527c45dcabdSAndy Whitcroft { 2528000d1cc1SJoe Perches WARN("LONG_LINE", 25296cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 25300a920b5bSAndy Whitcroft } 25310a920b5bSAndy Whitcroft 25328905a67cSAndy Whitcroft# check for adding lines without a newline. 25338905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2534000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 2535000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 25368905a67cSAndy Whitcroft } 25378905a67cSAndy Whitcroft 253842e41c54SMike Frysinger# Blackfin: use hi/lo macros 253942e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 254042e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 254142e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2542000d1cc1SJoe Perches ERROR("LO_MACRO", 2543000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 254442e41c54SMike Frysinger } 254542e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 254642e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2547000d1cc1SJoe Perches ERROR("HI_MACRO", 2548000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 254942e41c54SMike Frysinger } 255042e41c54SMike Frysinger } 255142e41c54SMike Frysinger 2552b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2553de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 25540a920b5bSAndy Whitcroft 25550a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 25560a920b5bSAndy Whitcroft# more than 8 must use tabs. 2557c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2558c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2559c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2560d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 25613705ce5bSJoe Perches if (ERROR("CODE_INDENT", 25623705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 25633705ce5bSJoe Perches $fix) { 2564194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 25653705ce5bSJoe Perches } 25660a920b5bSAndy Whitcroft } 25670a920b5bSAndy Whitcroft 256808e44365SAlberto Panizzo# check for space before tabs. 256908e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 257008e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 25713705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 25723705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 25733705ce5bSJoe Perches $fix) { 2574194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2575d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 2576194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2577c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 25783705ce5bSJoe Perches } 257908e44365SAlberto Panizzo } 258008e44365SAlberto Panizzo 2581d1fe9c09SJoe Perches# check for && or || at the start of a line 2582d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2583d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2584d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2585d1fe9c09SJoe Perches } 2586d1fe9c09SJoe Perches 2587d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2588d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 258991cb5195SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2590d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2591d1fe9c09SJoe Perches my $oldindent = $1; 2592d1fe9c09SJoe Perches my $rest = $2; 2593d1fe9c09SJoe Perches 2594d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2595d1fe9c09SJoe Perches if ($pos >= 0) { 2596b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2597b34a26f3SJoe Perches my $newindent = $2; 2598d1fe9c09SJoe Perches 2599d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2600d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2601d1fe9c09SJoe Perches " " x ($pos % 8); 2602d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2603d1fe9c09SJoe Perches 2604d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2605d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 26063705ce5bSJoe Perches 26073705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 26083705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 26093705ce5bSJoe Perches $fix && $line =~ /^\+/) { 2610194f66fcSJoe Perches $fixed[$fixlinenr] =~ 26113705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 26123705ce5bSJoe Perches } 2613d1fe9c09SJoe Perches } 2614d1fe9c09SJoe Perches } 2615d1fe9c09SJoe Perches } 2616d1fe9c09SJoe Perches 26176ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 26186ab3a970SJoe Perches# avoid checking a few false positives: 26196ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 26206ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 26216ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 26226ab3a970SJoe Perches# multiline macros that define functions 26236ab3a970SJoe Perches# known attributes or the __attribute__ keyword 26246ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 26256ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 26263705ce5bSJoe Perches if (CHK("SPACING", 2627f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 26283705ce5bSJoe Perches $fix) { 2629194f66fcSJoe Perches $fixed[$fixlinenr] =~ 2630f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 26313705ce5bSJoe Perches } 2632aad4f614SJoe Perches } 2633aad4f614SJoe Perches 263405880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2635fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 263685ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 263785ad978cSJoe Perches $realline > 2) { 263805880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 263905880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 264005880600SJoe Perches } 264105880600SJoe Perches 264205880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2643a605e32eSJoe Perches $prevrawline =~ /^\+[ \t]*\/\*/ && #starting /* 2644a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 264561135e96SJoe Perches $rawline =~ /^\+/ && #line is new 2646a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 2647a605e32eSJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 2648a605e32eSJoe Perches "networking block comments start with * on subsequent lines\n" . $hereprev); 2649a605e32eSJoe Perches } 2650a605e32eSJoe Perches 2651a605e32eSJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2652c24f9f19SJoe Perches $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 2653c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 2654c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 2655c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 265605880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 265705880600SJoe Perches "networking block comments put the trailing */ on a separate line\n" . $herecurr); 265805880600SJoe Perches } 265905880600SJoe Perches 26607f619191SJoe Perches# check for missing blank lines after struct/union declarations 26617f619191SJoe Perches# with exceptions for various attributes and macros 26627f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 26637f619191SJoe Perches $line =~ /^\+/ && 26647f619191SJoe Perches !($line =~ /^\+\s*$/ || 26657f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 26667f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 26677f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 26687f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 26697f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 26707f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 26717f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 2672d752fcc8SJoe Perches if (CHK("LINE_SPACING", 2673d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 2674d752fcc8SJoe Perches $fix) { 2675f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 2676d752fcc8SJoe Perches } 26777f619191SJoe Perches } 26787f619191SJoe Perches 2679365dd4eaSJoe Perches# check for multiple consecutive blank lines 2680365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 2681365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 2682365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 2683d752fcc8SJoe Perches if (CHK("LINE_SPACING", 2684d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 2685d752fcc8SJoe Perches $fix) { 2686f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 2687d752fcc8SJoe Perches } 2688d752fcc8SJoe Perches 2689365dd4eaSJoe Perches $last_blank_line = $linenr; 2690365dd4eaSJoe Perches } 2691365dd4eaSJoe Perches 26923b617e3bSJoe Perches# check for missing blank lines after declarations 26933f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 26943f7bac03SJoe Perches # actual declarations 26953f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 26965a4e1fd3SJoe Perches # function pointer declarations 26975a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 26983f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 26993f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 27003f7bac03SJoe Perches # known declaration macros 27013f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 27023f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 27033f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 27043f7bac03SJoe Perches # other possible extensions of declaration lines 27053f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 27063f7bac03SJoe Perches # not starting a section or a macro "\" extended line 27073f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 27083f7bac03SJoe Perches # looks like a declaration 27093f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 27105a4e1fd3SJoe Perches # function pointer declarations 27115a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 27123f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 27133f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 27143f7bac03SJoe Perches # known declaration macros 27153f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 27163f7bac03SJoe Perches # start of struct or union or enum 27173b617e3bSJoe Perches $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 27183f7bac03SJoe Perches # start or end of block or continuation of declaration 27193f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 27203f7bac03SJoe Perches # bitfield continuation 27213f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 27223f7bac03SJoe Perches # other possible extensions of declaration lines 27233f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 27243f7bac03SJoe Perches # indentation of previous and current line are the same 27253f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 2726d752fcc8SJoe Perches if (WARN("LINE_SPACING", 2727d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 2728d752fcc8SJoe Perches $fix) { 2729f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 2730d752fcc8SJoe Perches } 27313b617e3bSJoe Perches } 27323b617e3bSJoe Perches 27335f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 27346b4c5bebSAndy Whitcroft# Exceptions: 27356b4c5bebSAndy Whitcroft# 1) within comments 27366b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 27376b4c5bebSAndy Whitcroft# 3) hanging labels 27383705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 27395f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27403705ce5bSJoe Perches if (WARN("LEADING_SPACE", 27413705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 27423705ce5bSJoe Perches $fix) { 2743194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 27443705ce5bSJoe Perches } 27455f7ddae6SRaffaele Recalcati } 27465f7ddae6SRaffaele Recalcati 2747b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 2748b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 2749b9ea10d6SAndy Whitcroft 2750032a4c0fSJoe Perches# check indentation of any line with a bare else 2751840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 2752032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 2753032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 2754032a4c0fSJoe Perches my $tabs = length($1) + 1; 2755840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 2756840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 2757840080a0SJoe Perches defined $lines[$linenr] && 2758840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 2759032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 2760032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 2761032a4c0fSJoe Perches } 2762032a4c0fSJoe Perches } 2763032a4c0fSJoe Perches 2764c00df19aSJoe Perches# check indentation of a line with a break; 2765c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 2766c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 2767c00df19aSJoe Perches my $tabs = $1; 2768c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 2769c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 2770c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 2771c00df19aSJoe Perches } 2772c00df19aSJoe Perches } 2773c00df19aSJoe Perches 27741ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). 27751ba8dfd1SKees Cook if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { 27761ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 27771ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 27781ba8dfd1SKees Cook } 27791ba8dfd1SKees Cook 2780c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 2781cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 2782000d1cc1SJoe Perches WARN("CVS_KEYWORD", 2783000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 2784c2fdda0dSAndy Whitcroft } 278522f2a2efSAndy Whitcroft 278642e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 278742e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 278842e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2789000d1cc1SJoe Perches ERROR("CSYNC", 2790000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 279142e41c54SMike Frysinger } 279242e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 279342e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2794000d1cc1SJoe Perches ERROR("SSYNC", 2795000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 279642e41c54SMike Frysinger } 279742e41c54SMike Frysinger 279856e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 279956e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 280056e77d70SJoe Perches WARN("HOTPLUG_SECTION", 280156e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 280256e77d70SJoe Perches } 280356e77d70SJoe Perches 28049c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 28052b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 28062b474a1aSAndy Whitcroft $realline_next); 28073e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 28083e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 28091b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 2810170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 2811f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 2812171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 2813171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 2814171ae1a4SAndy Whitcroft 28153e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 28163e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 28173e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 28183e469cdcSAndy Whitcroft # until we hit end of it. 28193e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 28203e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 28213e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 28223e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 28233e469cdcSAndy Whitcroft } 2824f74bd194SAndy Whitcroft 28252b474a1aSAndy Whitcroft # Find the real next line. 28262b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 28272b474a1aSAndy Whitcroft if (defined $realline_next && 28282b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 28292b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 28302b474a1aSAndy Whitcroft $realline_next++; 28312b474a1aSAndy Whitcroft } 28322b474a1aSAndy Whitcroft 2833171ae1a4SAndy Whitcroft my $s = $stat; 2834171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 2835cf655043SAndy Whitcroft 2836c2fdda0dSAndy Whitcroft # Ignore goto labels. 2837171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 2838c2fdda0dSAndy Whitcroft 2839c2fdda0dSAndy Whitcroft # Ignore functions being called 2840171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 2841c2fdda0dSAndy Whitcroft 2842463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 2843463f2864SAndy Whitcroft 2844c45dcabdSAndy Whitcroft # declarations always start with types 2845d2506586SAndy Whitcroft } 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) { 2846c45dcabdSAndy Whitcroft my $type = $1; 2847c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 2848c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 2849c45dcabdSAndy Whitcroft 28506c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 2851a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 2852c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 2853c2fdda0dSAndy Whitcroft } 28548905a67cSAndy Whitcroft 28556c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 285665863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 2857c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 28589c0ca6f9SAndy Whitcroft } 28598905a67cSAndy Whitcroft 28608905a67cSAndy Whitcroft # Check for any sort of function declaration. 28618905a67cSAndy Whitcroft # int foo(something bar, other baz); 28628905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 2863171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 28648905a67cSAndy Whitcroft my ($name_len) = length($1); 28658905a67cSAndy Whitcroft 2866cf655043SAndy Whitcroft my $ctx = $s; 2867773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 28688905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 2869cf655043SAndy Whitcroft 28708905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 2871c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 28728905a67cSAndy Whitcroft 2873c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 28748905a67cSAndy Whitcroft } 28758905a67cSAndy Whitcroft } 28768905a67cSAndy Whitcroft } 28778905a67cSAndy Whitcroft 28789c0ca6f9SAndy Whitcroft } 28799c0ca6f9SAndy Whitcroft 288000df344fSAndy Whitcroft# 288100df344fSAndy Whitcroft# Checks which may be anchored in the context. 288200df344fSAndy Whitcroft# 288300df344fSAndy Whitcroft 288400df344fSAndy Whitcroft# Check for switch () and associated case and default 288500df344fSAndy Whitcroft# statements should be at the same indent. 288600df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 288700df344fSAndy Whitcroft my $err = ''; 288800df344fSAndy Whitcroft my $sep = ''; 288900df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 289000df344fSAndy Whitcroft shift(@ctx); 289100df344fSAndy Whitcroft for my $ctx (@ctx) { 289200df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 289300df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 289400df344fSAndy Whitcroft $indent != $cindent) { 289500df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 289600df344fSAndy Whitcroft $sep = ''; 289700df344fSAndy Whitcroft } else { 289800df344fSAndy Whitcroft $sep = "[...]\n"; 289900df344fSAndy Whitcroft } 290000df344fSAndy Whitcroft } 290100df344fSAndy Whitcroft if ($err ne '') { 2902000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 2903000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 2904de7d4f0eSAndy Whitcroft } 2905de7d4f0eSAndy Whitcroft } 2906de7d4f0eSAndy Whitcroft 2907de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 2908de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 29090fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 2910773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 2911773647a0SAndy Whitcroft 29129c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 29138eef05ddSJoe Perches 29148eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 29158eef05ddSJoe Perches WARN("DEEP_INDENTATION", 29168eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 29178eef05ddSJoe Perches } 29188eef05ddSJoe Perches 2919de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 2920de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 2921de7d4f0eSAndy Whitcroft 2922548596d5SAndy Whitcroft my $ctx_ln = $linenr; 2923548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 2924de7d4f0eSAndy Whitcroft 2925548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 2926548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 2927548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 2928548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 2929548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 2930773647a0SAndy Whitcroft $ctx_ln++; 2931773647a0SAndy Whitcroft } 2932548596d5SAndy Whitcroft 293353210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 293453210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 2935773647a0SAndy Whitcroft 2936773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 2937000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2938000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 293901464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 294000df344fSAndy Whitcroft } 2941773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 2942773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 2943773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 2944773647a0SAndy Whitcroft { 29459c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 29469c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 2947000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 2948000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 294901464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 29509c0ca6f9SAndy Whitcroft } 29519c0ca6f9SAndy Whitcroft } 295200df344fSAndy Whitcroft } 295300df344fSAndy Whitcroft 29544d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 29550fe3dc2bSJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 29563e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 29573e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 29583e469cdcSAndy Whitcroft if (!defined $stat); 29594d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 29604d001e4dSAndy Whitcroft 29614d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 29624d001e4dSAndy Whitcroft 29634d001e4dSAndy Whitcroft # Make sure we remove the line prefixes as we have 29644d001e4dSAndy Whitcroft # none on the first line, and are going to readd them 29654d001e4dSAndy Whitcroft # where necessary. 29664d001e4dSAndy Whitcroft $s =~ s/\n./\n/gs; 29674d001e4dSAndy Whitcroft 29684d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 29696f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 29706f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 29714d001e4dSAndy Whitcroft 29724d001e4dSAndy Whitcroft # We want to check the first line inside the block 29734d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 29744d001e4dSAndy Whitcroft # 1) any blank line termination 29754d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 29764d001e4dSAndy Whitcroft # 3) any do (...) { 29774d001e4dSAndy Whitcroft my $continuation = 0; 29784d001e4dSAndy Whitcroft my $check = 0; 29794d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 29804d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 29814d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 29824d001e4dSAndy Whitcroft $continuation = 1; 29834d001e4dSAndy Whitcroft } 29849bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 29854d001e4dSAndy Whitcroft $check = 1; 29864d001e4dSAndy Whitcroft $cond_lines++; 29874d001e4dSAndy Whitcroft } 29884d001e4dSAndy Whitcroft 29894d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 29904d001e4dSAndy Whitcroft # preprocessor statement. 29914d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 29924d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 29934d001e4dSAndy Whitcroft $check = 0; 29944d001e4dSAndy Whitcroft } 29954d001e4dSAndy Whitcroft 29969bd49efeSAndy Whitcroft my $cond_ptr = -1; 2997740504c6SAndy Whitcroft $continuation = 0; 29989bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 29999bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 30004d001e4dSAndy Whitcroft 3001f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3002f16fa28fSAndy Whitcroft # is not linear. 3003f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3004f16fa28fSAndy Whitcroft $check = 0; 3005f16fa28fSAndy Whitcroft } 3006f16fa28fSAndy Whitcroft 30079bd49efeSAndy Whitcroft # Ignore: 30089bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 30099bd49efeSAndy Whitcroft # 2) preprocessor lines, and 30109bd49efeSAndy Whitcroft # 3) labels. 3011740504c6SAndy Whitcroft if ($continuation || 3012740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 30139bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 30149bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3015740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 301630dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 30179bd49efeSAndy Whitcroft $cond_lines++; 30189bd49efeSAndy Whitcroft } 30194d001e4dSAndy Whitcroft } 302030dad6ebSAndy Whitcroft } 30214d001e4dSAndy Whitcroft 30224d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 30234d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 30244d001e4dSAndy Whitcroft 30254d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 30264d001e4dSAndy Whitcroft # this is not this patch's fault. 30274d001e4dSAndy Whitcroft if (!defined($stat_real) || 30284d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 30294d001e4dSAndy Whitcroft $check = 0; 30304d001e4dSAndy Whitcroft } 30314d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 30324d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 30334d001e4dSAndy Whitcroft } 30344d001e4dSAndy Whitcroft 30359bd49efeSAndy Whitcroft #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"; 30364d001e4dSAndy Whitcroft 30374d001e4dSAndy Whitcroft if ($check && (($sindent % 8) != 0 || 30384d001e4dSAndy Whitcroft ($sindent <= $indent && $s ne ''))) { 3039000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3040000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 30414d001e4dSAndy Whitcroft } 30424d001e4dSAndy Whitcroft } 30434d001e4dSAndy Whitcroft 30446c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 30456c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 30461f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 30471f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 30486c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3049c2fdda0dSAndy Whitcroft if ($dbg_values) { 3050c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3051cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3052cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 30531f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3054c2fdda0dSAndy Whitcroft } 30556c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 30566c72ffaaSAndy Whitcroft 305700df344fSAndy Whitcroft#ignore lines not being added 30583705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 305900df344fSAndy Whitcroft 3060653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 30617429c690SAndy Whitcroft if ($dbg_type) { 30627429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3063000d1cc1SJoe Perches ERROR("TEST_TYPE", 3064000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 30657429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3066000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3067000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 30687429c690SAndy Whitcroft } 3069653d4876SAndy Whitcroft next; 3070653d4876SAndy Whitcroft } 3071a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3072a1ef277eSAndy Whitcroft if ($dbg_attr) { 30739360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3074000d1cc1SJoe Perches ERROR("TEST_ATTR", 3075000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 30769360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3077000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3078000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3079a1ef277eSAndy Whitcroft } 3080a1ef277eSAndy Whitcroft next; 3081a1ef277eSAndy Whitcroft } 3082653d4876SAndy Whitcroft 3083f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 308499423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 308599423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3086d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3087d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3088f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3089f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3090f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3091d752fcc8SJoe Perches my $fixedline = $prevrawline; 3092d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3093f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3094d752fcc8SJoe Perches $fixedline = $line; 3095d752fcc8SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1/; 3096f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3097d752fcc8SJoe Perches } 3098f0a594c1SAndy Whitcroft } 3099f0a594c1SAndy Whitcroft 310000df344fSAndy Whitcroft# 310100df344fSAndy Whitcroft# Checks which are anchored on the added line. 310200df344fSAndy Whitcroft# 310300df344fSAndy Whitcroft 3104653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3105c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3106653d4876SAndy Whitcroft my $path = $1; 3107653d4876SAndy Whitcroft if ($path =~ m{//}) { 3108000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3109495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3110495e9d84SJoe Perches } 3111495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3112495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3113495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3114653d4876SAndy Whitcroft } 3115653d4876SAndy Whitcroft } 3116653d4876SAndy Whitcroft 311700df344fSAndy Whitcroft# no C99 // comments 311800df344fSAndy Whitcroft if ($line =~ m{//}) { 31193705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 31203705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 31213705ce5bSJoe Perches $fix) { 3122194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 31233705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 31243705ce5bSJoe Perches my $comment = trim($1); 3125194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 31263705ce5bSJoe Perches } 31273705ce5bSJoe Perches } 312800df344fSAndy Whitcroft } 312900df344fSAndy Whitcroft # Remove C99 comments. 31300a920b5bSAndy Whitcroft $line =~ s@//.*@@; 31316c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 31320a920b5bSAndy Whitcroft 31332b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 31342b474a1aSAndy Whitcroft# the whole statement. 31352b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 31362b474a1aSAndy Whitcroft if (defined $realline_next && 31372b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 31382b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 31392b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 31402b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 31413cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 31423cbf62dfSAndy Whitcroft # a prefix: 31433cbf62dfSAndy Whitcroft # XXX(foo); 31443cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3145653d4876SAndy Whitcroft my $name = $1; 314687a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 31473cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 31483cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 31493cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 31503cbf62dfSAndy Whitcroft 31513cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 31522b474a1aSAndy Whitcroft \n.}\s*$| 315348012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 315448012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 315548012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 31562b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 31572b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 315848012058SAndy Whitcroft )/x) { 31592b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 31602b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 31612b474a1aSAndy Whitcroft } else { 31622b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 31630a920b5bSAndy Whitcroft } 31640a920b5bSAndy Whitcroft } 31652b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 31662b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 31672b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 31682b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 31692b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 31702b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 31712b474a1aSAndy Whitcroft } 31722b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 31732b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3174000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3175000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 31762b474a1aSAndy Whitcroft } 31770a920b5bSAndy Whitcroft 31785150bda4SJoe Eloff# check for global initialisers. 31795129e87cSJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*(?:0|NULL|false)\s*;/) { 3180d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 3181000d1cc1SJoe Perches "do not initialise globals to 0 or NULL\n" . 3182d5e616fcSJoe Perches $herecurr) && 3183d5e616fcSJoe Perches $fix) { 31845129e87cSJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*(0|NULL|false)\s*;/$1;/; 3185d5e616fcSJoe Perches } 3186f0a594c1SAndy Whitcroft } 31870a920b5bSAndy Whitcroft# check for static initialisers. 3188d5e616fcSJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) { 3189d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 3190000d1cc1SJoe Perches "do not initialise statics to 0 or NULL\n" . 3191d5e616fcSJoe Perches $herecurr) && 3192d5e616fcSJoe Perches $fix) { 3193194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/; 3194d5e616fcSJoe Perches } 31950a920b5bSAndy Whitcroft } 31960a920b5bSAndy Whitcroft 31971813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 31981813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 31991813087dSJoe Perches my $tmp = trim($1); 32001813087dSJoe Perches WARN("MISORDERED_TYPE", 32011813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 32021813087dSJoe Perches } 32031813087dSJoe Perches 3204cb710ecaSJoe Perches# check for static const char * arrays. 3205cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3206000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3207000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3208cb710ecaSJoe Perches $herecurr); 3209cb710ecaSJoe Perches } 3210cb710ecaSJoe Perches 3211cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3212cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3213000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3214000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3215cb710ecaSJoe Perches $herecurr); 3216cb710ecaSJoe Perches } 3217cb710ecaSJoe Perches 3218ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3219ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3220ab7e23f3SJoe Perches my $found = $1; 3221ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3222ab7e23f3SJoe Perches WARN("CONST_CONST", 3223ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3224ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3225ab7e23f3SJoe Perches WARN("CONST_CONST", 3226ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3227ab7e23f3SJoe Perches } 3228ab7e23f3SJoe Perches } 3229ab7e23f3SJoe Perches 32309b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 32319b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 32329b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 32339b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 32349b0fa60dSJoe Perches $herecurr); 32359b0fa60dSJoe Perches } 32369b0fa60dSJoe Perches 3237b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3238b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3239b598b670SJoe Perches my $array = $1; 3240b598b670SJoe Perches if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { 3241b598b670SJoe Perches my $array_div = $1; 3242b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3243b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3244b598b670SJoe Perches $fix) { 3245b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3246b598b670SJoe Perches } 3247b598b670SJoe Perches } 3248b598b670SJoe Perches } 3249b598b670SJoe Perches 3250b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3251b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3252b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3253b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3254b36190c5SJoe Perches $fix) { 3255194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3256b36190c5SJoe Perches } 3257b36190c5SJoe Perches } 3258b36190c5SJoe Perches 325992e112fdSJoe Perches# check for uses of DEFINE_PCI_DEVICE_TABLE 326092e112fdSJoe Perches if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) { 326192e112fdSJoe Perches if (WARN("DEFINE_PCI_DEVICE_TABLE", 326292e112fdSJoe Perches "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) && 326392e112fdSJoe Perches $fix) { 3264194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /; 326592e112fdSJoe Perches } 326693ed0e2dSJoe Perches } 326793ed0e2dSJoe Perches 3268653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3269653d4876SAndy Whitcroft# make sense. 3270653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 32718054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3272c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 32738ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 3274653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 3275000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3276000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 32770a920b5bSAndy Whitcroft } 32780a920b5bSAndy Whitcroft 32790a920b5bSAndy Whitcroft# * goes on variable not on type 328065863862SAndy Whitcroft # (char*[ const]) 3281bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3282bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 32833705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3284d8aaf121SAndy Whitcroft 328565863862SAndy Whitcroft # Should start with a space. 328665863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 328765863862SAndy Whitcroft # Should not end with a space. 328865863862SAndy Whitcroft $to =~ s/\s+$//; 328965863862SAndy Whitcroft # '*'s should not have spaces between. 3290f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 329165863862SAndy Whitcroft } 3292d8aaf121SAndy Whitcroft 32933705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 329465863862SAndy Whitcroft if ($from ne $to) { 32953705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 32963705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 32973705ce5bSJoe Perches $fix) { 32983705ce5bSJoe Perches my $sub_from = $ident; 32993705ce5bSJoe Perches my $sub_to = $ident; 33003705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3301194f66fcSJoe Perches $fixed[$fixlinenr] =~ 33023705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 33033705ce5bSJoe Perches } 330465863862SAndy Whitcroft } 3305bfcb2cc7SAndy Whitcroft } 3306bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3307bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 33083705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3309d8aaf121SAndy Whitcroft 331065863862SAndy Whitcroft # Should start with a space. 331165863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 331265863862SAndy Whitcroft # Should not end with a space. 331365863862SAndy Whitcroft $to =~ s/\s+$//; 331465863862SAndy Whitcroft # '*'s should not have spaces between. 3315f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 331665863862SAndy Whitcroft } 331765863862SAndy Whitcroft # Modifiers should have spaces. 331865863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 331965863862SAndy Whitcroft 33203705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3321667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 33223705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 33233705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 33243705ce5bSJoe Perches $fix) { 33253705ce5bSJoe Perches 33263705ce5bSJoe Perches my $sub_from = $match; 33273705ce5bSJoe Perches my $sub_to = $match; 33283705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3329194f66fcSJoe Perches $fixed[$fixlinenr] =~ 33303705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 33313705ce5bSJoe Perches } 333265863862SAndy Whitcroft } 33330a920b5bSAndy Whitcroft } 33340a920b5bSAndy Whitcroft 33350a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 33360a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 33370a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 33380a920b5bSAndy Whitcroft# print "$herecurr"; 33390a920b5bSAndy Whitcroft# $clean = 0; 33400a920b5bSAndy Whitcroft# } 33410a920b5bSAndy Whitcroft 33428905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3343000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3344000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 33458905a67cSAndy Whitcroft } 33468905a67cSAndy Whitcroft 334717441227SJoe Perches# check for uses of printk_ratelimit 334817441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3349000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3350000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 335117441227SJoe Perches } 335217441227SJoe Perches 335300df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 335400df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 335500df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 335625985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 335700df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3358f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 335900df344fSAndy Whitcroft my $ok = 0; 336000df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 336100df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 336225985edcSLucas De Marchi # we have a preceding printk if it ends 336300df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 336400df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 336500df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 336600df344fSAndy Whitcroft $ok = 1; 336700df344fSAndy Whitcroft } 336800df344fSAndy Whitcroft last; 336900df344fSAndy Whitcroft } 337000df344fSAndy Whitcroft } 337100df344fSAndy Whitcroft if ($ok == 0) { 3372000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3373000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 33740a920b5bSAndy Whitcroft } 337500df344fSAndy Whitcroft } 33760a920b5bSAndy Whitcroft 3377243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3378243f3803SJoe Perches my $orig = $1; 3379243f3803SJoe Perches my $level = lc($orig); 3380243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 33818f26b837SJoe Perches my $level2 = $level; 33828f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3383243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3384daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3385243f3803SJoe Perches } 3386243f3803SJoe Perches 3387243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3388d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3389d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3390d5e616fcSJoe Perches $fix) { 3391194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3392d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3393d5e616fcSJoe Perches } 3394243f3803SJoe Perches } 3395243f3803SJoe Perches 3396dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3397dc139313SJoe Perches my $orig = $1; 3398dc139313SJoe Perches my $level = lc($orig); 3399dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3400dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3401dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3402dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3403dc139313SJoe Perches } 3404dc139313SJoe Perches 340591c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 340691c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 340791c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 340891c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 340991c9afafSAndy Lutomirski WARN("ENOSYS", 341091c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 341191c9afafSAndy Lutomirski } 341291c9afafSAndy Lutomirski 3413653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3414653d4876SAndy Whitcroft# or if closed on same line 34158d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 3416c45dcabdSAndy Whitcroft !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { 34178d182478SJoe Perches if (ERROR("OPEN_BRACE", 34188d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 34198d182478SJoe Perches $fix) { 34208d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 34218d182478SJoe Perches my $fixed_line = $rawline; 34228d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 34238d182478SJoe Perches my $line1 = $1; 34248d182478SJoe Perches my $line2 = $2; 34258d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 34268d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 34278d182478SJoe Perches if ($line2 !~ /^\s*$/) { 34288d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 34298d182478SJoe Perches } 34308d182478SJoe Perches } 34310a920b5bSAndy Whitcroft } 3432653d4876SAndy Whitcroft 34338905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 34348905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 34358905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 34368d182478SJoe Perches if (ERROR("OPEN_BRACE", 34378d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 34388d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 34398d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 34408d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 34418d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 34428d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 34438d182478SJoe Perches $fixedline = $rawline; 34448d182478SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1\t/; 34458d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 34468d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 34478d182478SJoe Perches } 34488d182478SJoe Perches } 34498905a67cSAndy Whitcroft } 34508905a67cSAndy Whitcroft 34510c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 34523705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 34533705ce5bSJoe Perches if (WARN("SPACING", 34543705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 34553705ce5bSJoe Perches $fix) { 3456194f66fcSJoe Perches $fixed[$fixlinenr] =~ 34573705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 34583705ce5bSJoe Perches } 34590c73b4ebSAndy Whitcroft } 34600c73b4ebSAndy Whitcroft 346131070b5dSJoe Perches# Function pointer declarations 346231070b5dSJoe Perches# check spacing between type, funcptr, and args 346331070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 346491f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 346531070b5dSJoe Perches my $declare = $1; 346631070b5dSJoe Perches my $pre_pointer_space = $2; 346731070b5dSJoe Perches my $post_pointer_space = $3; 346831070b5dSJoe Perches my $funcname = $4; 346931070b5dSJoe Perches my $post_funcname_space = $5; 347031070b5dSJoe Perches my $pre_args_space = $6; 347131070b5dSJoe Perches 347291f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 347391f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 347491f72e9cSJoe Perches# don't need a space so don't warn for those. 347591f72e9cSJoe Perches my $post_declare_space = ""; 347691f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 347791f72e9cSJoe Perches $post_declare_space = $1; 347891f72e9cSJoe Perches $declare = rtrim($declare); 347991f72e9cSJoe Perches } 348091f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 348131070b5dSJoe Perches WARN("SPACING", 348231070b5dSJoe Perches "missing space after return type\n" . $herecurr); 348391f72e9cSJoe Perches $post_declare_space = " "; 348431070b5dSJoe Perches } 348531070b5dSJoe Perches 348631070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 348791f72e9cSJoe Perches# This test is not currently implemented because these declarations are 348891f72e9cSJoe Perches# equivalent to 348991f72e9cSJoe Perches# int foo(int bar, ...) 349091f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 349191f72e9cSJoe Perches# 349291f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 349391f72e9cSJoe Perches# WARN("SPACING", 349491f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 349591f72e9cSJoe Perches# } 349631070b5dSJoe Perches 349731070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 349831070b5dSJoe Perches if (defined $pre_pointer_space && 349931070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 350031070b5dSJoe Perches WARN("SPACING", 350131070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 350231070b5dSJoe Perches } 350331070b5dSJoe Perches 350431070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 350531070b5dSJoe Perches if (defined $post_pointer_space && 350631070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 350731070b5dSJoe Perches WARN("SPACING", 350831070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 350931070b5dSJoe Perches } 351031070b5dSJoe Perches 351131070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 351231070b5dSJoe Perches if (defined $post_funcname_space && 351331070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 351431070b5dSJoe Perches WARN("SPACING", 351531070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 351631070b5dSJoe Perches } 351731070b5dSJoe Perches 351831070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 351931070b5dSJoe Perches if (defined $pre_args_space && 352031070b5dSJoe Perches $pre_args_space =~ /^\s/) { 352131070b5dSJoe Perches WARN("SPACING", 352231070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 352331070b5dSJoe Perches } 352431070b5dSJoe Perches 352531070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3526194f66fcSJoe Perches $fixed[$fixlinenr] =~ 352791f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 352831070b5dSJoe Perches } 352931070b5dSJoe Perches } 353031070b5dSJoe Perches 35318d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 35328d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3533fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3534fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 35358d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 35368d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 35378d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3538fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3539daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 35403705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 35413705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 35423705ce5bSJoe Perches $fix) { 3543194f66fcSJoe Perches $fixed[$fixlinenr] =~ 35443705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 35453705ce5bSJoe Perches } 35468d31cfceSAndy Whitcroft } 35478d31cfceSAndy Whitcroft } 35488d31cfceSAndy Whitcroft 3549f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 35506c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 3551c2fdda0dSAndy Whitcroft my $name = $1; 3552773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 3553773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 3554c2fdda0dSAndy Whitcroft 3555c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 3556773647a0SAndy Whitcroft if ($name =~ /^(?: 3557773647a0SAndy Whitcroft if|for|while|switch|return|case| 3558773647a0SAndy Whitcroft volatile|__volatile__| 3559773647a0SAndy Whitcroft __attribute__|format|__extension__| 3560773647a0SAndy Whitcroft asm|__asm__)$/x) 3561773647a0SAndy Whitcroft { 3562c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 3563c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 3564c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 3565c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 3566773647a0SAndy Whitcroft 3567773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 3568c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 3569c2fdda0dSAndy Whitcroft 3570c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 3571c2fdda0dSAndy Whitcroft # likely a typedef for a function. 3572773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 3573c2fdda0dSAndy Whitcroft 3574c2fdda0dSAndy Whitcroft } else { 35753705ce5bSJoe Perches if (WARN("SPACING", 35763705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 35773705ce5bSJoe Perches $fix) { 3578194f66fcSJoe Perches $fixed[$fixlinenr] =~ 35793705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 35803705ce5bSJoe Perches } 3581f0a594c1SAndy Whitcroft } 35826c72ffaaSAndy Whitcroft } 35839a4cad4eSEric Nelson 3584653d4876SAndy Whitcroft# Check operator spacing. 35850a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 35863705ce5bSJoe Perches my $fixed_line = ""; 35873705ce5bSJoe Perches my $line_fixed = 0; 35883705ce5bSJoe Perches 35899c0ca6f9SAndy Whitcroft my $ops = qr{ 35909c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 35919c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 35929c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 35931f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 359484731623SJoe Perches \?:|\?|: 35959c0ca6f9SAndy Whitcroft }x; 3596cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 35973705ce5bSJoe Perches 35983705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 35993705ce5bSJoe Perches## foreach my $el (@elements) { 36003705ce5bSJoe Perches## print("el: <$el>\n"); 36013705ce5bSJoe Perches## } 36023705ce5bSJoe Perches 36033705ce5bSJoe Perches my @fix_elements = (); 360400df344fSAndy Whitcroft my $off = 0; 36056c72ffaaSAndy Whitcroft 36063705ce5bSJoe Perches foreach my $el (@elements) { 36073705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 36083705ce5bSJoe Perches $off += length($el); 36093705ce5bSJoe Perches } 36103705ce5bSJoe Perches 36113705ce5bSJoe Perches $off = 0; 36123705ce5bSJoe Perches 36136c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 3614b34c648bSJoe Perches my $last_after = -1; 36156c72ffaaSAndy Whitcroft 36160a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 36173705ce5bSJoe Perches 36183705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 36193705ce5bSJoe Perches 36203705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 36213705ce5bSJoe Perches 36224a0df2efSAndy Whitcroft $off += length($elements[$n]); 36234a0df2efSAndy Whitcroft 362425985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 3625773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 3626773647a0SAndy Whitcroft my $cc = ''; 3627773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 3628773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 3629773647a0SAndy Whitcroft } 3630773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 3631773647a0SAndy Whitcroft 36324a0df2efSAndy Whitcroft my $a = ''; 36334a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 36344a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 3635cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 36364a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 36374a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 3638773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 36394a0df2efSAndy Whitcroft 36400a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 36414a0df2efSAndy Whitcroft 36424a0df2efSAndy Whitcroft my $c = ''; 36430a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 36444a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 36454a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 3646cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 36474a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 36484a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 36498b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 36504a0df2efSAndy Whitcroft } else { 36514a0df2efSAndy Whitcroft $c = 'E'; 36520a920b5bSAndy Whitcroft } 36530a920b5bSAndy Whitcroft 36544a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 36554a0df2efSAndy Whitcroft 36564a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 36574a0df2efSAndy Whitcroft 36586c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 3659de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 36600a920b5bSAndy Whitcroft 366174048ed8SAndy Whitcroft # Pull out the value of this operator. 36626c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 36630a920b5bSAndy Whitcroft 36641f65f947SAndy Whitcroft # Get the full operator variant. 36651f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 36661f65f947SAndy Whitcroft 366713214adfSAndy Whitcroft # Ignore operators passed as parameters. 366813214adfSAndy Whitcroft if ($op_type ne 'V' && 3669d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 367013214adfSAndy Whitcroft 3671cf655043SAndy Whitcroft# # Ignore comments 3672cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 367313214adfSAndy Whitcroft 3674d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 367513214adfSAndy Whitcroft } elsif ($op eq ';') { 3676cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 3677cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 36783705ce5bSJoe Perches if (ERROR("SPACING", 36793705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 3680b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 36813705ce5bSJoe Perches $line_fixed = 1; 36823705ce5bSJoe Perches } 3683d8aaf121SAndy Whitcroft } 3684d8aaf121SAndy Whitcroft 3685d8aaf121SAndy Whitcroft # // is a comment 3686d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 36870a920b5bSAndy Whitcroft 3688b00e4814SJoe Perches # : when part of a bitfield 3689b00e4814SJoe Perches } elsif ($opv eq ':B') { 3690b00e4814SJoe Perches # skip the bitfield test for now 3691b00e4814SJoe Perches 36921f65f947SAndy Whitcroft # No spaces for: 36931f65f947SAndy Whitcroft # -> 3694b00e4814SJoe Perches } elsif ($op eq '->') { 36954a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 36963705ce5bSJoe Perches if (ERROR("SPACING", 36973705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 3698b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 36993705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 37003705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 37013705ce5bSJoe Perches } 3702b34c648bSJoe Perches $line_fixed = 1; 37033705ce5bSJoe Perches } 37040a920b5bSAndy Whitcroft } 37050a920b5bSAndy Whitcroft 37062381097bSJoe Perches # , must not have a space before and must have a space on the right. 37070a920b5bSAndy Whitcroft } elsif ($op eq ',') { 37082381097bSJoe Perches my $rtrim_before = 0; 37092381097bSJoe Perches my $space_after = 0; 37102381097bSJoe Perches if ($ctx =~ /Wx./) { 37112381097bSJoe Perches if (ERROR("SPACING", 37122381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 37132381097bSJoe Perches $line_fixed = 1; 37142381097bSJoe Perches $rtrim_before = 1; 37152381097bSJoe Perches } 37162381097bSJoe Perches } 3717cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 37183705ce5bSJoe Perches if (ERROR("SPACING", 37193705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 37203705ce5bSJoe Perches $line_fixed = 1; 3721b34c648bSJoe Perches $last_after = $n; 37222381097bSJoe Perches $space_after = 1; 37232381097bSJoe Perches } 37242381097bSJoe Perches } 37252381097bSJoe Perches if ($rtrim_before || $space_after) { 37262381097bSJoe Perches if ($rtrim_before) { 37272381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 37282381097bSJoe Perches } else { 37292381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 37302381097bSJoe Perches } 37312381097bSJoe Perches if ($space_after) { 37322381097bSJoe Perches $good .= " "; 37333705ce5bSJoe Perches } 37340a920b5bSAndy Whitcroft } 37350a920b5bSAndy Whitcroft 37369c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 373774048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 37389c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 37399c0ca6f9SAndy Whitcroft 37409c0ca6f9SAndy Whitcroft # unary operators should have a space before and 37419c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 37429c0ca6f9SAndy Whitcroft # unary operator, or a cast 37439c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 374474048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 37450d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 3746cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 37473705ce5bSJoe Perches if (ERROR("SPACING", 37483705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 3749b34c648bSJoe Perches if ($n != $last_after + 2) { 3750b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 37513705ce5bSJoe Perches $line_fixed = 1; 37523705ce5bSJoe Perches } 37530a920b5bSAndy Whitcroft } 3754b34c648bSJoe Perches } 3755a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 3756171ae1a4SAndy Whitcroft # A unary '*' may be const 3757171ae1a4SAndy Whitcroft 3758171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 37593705ce5bSJoe Perches if (ERROR("SPACING", 37603705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 3761b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 37623705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 37633705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 37643705ce5bSJoe Perches } 3765b34c648bSJoe Perches $line_fixed = 1; 37663705ce5bSJoe Perches } 37670a920b5bSAndy Whitcroft } 37680a920b5bSAndy Whitcroft 37690a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 37700a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 3771773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 37723705ce5bSJoe Perches if (ERROR("SPACING", 37733705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 3774b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 37753705ce5bSJoe Perches $line_fixed = 1; 37763705ce5bSJoe Perches } 37770a920b5bSAndy Whitcroft } 3778773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 3779773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 37803705ce5bSJoe Perches if (ERROR("SPACING", 37813705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 3782b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 37833705ce5bSJoe Perches $line_fixed = 1; 37843705ce5bSJoe Perches } 3785653d4876SAndy Whitcroft } 3786773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 37873705ce5bSJoe Perches if (ERROR("SPACING", 37883705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 3789b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 37903705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 37913705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 3792773647a0SAndy Whitcroft } 3793b34c648bSJoe Perches $line_fixed = 1; 37943705ce5bSJoe Perches } 37953705ce5bSJoe Perches } 37960a920b5bSAndy Whitcroft 37970a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 37989c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 37999c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 38009c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 3801c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 3802c2fdda0dSAndy Whitcroft $op eq '%') 38030a920b5bSAndy Whitcroft { 3804d2e025f3SJoe Perches if ($check) { 3805d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 3806d2e025f3SJoe Perches if (CHK("SPACING", 3807d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 3808d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 3809d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 3810d2e025f3SJoe Perches $line_fixed = 1; 3811d2e025f3SJoe Perches } 3812d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 3813d2e025f3SJoe Perches if (CHK("SPACING", 3814d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 3815d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 3816d2e025f3SJoe Perches $line_fixed = 1; 3817d2e025f3SJoe Perches } 3818d2e025f3SJoe Perches } 3819d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 38203705ce5bSJoe Perches if (ERROR("SPACING", 38213705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 3822b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 3823b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 3824b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 3825b34c648bSJoe Perches } 38263705ce5bSJoe Perches $line_fixed = 1; 38273705ce5bSJoe Perches } 38280a920b5bSAndy Whitcroft } 38290a920b5bSAndy Whitcroft 38301f65f947SAndy Whitcroft # A colon needs no spaces before when it is 38311f65f947SAndy Whitcroft # terminating a case value or a label. 38321f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 38331f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 38343705ce5bSJoe Perches if (ERROR("SPACING", 38353705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 3836b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 38373705ce5bSJoe Perches $line_fixed = 1; 38383705ce5bSJoe Perches } 38391f65f947SAndy Whitcroft } 38401f65f947SAndy Whitcroft 38410a920b5bSAndy Whitcroft # All the others need spaces both sides. 3842cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 38431f65f947SAndy Whitcroft my $ok = 0; 38441f65f947SAndy Whitcroft 384522f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 38461f65f947SAndy Whitcroft if (($op eq '<' && 38471f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 38481f65f947SAndy Whitcroft ($op eq '>' && 38491f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 38501f65f947SAndy Whitcroft { 38511f65f947SAndy Whitcroft $ok = 1; 38521f65f947SAndy Whitcroft } 38531f65f947SAndy Whitcroft 3854e0df7e1fSJoe Perches # for asm volatile statements 3855e0df7e1fSJoe Perches # ignore a colon with another 3856e0df7e1fSJoe Perches # colon immediately before or after 3857e0df7e1fSJoe Perches if (($op eq ':') && 3858e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 3859e0df7e1fSJoe Perches $ok = 1; 3860e0df7e1fSJoe Perches } 3861e0df7e1fSJoe Perches 386284731623SJoe Perches # messages are ERROR, but ?: are CHK 38631f65f947SAndy Whitcroft if ($ok == 0) { 386484731623SJoe Perches my $msg_type = \&ERROR; 386584731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 386684731623SJoe Perches 386784731623SJoe Perches if (&{$msg_type}("SPACING", 38683705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 3869b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 3870b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 3871b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 3872b34c648bSJoe Perches } 38733705ce5bSJoe Perches $line_fixed = 1; 38743705ce5bSJoe Perches } 38750a920b5bSAndy Whitcroft } 387622f2a2efSAndy Whitcroft } 38774a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 38783705ce5bSJoe Perches 38793705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 38803705ce5bSJoe Perches 38813705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 38820a920b5bSAndy Whitcroft } 38833705ce5bSJoe Perches 38843705ce5bSJoe Perches if (($#elements % 2) == 0) { 38853705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 38863705ce5bSJoe Perches } 38873705ce5bSJoe Perches 3888194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 3889194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 38903705ce5bSJoe Perches } 38913705ce5bSJoe Perches 38923705ce5bSJoe Perches 38930a920b5bSAndy Whitcroft } 38940a920b5bSAndy Whitcroft 3895786b6326SJoe Perches# check for whitespace before a non-naked semicolon 3896d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 3897786b6326SJoe Perches if (WARN("SPACING", 3898786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 3899786b6326SJoe Perches $fix) { 3900194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 3901786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 3902786b6326SJoe Perches } 3903786b6326SJoe Perches } 3904786b6326SJoe Perches 3905f0a594c1SAndy Whitcroft# check for multiple assignments 3906f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 3907000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 3908000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 3909f0a594c1SAndy Whitcroft } 3910f0a594c1SAndy Whitcroft 391122f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 391222f2a2efSAndy Whitcroft## # continuation. 391322f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 391422f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 391522f2a2efSAndy Whitcroft## 391622f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 391722f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 391822f2a2efSAndy Whitcroft## my $ln = $line; 391922f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 392022f2a2efSAndy Whitcroft## } 392122f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 3922000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 3923000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 392422f2a2efSAndy Whitcroft## } 392522f2a2efSAndy Whitcroft## } 3926f0a594c1SAndy Whitcroft 39270a920b5bSAndy Whitcroft#need space before brace following if, while, etc 392822f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 392922f2a2efSAndy Whitcroft $line =~ /do{/) { 39303705ce5bSJoe Perches if (ERROR("SPACING", 39313705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 39323705ce5bSJoe Perches $fix) { 3933194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; 39343705ce5bSJoe Perches } 3935de7d4f0eSAndy Whitcroft } 3936de7d4f0eSAndy Whitcroft 3937c4a62ef9SJoe Perches## # check for blank lines before declarations 3938c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 3939c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 3940c4a62ef9SJoe Perches## WARN("SPACING", 3941c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 3942c4a62ef9SJoe Perches## } 3943c4a62ef9SJoe Perches## 3944c4a62ef9SJoe Perches 3945de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 3946de7d4f0eSAndy Whitcroft# on the line 3947de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 3948d5e616fcSJoe Perches if (ERROR("SPACING", 3949d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 3950d5e616fcSJoe Perches $fix) { 3951194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3952d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 3953d5e616fcSJoe Perches } 39540a920b5bSAndy Whitcroft } 39550a920b5bSAndy Whitcroft 395622f2a2efSAndy Whitcroft# check spacing on square brackets 395722f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 39583705ce5bSJoe Perches if (ERROR("SPACING", 39593705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 39603705ce5bSJoe Perches $fix) { 3961194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39623705ce5bSJoe Perches s/\[\s+/\[/; 39633705ce5bSJoe Perches } 396422f2a2efSAndy Whitcroft } 396522f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 39663705ce5bSJoe Perches if (ERROR("SPACING", 39673705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 39683705ce5bSJoe Perches $fix) { 3969194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39703705ce5bSJoe Perches s/\s+\]/\]/; 39713705ce5bSJoe Perches } 397222f2a2efSAndy Whitcroft } 397322f2a2efSAndy Whitcroft 3974c45dcabdSAndy Whitcroft# check spacing on parentheses 39759c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 39769c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 39773705ce5bSJoe Perches if (ERROR("SPACING", 39783705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 39793705ce5bSJoe Perches $fix) { 3980194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39813705ce5bSJoe Perches s/\(\s+/\(/; 39823705ce5bSJoe Perches } 398322f2a2efSAndy Whitcroft } 398413214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 3985c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 3986c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 39873705ce5bSJoe Perches if (ERROR("SPACING", 39883705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 39893705ce5bSJoe Perches $fix) { 3990194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39913705ce5bSJoe Perches s/\s+\)/\)/; 39923705ce5bSJoe Perches } 399322f2a2efSAndy Whitcroft } 399422f2a2efSAndy Whitcroft 3995e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 3996e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 3997e2826fd0SJoe Perches 3998e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 3999ea4acbb1SJoe Perches my $var = $1; 4000ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4001ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4002ea4acbb1SJoe Perches $fix) { 4003ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4004ea4acbb1SJoe Perches } 4005ea4acbb1SJoe Perches } 4006ea4acbb1SJoe Perches 4007ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4008ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4009ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4010ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4011ea4acbb1SJoe Perches my $var = $2; 4012ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4013ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4014ea4acbb1SJoe Perches $fix) { 4015ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4016ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4017ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4018ea4acbb1SJoe Perches } 4019e2826fd0SJoe Perches } 4020e2826fd0SJoe Perches 40210a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 40224a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 40230a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 40243705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 40253705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 40263705ce5bSJoe Perches $fix) { 4027194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40283705ce5bSJoe Perches s/^(.)\s+/$1/; 40293705ce5bSJoe Perches } 40300a920b5bSAndy Whitcroft } 40310a920b5bSAndy Whitcroft 40325b9553abSJoe Perches# return is not a function 4033507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4034c45dcabdSAndy Whitcroft my $spacing = $1; 4035507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 40365b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 40375b9553abSJoe Perches my $value = $1; 40385b9553abSJoe Perches $value = deparenthesize($value); 40395b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4040000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4041000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 40425b9553abSJoe Perches } 4043c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4044000d1cc1SJoe Perches ERROR("SPACING", 4045000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4046c45dcabdSAndy Whitcroft } 4047c45dcabdSAndy Whitcroft } 4048507e5141SJoe Perches 4049b43ae21bSJoe Perches# unnecessary return in a void function 4050b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4051b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4052b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4053b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4054b43ae21bSJoe Perches $linenr >= 3 && 4055b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4056b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 40579819cf25SJoe Perches WARN("RETURN_VOID", 4058b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 40599819cf25SJoe Perches } 40609819cf25SJoe Perches 4061189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4062189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4063189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4064189248d8SJoe Perches my $openparens = $1; 4065189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4066189248d8SJoe Perches my $msg = ""; 4067189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4068189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4069189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4070189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4071189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4072189248d8SJoe Perches } 4073189248d8SJoe Perches } 4074189248d8SJoe Perches 4075f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4076f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 407753a3c448SAndy Whitcroft my $name = $1; 407853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4079000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4080f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 408153a3c448SAndy Whitcroft } 408253a3c448SAndy Whitcroft } 4083c45dcabdSAndy Whitcroft 40840a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 40854a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 40863705ce5bSJoe Perches if (ERROR("SPACING", 40873705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 40883705ce5bSJoe Perches $fix) { 4089194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40903705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 40913705ce5bSJoe Perches } 40920a920b5bSAndy Whitcroft } 40930a920b5bSAndy Whitcroft 4094f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4095f5fe35ddSAndy Whitcroft# statements after the conditional. 4096170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 40973e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 40983e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 40993e469cdcSAndy Whitcroft if (!defined $stat); 4100170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4101170d3a22SAndy Whitcroft $remain_next, $off_next); 4102170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4103170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4104170d3a22SAndy Whitcroft 4105170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4106170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4107170d3a22SAndy Whitcroft # then count those as offsets. 4108170d3a22SAndy Whitcroft my ($whitespace) = 4109170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4110170d3a22SAndy Whitcroft my $offset = 4111170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4112170d3a22SAndy Whitcroft 4113170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4114170d3a22SAndy Whitcroft $offset} = 1; 4115170d3a22SAndy Whitcroft } 4116170d3a22SAndy Whitcroft } 4117170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4118c11230f4SJoe Perches defined($stat) && defined($cond) && 4119170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4120171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 41218905a67cSAndy Whitcroft 4122b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4123000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4124000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 41258905a67cSAndy Whitcroft } 41268905a67cSAndy Whitcroft 41278905a67cSAndy Whitcroft # Find out what is on the end of the line after the 41288905a67cSAndy Whitcroft # conditional. 4129773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 41308905a67cSAndy Whitcroft $s =~ s/\n.*//g; 413113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 413253210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 413353210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4134773647a0SAndy Whitcroft { 4135bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4136bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4137bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 413842bdf74cSHidetoshi Seto my $stat_real = ''; 4139bb44ad39SAndy Whitcroft 414042bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 414142bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4142bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4143bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4144bb44ad39SAndy Whitcroft } 4145bb44ad39SAndy Whitcroft 4146000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4147000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 41488905a67cSAndy Whitcroft } 41498905a67cSAndy Whitcroft } 41508905a67cSAndy Whitcroft 415113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 415213214adfSAndy Whitcroft if ($line =~ / 415313214adfSAndy Whitcroft (?: 415413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 415513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 415613214adfSAndy Whitcroft (?:\&\&|\|\|) 415713214adfSAndy Whitcroft | 415813214adfSAndy Whitcroft (?:\&\&|\|\|) 415913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 416013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 416113214adfSAndy Whitcroft )/x) 416213214adfSAndy Whitcroft { 4163000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4164000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 416513214adfSAndy Whitcroft } 416613214adfSAndy Whitcroft 41678905a67cSAndy Whitcroft# if and else should not have general statements after it 416813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 416913214adfSAndy Whitcroft my $s = $1; 417013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 417113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4172000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4173000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 41740a920b5bSAndy Whitcroft } 417513214adfSAndy Whitcroft } 417639667782SAndy Whitcroft# if should not continue a brace 417739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4178000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4179048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 418039667782SAndy Whitcroft $herecurr); 418139667782SAndy Whitcroft } 4182a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4183a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4184a1080bf8SAndy Whitcroft $line !~ /\G(?: 41853fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4186a1080bf8SAndy Whitcroft \s*return\s+ 4187a1080bf8SAndy Whitcroft )/xg) 4188a1080bf8SAndy Whitcroft { 4189000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4190000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4191a1080bf8SAndy Whitcroft } 41920a920b5bSAndy Whitcroft 41930a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 41940a920b5bSAndy Whitcroft # indent level to be relevant to each other. 41958b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 41960a920b5bSAndy Whitcroft $previndent == $indent) { 41978b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 41988b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 41998b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 42008b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 42018b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 42028b8856f4SJoe Perches my $fixedline = $prevrawline; 42038b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 42048b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 42058b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42068b8856f4SJoe Perches } 42078b8856f4SJoe Perches $fixedline = $rawline; 42088b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 42098b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42108b8856f4SJoe Perches } 42110a920b5bSAndy Whitcroft } 42120a920b5bSAndy Whitcroft 42138b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4214c2fdda0dSAndy Whitcroft $previndent == $indent) { 4215c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4216c2fdda0dSAndy Whitcroft 4217c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4218c2fdda0dSAndy Whitcroft # conditional. 4219773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4220c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4221c2fdda0dSAndy Whitcroft 4222c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 42238b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 42248b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 42258b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 42268b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 42278b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 42288b8856f4SJoe Perches my $fixedline = $prevrawline; 42298b8856f4SJoe Perches my $trailing = $rawline; 42308b8856f4SJoe Perches $trailing =~ s/^\+//; 42318b8856f4SJoe Perches $trailing = trim($trailing); 42328b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 42338b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42348b8856f4SJoe Perches } 4235c2fdda0dSAndy Whitcroft } 4236c2fdda0dSAndy Whitcroft } 4237c2fdda0dSAndy Whitcroft 423895e2c602SJoe Perches#Specific variable tests 4239323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4240323c1260SJoe Perches my $var = $1; 424195e2c602SJoe Perches 424295e2c602SJoe Perches#gcc binary extension 424395e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4244d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4245d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4246d5e616fcSJoe Perches $fix) { 4247d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4248194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4249d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4250d5e616fcSJoe Perches } 425195e2c602SJoe Perches } 425295e2c602SJoe Perches 425395e2c602SJoe Perches#CamelCase 4254807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4255be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 425622735ce8SJoe Perches#Ignore Page<foo> variants 4257807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 425822735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4259f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4260f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4261f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 42627e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 42637e781f67SJoe Perches my $word = $1; 42647e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4265d8b07710SJoe Perches if ($check) { 4266d8b07710SJoe Perches seed_camelcase_includes(); 4267d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4268d8b07710SJoe Perches seed_camelcase_file($realfile); 4269d8b07710SJoe Perches $camelcase_file_seeded = 1; 4270d8b07710SJoe Perches } 4271d8b07710SJoe Perches } 42727e781f67SJoe Perches if (!defined $camelcase{$word}) { 42737e781f67SJoe Perches $camelcase{$word} = 1; 4274be79794bSJoe Perches CHK("CAMELCASE", 42757e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 42767e781f67SJoe Perches } 4277323c1260SJoe Perches } 4278323c1260SJoe Perches } 42793445686aSJoe Perches } 42800a920b5bSAndy Whitcroft 42810a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4282d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4283d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4284d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4285d5e616fcSJoe Perches $fix) { 4286194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4287d5e616fcSJoe Perches } 42880a920b5bSAndy Whitcroft } 42890a920b5bSAndy Whitcroft 42900e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 42910e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4292c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4293e09dec48SAndy Whitcroft my $file = "$1.h"; 4294e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4295e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4296e09dec48SAndy Whitcroft $realfile ne $checkfile && 42977840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4298c45dcabdSAndy Whitcroft { 42990e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 43000e212e0aSFabian Frederick if ($asminclude > 0) { 4301e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4302000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4303000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4304e09dec48SAndy Whitcroft } else { 4305000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4306000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4307e09dec48SAndy Whitcroft } 43080a920b5bSAndy Whitcroft } 43090a920b5bSAndy Whitcroft } 43100e212e0aSFabian Frederick } 43110a920b5bSAndy Whitcroft 4312653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4313653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4314cf655043SAndy Whitcroft# in a known good container 4315b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4316b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4317d8aaf121SAndy Whitcroft my $ln = $linenr; 4318d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4319c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4320c45dcabdSAndy Whitcroft my $ctx = ''; 432108a2843eSJoe Perches my $has_flow_statement = 0; 432208a2843eSJoe Perches my $has_arg_concat = 0; 4323c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4324f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4325f74bd194SAndy Whitcroft $ctx = $dstat; 4326c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4327a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4328c45dcabdSAndy Whitcroft 432908a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 433008a2843eSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/); 433108a2843eSJoe Perches 4332f74bd194SAndy Whitcroft $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; 4333292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4334c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4335c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4336c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4337c45dcabdSAndy Whitcroft 4338c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4339bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4340bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 4341c81769fdSAndy Whitcroft $dstat =~ s/\[[^\[\]]*\]/1/) 4342bf30d6edSAndy Whitcroft { 4343c45dcabdSAndy Whitcroft } 4344c45dcabdSAndy Whitcroft 4345e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 4346e45bab8eSAndy Whitcroft while ($dstat =~ s/("X*")\s*$Ident/$1/ || 4347e45bab8eSAndy Whitcroft $dstat =~ s/$Ident\s*("X*")/$1/) 4348e45bab8eSAndy Whitcroft { 4349e45bab8eSAndy Whitcroft } 4350e45bab8eSAndy Whitcroft 4351c45dcabdSAndy Whitcroft my $exceptions = qr{ 4352c45dcabdSAndy Whitcroft $Declare| 4353c45dcabdSAndy Whitcroft module_param_named| 4354a0a0a7a9SKees Cook MODULE_PARM_DESC| 4355c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4356c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4357383099fdSAndy Whitcroft __typeof__\(| 435822fd2d3eSStefani Seibold union| 435922fd2d3eSStefani Seibold struct| 4360ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 4361ea71a0a0SAndy Whitcroft ^\"|\"$ 4362c45dcabdSAndy Whitcroft }x; 43635eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4364f74bd194SAndy Whitcroft if ($dstat ne '' && 4365f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4366f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 43673cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4368356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4369f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4370f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4371e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 437272f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4373f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4374f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4375f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 4376f95a7e6aSJoe Perches $dstat !~ /^\({/ && # ({... 4377f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4378c45dcabdSAndy Whitcroft { 4379f74bd194SAndy Whitcroft $ctx =~ s/\n*$//; 4380f74bd194SAndy Whitcroft my $herectx = $here . "\n"; 4381f74bd194SAndy Whitcroft my $cnt = statement_rawlines($ctx); 4382f74bd194SAndy Whitcroft 4383f74bd194SAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 4384f74bd194SAndy Whitcroft $herectx .= raw_line($linenr, $n) . "\n"; 4385c45dcabdSAndy Whitcroft } 4386c45dcabdSAndy Whitcroft 4387f74bd194SAndy Whitcroft if ($dstat =~ /;/) { 4388f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4389f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4390f74bd194SAndy Whitcroft } else { 4391000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4392388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4393d8aaf121SAndy Whitcroft } 43940a920b5bSAndy Whitcroft } 43955023d347SJoe Perches 439608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 439708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 439808a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 439908a2843eSJoe Perches my $herectx = $here . "\n"; 440008a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 440108a2843eSJoe Perches 440208a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 440308a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 440408a2843eSJoe Perches } 440508a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 440608a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 440708a2843eSJoe Perches } 440808a2843eSJoe Perches 4409481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 44105023d347SJoe Perches 44115023d347SJoe Perches } else { 44125023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4413481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4414481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 44155023d347SJoe Perches $line =~ /^\+.*\\$/) { 44165023d347SJoe Perches WARN("LINE_CONTINUATIONS", 44175023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 44185023d347SJoe Perches } 4419653d4876SAndy Whitcroft } 44200a920b5bSAndy Whitcroft 4421b13edf7fSJoe Perches# do {} while (0) macro tests: 4422b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4423b13edf7fSJoe Perches# macro should not end with a semicolon 4424b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4425b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4426b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4427b13edf7fSJoe Perches my $ln = $linenr; 4428b13edf7fSJoe Perches my $cnt = $realcnt; 4429b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4430b13edf7fSJoe Perches my $ctx = ''; 4431b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4432b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4433b13edf7fSJoe Perches $ctx = $dstat; 4434b13edf7fSJoe Perches 4435b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 44361b36b201SJoe Perches $dstat =~ s/$;/ /g; 4437b13edf7fSJoe Perches 4438b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4439b13edf7fSJoe Perches my $stmts = $2; 4440b13edf7fSJoe Perches my $semis = $3; 4441b13edf7fSJoe Perches 4442b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4443b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4444b13edf7fSJoe Perches my $herectx = $here . "\n"; 4445b13edf7fSJoe Perches 4446b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4447b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4448b13edf7fSJoe Perches } 4449b13edf7fSJoe Perches 4450ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4451ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4452b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4453b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4454b13edf7fSJoe Perches } 4455b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4456b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4457b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 4458b13edf7fSJoe Perches } 4459f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 4460f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 4461f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 4462f5ef95b1SJoe Perches my $herectx = $here . "\n"; 4463f5ef95b1SJoe Perches 4464f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4465f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4466f5ef95b1SJoe Perches } 4467f5ef95b1SJoe Perches 4468f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 4469f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 4470b13edf7fSJoe Perches } 4471b13edf7fSJoe Perches } 4472b13edf7fSJoe Perches 4473080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 4474080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 4475080ba929SMike Frysinger# . 4476080ba929SMike Frysinger# ALIGN(...) 4477080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 4478080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 4479000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 4480000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 4481080ba929SMike Frysinger } 4482080ba929SMike Frysinger 4483f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 448413214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 448513214adfSAndy Whitcroft my ($level, $endln, @chunks) = 4486cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 448713214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 4488cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 4489cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 4490aad4f614SJoe Perches my @allowed = (); 4491aad4f614SJoe Perches my $allow = 0; 449213214adfSAndy Whitcroft my $seen = 0; 4493773647a0SAndy Whitcroft my $herectx = $here . "\n"; 4494cf655043SAndy Whitcroft my $ln = $linenr - 1; 449513214adfSAndy Whitcroft for my $chunk (@chunks) { 449613214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 449713214adfSAndy Whitcroft 4498773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 4499773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 4500773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 4501773647a0SAndy Whitcroft 4502aad4f614SJoe Perches $allowed[$allow] = 0; 4503773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 4504773647a0SAndy Whitcroft 4505773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 4506773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 4507773647a0SAndy Whitcroft 4508773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 4509cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 4510cf655043SAndy Whitcroft 4511773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 451213214adfSAndy Whitcroft 451313214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 451413214adfSAndy Whitcroft 4515aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 4516cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 4517cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 4518aad4f614SJoe Perches $allowed[$allow] = 1; 451913214adfSAndy Whitcroft } 452013214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 4521cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 4522aad4f614SJoe Perches $allowed[$allow] = 1; 452313214adfSAndy Whitcroft } 4524cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 4525cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 4526aad4f614SJoe Perches $allowed[$allow] = 1; 452713214adfSAndy Whitcroft } 4528aad4f614SJoe Perches $allow++; 452913214adfSAndy Whitcroft } 4530aad4f614SJoe Perches if ($seen) { 4531aad4f614SJoe Perches my $sum_allowed = 0; 4532aad4f614SJoe Perches foreach (@allowed) { 4533aad4f614SJoe Perches $sum_allowed += $_; 4534aad4f614SJoe Perches } 4535aad4f614SJoe Perches if ($sum_allowed == 0) { 4536000d1cc1SJoe Perches WARN("BRACES", 4537000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 4538aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 4539aad4f614SJoe Perches $seen != $allow) { 4540aad4f614SJoe Perches CHK("BRACES", 4541aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 4542aad4f614SJoe Perches } 454313214adfSAndy Whitcroft } 454413214adfSAndy Whitcroft } 454513214adfSAndy Whitcroft } 4546773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 454713214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 4548cf655043SAndy Whitcroft my $allowed = 0; 4549f0a594c1SAndy Whitcroft 4550cf655043SAndy Whitcroft # Check the pre-context. 4551cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 4552cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 4553cf655043SAndy Whitcroft $allowed = 1; 4554f0a594c1SAndy Whitcroft } 4555773647a0SAndy Whitcroft 4556773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 4557773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 4558773647a0SAndy Whitcroft 4559cf655043SAndy Whitcroft # Check the condition. 4560cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 4561773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 4562cf655043SAndy Whitcroft if (defined $cond) { 4563773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 4564cf655043SAndy Whitcroft } 4565cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 4566cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 4567cf655043SAndy Whitcroft $allowed = 1; 4568cf655043SAndy Whitcroft } 4569cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 4570cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 4571cf655043SAndy Whitcroft $allowed = 1; 4572cf655043SAndy Whitcroft } 4573cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 4574cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 4575cf655043SAndy Whitcroft $allowed = 1; 4576cf655043SAndy Whitcroft } 4577cf655043SAndy Whitcroft # Check the post-context. 4578cf655043SAndy Whitcroft if (defined $chunks[1]) { 4579cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 4580cf655043SAndy Whitcroft if (defined $cond) { 4581773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 4582cf655043SAndy Whitcroft } 4583cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 4584cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 4585cf655043SAndy Whitcroft $allowed = 1; 4586cf655043SAndy Whitcroft } 4587cf655043SAndy Whitcroft } 4588cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 458969932487SJustin P. Mattock my $herectx = $here . "\n"; 4590f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 4591cf655043SAndy Whitcroft 4592f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 459369932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 4594cf655043SAndy Whitcroft } 4595cf655043SAndy Whitcroft 4596000d1cc1SJoe Perches WARN("BRACES", 4597000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 4598f0a594c1SAndy Whitcroft } 4599f0a594c1SAndy Whitcroft } 4600f0a594c1SAndy Whitcroft 46010979ae66SJoe Perches# check for unnecessary blank lines around braces 460277b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 4603f8e58219SJoe Perches if (CHK("BRACES", 4604f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 4605f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 4606f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 4607f8e58219SJoe Perches } 46080979ae66SJoe Perches } 460977b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 4610f8e58219SJoe Perches if (CHK("BRACES", 4611f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 4612f8e58219SJoe Perches $fix) { 4613f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 4614f8e58219SJoe Perches } 46150979ae66SJoe Perches } 46160979ae66SJoe Perches 46174a0df2efSAndy Whitcroft# no volatiles please 46186c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 46196c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 4620000d1cc1SJoe Perches WARN("VOLATILE", 4621000d1cc1SJoe Perches "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 46224a0df2efSAndy Whitcroft } 46234a0df2efSAndy Whitcroft 46245e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 46255e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 46265e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 46275e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 46285e4f6ba5SJoe Perches if ($line =~ /^\+\s*"[X\t]*"/ && 46295e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 46305e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 46315e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 46325e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 46335e4f6ba5SJoe Perches $fix && 46345e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 46355e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 46365e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 46375e4f6ba5SJoe Perches my $comma_close = ""; 46385e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 46395e4f6ba5SJoe Perches $comma_close = $1; 46405e4f6ba5SJoe Perches } 46415e4f6ba5SJoe Perches 46425e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46435e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 46445e4f6ba5SJoe Perches my $fixedline = $prevrawline; 46455e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 46465e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 46475e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 46485e4f6ba5SJoe Perches $fixedline = $rawline; 46495e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 46505e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 46515e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46525e4f6ba5SJoe Perches } 46535e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 46545e4f6ba5SJoe Perches } 46555e4f6ba5SJoe Perches } 46565e4f6ba5SJoe Perches 46575e4f6ba5SJoe Perches# check for missing a space in a string concatenation 46585e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 46595e4f6ba5SJoe Perches WARN('MISSING_SPACE', 46605e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 46615e4f6ba5SJoe Perches } 46625e4f6ba5SJoe Perches 46635e4f6ba5SJoe Perches# check for spaces before a quoted newline 46645e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 46655e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 46665e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 46675e4f6ba5SJoe Perches $fix) { 46685e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 46695e4f6ba5SJoe Perches } 46705e4f6ba5SJoe Perches 46715e4f6ba5SJoe Perches } 46725e4f6ba5SJoe Perches 4673f17dba4fSJoe Perches# concatenated string without spaces between elements 4674f17dba4fSJoe Perches if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) { 4675f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 4676f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 4677f17dba4fSJoe Perches } 4678f17dba4fSJoe Perches 467990ad30e5SJoe Perches# uncoalesced string fragments 468090ad30e5SJoe Perches if ($line =~ /"X*"\s*"/) { 468190ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 468290ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 468390ad30e5SJoe Perches } 468490ad30e5SJoe Perches 46855e4f6ba5SJoe Perches# check for %L{u,d,i} in strings 46865e4f6ba5SJoe Perches my $string; 46875e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 46885e4f6ba5SJoe Perches $string = substr($rawline, $-[1], $+[1] - $-[1]); 46895e4f6ba5SJoe Perches $string =~ s/%%/__/g; 46905e4f6ba5SJoe Perches if ($string =~ /(?<!%)%L[udi]/) { 46915e4f6ba5SJoe Perches WARN("PRINTF_L", 46925e4f6ba5SJoe Perches "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 46935e4f6ba5SJoe Perches last; 46945e4f6ba5SJoe Perches } 46955e4f6ba5SJoe Perches } 46965e4f6ba5SJoe Perches 46975e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 46985e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 46995e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 47005e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 47015e4f6ba5SJoe Perches } 47025e4f6ba5SJoe Perches 470300df344fSAndy Whitcroft# warn about #if 0 4704c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 4705000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 4706000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 4707de7d4f0eSAndy Whitcroft $herecurr); 47084a0df2efSAndy Whitcroft } 47094a0df2efSAndy Whitcroft 471003df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 471103df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 471203df4b51SAndy Whitcroft my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; 471303df4b51SAndy Whitcroft if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { 471403df4b51SAndy Whitcroft WARN('NEEDLESS_IF', 471515160f90SFabio Estevam "$1(NULL) is safe and this check is probably not required\n" . $hereprev); 47164c432a8fSGreg Kroah-Hartman } 47174c432a8fSGreg Kroah-Hartman } 4718f0a594c1SAndy Whitcroft 4719ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 4720ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 4721ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 4722ebfdc409SJoe Perches (defined $1 || defined $3) && 4723ebfdc409SJoe Perches $linenr > 3) { 4724ebfdc409SJoe Perches my $testval = $2; 4725ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 4726ebfdc409SJoe Perches 4727ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 4728ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 4729ebfdc409SJoe Perches 4730ebfdc409SJoe Perches if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) { 4731ebfdc409SJoe Perches WARN("OOM_MESSAGE", 4732ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 4733ebfdc409SJoe Perches } 4734ebfdc409SJoe Perches } 4735ebfdc409SJoe Perches 4736f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 4737dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 4738f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 4739f78d98f6SJoe Perches my $level = $1; 4740f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 4741f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 4742f78d98f6SJoe Perches $fix) { 4743f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 4744f78d98f6SJoe Perches } 4745f78d98f6SJoe Perches } 4746f78d98f6SJoe Perches 4747abb08a53SJoe Perches# check for mask then right shift without a parentheses 4748abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 4749abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 4750abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 4751abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 4752abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 4753abb08a53SJoe Perches } 4754abb08a53SJoe Perches 4755b75ac618SJoe Perches# check for pointer comparisons to NULL 4756b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 4757b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 4758b75ac618SJoe Perches my $val = $1; 4759b75ac618SJoe Perches my $equal = "!"; 4760b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 4761b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 4762b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 4763b75ac618SJoe Perches $fix) { 4764b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 4765b75ac618SJoe Perches } 4766b75ac618SJoe Perches } 4767b75ac618SJoe Perches } 4768b75ac618SJoe Perches 47698716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 47708716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 47718716de38SJoe Perches my $attr = $1; 47728716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 47738716de38SJoe Perches my $ptr = $1; 47748716de38SJoe Perches my $var = $2; 47758716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 47768716de38SJoe Perches ERROR("MISPLACED_INIT", 47778716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 47788716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 47798716de38SJoe Perches WARN("MISPLACED_INIT", 47808716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 47818716de38SJoe Perches $fix) { 4782194f66fcSJoe Perches $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; 47838716de38SJoe Perches } 47848716de38SJoe Perches } 47858716de38SJoe Perches } 47868716de38SJoe Perches 4787e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 4788e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 4789e970b884SJoe Perches my $attr = $1; 4790e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 4791e970b884SJoe Perches my $attr_prefix = $1; 4792e970b884SJoe Perches my $attr_type = $2; 4793e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 4794e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 4795e970b884SJoe Perches $fix) { 4796194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4797e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 4798e970b884SJoe Perches } 4799e970b884SJoe Perches } 4800e970b884SJoe Perches 4801e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 4802e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 4803e970b884SJoe Perches my $attr = $1; 4804e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 4805e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 4806e970b884SJoe Perches $fix) { 4807194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 4808e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 4809e970b884SJoe Perches $lead = rtrim($1); 4810e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 4811e970b884SJoe Perches $lead = "${lead}const "; 4812194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 4813e970b884SJoe Perches } 4814e970b884SJoe Perches } 4815e970b884SJoe Perches 4816c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 4817c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 4818c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 4819c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 4820c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 4821c17893c7SJoe Perches $fix) { 4822c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 4823c17893c7SJoe Perches } 4824c17893c7SJoe Perches } 4825c17893c7SJoe Perches 4826fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 4827fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 4828fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 4829fbdb8138SJoe Perches my $constant_func = $1; 4830fbdb8138SJoe Perches my $func = $constant_func; 4831fbdb8138SJoe Perches $func =~ s/^__constant_//; 4832fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 4833fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 4834fbdb8138SJoe Perches $fix) { 4835194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 4836fbdb8138SJoe Perches } 4837fbdb8138SJoe Perches } 4838fbdb8138SJoe Perches 48391a15a250SPatrick Pannuto# prefer usleep_range over udelay 484037581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 484143c1d77cSJoe Perches my $delay = $1; 48421a15a250SPatrick Pannuto # ignore udelay's < 10, however 484343c1d77cSJoe Perches if (! ($delay < 10) ) { 4844000d1cc1SJoe Perches CHK("USLEEP_RANGE", 484543c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 484643c1d77cSJoe Perches } 484743c1d77cSJoe Perches if ($delay > 2000) { 484843c1d77cSJoe Perches WARN("LONG_UDELAY", 484943c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 48501a15a250SPatrick Pannuto } 48511a15a250SPatrick Pannuto } 48521a15a250SPatrick Pannuto 485309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 485409ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 485509ef8725SPatrick Pannuto if ($1 < 20) { 4856000d1cc1SJoe Perches WARN("MSLEEP", 485743c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 485809ef8725SPatrick Pannuto } 485909ef8725SPatrick Pannuto } 486009ef8725SPatrick Pannuto 486136ec1939SJoe Perches# check for comparisons of jiffies 486236ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 486336ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 486436ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 486536ec1939SJoe Perches } 486636ec1939SJoe Perches 48679d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 48689d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 48699d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 48709d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 48719d7a34a5SJoe Perches } 48729d7a34a5SJoe Perches 487300df344fSAndy Whitcroft# warn about #ifdefs in C files 4874c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 487500df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 487600df344fSAndy Whitcroft# print "$herecurr"; 487700df344fSAndy Whitcroft# $clean = 0; 487800df344fSAndy Whitcroft# } 487900df344fSAndy Whitcroft 488022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 4881c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 48823705ce5bSJoe Perches if (ERROR("SPACING", 48833705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 48843705ce5bSJoe Perches $fix) { 4885194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48863705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 48873705ce5bSJoe Perches } 48883705ce5bSJoe Perches 488922f2a2efSAndy Whitcroft } 489022f2a2efSAndy Whitcroft 48914a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 4892171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 4893171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 48944a0df2efSAndy Whitcroft my $which = $1; 48954a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 4896000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 4897000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 48984a0df2efSAndy Whitcroft } 48994a0df2efSAndy Whitcroft } 49004a0df2efSAndy Whitcroft# check for memory barriers without a comment. 49014a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 49024a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 4903c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 4904000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 49054a0df2efSAndy Whitcroft } 49064a0df2efSAndy Whitcroft } 4907cb426e99SJoe Perches# check for waitqueue_active without a comment. 4908cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 4909cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 4910cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 4911cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 4912cb426e99SJoe Perches } 4913cb426e99SJoe Perches } 49144a0df2efSAndy Whitcroft# check of hardware specific defines 4915c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 4916000d1cc1SJoe Perches CHK("ARCH_DEFINES", 4917000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 49180a920b5bSAndy Whitcroft } 4919653d4876SAndy Whitcroft 4920d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 4921d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 4922000d1cc1SJoe Perches WARN("STORAGE_CLASS", 4923000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 4924d4977c78STobias Klauser } 4925d4977c78STobias Klauser 4926de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 4927de7d4f0eSAndy Whitcroft# storage class and type. 49289c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 49299c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 4930000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 4931000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 4932de7d4f0eSAndy Whitcroft } 4933de7d4f0eSAndy Whitcroft 49348905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 49352b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 49362b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 4937d5e616fcSJoe Perches if (WARN("INLINE", 4938d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 4939d5e616fcSJoe Perches $fix) { 4940194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 4941d5e616fcSJoe Perches 4942d5e616fcSJoe Perches } 49438905a67cSAndy Whitcroft } 49448905a67cSAndy Whitcroft 49453d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 49462b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 49472b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 4948000d1cc1SJoe Perches WARN("PREFER_PACKED", 4949000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 49503d130fd0SJoe Perches } 49513d130fd0SJoe Perches 495239b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 49532b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 49542b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 4955000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 4956000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 495739b7e287SJoe Perches } 495839b7e287SJoe Perches 49595f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 49602b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 49612b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 4962d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 4963d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 4964d5e616fcSJoe Perches $fix) { 4965194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 4966d5e616fcSJoe Perches 4967d5e616fcSJoe Perches } 49685f14d3bdSJoe Perches } 49695f14d3bdSJoe Perches 49706061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 49712b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 49722b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 4973d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 4974d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 4975d5e616fcSJoe Perches $fix) { 4976194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 4977d5e616fcSJoe Perches } 49786061d949SJoe Perches } 49796061d949SJoe Perches 4980619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 4981619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 4982619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 4983619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 4984619a908aSJoe Perches $line =~ /\b__weak\b/)) { 4985619a908aSJoe Perches ERROR("WEAK_DECLARATION", 4986619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 4987619a908aSJoe Perches } 4988619a908aSJoe Perches 4989e6176fa4SJoe Perches# check for c99 types like uint8_t used outside of uapi/ 4990e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 4991e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 4992e6176fa4SJoe Perches my $type = $1; 4993e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 4994e6176fa4SJoe Perches $type = $1; 4995e6176fa4SJoe Perches my $kernel_type = 'u'; 4996e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 4997e6176fa4SJoe Perches $type =~ /(\d+)/; 4998e6176fa4SJoe Perches $kernel_type .= $1; 4999e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5000e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5001e6176fa4SJoe Perches $fix) { 5002e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5003e6176fa4SJoe Perches } 5004e6176fa4SJoe Perches } 5005e6176fa4SJoe Perches } 5006e6176fa4SJoe Perches 50078f53a9b8SJoe Perches# check for sizeof(&) 50088f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5009000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5010000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 50118f53a9b8SJoe Perches } 50128f53a9b8SJoe Perches 501366c80b60SJoe Perches# check for sizeof without parenthesis 501466c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5015d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5016d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5017d5e616fcSJoe Perches $fix) { 5018194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5019d5e616fcSJoe Perches } 502066c80b60SJoe Perches } 502166c80b60SJoe Perches 502288982feaSJoe Perches# check for struct spinlock declarations 502388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 502488982feaSJoe Perches WARN("USE_SPINLOCK_T", 502588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 502688982feaSJoe Perches } 502788982feaSJoe Perches 5028a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 502906668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5030a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5031caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5032caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5033d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5034d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5035d5e616fcSJoe Perches $fix) { 5036194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5037d5e616fcSJoe Perches } 5038a6962d72SJoe Perches } 5039a6962d72SJoe Perches } 5040a6962d72SJoe Perches 5041554e165cSAndy Whitcroft# Check for misused memsets 5042d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5043d1fe9c09SJoe Perches defined $stat && 5044d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { 5045554e165cSAndy Whitcroft 5046d7c76ba7SJoe Perches my $ms_addr = $2; 5047d1fe9c09SJoe Perches my $ms_val = $7; 5048d1fe9c09SJoe Perches my $ms_size = $12; 5049d7c76ba7SJoe Perches 5050554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5051554e165cSAndy Whitcroft ERROR("MEMSET", 5052d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5053554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5054554e165cSAndy Whitcroft WARN("MEMSET", 5055d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5056d7c76ba7SJoe Perches } 5057d7c76ba7SJoe Perches } 5058d7c76ba7SJoe Perches 505998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 506098a9bba5SJoe Perches if ($^V && $^V ge 5.10.0 && 506198a9bba5SJoe Perches $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) { 506298a9bba5SJoe Perches if (WARN("PREFER_ETHER_ADDR_COPY", 506398a9bba5SJoe Perches "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) && 506498a9bba5SJoe Perches $fix) { 5065194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 506698a9bba5SJoe Perches } 506798a9bba5SJoe Perches } 506898a9bba5SJoe Perches 5069d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5070d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5071d1fe9c09SJoe Perches defined $stat && 5072d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5073d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5074d7c76ba7SJoe Perches my $call = $1; 5075d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5076d7c76ba7SJoe Perches my $arg1 = $3; 5077d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5078d1fe9c09SJoe Perches my $arg2 = $8; 5079d7c76ba7SJoe Perches my $cast; 5080d7c76ba7SJoe Perches 5081d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5082d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5083d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5084d7c76ba7SJoe Perches $cast = $cast1; 5085d7c76ba7SJoe Perches } else { 5086d7c76ba7SJoe Perches $cast = $cast2; 5087d7c76ba7SJoe Perches } 5088d7c76ba7SJoe Perches WARN("MINMAX", 5089d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5090554e165cSAndy Whitcroft } 5091554e165cSAndy Whitcroft } 5092554e165cSAndy Whitcroft 50934a273195SJoe Perches# check usleep_range arguments 50944a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 50954a273195SJoe Perches defined $stat && 50964a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 50974a273195SJoe Perches my $min = $1; 50984a273195SJoe Perches my $max = $7; 50994a273195SJoe Perches if ($min eq $max) { 51004a273195SJoe Perches WARN("USLEEP_RANGE", 51014a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 51024a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 51034a273195SJoe Perches $min > $max) { 51044a273195SJoe Perches WARN("USLEEP_RANGE", 51054a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 51064a273195SJoe Perches } 51074a273195SJoe Perches } 51084a273195SJoe Perches 5109823b794cSJoe Perches# check for naked sscanf 5110823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5111823b794cSJoe Perches defined $stat && 51126c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5113823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5114823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5115823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5116823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5117823b794cSJoe Perches $lc = $lc + $linenr; 5118823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5119823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5120823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5121823b794cSJoe Perches } 5122823b794cSJoe Perches WARN("NAKED_SSCANF", 5123823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5124823b794cSJoe Perches } 5125823b794cSJoe Perches 5126afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5127afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5128afc819abSJoe Perches defined $stat && 5129afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5130afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5131afc819abSJoe Perches $lc = $lc + $linenr; 5132afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5133afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5134afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5135afc819abSJoe Perches } 5136afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5137afc819abSJoe Perches my $format = $6; 5138afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5139afc819abSJoe Perches if ($count == 1 && 5140afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5141afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5142afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5143afc819abSJoe Perches } 5144afc819abSJoe Perches } 5145afc819abSJoe Perches } 5146afc819abSJoe Perches 514770dc8a48SJoe Perches# check for new externs in .h files. 514870dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 514970dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5150d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 515170dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 515270dc8a48SJoe Perches $fix) { 5153194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 515470dc8a48SJoe Perches } 515570dc8a48SJoe Perches } 515670dc8a48SJoe Perches 5157de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5158171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5159c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5160171ae1a4SAndy Whitcroft { 5161c45dcabdSAndy Whitcroft my $function_name = $1; 5162c45dcabdSAndy Whitcroft my $paren_space = $2; 5163171ae1a4SAndy Whitcroft 5164171ae1a4SAndy Whitcroft my $s = $stat; 5165171ae1a4SAndy Whitcroft if (defined $cond) { 5166171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5167171ae1a4SAndy Whitcroft } 5168c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5169c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5170c45dcabdSAndy Whitcroft { 5171000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5172000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5173de7d4f0eSAndy Whitcroft } 5174de7d4f0eSAndy Whitcroft 5175171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5176000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5177000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5178171ae1a4SAndy Whitcroft } 51799c9ba34eSAndy Whitcroft 51809c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 51819c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 51829c9ba34eSAndy Whitcroft { 5183000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5184000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5185171ae1a4SAndy Whitcroft } 5186171ae1a4SAndy Whitcroft 5187de7d4f0eSAndy Whitcroft# checks for new __setup's 5188de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5189de7d4f0eSAndy Whitcroft my $name = $1; 5190de7d4f0eSAndy Whitcroft 5191de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5192000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 5193000d1cc1SJoe Perches "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 5194de7d4f0eSAndy Whitcroft } 5195653d4876SAndy Whitcroft } 51969c0ca6f9SAndy Whitcroft 51979c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5198caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5199000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5200000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 52019c0ca6f9SAndy Whitcroft } 520213214adfSAndy Whitcroft 5203a640d25cSJoe Perches# alloc style 5204a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5205a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5206a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5207a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5208a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5209a640d25cSJoe Perches } 5210a640d25cSJoe Perches 521160a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 521260a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 5213e367455aSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 521460a55369SJoe Perches my $oldfunc = $3; 521560a55369SJoe Perches my $a1 = $4; 521660a55369SJoe Perches my $a2 = $10; 521760a55369SJoe Perches my $newfunc = "kmalloc_array"; 521860a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 521960a55369SJoe Perches my $r1 = $a1; 522060a55369SJoe Perches my $r2 = $a2; 522160a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 522260a55369SJoe Perches $r1 = $a2; 522360a55369SJoe Perches $r2 = $a1; 522460a55369SJoe Perches } 5225e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5226e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 5227e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 5228e367455aSJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herecurr) && 5229e367455aSJoe Perches $fix) { 5230194f66fcSJoe Perches $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; 523160a55369SJoe Perches 523260a55369SJoe Perches } 523360a55369SJoe Perches } 523460a55369SJoe Perches } 523560a55369SJoe Perches 5236972fdea2SJoe Perches# check for krealloc arg reuse 5237972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5238972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5239972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5240972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 5241972fdea2SJoe Perches } 5242972fdea2SJoe Perches 52435ce59ae0SJoe Perches# check for alloc argument mismatch 52445ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 52455ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 52465ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 52475ce59ae0SJoe Perches } 52485ce59ae0SJoe Perches 5249caf2a54fSJoe Perches# check for multiple semicolons 5250caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 5251d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 5252d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 5253d5e616fcSJoe Perches $fix) { 5254194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 5255d5e616fcSJoe Perches } 5256d1e2ad07SJoe Perches } 5257d1e2ad07SJoe Perches 52580ab90191SJoe Perches# check for #defines like: 1 << <digit> that could be BIT(digit) 52590ab90191SJoe Perches if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 52600ab90191SJoe Perches my $ull = ""; 52610ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 52620ab90191SJoe Perches if (CHK("BIT_MACRO", 52630ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 52640ab90191SJoe Perches $fix) { 52650ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 52660ab90191SJoe Perches } 52670ab90191SJoe Perches } 52680ab90191SJoe Perches 5269e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 5270c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 5271c34c09a8SJoe Perches my $has_break = 0; 5272c34c09a8SJoe Perches my $has_statement = 0; 5273c34c09a8SJoe Perches my $count = 0; 5274c34c09a8SJoe Perches my $prevline = $linenr; 5275e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 5276c34c09a8SJoe Perches $prevline--; 5277c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 5278c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 5279c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 5280c34c09a8SJoe Perches next if ($fline =~ /^\-/); 5281c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 5282c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 5283c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 5284c34c09a8SJoe Perches $has_statement = 1; 5285c34c09a8SJoe Perches $count++; 5286c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 5287c34c09a8SJoe Perches } 5288c34c09a8SJoe Perches if (!$has_break && $has_statement) { 5289c34c09a8SJoe Perches WARN("MISSING_BREAK", 5290c34c09a8SJoe Perches "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr); 5291c34c09a8SJoe Perches } 5292c34c09a8SJoe Perches } 5293c34c09a8SJoe Perches 5294d1e2ad07SJoe Perches# check for switch/default statements without a break; 5295d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 5296d1e2ad07SJoe Perches defined $stat && 5297d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 5298d1e2ad07SJoe Perches my $ctx = ''; 5299d1e2ad07SJoe Perches my $herectx = $here . "\n"; 5300d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 5301d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 5302d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 5303d1e2ad07SJoe Perches } 5304d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 5305d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 5306caf2a54fSJoe Perches } 5307caf2a54fSJoe Perches 530813214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 5309d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 5310d5e616fcSJoe Perches if (WARN("USE_FUNC", 5311d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 5312d5e616fcSJoe Perches $fix) { 5313194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 5314d5e616fcSJoe Perches } 531513214adfSAndy Whitcroft } 5316773647a0SAndy Whitcroft 531762ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 531862ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 531962ec818fSJoe Perches ERROR("DATE_TIME", 532062ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 532162ec818fSJoe Perches } 532262ec818fSJoe Perches 53232c92488aSJoe Perches# check for use of yield() 53242c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 53252c92488aSJoe Perches WARN("YIELD", 53262c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 53272c92488aSJoe Perches } 53282c92488aSJoe Perches 5329179f8f40SJoe Perches# check for comparisons against true and false 5330179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 5331179f8f40SJoe Perches my $lead = $1; 5332179f8f40SJoe Perches my $arg = $2; 5333179f8f40SJoe Perches my $test = $3; 5334179f8f40SJoe Perches my $otype = $4; 5335179f8f40SJoe Perches my $trail = $5; 5336179f8f40SJoe Perches my $op = "!"; 5337179f8f40SJoe Perches 5338179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 5339179f8f40SJoe Perches 5340179f8f40SJoe Perches my $type = lc($otype); 5341179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 5342179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 5343179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 5344179f8f40SJoe Perches $op = ""; 5345179f8f40SJoe Perches } 5346179f8f40SJoe Perches 5347179f8f40SJoe Perches CHK("BOOL_COMPARISON", 5348179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 5349179f8f40SJoe Perches 5350179f8f40SJoe Perches## maybe suggesting a correct construct would better 5351179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 5352179f8f40SJoe Perches 5353179f8f40SJoe Perches } 5354179f8f40SJoe Perches } 5355179f8f40SJoe Perches 53564882720bSThomas Gleixner# check for semaphores initialized locked 53574882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 5358000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 5359000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 5360773647a0SAndy Whitcroft } 53616712d858SJoe Perches 536267d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 536367d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 5364000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 536567d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 5366773647a0SAndy Whitcroft } 53676712d858SJoe Perches 5368ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 5369f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 5370000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 5371ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 5372f3db6639SMichael Ellerman } 53736712d858SJoe Perches 53740f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 53750f3c5aabSJoe Perches my $const_structs = qr{ 53760f3c5aabSJoe Perches acpi_dock_ops| 537779404849SEmese Revfy address_space_operations| 537879404849SEmese Revfy backlight_ops| 537979404849SEmese Revfy block_device_operations| 538079404849SEmese Revfy dentry_operations| 538179404849SEmese Revfy dev_pm_ops| 538279404849SEmese Revfy dma_map_ops| 538379404849SEmese Revfy extent_io_ops| 538479404849SEmese Revfy file_lock_operations| 538579404849SEmese Revfy file_operations| 538679404849SEmese Revfy hv_ops| 538779404849SEmese Revfy ide_dma_ops| 538879404849SEmese Revfy intel_dvo_dev_ops| 538979404849SEmese Revfy item_operations| 539079404849SEmese Revfy iwl_ops| 539179404849SEmese Revfy kgdb_arch| 539279404849SEmese Revfy kgdb_io| 539379404849SEmese Revfy kset_uevent_ops| 539479404849SEmese Revfy lock_manager_operations| 539579404849SEmese Revfy microcode_ops| 539679404849SEmese Revfy mtrr_ops| 539779404849SEmese Revfy neigh_ops| 539879404849SEmese Revfy nlmsvc_binding| 53990f3c5aabSJoe Perches of_device_id| 540079404849SEmese Revfy pci_raw_ops| 540179404849SEmese Revfy pipe_buf_operations| 540279404849SEmese Revfy platform_hibernation_ops| 540379404849SEmese Revfy platform_suspend_ops| 540479404849SEmese Revfy proto_ops| 540579404849SEmese Revfy rpc_pipe_ops| 540679404849SEmese Revfy seq_operations| 540779404849SEmese Revfy snd_ac97_build_ops| 540879404849SEmese Revfy soc_pcmcia_socket_ops| 540979404849SEmese Revfy stacktrace_ops| 541079404849SEmese Revfy sysfs_ops| 541179404849SEmese Revfy tty_operations| 54126d07d01bSJoe Perches uart_ops| 541379404849SEmese Revfy usb_mon_operations| 541479404849SEmese Revfy wd_ops}x; 54156903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 54160f3c5aabSJoe Perches $line =~ /\bstruct\s+($const_structs)\b/) { 5417000d1cc1SJoe Perches WARN("CONST_STRUCT", 5418000d1cc1SJoe Perches "struct $1 should normally be const\n" . 54196903ffb2SAndy Whitcroft $herecurr); 54202b6db5cbSAndy Whitcroft } 5421773647a0SAndy Whitcroft 5422773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 5423773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 5424773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 5425c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 5426c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 5427171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 5428171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 5429171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 5430773647a0SAndy Whitcroft { 5431000d1cc1SJoe Perches WARN("NR_CPUS", 5432000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 5433773647a0SAndy Whitcroft } 54349c9ba34eSAndy Whitcroft 543552ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 543652ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 543752ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 543852ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 543952ea8506SJoe Perches } 544052ea8506SJoe Perches 5441acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 5442acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 5443acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 5444acd9362cSJoe Perches WARN("LIKELY_MISUSE", 5445acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 5446acd9362cSJoe Perches } 5447acd9362cSJoe Perches 5448691d77b6SAndy Whitcroft# whine mightly about in_atomic 5449691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 5450691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 5451000d1cc1SJoe Perches ERROR("IN_ATOMIC", 5452000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 5453f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 5454000d1cc1SJoe Perches WARN("IN_ATOMIC", 5455000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 5456691d77b6SAndy Whitcroft } 5457691d77b6SAndy Whitcroft } 54581704f47bSPeter Zijlstra 54591704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 54601704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 54611704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 54621704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 54631704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 54641704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 5465000d1cc1SJoe Perches ERROR("LOCKDEP", 5466000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 54671704f47bSPeter Zijlstra } 54681704f47bSPeter Zijlstra } 546988f8831cSDave Jones 5470b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 5471b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 5472000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 5473000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 547488f8831cSDave Jones } 54752435880fSJoe Perches 5476515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 5477515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 5478515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 5479515a235eSJoe Perches $line =~ /$mode_perms_search/) { 54802435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 54812435880fSJoe Perches my $func = $entry->[0]; 54822435880fSJoe Perches my $arg_pos = $entry->[1]; 54832435880fSJoe Perches 54842435880fSJoe Perches my $skip_args = ""; 54852435880fSJoe Perches if ($arg_pos > 1) { 54862435880fSJoe Perches $arg_pos--; 54872435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 54882435880fSJoe Perches } 54892435880fSJoe Perches my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]"; 5490515a235eSJoe Perches if ($line =~ /$test/) { 54912435880fSJoe Perches my $val = $1; 54922435880fSJoe Perches $val = $6 if ($skip_args ne ""); 54932435880fSJoe Perches 54941727cc70SJoe Perches if ($val !~ /^0$/ && 54951727cc70SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 54961727cc70SJoe Perches length($val) ne 4)) { 54972435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 54981727cc70SJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr); 5499c0a5c898SJoe Perches } elsif ($val =~ /^$Octal$/ && (oct($val) & 02)) { 5500c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 5501c0a5c898SJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 55022435880fSJoe Perches } 55032435880fSJoe Perches } 55042435880fSJoe Perches } 550513214adfSAndy Whitcroft } 5506515a235eSJoe Perches } 550713214adfSAndy Whitcroft 550813214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 550913214adfSAndy Whitcroft # so just keep quiet. 551013214adfSAndy Whitcroft if ($#rawlines == -1) { 551113214adfSAndy Whitcroft exit(0); 55120a920b5bSAndy Whitcroft } 55130a920b5bSAndy Whitcroft 55148905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 55158905a67cSAndy Whitcroft # things that appear to be patches. 55168905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 55178905a67cSAndy Whitcroft exit(0); 55188905a67cSAndy Whitcroft } 55198905a67cSAndy Whitcroft 55208905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 55218905a67cSAndy Whitcroft # just keep quiet. 55228905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 55238905a67cSAndy Whitcroft exit(0); 55248905a67cSAndy Whitcroft } 55258905a67cSAndy Whitcroft 55268905a67cSAndy Whitcroft if (!$is_patch) { 5527000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 5528000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 55290a920b5bSAndy Whitcroft } 55300a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 5531000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 5532000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 55330a920b5bSAndy Whitcroft } 55340a920b5bSAndy Whitcroft 5535f0a594c1SAndy Whitcroft print report_dump(); 553613214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 553713214adfSAndy Whitcroft print "$filename " if ($summary_file); 55386c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 55396c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 55406c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 55418905a67cSAndy Whitcroft print "\n" if ($quiet == 0); 55426c72ffaaSAndy Whitcroft } 55438905a67cSAndy Whitcroft 5544d2c0a235SAndy Whitcroft if ($quiet == 0) { 5545d1fe9c09SJoe Perches 5546d1fe9c09SJoe Perches if ($^V lt 5.10.0) { 5547d1fe9c09SJoe Perches print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); 5548d1fe9c09SJoe Perches print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); 5549d1fe9c09SJoe Perches } 5550d1fe9c09SJoe Perches 5551d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 5552d2c0a235SAndy Whitcroft # then suggest that. 5553d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 5554d2c0a235SAndy Whitcroft print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 5555d2c0a235SAndy Whitcroft print " scripts/cleanfile\n\n"; 5556b0781216SMike Frysinger $rpt_cleaners = 0; 5557d2c0a235SAndy Whitcroft } 5558d2c0a235SAndy Whitcroft } 5559d2c0a235SAndy Whitcroft 556091bfe484SJoe Perches hash_show_words(\%use_type, "Used"); 556191bfe484SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 5562000d1cc1SJoe Perches 5563d752fcc8SJoe Perches if ($clean == 0 && $fix && 5564d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 5565d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 55669624b8d6SJoe Perches my $newfile = $filename; 55679624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 55683705ce5bSJoe Perches my $linecount = 0; 55693705ce5bSJoe Perches my $f; 55703705ce5bSJoe Perches 5571d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 5572d752fcc8SJoe Perches 55733705ce5bSJoe Perches open($f, '>', $newfile) 55743705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 55753705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 55763705ce5bSJoe Perches $linecount++; 55773705ce5bSJoe Perches if ($file) { 55783705ce5bSJoe Perches if ($linecount > 3) { 55793705ce5bSJoe Perches $fixed_line =~ s/^\+//; 55803705ce5bSJoe Perches print $f $fixed_line . "\n"; 55813705ce5bSJoe Perches } 55823705ce5bSJoe Perches } else { 55833705ce5bSJoe Perches print $f $fixed_line . "\n"; 55843705ce5bSJoe Perches } 55853705ce5bSJoe Perches } 55863705ce5bSJoe Perches close($f); 55873705ce5bSJoe Perches 55883705ce5bSJoe Perches if (!$quiet) { 55893705ce5bSJoe Perches print << "EOM"; 55903705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 55913705ce5bSJoe Perches 55923705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 55933705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 55943705ce5bSJoe Perches 55953705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 55963705ce5bSJoe PerchesNo warranties, expressed or implied... 55973705ce5bSJoe Perches 55983705ce5bSJoe PerchesEOM 55993705ce5bSJoe Perches } 56003705ce5bSJoe Perches } 56013705ce5bSJoe Perches 56020a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 5603c2fdda0dSAndy Whitcroft print "$vname has no obvious style problems and is ready for submission.\n" 56040a920b5bSAndy Whitcroft } 56050a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 5606000d1cc1SJoe Perches print << "EOM"; 5607000d1cc1SJoe Perches$vname has style problems, please review. 5608000d1cc1SJoe Perches 5609000d1cc1SJoe PerchesIf any of these errors are false positives, please report 5610000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS. 5611000d1cc1SJoe PerchesEOM 56120a920b5bSAndy Whitcroft } 561313214adfSAndy Whitcroft 56140a920b5bSAndy Whitcroft return $clean; 56150a920b5bSAndy Whitcroft} 5616