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; 100a920b5bSAndy Whitcroft 110a920b5bSAndy Whitcroftmy $P = $0; 1200df344fSAndy Whitcroft$P =~ s@.*/@@g; 130a920b5bSAndy Whitcroft 14000d1cc1SJoe Perchesmy $V = '0.32'; 150a920b5bSAndy Whitcroft 160a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 170a920b5bSAndy Whitcroft 180a920b5bSAndy Whitcroftmy $quiet = 0; 190a920b5bSAndy Whitcroftmy $tree = 1; 200a920b5bSAndy Whitcroftmy $chk_signoff = 1; 210a920b5bSAndy Whitcroftmy $chk_patch = 1; 22773647a0SAndy Whitcroftmy $tst_only; 236c72ffaaSAndy Whitcroftmy $emacs = 0; 248905a67cSAndy Whitcroftmy $terse = 0; 256c72ffaaSAndy Whitcroftmy $file = 0; 266c72ffaaSAndy Whitcroftmy $check = 0; 278905a67cSAndy Whitcroftmy $summary = 1; 288905a67cSAndy Whitcroftmy $mailback = 0; 2913214adfSAndy Whitcroftmy $summary_file = 0; 30000d1cc1SJoe Perchesmy $show_types = 0; 313705ce5bSJoe Perchesmy $fix = 0; 326c72ffaaSAndy Whitcroftmy $root; 33c2fdda0dSAndy Whitcroftmy %debug; 34000d1cc1SJoe Perchesmy %ignore_type = (); 353445686aSJoe Perchesmy %camelcase = (); 36000d1cc1SJoe Perchesmy @ignore = (); 3777f5b10aSHannes Edermy $help = 0; 38000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 396cd7f386SJoe Perchesmy $max_line_length = 80; 40d62a201fSDave Hansenmy $ignore_perl_version = 0; 41d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 4277f5b10aSHannes Eder 4377f5b10aSHannes Edersub help { 4477f5b10aSHannes Eder my ($exitcode) = @_; 4577f5b10aSHannes Eder 4677f5b10aSHannes Eder print << "EOM"; 4777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 4877f5b10aSHannes EderVersion: $V 4977f5b10aSHannes Eder 5077f5b10aSHannes EderOptions: 5177f5b10aSHannes Eder -q, --quiet quiet 5277f5b10aSHannes Eder --no-tree run without a kernel tree 5377f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 5477f5b10aSHannes Eder --patch treat FILE as patchfile (default) 5577f5b10aSHannes Eder --emacs emacs compile window format 5677f5b10aSHannes Eder --terse one line per report 5777f5b10aSHannes Eder -f, --file treat FILE as regular source file 5877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 59000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 606cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 61000d1cc1SJoe Perches --show-types show the message "types" in the output 6277f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 6377f5b10aSHannes Eder --no-summary suppress the per-file summary 6477f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 6577f5b10aSHannes Eder --summary-file include the filename in summary 6677f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 6777f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 6877f5b10aSHannes Eder is all off) 6977f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 7077f5b10aSHannes Eder literally 713705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 723705ce5bSJoe Perches If correctable single-line errors exist, create 733705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 743705ce5bSJoe Perches with potential errors corrected to the preferred 753705ce5bSJoe Perches checkpatch style 76d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 77d62a201fSDave Hansen runtime errors. 7877f5b10aSHannes Eder -h, --help, --version display this help and exit 7977f5b10aSHannes Eder 8077f5b10aSHannes EderWhen FILE is - read standard input. 8177f5b10aSHannes EderEOM 8277f5b10aSHannes Eder 8377f5b10aSHannes Eder exit($exitcode); 8477f5b10aSHannes Eder} 8577f5b10aSHannes Eder 86000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 87000d1cc1SJoe Perchesif (-f $conf) { 88000d1cc1SJoe Perches my @conf_args; 89000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 90000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 91000d1cc1SJoe Perches 92000d1cc1SJoe Perches while (<$conffile>) { 93000d1cc1SJoe Perches my $line = $_; 94000d1cc1SJoe Perches 95000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 96000d1cc1SJoe Perches $line =~ s/^\s*//g; 97000d1cc1SJoe Perches $line =~ s/\s+/ /g; 98000d1cc1SJoe Perches 99000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 100000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 101000d1cc1SJoe Perches 102000d1cc1SJoe Perches my @words = split(" ", $line); 103000d1cc1SJoe Perches foreach my $word (@words) { 104000d1cc1SJoe Perches last if ($word =~ m/^#/); 105000d1cc1SJoe Perches push (@conf_args, $word); 106000d1cc1SJoe Perches } 107000d1cc1SJoe Perches } 108000d1cc1SJoe Perches close($conffile); 109000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 110000d1cc1SJoe Perches} 111000d1cc1SJoe Perches 1120a920b5bSAndy WhitcroftGetOptions( 1136c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 1140a920b5bSAndy Whitcroft 'tree!' => \$tree, 1150a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 1160a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 1176c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 1188905a67cSAndy Whitcroft 'terse!' => \$terse, 11977f5b10aSHannes Eder 'f|file!' => \$file, 1206c72ffaaSAndy Whitcroft 'subjective!' => \$check, 1216c72ffaaSAndy Whitcroft 'strict!' => \$check, 122000d1cc1SJoe Perches 'ignore=s' => \@ignore, 123000d1cc1SJoe Perches 'show-types!' => \$show_types, 1246cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 1256c72ffaaSAndy Whitcroft 'root=s' => \$root, 1268905a67cSAndy Whitcroft 'summary!' => \$summary, 1278905a67cSAndy Whitcroft 'mailback!' => \$mailback, 12813214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 1293705ce5bSJoe Perches 'fix!' => \$fix, 130d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 131c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 132773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 13377f5b10aSHannes Eder 'h|help' => \$help, 13477f5b10aSHannes Eder 'version' => \$help 13577f5b10aSHannes Eder) or help(1); 13677f5b10aSHannes Eder 13777f5b10aSHannes Ederhelp(0) if ($help); 1380a920b5bSAndy Whitcroft 1390a920b5bSAndy Whitcroftmy $exit = 0; 1400a920b5bSAndy Whitcroft 141d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 142d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 143d62a201fSDave Hansen if (!$ignore_perl_version) { 144d62a201fSDave Hansen exit(1); 145d62a201fSDave Hansen } 146d62a201fSDave Hansen} 147d62a201fSDave Hansen 1480a920b5bSAndy Whitcroftif ($#ARGV < 0) { 14977f5b10aSHannes Eder print "$P: no input files\n"; 1500a920b5bSAndy Whitcroft exit(1); 1510a920b5bSAndy Whitcroft} 1520a920b5bSAndy Whitcroft 153000d1cc1SJoe Perches@ignore = split(/,/, join(',',@ignore)); 154000d1cc1SJoe Perchesforeach my $word (@ignore) { 155000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 156000d1cc1SJoe Perches $word =~ s/^\s*//g; 157000d1cc1SJoe Perches $word =~ s/\s+/ /g; 158000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 159000d1cc1SJoe Perches 160000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 161000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 162000d1cc1SJoe Perches 163000d1cc1SJoe Perches $ignore_type{$word}++; 164000d1cc1SJoe Perches} 165000d1cc1SJoe Perches 166c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 167c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 1687429c690SAndy Whitcroftmy $dbg_type = 0; 169a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 170c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 17121caa13cSAndy Whitcroft ## no critic 17221caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 17321caa13cSAndy Whitcroft die "$@" if ($@); 174c2fdda0dSAndy Whitcroft} 175c2fdda0dSAndy Whitcroft 176d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 177d2c0a235SAndy Whitcroft 1788905a67cSAndy Whitcroftif ($terse) { 1798905a67cSAndy Whitcroft $emacs = 1; 1808905a67cSAndy Whitcroft $quiet++; 1818905a67cSAndy Whitcroft} 1828905a67cSAndy Whitcroft 1836c72ffaaSAndy Whitcroftif ($tree) { 1846c72ffaaSAndy Whitcroft if (defined $root) { 1856c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 1866c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 1876c72ffaaSAndy Whitcroft } 1886c72ffaaSAndy Whitcroft } else { 1896c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 1906c72ffaaSAndy Whitcroft $root = '.'; 1916c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 1926c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 1936c72ffaaSAndy Whitcroft $root = $1; 1946c72ffaaSAndy Whitcroft } 1956c72ffaaSAndy Whitcroft } 1966c72ffaaSAndy Whitcroft 1976c72ffaaSAndy Whitcroft if (!defined $root) { 1980a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 1990a920b5bSAndy Whitcroft exit(2); 2000a920b5bSAndy Whitcroft } 2016c72ffaaSAndy Whitcroft} 2026c72ffaaSAndy Whitcroft 2036c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 2046c72ffaaSAndy Whitcroft 2052ceb532bSAndy Whitcroftour $Ident = qr{ 2062ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 2072ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 2082ceb532bSAndy Whitcroft }x; 2096c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 2106c72ffaaSAndy Whitcroftour $Sparse = qr{ 2116c72ffaaSAndy Whitcroft __user| 2126c72ffaaSAndy Whitcroft __kernel| 2136c72ffaaSAndy Whitcroft __force| 2146c72ffaaSAndy Whitcroft __iomem| 2156c72ffaaSAndy Whitcroft __must_check| 2166c72ffaaSAndy Whitcroft __init_refok| 217417495edSAndy Whitcroft __kprobes| 218165e72a6SSven Eckelmann __ref| 219165e72a6SSven Eckelmann __rcu 2206c72ffaaSAndy Whitcroft }x; 22152131292SWolfram Sang 22252131292SWolfram Sang# Notes to $Attribute: 22352131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 2246c72ffaaSAndy Whitcroftour $Attribute = qr{ 2256c72ffaaSAndy Whitcroft const| 22603f1df7dSJoe Perches __percpu| 22703f1df7dSJoe Perches __nocast| 22803f1df7dSJoe Perches __safe| 22903f1df7dSJoe Perches __bitwise__| 23003f1df7dSJoe Perches __packed__| 23103f1df7dSJoe Perches __packed2__| 23203f1df7dSJoe Perches __naked| 23303f1df7dSJoe Perches __maybe_unused| 23403f1df7dSJoe Perches __always_unused| 23503f1df7dSJoe Perches __noreturn| 23603f1df7dSJoe Perches __used| 23703f1df7dSJoe Perches __cold| 23803f1df7dSJoe Perches __noclone| 23903f1df7dSJoe Perches __deprecated| 2406c72ffaaSAndy Whitcroft __read_mostly| 2416c72ffaaSAndy Whitcroft __kprobes| 24252131292SWolfram Sang __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| 24324e1d81aSAndy Whitcroft ____cacheline_aligned| 24424e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 2455fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 2465fe3af11SAndy Whitcroft __weak 2476c72ffaaSAndy Whitcroft }x; 248c45dcabdSAndy Whitcroftour $Modifier; 2496c72ffaaSAndy Whitcroftour $Inline = qr{inline|__always_inline|noinline}; 2506c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 2516c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 2526c72ffaaSAndy Whitcroft 25395e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 25495e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 25595e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 25695e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 257326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 258326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 259326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 26074349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 26195e2c602SJoe Perchesour $Constant = qr{$Float|$Binary|$Hex|$Int}; 262326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 26386f9d059SAndy Whitcroftour $Compare = qr{<=|>=|==|!=|<|>}; 26423f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 2656c72ffaaSAndy Whitcroftour $Operators = qr{ 2666c72ffaaSAndy Whitcroft <=|>=|==|!=| 2676c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 26823f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 2696c72ffaaSAndy Whitcroft }x; 2706c72ffaaSAndy Whitcroft 2718905a67cSAndy Whitcroftour $NonptrType; 2728905a67cSAndy Whitcroftour $Type; 2738905a67cSAndy Whitcroftour $Declare; 2748905a67cSAndy Whitcroft 27515662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 27615662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 277171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 278171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 279171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 280171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 281171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 282171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 283171ae1a4SAndy Whitcroft}x; 284171ae1a4SAndy Whitcroft 28515662b3eSJoe Perchesour $UTF8 = qr{ 28615662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 28715662b3eSJoe Perches | $NON_ASCII_UTF8 28815662b3eSJoe Perches}x; 28915662b3eSJoe Perches 2908ed22cadSAndy Whitcroftour $typeTypedefs = qr{(?x: 291fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 2928ed22cadSAndy Whitcroft atomic_t 2938ed22cadSAndy Whitcroft)}; 2948ed22cadSAndy Whitcroft 295691e669bSJoe Perchesour $logFunctions = qr{(?x: 2966e60c02eSJoe Perches printk(?:_ratelimited|_once|)| 2977d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 2986e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 299b0531722SJoe Perches panic| 300b0531722SJoe Perches MODULE_[A-Z_]+ 301691e669bSJoe Perches)}; 302691e669bSJoe Perches 30320112475SJoe Perchesour $signature_tags = qr{(?xi: 30420112475SJoe Perches Signed-off-by:| 30520112475SJoe Perches Acked-by:| 30620112475SJoe Perches Tested-by:| 30720112475SJoe Perches Reviewed-by:| 30820112475SJoe Perches Reported-by:| 3098543ae12SMugunthan V N Suggested-by:| 31020112475SJoe Perches To:| 31120112475SJoe Perches Cc: 31220112475SJoe Perches)}; 31320112475SJoe Perches 3148905a67cSAndy Whitcroftour @typeList = ( 3158905a67cSAndy Whitcroft qr{void}, 316c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?char}, 317c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?short}, 318c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?int}, 319c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long}, 320c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+int}, 321c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+long}, 322c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+long\s+int}, 3238905a67cSAndy Whitcroft qr{unsigned}, 3248905a67cSAndy Whitcroft qr{float}, 3258905a67cSAndy Whitcroft qr{double}, 3268905a67cSAndy Whitcroft qr{bool}, 3278905a67cSAndy Whitcroft qr{struct\s+$Ident}, 3288905a67cSAndy Whitcroft qr{union\s+$Ident}, 3298905a67cSAndy Whitcroft qr{enum\s+$Ident}, 3308905a67cSAndy Whitcroft qr{${Ident}_t}, 3318905a67cSAndy Whitcroft qr{${Ident}_handler}, 3328905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 3338905a67cSAndy Whitcroft); 334c45dcabdSAndy Whitcroftour @modifierList = ( 335c45dcabdSAndy Whitcroft qr{fastcall}, 336c45dcabdSAndy Whitcroft); 3378905a67cSAndy Whitcroft 3387840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 3397840a94cSWolfram Sang irq| 3407840a94cSWolfram Sang memory 3417840a94cSWolfram Sang)}; 3427840a94cSWolfram Sang# memory.h: ARM has a custom one 3437840a94cSWolfram Sang 3448905a67cSAndy Whitcroftsub build_types { 345d2172eb5SAndy Whitcroft my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 346d2172eb5SAndy Whitcroft my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 347c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 3488905a67cSAndy Whitcroft $NonptrType = qr{ 349d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 350cf655043SAndy Whitcroft (?: 3516b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 3528ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 353c45dcabdSAndy Whitcroft (?:${all}\b) 354cf655043SAndy Whitcroft ) 355c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 3568905a67cSAndy Whitcroft }x; 3578905a67cSAndy Whitcroft $Type = qr{ 358c45dcabdSAndy Whitcroft $NonptrType 359b337d8b8SAndy Whitcroft (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? 360c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 3618905a67cSAndy Whitcroft }x; 3628905a67cSAndy Whitcroft $Declare = qr{(?:$Storage\s+)?$Type}; 3638905a67cSAndy Whitcroft} 3648905a67cSAndy Whitcroftbuild_types(); 3656c72ffaaSAndy Whitcroft 3667d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 367d1fe9c09SJoe Perches 368d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 369d1fe9c09SJoe Perches# requires at least perl version v5.10.0 370d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 371d1fe9c09SJoe Perches 372d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 373d1fe9c09SJoe Perchesour $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; 374d7c76ba7SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; 3757d2367afSJoe Perches 3767d2367afSJoe Perchessub deparenthesize { 3777d2367afSJoe Perches my ($string) = @_; 3787d2367afSJoe Perches return "" if (!defined($string)); 3797d2367afSJoe Perches $string =~ s@^\s*\(\s*@@g; 3807d2367afSJoe Perches $string =~ s@\s*\)\s*$@@g; 3817d2367afSJoe Perches $string =~ s@\s+@ @g; 3827d2367afSJoe Perches return $string; 3837d2367afSJoe Perches} 3847d2367afSJoe Perches 3853445686aSJoe Perchessub seed_camelcase_file { 3863445686aSJoe Perches my ($file) = @_; 3873445686aSJoe Perches 3883445686aSJoe Perches return if (!(-f $file)); 3893445686aSJoe Perches 3903445686aSJoe Perches local $/; 3913445686aSJoe Perches 3923445686aSJoe Perches open(my $include_file, '<', "$file") 3933445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 3943445686aSJoe Perches my $text = <$include_file>; 3953445686aSJoe Perches close($include_file); 3963445686aSJoe Perches 3973445686aSJoe Perches my @lines = split('\n', $text); 3983445686aSJoe Perches 3993445686aSJoe Perches foreach my $line (@lines) { 4003445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 4013445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 4023445686aSJoe Perches $camelcase{$1} = 1; 4033445686aSJoe Perches } 4043445686aSJoe Perches elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*\(/) { 4053445686aSJoe Perches $camelcase{$1} = 1; 4063445686aSJoe Perches } 4073445686aSJoe Perches } 4083445686aSJoe Perches} 4093445686aSJoe Perches 4103445686aSJoe Perchesmy $camelcase_seeded = 0; 4113445686aSJoe Perchessub seed_camelcase_includes { 4123445686aSJoe Perches return if ($camelcase_seeded); 4133445686aSJoe Perches 4143445686aSJoe Perches my $files; 415c707a81dSJoe Perches my $camelcase_cache = ""; 416c707a81dSJoe Perches my @include_files = (); 417c707a81dSJoe Perches 418c707a81dSJoe Perches $camelcase_seeded = 1; 419351b2a1fSJoe Perches 4203445686aSJoe Perches if (-d ".git") { 421351b2a1fSJoe Perches my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; 422351b2a1fSJoe Perches chomp $git_last_include_commit; 423c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 424c707a81dSJoe Perches } else { 425c707a81dSJoe Perches my $last_mod_date = 0; 426c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 427c707a81dSJoe Perches @include_files = split('\n', $files); 428c707a81dSJoe Perches foreach my $file (@include_files) { 429c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 430c707a81dSJoe Perches localtime((stat $file)[9])); 431c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 432c707a81dSJoe Perches } 433c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 434c707a81dSJoe Perches } 435c707a81dSJoe Perches 436c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 437c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 438c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 439351b2a1fSJoe Perches while (<$camelcase_file>) { 440351b2a1fSJoe Perches chomp; 441351b2a1fSJoe Perches $camelcase{$_} = 1; 442351b2a1fSJoe Perches } 443351b2a1fSJoe Perches close($camelcase_file); 444351b2a1fSJoe Perches 445351b2a1fSJoe Perches return; 446351b2a1fSJoe Perches } 447c707a81dSJoe Perches 448c707a81dSJoe Perches if (-d ".git") { 449c707a81dSJoe Perches $files = `git ls-files "include/*.h"`; 450c707a81dSJoe Perches @include_files = split('\n', $files); 4513445686aSJoe Perches } 452c707a81dSJoe Perches 4533445686aSJoe Perches foreach my $file (@include_files) { 4543445686aSJoe Perches seed_camelcase_file($file); 4553445686aSJoe Perches } 456351b2a1fSJoe Perches 457c707a81dSJoe Perches if ($camelcase_cache ne "") { 458351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 459c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 460c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 461351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 462351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 463351b2a1fSJoe Perches } 464351b2a1fSJoe Perches close($camelcase_file); 465351b2a1fSJoe Perches } 4663445686aSJoe Perches} 4673445686aSJoe Perches 4686c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 4690a920b5bSAndy Whitcroft 47000df344fSAndy Whitcroftmy @rawlines = (); 471c2fdda0dSAndy Whitcroftmy @lines = (); 4723705ce5bSJoe Perchesmy @fixed = (); 473c2fdda0dSAndy Whitcroftmy $vname; 4746c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 47521caa13cSAndy Whitcroft my $FILE; 4766c72ffaaSAndy Whitcroft if ($file) { 47721caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 4786c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 47921caa13cSAndy Whitcroft } elsif ($filename eq '-') { 48021caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 4816c72ffaaSAndy Whitcroft } else { 48221caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 4836c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 4846c72ffaaSAndy Whitcroft } 485c2fdda0dSAndy Whitcroft if ($filename eq '-') { 486c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 487c2fdda0dSAndy Whitcroft } else { 488c2fdda0dSAndy Whitcroft $vname = $filename; 489c2fdda0dSAndy Whitcroft } 49021caa13cSAndy Whitcroft while (<$FILE>) { 4910a920b5bSAndy Whitcroft chomp; 49200df344fSAndy Whitcroft push(@rawlines, $_); 4936c72ffaaSAndy Whitcroft } 49421caa13cSAndy Whitcroft close($FILE); 495c2fdda0dSAndy Whitcroft if (!process($filename)) { 4960a920b5bSAndy Whitcroft $exit = 1; 4970a920b5bSAndy Whitcroft } 49800df344fSAndy Whitcroft @rawlines = (); 49913214adfSAndy Whitcroft @lines = (); 5003705ce5bSJoe Perches @fixed = (); 5010a920b5bSAndy Whitcroft} 5020a920b5bSAndy Whitcroft 5030a920b5bSAndy Whitcroftexit($exit); 5040a920b5bSAndy Whitcroft 5050a920b5bSAndy Whitcroftsub top_of_kernel_tree { 5066c72ffaaSAndy Whitcroft my ($root) = @_; 5076c72ffaaSAndy Whitcroft 5086c72ffaaSAndy Whitcroft my @tree_check = ( 5096c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 5106c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 5116c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 5126c72ffaaSAndy Whitcroft ); 5136c72ffaaSAndy Whitcroft 5146c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 5156c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 5160a920b5bSAndy Whitcroft return 0; 5170a920b5bSAndy Whitcroft } 5186c72ffaaSAndy Whitcroft } 5196c72ffaaSAndy Whitcroft return 1; 5206c72ffaaSAndy Whitcroft} 5210a920b5bSAndy Whitcroft 52220112475SJoe Perchessub parse_email { 52320112475SJoe Perches my ($formatted_email) = @_; 52420112475SJoe Perches 52520112475SJoe Perches my $name = ""; 52620112475SJoe Perches my $address = ""; 52720112475SJoe Perches my $comment = ""; 52820112475SJoe Perches 52920112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 53020112475SJoe Perches $name = $1; 53120112475SJoe Perches $address = $2; 53220112475SJoe Perches $comment = $3 if defined $3; 53320112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 53420112475SJoe Perches $address = $1; 53520112475SJoe Perches $comment = $2 if defined $2; 53620112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 53720112475SJoe Perches $address = $1; 53820112475SJoe Perches $comment = $2 if defined $2; 53920112475SJoe Perches $formatted_email =~ s/$address.*$//; 54020112475SJoe Perches $name = $formatted_email; 5413705ce5bSJoe Perches $name = trim($name); 54220112475SJoe Perches $name =~ s/^\"|\"$//g; 54320112475SJoe Perches # If there's a name left after stripping spaces and 54420112475SJoe Perches # leading quotes, and the address doesn't have both 54520112475SJoe Perches # leading and trailing angle brackets, the address 54620112475SJoe Perches # is invalid. ie: 54720112475SJoe Perches # "joe smith [email protected]" bad 54820112475SJoe Perches # "joe smith <[email protected]" bad 54920112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 55020112475SJoe Perches $name = ""; 55120112475SJoe Perches $address = ""; 55220112475SJoe Perches $comment = ""; 55320112475SJoe Perches } 55420112475SJoe Perches } 55520112475SJoe Perches 5563705ce5bSJoe Perches $name = trim($name); 55720112475SJoe Perches $name =~ s/^\"|\"$//g; 5583705ce5bSJoe Perches $address = trim($address); 55920112475SJoe Perches $address =~ s/^\<|\>$//g; 56020112475SJoe Perches 56120112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 56220112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 56320112475SJoe Perches $name = "\"$name\""; 56420112475SJoe Perches } 56520112475SJoe Perches 56620112475SJoe Perches return ($name, $address, $comment); 56720112475SJoe Perches} 56820112475SJoe Perches 56920112475SJoe Perchessub format_email { 57020112475SJoe Perches my ($name, $address) = @_; 57120112475SJoe Perches 57220112475SJoe Perches my $formatted_email; 57320112475SJoe Perches 5743705ce5bSJoe Perches $name = trim($name); 57520112475SJoe Perches $name =~ s/^\"|\"$//g; 5763705ce5bSJoe Perches $address = trim($address); 57720112475SJoe Perches 57820112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 57920112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 58020112475SJoe Perches $name = "\"$name\""; 58120112475SJoe Perches } 58220112475SJoe Perches 58320112475SJoe Perches if ("$name" eq "") { 58420112475SJoe Perches $formatted_email = "$address"; 58520112475SJoe Perches } else { 58620112475SJoe Perches $formatted_email = "$name <$address>"; 58720112475SJoe Perches } 58820112475SJoe Perches 58920112475SJoe Perches return $formatted_email; 59020112475SJoe Perches} 59120112475SJoe Perches 592000d1cc1SJoe Perchessub which_conf { 593000d1cc1SJoe Perches my ($conf) = @_; 594000d1cc1SJoe Perches 595000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 596000d1cc1SJoe Perches if (-e "$path/$conf") { 597000d1cc1SJoe Perches return "$path/$conf"; 598000d1cc1SJoe Perches } 599000d1cc1SJoe Perches } 600000d1cc1SJoe Perches 601000d1cc1SJoe Perches return ""; 602000d1cc1SJoe Perches} 603000d1cc1SJoe Perches 6040a920b5bSAndy Whitcroftsub expand_tabs { 6050a920b5bSAndy Whitcroft my ($str) = @_; 6060a920b5bSAndy Whitcroft 6070a920b5bSAndy Whitcroft my $res = ''; 6080a920b5bSAndy Whitcroft my $n = 0; 6090a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 6100a920b5bSAndy Whitcroft if ($c eq "\t") { 6110a920b5bSAndy Whitcroft $res .= ' '; 6120a920b5bSAndy Whitcroft $n++; 6130a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 6140a920b5bSAndy Whitcroft $res .= ' '; 6150a920b5bSAndy Whitcroft } 6160a920b5bSAndy Whitcroft next; 6170a920b5bSAndy Whitcroft } 6180a920b5bSAndy Whitcroft $res .= $c; 6190a920b5bSAndy Whitcroft $n++; 6200a920b5bSAndy Whitcroft } 6210a920b5bSAndy Whitcroft 6220a920b5bSAndy Whitcroft return $res; 6230a920b5bSAndy Whitcroft} 6246c72ffaaSAndy Whitcroftsub copy_spacing { 625773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 6266c72ffaaSAndy Whitcroft return $res; 6276c72ffaaSAndy Whitcroft} 6280a920b5bSAndy Whitcroft 6294a0df2efSAndy Whitcroftsub line_stats { 6304a0df2efSAndy Whitcroft my ($line) = @_; 6314a0df2efSAndy Whitcroft 6324a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 6334a0df2efSAndy Whitcroft $line =~ s/^.//; 6344a0df2efSAndy Whitcroft $line = expand_tabs($line); 6354a0df2efSAndy Whitcroft 6364a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 6374a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 6384a0df2efSAndy Whitcroft 6394a0df2efSAndy Whitcroft return (length($line), length($white)); 6404a0df2efSAndy Whitcroft} 6414a0df2efSAndy Whitcroft 642773647a0SAndy Whitcroftmy $sanitise_quote = ''; 643773647a0SAndy Whitcroft 644773647a0SAndy Whitcroftsub sanitise_line_reset { 645773647a0SAndy Whitcroft my ($in_comment) = @_; 646773647a0SAndy Whitcroft 647773647a0SAndy Whitcroft if ($in_comment) { 648773647a0SAndy Whitcroft $sanitise_quote = '*/'; 649773647a0SAndy Whitcroft } else { 650773647a0SAndy Whitcroft $sanitise_quote = ''; 651773647a0SAndy Whitcroft } 652773647a0SAndy Whitcroft} 65300df344fSAndy Whitcroftsub sanitise_line { 65400df344fSAndy Whitcroft my ($line) = @_; 65500df344fSAndy Whitcroft 65600df344fSAndy Whitcroft my $res = ''; 65700df344fSAndy Whitcroft my $l = ''; 65800df344fSAndy Whitcroft 659c2fdda0dSAndy Whitcroft my $qlen = 0; 660773647a0SAndy Whitcroft my $off = 0; 661773647a0SAndy Whitcroft my $c; 66200df344fSAndy Whitcroft 663773647a0SAndy Whitcroft # Always copy over the diff marker. 664773647a0SAndy Whitcroft $res = substr($line, 0, 1); 665773647a0SAndy Whitcroft 666773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 667773647a0SAndy Whitcroft $c = substr($line, $off, 1); 668773647a0SAndy Whitcroft 669773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 670773647a0SAndy Whitcroft # and end, all to $;. 671773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 672773647a0SAndy Whitcroft $sanitise_quote = '*/'; 673773647a0SAndy Whitcroft 674773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 675773647a0SAndy Whitcroft $off++; 67600df344fSAndy Whitcroft next; 677773647a0SAndy Whitcroft } 67881bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 679773647a0SAndy Whitcroft $sanitise_quote = ''; 680773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 681773647a0SAndy Whitcroft $off++; 682773647a0SAndy Whitcroft next; 683773647a0SAndy Whitcroft } 684113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 685113f04a8SDaniel Walker $sanitise_quote = '//'; 686113f04a8SDaniel Walker 687113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 688113f04a8SDaniel Walker $off++; 689113f04a8SDaniel Walker next; 690113f04a8SDaniel Walker } 691773647a0SAndy Whitcroft 692773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 693773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 694773647a0SAndy Whitcroft $c eq "\\") { 695773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 696773647a0SAndy Whitcroft $off++; 697773647a0SAndy Whitcroft next; 698773647a0SAndy Whitcroft } 699773647a0SAndy Whitcroft # Regular quotes. 700773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 701773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 702773647a0SAndy Whitcroft $sanitise_quote = $c; 703773647a0SAndy Whitcroft 704773647a0SAndy Whitcroft substr($res, $off, 1, $c); 705773647a0SAndy Whitcroft next; 706773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 707773647a0SAndy Whitcroft $sanitise_quote = ''; 70800df344fSAndy Whitcroft } 70900df344fSAndy Whitcroft } 710773647a0SAndy Whitcroft 711fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 712773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 713773647a0SAndy Whitcroft substr($res, $off, 1, $;); 714113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 715113f04a8SDaniel Walker substr($res, $off, 1, $;); 716773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 717773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 71800df344fSAndy Whitcroft } else { 719773647a0SAndy Whitcroft substr($res, $off, 1, $c); 72000df344fSAndy Whitcroft } 721c2fdda0dSAndy Whitcroft } 722c2fdda0dSAndy Whitcroft 723113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 724113f04a8SDaniel Walker $sanitise_quote = ''; 725113f04a8SDaniel Walker } 726113f04a8SDaniel Walker 727c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 728c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 729c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 730c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 731c2fdda0dSAndy Whitcroft 732c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 733c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 734c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 735c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 736c2fdda0dSAndy Whitcroft } 737c2fdda0dSAndy Whitcroft 73800df344fSAndy Whitcroft return $res; 73900df344fSAndy Whitcroft} 74000df344fSAndy Whitcroft 741a6962d72SJoe Perchessub get_quoted_string { 742a6962d72SJoe Perches my ($line, $rawline) = @_; 743a6962d72SJoe Perches 744a6962d72SJoe Perches return "" if ($line !~ m/(\"[X]+\")/g); 745a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 746a6962d72SJoe Perches} 747a6962d72SJoe Perches 7488905a67cSAndy Whitcroftsub ctx_statement_block { 7498905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 7508905a67cSAndy Whitcroft my $line = $linenr - 1; 7518905a67cSAndy Whitcroft my $blk = ''; 7528905a67cSAndy Whitcroft my $soff = $off; 7538905a67cSAndy Whitcroft my $coff = $off - 1; 754773647a0SAndy Whitcroft my $coff_set = 0; 7558905a67cSAndy Whitcroft 75613214adfSAndy Whitcroft my $loff = 0; 75713214adfSAndy Whitcroft 7588905a67cSAndy Whitcroft my $type = ''; 7598905a67cSAndy Whitcroft my $level = 0; 760a2750645SAndy Whitcroft my @stack = (); 761cf655043SAndy Whitcroft my $p; 7628905a67cSAndy Whitcroft my $c; 7638905a67cSAndy Whitcroft my $len = 0; 76413214adfSAndy Whitcroft 76513214adfSAndy Whitcroft my $remainder; 7668905a67cSAndy Whitcroft while (1) { 767a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 768a2750645SAndy Whitcroft 769773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 7708905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 7718905a67cSAndy Whitcroft # context. 7728905a67cSAndy Whitcroft if ($off >= $len) { 7738905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 774dea33496SAndy Whitcroft last if (!defined $lines[$line]); 775c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 7768905a67cSAndy Whitcroft $remain--; 77713214adfSAndy Whitcroft $loff = $len; 778c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 7798905a67cSAndy Whitcroft $len = length($blk); 7808905a67cSAndy Whitcroft $line++; 7818905a67cSAndy Whitcroft last; 7828905a67cSAndy Whitcroft } 7838905a67cSAndy Whitcroft # Bail if there is no further context. 7848905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 78513214adfSAndy Whitcroft if ($off >= $len) { 7868905a67cSAndy Whitcroft last; 7878905a67cSAndy Whitcroft } 788f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 789f74bd194SAndy Whitcroft $level++; 790f74bd194SAndy Whitcroft $type = '#'; 791f74bd194SAndy Whitcroft } 7928905a67cSAndy Whitcroft } 793cf655043SAndy Whitcroft $p = $c; 7948905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 79513214adfSAndy Whitcroft $remainder = substr($blk, $off); 7968905a67cSAndy Whitcroft 797773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 7984635f4fbSAndy Whitcroft 7994635f4fbSAndy Whitcroft # Handle nested #if/#else. 8004635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 8014635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 8024635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 8034635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 8044635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 8054635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 8064635f4fbSAndy Whitcroft } 8074635f4fbSAndy Whitcroft 8088905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 8098905a67cSAndy Whitcroft # outermost level. 8108905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 8118905a67cSAndy Whitcroft last; 8128905a67cSAndy Whitcroft } 8138905a67cSAndy Whitcroft 81413214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 815773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 816773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 817773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 818773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 819773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 820773647a0SAndy Whitcroft $coff_set = 1; 821773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 822773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 82313214adfSAndy Whitcroft } 82413214adfSAndy Whitcroft 8258905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 8268905a67cSAndy Whitcroft $level++; 8278905a67cSAndy Whitcroft $type = '('; 8288905a67cSAndy Whitcroft } 8298905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 8308905a67cSAndy Whitcroft $level--; 8318905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 8328905a67cSAndy Whitcroft 8338905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 8348905a67cSAndy Whitcroft $coff = $off; 835773647a0SAndy Whitcroft $coff_set = 1; 836773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 8378905a67cSAndy Whitcroft } 8388905a67cSAndy Whitcroft } 8398905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 8408905a67cSAndy Whitcroft $level++; 8418905a67cSAndy Whitcroft $type = '{'; 8428905a67cSAndy Whitcroft } 8438905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 8448905a67cSAndy Whitcroft $level--; 8458905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 8468905a67cSAndy Whitcroft 8478905a67cSAndy Whitcroft if ($level == 0) { 848b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 849b998e001SPatrick Pannuto $off++; 850b998e001SPatrick Pannuto } 8518905a67cSAndy Whitcroft last; 8528905a67cSAndy Whitcroft } 8538905a67cSAndy Whitcroft } 854f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 855f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 856f74bd194SAndy Whitcroft $level--; 857f74bd194SAndy Whitcroft $type = ''; 858f74bd194SAndy Whitcroft $off++; 859f74bd194SAndy Whitcroft last; 860f74bd194SAndy Whitcroft } 8618905a67cSAndy Whitcroft $off++; 8628905a67cSAndy Whitcroft } 863a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 86413214adfSAndy Whitcroft if ($off == $len) { 865a3bb97a7SAndy Whitcroft $loff = $len + 1; 86613214adfSAndy Whitcroft $line++; 86713214adfSAndy Whitcroft $remain--; 86813214adfSAndy Whitcroft } 8698905a67cSAndy Whitcroft 8708905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 8718905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 8728905a67cSAndy Whitcroft 8738905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 8748905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 8758905a67cSAndy Whitcroft 876773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 87713214adfSAndy Whitcroft 87813214adfSAndy Whitcroft return ($statement, $condition, 87913214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 88013214adfSAndy Whitcroft} 88113214adfSAndy Whitcroft 882cf655043SAndy Whitcroftsub statement_lines { 883cf655043SAndy Whitcroft my ($stmt) = @_; 884cf655043SAndy Whitcroft 885cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 886cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 887cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 888cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 889cf655043SAndy Whitcroft 890cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 891cf655043SAndy Whitcroft 892cf655043SAndy Whitcroft return $#stmt_lines + 2; 893cf655043SAndy Whitcroft} 894cf655043SAndy Whitcroft 895cf655043SAndy Whitcroftsub statement_rawlines { 896cf655043SAndy Whitcroft my ($stmt) = @_; 897cf655043SAndy Whitcroft 898cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 899cf655043SAndy Whitcroft 900cf655043SAndy Whitcroft return $#stmt_lines + 2; 901cf655043SAndy Whitcroft} 902cf655043SAndy Whitcroft 903cf655043SAndy Whitcroftsub statement_block_size { 904cf655043SAndy Whitcroft my ($stmt) = @_; 905cf655043SAndy Whitcroft 906cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 907cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 908cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 909cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 910cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 911cf655043SAndy Whitcroft 912cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 913cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 914cf655043SAndy Whitcroft 915cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 916cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 917cf655043SAndy Whitcroft 918cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 919cf655043SAndy Whitcroft return $stmt_lines; 920cf655043SAndy Whitcroft } else { 921cf655043SAndy Whitcroft return $stmt_statements; 922cf655043SAndy Whitcroft } 923cf655043SAndy Whitcroft} 924cf655043SAndy Whitcroft 92513214adfSAndy Whitcroftsub ctx_statement_full { 92613214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 92713214adfSAndy Whitcroft my ($statement, $condition, $level); 92813214adfSAndy Whitcroft 92913214adfSAndy Whitcroft my (@chunks); 93013214adfSAndy Whitcroft 931cf655043SAndy Whitcroft # Grab the first conditional/block pair. 93213214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 93313214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 934773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 93513214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 936cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 937cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 938cf655043SAndy Whitcroft } 939cf655043SAndy Whitcroft 940cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 941cf655043SAndy Whitcroft # could continue the statement. 942cf655043SAndy Whitcroft for (;;) { 94313214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 94413214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 945cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 946773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 947cf655043SAndy Whitcroft #print "C: push\n"; 948cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 94913214adfSAndy Whitcroft } 95013214adfSAndy Whitcroft 95113214adfSAndy Whitcroft return ($level, $linenr, @chunks); 9528905a67cSAndy Whitcroft} 9538905a67cSAndy Whitcroft 9544a0df2efSAndy Whitcroftsub ctx_block_get { 955f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 9564a0df2efSAndy Whitcroft my $line; 9574a0df2efSAndy Whitcroft my $start = $linenr - 1; 9584a0df2efSAndy Whitcroft my $blk = ''; 9594a0df2efSAndy Whitcroft my @o; 9604a0df2efSAndy Whitcroft my @c; 9614a0df2efSAndy Whitcroft my @res = (); 9624a0df2efSAndy Whitcroft 963f0a594c1SAndy Whitcroft my $level = 0; 9644635f4fbSAndy Whitcroft my @stack = ($level); 96500df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 96600df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 96700df344fSAndy Whitcroft $remain--; 96800df344fSAndy Whitcroft 96900df344fSAndy Whitcroft $blk .= $rawlines[$line]; 9704635f4fbSAndy Whitcroft 9714635f4fbSAndy Whitcroft # Handle nested #if/#else. 97201464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 9734635f4fbSAndy Whitcroft push(@stack, $level); 97401464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 9754635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 97601464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 9774635f4fbSAndy Whitcroft $level = pop(@stack); 9784635f4fbSAndy Whitcroft } 9794635f4fbSAndy Whitcroft 98001464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 981f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 982f0a594c1SAndy Whitcroft if ($off > 0) { 983f0a594c1SAndy Whitcroft $off--; 984f0a594c1SAndy Whitcroft next; 985f0a594c1SAndy Whitcroft } 9864a0df2efSAndy Whitcroft 987f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 988f0a594c1SAndy Whitcroft $level--; 989f0a594c1SAndy Whitcroft last if ($level == 0); 990f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 991f0a594c1SAndy Whitcroft $level++; 992f0a594c1SAndy Whitcroft } 993f0a594c1SAndy Whitcroft } 9944a0df2efSAndy Whitcroft 995f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 99600df344fSAndy Whitcroft push(@res, $rawlines[$line]); 9974a0df2efSAndy Whitcroft } 9984a0df2efSAndy Whitcroft 999f0a594c1SAndy Whitcroft last if ($level == 0); 10004a0df2efSAndy Whitcroft } 10014a0df2efSAndy Whitcroft 1002f0a594c1SAndy Whitcroft return ($level, @res); 10034a0df2efSAndy Whitcroft} 10044a0df2efSAndy Whitcroftsub ctx_block_outer { 10054a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 10064a0df2efSAndy Whitcroft 1007f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1008f0a594c1SAndy Whitcroft return @r; 10094a0df2efSAndy Whitcroft} 10104a0df2efSAndy Whitcroftsub ctx_block { 10114a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 10124a0df2efSAndy Whitcroft 1013f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1014f0a594c1SAndy Whitcroft return @r; 1015653d4876SAndy Whitcroft} 1016653d4876SAndy Whitcroftsub ctx_statement { 1017f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1018f0a594c1SAndy Whitcroft 1019f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1020f0a594c1SAndy Whitcroft return @r; 1021f0a594c1SAndy Whitcroft} 1022f0a594c1SAndy Whitcroftsub ctx_block_level { 1023653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1024653d4876SAndy Whitcroft 1025f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 10264a0df2efSAndy Whitcroft} 10279c0ca6f9SAndy Whitcroftsub ctx_statement_level { 10289c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 10299c0ca6f9SAndy Whitcroft 10309c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 10319c0ca6f9SAndy Whitcroft} 10324a0df2efSAndy Whitcroft 10334a0df2efSAndy Whitcroftsub ctx_locate_comment { 10344a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 10354a0df2efSAndy Whitcroft 10364a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1037beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 10384a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 10394a0df2efSAndy Whitcroft 10404a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 10414a0df2efSAndy Whitcroft # comment. 10424a0df2efSAndy Whitcroft my $in_comment = 0; 10434a0df2efSAndy Whitcroft $current_comment = ''; 10444a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 104500df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 104600df344fSAndy Whitcroft #warn " $line\n"; 10474a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 10484a0df2efSAndy Whitcroft $in_comment = 1; 10494a0df2efSAndy Whitcroft } 10504a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 10514a0df2efSAndy Whitcroft $in_comment = 1; 10524a0df2efSAndy Whitcroft } 10534a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 10544a0df2efSAndy Whitcroft $current_comment = ''; 10554a0df2efSAndy Whitcroft } 10564a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 10574a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 10584a0df2efSAndy Whitcroft $in_comment = 0; 10594a0df2efSAndy Whitcroft } 10604a0df2efSAndy Whitcroft } 10614a0df2efSAndy Whitcroft 10624a0df2efSAndy Whitcroft chomp($current_comment); 10634a0df2efSAndy Whitcroft return($current_comment); 10644a0df2efSAndy Whitcroft} 10654a0df2efSAndy Whitcroftsub ctx_has_comment { 10664a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 10674a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 10684a0df2efSAndy Whitcroft 106900df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 10704a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 10714a0df2efSAndy Whitcroft 10724a0df2efSAndy Whitcroft return ($cmt ne ''); 10734a0df2efSAndy Whitcroft} 10744a0df2efSAndy Whitcroft 10754d001e4dSAndy Whitcroftsub raw_line { 10764d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 10774d001e4dSAndy Whitcroft 10784d001e4dSAndy Whitcroft my $offset = $linenr - 1; 10794d001e4dSAndy Whitcroft $cnt++; 10804d001e4dSAndy Whitcroft 10814d001e4dSAndy Whitcroft my $line; 10824d001e4dSAndy Whitcroft while ($cnt) { 10834d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 10844d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 10854d001e4dSAndy Whitcroft $cnt--; 10864d001e4dSAndy Whitcroft } 10874d001e4dSAndy Whitcroft 10884d001e4dSAndy Whitcroft return $line; 10894d001e4dSAndy Whitcroft} 10904d001e4dSAndy Whitcroft 10910a920b5bSAndy Whitcroftsub cat_vet { 10920a920b5bSAndy Whitcroft my ($vet) = @_; 10939c0ca6f9SAndy Whitcroft my ($res, $coded); 10940a920b5bSAndy Whitcroft 10959c0ca6f9SAndy Whitcroft $res = ''; 10966c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 10976c72ffaaSAndy Whitcroft $res .= $1; 10986c72ffaaSAndy Whitcroft if ($2 ne '') { 10999c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 11006c72ffaaSAndy Whitcroft $res .= $coded; 11016c72ffaaSAndy Whitcroft } 11029c0ca6f9SAndy Whitcroft } 11039c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 11040a920b5bSAndy Whitcroft 11059c0ca6f9SAndy Whitcroft return $res; 11060a920b5bSAndy Whitcroft} 11070a920b5bSAndy Whitcroft 1108c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1109cf655043SAndy Whitcroftmy $av_pending; 1110c2fdda0dSAndy Whitcroftmy @av_paren_type; 11111f65f947SAndy Whitcroftmy $av_pend_colon; 1112c2fdda0dSAndy Whitcroft 1113c2fdda0dSAndy Whitcroftsub annotate_reset { 1114c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1115cf655043SAndy Whitcroft $av_pending = '_'; 1116cf655043SAndy Whitcroft @av_paren_type = ('E'); 11171f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1118c2fdda0dSAndy Whitcroft} 1119c2fdda0dSAndy Whitcroft 11206c72ffaaSAndy Whitcroftsub annotate_values { 11216c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 11226c72ffaaSAndy Whitcroft 11236c72ffaaSAndy Whitcroft my $res; 11241f65f947SAndy Whitcroft my $var = '_' x length($stream); 11256c72ffaaSAndy Whitcroft my $cur = $stream; 11266c72ffaaSAndy Whitcroft 1127c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 11286c72ffaaSAndy Whitcroft 11296c72ffaaSAndy Whitcroft while (length($cur)) { 1130773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1131cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1132171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 11336c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1134c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1135c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1136cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1137c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 11386c72ffaaSAndy Whitcroft } 11396c72ffaaSAndy Whitcroft 1140c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 11419446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 11429446ef56SAndy Whitcroft push(@av_paren_type, $type); 1143addcdceaSAndy Whitcroft $type = 'c'; 11449446ef56SAndy Whitcroft 1145e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1146c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 11476c72ffaaSAndy Whitcroft $type = 'T'; 11486c72ffaaSAndy Whitcroft 1149389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1150389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1151389a2fe5SAndy Whitcroft $type = 'T'; 1152389a2fe5SAndy Whitcroft 1153c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1154171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1155c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1156171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1157171ae1a4SAndy Whitcroft if ($2 ne '') { 1158cf655043SAndy Whitcroft $av_pending = 'N'; 1159171ae1a4SAndy Whitcroft } 1160171ae1a4SAndy Whitcroft $type = 'E'; 1161171ae1a4SAndy Whitcroft 1162c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1163171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1164171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1165171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 11666c72ffaaSAndy Whitcroft 1167c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1168cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1169c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1170cf655043SAndy Whitcroft 1171cf655043SAndy Whitcroft push(@av_paren_type, $type); 1172cf655043SAndy Whitcroft push(@av_paren_type, $type); 1173171ae1a4SAndy Whitcroft $type = 'E'; 1174cf655043SAndy Whitcroft 1175c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1176cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1177cf655043SAndy Whitcroft $av_preprocessor = 1; 1178cf655043SAndy Whitcroft 1179cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1180cf655043SAndy Whitcroft 1181171ae1a4SAndy Whitcroft $type = 'E'; 1182cf655043SAndy Whitcroft 1183c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1184cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1185cf655043SAndy Whitcroft 1186cf655043SAndy Whitcroft $av_preprocessor = 1; 1187cf655043SAndy Whitcroft 1188cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1189cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1190cf655043SAndy Whitcroft pop(@av_paren_type); 1191cf655043SAndy Whitcroft push(@av_paren_type, $type); 1192171ae1a4SAndy Whitcroft $type = 'E'; 11936c72ffaaSAndy Whitcroft 11946c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1195c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 11966c72ffaaSAndy Whitcroft 1197171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1198171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1199171ae1a4SAndy Whitcroft $av_pending = $type; 1200171ae1a4SAndy Whitcroft $type = 'N'; 1201171ae1a4SAndy Whitcroft 12026c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1203c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 12046c72ffaaSAndy Whitcroft if (defined $2) { 1205cf655043SAndy Whitcroft $av_pending = 'V'; 12066c72ffaaSAndy Whitcroft } 12076c72ffaaSAndy Whitcroft $type = 'N'; 12086c72ffaaSAndy Whitcroft 120914b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1210c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 121114b111c1SAndy Whitcroft $av_pending = 'E'; 12126c72ffaaSAndy Whitcroft $type = 'N'; 12136c72ffaaSAndy Whitcroft 12141f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 12151f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 12161f65f947SAndy Whitcroft $av_pend_colon = 'C'; 12171f65f947SAndy Whitcroft $type = 'N'; 12181f65f947SAndy Whitcroft 121914b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1220c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 12216c72ffaaSAndy Whitcroft $type = 'N'; 12226c72ffaaSAndy Whitcroft 12236c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1224c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1225cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1226cf655043SAndy Whitcroft $av_pending = '_'; 12276c72ffaaSAndy Whitcroft $type = 'N'; 12286c72ffaaSAndy Whitcroft 12296c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1230cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1231cf655043SAndy Whitcroft if ($new_type ne '_') { 1232cf655043SAndy Whitcroft $type = $new_type; 1233c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1234c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 12356c72ffaaSAndy Whitcroft } else { 1236c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 12376c72ffaaSAndy Whitcroft } 12386c72ffaaSAndy Whitcroft 1239c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1240c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1241c8cb2ca3SAndy Whitcroft $type = 'V'; 1242cf655043SAndy Whitcroft $av_pending = 'V'; 12436c72ffaaSAndy Whitcroft 12448e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 12458e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 12461f65f947SAndy Whitcroft $av_pend_colon = 'B'; 12478e761b04SAndy Whitcroft } elsif ($type eq 'E') { 12488e761b04SAndy Whitcroft $av_pend_colon = 'L'; 12491f65f947SAndy Whitcroft } 12501f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 12511f65f947SAndy Whitcroft $type = 'V'; 12521f65f947SAndy Whitcroft 12536c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1254c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 12556c72ffaaSAndy Whitcroft $type = 'V'; 12566c72ffaaSAndy Whitcroft 12576c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1258c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 12596c72ffaaSAndy Whitcroft $type = 'N'; 12606c72ffaaSAndy Whitcroft 1261cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1262c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 126313214adfSAndy Whitcroft $type = 'E'; 12641f65f947SAndy Whitcroft $av_pend_colon = 'O'; 126513214adfSAndy Whitcroft 12668e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 12678e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 12688e761b04SAndy Whitcroft $type = 'C'; 12698e761b04SAndy Whitcroft 12701f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 12711f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 12721f65f947SAndy Whitcroft $type = 'N'; 12731f65f947SAndy Whitcroft 12741f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 12751f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 12761f65f947SAndy Whitcroft 12771f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 12781f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 12791f65f947SAndy Whitcroft $type = 'E'; 12801f65f947SAndy Whitcroft } else { 12811f65f947SAndy Whitcroft $type = 'N'; 12821f65f947SAndy Whitcroft } 12831f65f947SAndy Whitcroft $av_pend_colon = 'O'; 12841f65f947SAndy Whitcroft 12858e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 128613214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 12876c72ffaaSAndy Whitcroft $type = 'N'; 12886c72ffaaSAndy Whitcroft 12890d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 129074048ed8SAndy Whitcroft my $variant; 129174048ed8SAndy Whitcroft 129274048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 129374048ed8SAndy Whitcroft if ($type eq 'V') { 129474048ed8SAndy Whitcroft $variant = 'B'; 129574048ed8SAndy Whitcroft } else { 129674048ed8SAndy Whitcroft $variant = 'U'; 129774048ed8SAndy Whitcroft } 129874048ed8SAndy Whitcroft 129974048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 130074048ed8SAndy Whitcroft $type = 'N'; 130174048ed8SAndy Whitcroft 13026c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1303c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 13046c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 13056c72ffaaSAndy Whitcroft $type = 'N'; 13066c72ffaaSAndy Whitcroft } 13076c72ffaaSAndy Whitcroft 13086c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1309c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 13106c72ffaaSAndy Whitcroft } 13116c72ffaaSAndy Whitcroft if (defined $1) { 13126c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 13136c72ffaaSAndy Whitcroft $res .= $type x length($1); 13146c72ffaaSAndy Whitcroft } 13156c72ffaaSAndy Whitcroft } 13166c72ffaaSAndy Whitcroft 13171f65f947SAndy Whitcroft return ($res, $var); 13186c72ffaaSAndy Whitcroft} 13196c72ffaaSAndy Whitcroft 13208905a67cSAndy Whitcroftsub possible { 132113214adfSAndy Whitcroft my ($possible, $line) = @_; 13229a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 13230776e594SAndy Whitcroft ^(?: 13240776e594SAndy Whitcroft $Modifier| 13250776e594SAndy Whitcroft $Storage| 13260776e594SAndy Whitcroft $Type| 13279a974fdbSAndy Whitcroft DEFINE_\S+ 13289a974fdbSAndy Whitcroft )$| 13299a974fdbSAndy Whitcroft ^(?: 13300776e594SAndy Whitcroft goto| 13310776e594SAndy Whitcroft return| 13320776e594SAndy Whitcroft case| 13330776e594SAndy Whitcroft else| 13340776e594SAndy Whitcroft asm|__asm__| 133589a88353SAndy Whitcroft do| 133689a88353SAndy Whitcroft \#| 133789a88353SAndy Whitcroft \#\#| 13389a974fdbSAndy Whitcroft )(?:\s|$)| 13390776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 13409a974fdbSAndy Whitcroft )}x; 13419a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 13429a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1343c45dcabdSAndy Whitcroft # Check for modifiers. 1344c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1345c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1346c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1347c45dcabdSAndy Whitcroft 1348c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1349c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1350d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 13519a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1352d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1353d2506586SAndy Whitcroft push(@modifierList, $modifier); 1354d2506586SAndy Whitcroft } 13559a974fdbSAndy Whitcroft } 1356c45dcabdSAndy Whitcroft 1357c45dcabdSAndy Whitcroft } else { 135813214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 13598905a67cSAndy Whitcroft push(@typeList, $possible); 1360c45dcabdSAndy Whitcroft } 13618905a67cSAndy Whitcroft build_types(); 13620776e594SAndy Whitcroft } else { 13630776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 13648905a67cSAndy Whitcroft } 13658905a67cSAndy Whitcroft} 13668905a67cSAndy Whitcroft 13676c72ffaaSAndy Whitcroftmy $prefix = ''; 13686c72ffaaSAndy Whitcroft 1369000d1cc1SJoe Perchessub show_type { 1370000d1cc1SJoe Perches return !defined $ignore_type{$_[0]}; 1371000d1cc1SJoe Perches} 1372000d1cc1SJoe Perches 1373f0a594c1SAndy Whitcroftsub report { 1374000d1cc1SJoe Perches if (!show_type($_[1]) || 1375000d1cc1SJoe Perches (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { 1376773647a0SAndy Whitcroft return 0; 1377773647a0SAndy Whitcroft } 1378000d1cc1SJoe Perches my $line; 1379000d1cc1SJoe Perches if ($show_types) { 1380000d1cc1SJoe Perches $line = "$prefix$_[0]:$_[1]: $_[2]\n"; 1381000d1cc1SJoe Perches } else { 1382000d1cc1SJoe Perches $line = "$prefix$_[0]: $_[2]\n"; 1383000d1cc1SJoe Perches } 13848905a67cSAndy Whitcroft $line = (split('\n', $line))[0] . "\n" if ($terse); 13858905a67cSAndy Whitcroft 138613214adfSAndy Whitcroft push(our @report, $line); 1387773647a0SAndy Whitcroft 1388773647a0SAndy Whitcroft return 1; 1389f0a594c1SAndy Whitcroft} 1390f0a594c1SAndy Whitcroftsub report_dump { 139113214adfSAndy Whitcroft our @report; 1392f0a594c1SAndy Whitcroft} 1393000d1cc1SJoe Perches 1394de7d4f0eSAndy Whitcroftsub ERROR { 1395000d1cc1SJoe Perches if (report("ERROR", $_[0], $_[1])) { 1396de7d4f0eSAndy Whitcroft our $clean = 0; 13976c72ffaaSAndy Whitcroft our $cnt_error++; 13983705ce5bSJoe Perches return 1; 1399de7d4f0eSAndy Whitcroft } 14003705ce5bSJoe Perches return 0; 1401773647a0SAndy Whitcroft} 1402de7d4f0eSAndy Whitcroftsub WARN { 1403000d1cc1SJoe Perches if (report("WARNING", $_[0], $_[1])) { 1404de7d4f0eSAndy Whitcroft our $clean = 0; 14056c72ffaaSAndy Whitcroft our $cnt_warn++; 14063705ce5bSJoe Perches return 1; 1407de7d4f0eSAndy Whitcroft } 14083705ce5bSJoe Perches return 0; 1409773647a0SAndy Whitcroft} 1410de7d4f0eSAndy Whitcroftsub CHK { 1411000d1cc1SJoe Perches if ($check && report("CHECK", $_[0], $_[1])) { 1412de7d4f0eSAndy Whitcroft our $clean = 0; 14136c72ffaaSAndy Whitcroft our $cnt_chk++; 14143705ce5bSJoe Perches return 1; 14156c72ffaaSAndy Whitcroft } 14163705ce5bSJoe Perches return 0; 1417de7d4f0eSAndy Whitcroft} 1418de7d4f0eSAndy Whitcroft 14196ecd9674SAndy Whitcroftsub check_absolute_file { 14206ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 14216ecd9674SAndy Whitcroft my $file = $absolute; 14226ecd9674SAndy Whitcroft 14236ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 14246ecd9674SAndy Whitcroft 14256ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 14266ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 14276ecd9674SAndy Whitcroft if (-f "$root/$file") { 14286ecd9674SAndy Whitcroft ##print "file<$file>\n"; 14296ecd9674SAndy Whitcroft last; 14306ecd9674SAndy Whitcroft } 14316ecd9674SAndy Whitcroft } 14326ecd9674SAndy Whitcroft if (! -f _) { 14336ecd9674SAndy Whitcroft return 0; 14346ecd9674SAndy Whitcroft } 14356ecd9674SAndy Whitcroft 14366ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 14376ecd9674SAndy Whitcroft my $prefix = $absolute; 14386ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 14396ecd9674SAndy Whitcroft 14406ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 14416ecd9674SAndy Whitcroft if ($prefix ne ".../") { 1442000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 1443000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 14446ecd9674SAndy Whitcroft } 14456ecd9674SAndy Whitcroft} 14466ecd9674SAndy Whitcroft 14473705ce5bSJoe Perchessub trim { 14483705ce5bSJoe Perches my ($string) = @_; 14493705ce5bSJoe Perches 14503705ce5bSJoe Perches $string =~ s/(^\s+|\s+$)//g; 14513705ce5bSJoe Perches 14523705ce5bSJoe Perches return $string; 14533705ce5bSJoe Perches} 14543705ce5bSJoe Perches 14553705ce5bSJoe Perchessub tabify { 14563705ce5bSJoe Perches my ($leading) = @_; 14573705ce5bSJoe Perches 14583705ce5bSJoe Perches my $source_indent = 8; 14593705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 14603705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 14613705ce5bSJoe Perches 14623705ce5bSJoe Perches #convert leading spaces to tabs 14633705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 14643705ce5bSJoe Perches #Remove spaces before a tab 14653705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 14663705ce5bSJoe Perches 14673705ce5bSJoe Perches return "$leading"; 14683705ce5bSJoe Perches} 14693705ce5bSJoe Perches 1470d1fe9c09SJoe Perchessub pos_last_openparen { 1471d1fe9c09SJoe Perches my ($line) = @_; 1472d1fe9c09SJoe Perches 1473d1fe9c09SJoe Perches my $pos = 0; 1474d1fe9c09SJoe Perches 1475d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 1476d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 1477d1fe9c09SJoe Perches 1478d1fe9c09SJoe Perches my $last_openparen = 0; 1479d1fe9c09SJoe Perches 1480d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 1481d1fe9c09SJoe Perches return -1; 1482d1fe9c09SJoe Perches } 1483d1fe9c09SJoe Perches 1484d1fe9c09SJoe Perches my $len = length($line); 1485d1fe9c09SJoe Perches 1486d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 1487d1fe9c09SJoe Perches my $string = substr($line, $pos); 1488d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 1489d1fe9c09SJoe Perches $pos += length($1) - 1; 1490d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 1491d1fe9c09SJoe Perches $last_openparen = $pos; 1492d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 1493d1fe9c09SJoe Perches last; 1494d1fe9c09SJoe Perches } 1495d1fe9c09SJoe Perches } 1496d1fe9c09SJoe Perches 1497d1fe9c09SJoe Perches return $last_openparen + 1; 1498d1fe9c09SJoe Perches} 1499d1fe9c09SJoe Perches 15000a920b5bSAndy Whitcroftsub process { 15010a920b5bSAndy Whitcroft my $filename = shift; 15020a920b5bSAndy Whitcroft 15030a920b5bSAndy Whitcroft my $linenr=0; 15040a920b5bSAndy Whitcroft my $prevline=""; 1505c2fdda0dSAndy Whitcroft my $prevrawline=""; 15060a920b5bSAndy Whitcroft my $stashline=""; 1507c2fdda0dSAndy Whitcroft my $stashrawline=""; 15080a920b5bSAndy Whitcroft 15094a0df2efSAndy Whitcroft my $length; 15100a920b5bSAndy Whitcroft my $indent; 15110a920b5bSAndy Whitcroft my $previndent=0; 15120a920b5bSAndy Whitcroft my $stashindent=0; 15130a920b5bSAndy Whitcroft 1514de7d4f0eSAndy Whitcroft our $clean = 1; 15150a920b5bSAndy Whitcroft my $signoff = 0; 15160a920b5bSAndy Whitcroft my $is_patch = 0; 15170a920b5bSAndy Whitcroft 151815662b3eSJoe Perches my $in_header_lines = 1; 151915662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 152015662b3eSJoe Perches 1521fa64205dSPasi Savanainen my $non_utf8_charset = 0; 1522fa64205dSPasi Savanainen 152313214adfSAndy Whitcroft our @report = (); 15246c72ffaaSAndy Whitcroft our $cnt_lines = 0; 15256c72ffaaSAndy Whitcroft our $cnt_error = 0; 15266c72ffaaSAndy Whitcroft our $cnt_warn = 0; 15276c72ffaaSAndy Whitcroft our $cnt_chk = 0; 15286c72ffaaSAndy Whitcroft 15290a920b5bSAndy Whitcroft # Trace the real file/line as we go. 15300a920b5bSAndy Whitcroft my $realfile = ''; 15310a920b5bSAndy Whitcroft my $realline = 0; 15320a920b5bSAndy Whitcroft my $realcnt = 0; 15330a920b5bSAndy Whitcroft my $here = ''; 15340a920b5bSAndy Whitcroft my $in_comment = 0; 1535c2fdda0dSAndy Whitcroft my $comment_edge = 0; 15360a920b5bSAndy Whitcroft my $first_line = 0; 15371e855726SWolfram Sang my $p1_prefix = ''; 15380a920b5bSAndy Whitcroft 153913214adfSAndy Whitcroft my $prev_values = 'E'; 154013214adfSAndy Whitcroft 154113214adfSAndy Whitcroft # suppression flags 1542773647a0SAndy Whitcroft my %suppress_ifbraces; 1543170d3a22SAndy Whitcroft my %suppress_whiletrailers; 15442b474a1aSAndy Whitcroft my %suppress_export; 15453e469cdcSAndy Whitcroft my $suppress_statement = 0; 1546653d4876SAndy Whitcroft 15477e51f197SJoe Perches my %signatures = (); 1548323c1260SJoe Perches 1549c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 1550de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 1551c2fdda0dSAndy Whitcroft # 1552de7d4f0eSAndy Whitcroft my @setup_docs = (); 1553de7d4f0eSAndy Whitcroft my $setup_docs = 0; 1554773647a0SAndy Whitcroft 1555773647a0SAndy Whitcroft sanitise_line_reset(); 1556c2fdda0dSAndy Whitcroft my $line; 1557c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 1558773647a0SAndy Whitcroft $linenr++; 1559773647a0SAndy Whitcroft $line = $rawline; 1560c2fdda0dSAndy Whitcroft 15613705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 15623705ce5bSJoe Perches 1563773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 1564de7d4f0eSAndy Whitcroft $setup_docs = 0; 1565de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 1566de7d4f0eSAndy Whitcroft $setup_docs = 1; 1567de7d4f0eSAndy Whitcroft } 1568773647a0SAndy Whitcroft #next; 1569de7d4f0eSAndy Whitcroft } 1570773647a0SAndy Whitcroft if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1571773647a0SAndy Whitcroft $realline=$1-1; 1572773647a0SAndy Whitcroft if (defined $2) { 1573773647a0SAndy Whitcroft $realcnt=$3+1; 1574773647a0SAndy Whitcroft } else { 1575773647a0SAndy Whitcroft $realcnt=1+1; 1576773647a0SAndy Whitcroft } 1577c45dcabdSAndy Whitcroft $in_comment = 0; 1578773647a0SAndy Whitcroft 1579773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 1580773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 1581773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 1582773647a0SAndy Whitcroft # at context start. 1583773647a0SAndy Whitcroft my $edge; 158401fa9147SAndy Whitcroft my $cnt = $realcnt; 158501fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 158601fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 158701fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 158801fa9147SAndy Whitcroft $cnt--; 158901fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 1590721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 1591fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1592fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1593fae17daeSAndy Whitcroft ($edge) = $1; 1594fae17daeSAndy Whitcroft last; 1595fae17daeSAndy Whitcroft } 1596773647a0SAndy Whitcroft } 1597773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 1598773647a0SAndy Whitcroft $in_comment = 1; 1599773647a0SAndy Whitcroft } 1600773647a0SAndy Whitcroft 1601773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 1602773647a0SAndy Whitcroft # is the start of a diff block and this line starts 1603773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 1604773647a0SAndy Whitcroft if (!defined $edge && 160583242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 1606773647a0SAndy Whitcroft { 1607773647a0SAndy Whitcroft $in_comment = 1; 1608773647a0SAndy Whitcroft } 1609773647a0SAndy Whitcroft 1610773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 1611773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 1612773647a0SAndy Whitcroft 1613171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 1614773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 1615171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 1616773647a0SAndy Whitcroft $line = sanitise_line($rawline); 1617773647a0SAndy Whitcroft } 1618773647a0SAndy Whitcroft push(@lines, $line); 1619773647a0SAndy Whitcroft 1620773647a0SAndy Whitcroft if ($realcnt > 1) { 1621773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 1622773647a0SAndy Whitcroft } else { 1623773647a0SAndy Whitcroft $realcnt = 0; 1624773647a0SAndy Whitcroft } 1625773647a0SAndy Whitcroft 1626773647a0SAndy Whitcroft #print "==>$rawline\n"; 1627773647a0SAndy Whitcroft #print "-->$line\n"; 1628de7d4f0eSAndy Whitcroft 1629de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 1630de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 1631de7d4f0eSAndy Whitcroft } 1632de7d4f0eSAndy Whitcroft } 1633de7d4f0eSAndy Whitcroft 16346c72ffaaSAndy Whitcroft $prefix = ''; 16356c72ffaaSAndy Whitcroft 1636773647a0SAndy Whitcroft $realcnt = 0; 1637773647a0SAndy Whitcroft $linenr = 0; 16380a920b5bSAndy Whitcroft foreach my $line (@lines) { 16390a920b5bSAndy Whitcroft $linenr++; 16400a920b5bSAndy Whitcroft 1641c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 16426c72ffaaSAndy Whitcroft 16430a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 16446c72ffaaSAndy Whitcroft if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 16450a920b5bSAndy Whitcroft $is_patch = 1; 16464a0df2efSAndy Whitcroft $first_line = $linenr + 1; 16470a920b5bSAndy Whitcroft $realline=$1-1; 16480a920b5bSAndy Whitcroft if (defined $2) { 16490a920b5bSAndy Whitcroft $realcnt=$3+1; 16500a920b5bSAndy Whitcroft } else { 16510a920b5bSAndy Whitcroft $realcnt=1+1; 16520a920b5bSAndy Whitcroft } 1653c2fdda0dSAndy Whitcroft annotate_reset(); 165413214adfSAndy Whitcroft $prev_values = 'E'; 165513214adfSAndy Whitcroft 1656773647a0SAndy Whitcroft %suppress_ifbraces = (); 1657170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 16582b474a1aSAndy Whitcroft %suppress_export = (); 16593e469cdcSAndy Whitcroft $suppress_statement = 0; 16600a920b5bSAndy Whitcroft next; 16610a920b5bSAndy Whitcroft 16624a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 16634a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 16644a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 1665773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 16660a920b5bSAndy Whitcroft $realline++; 1667d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 16680a920b5bSAndy Whitcroft 16694a0df2efSAndy Whitcroft # Measure the line length and indent. 1670c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 16710a920b5bSAndy Whitcroft 16720a920b5bSAndy Whitcroft # Track the previous line. 16730a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 16740a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 1675c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 1676c2fdda0dSAndy Whitcroft 1677773647a0SAndy Whitcroft #warn "line<$line>\n"; 16786c72ffaaSAndy Whitcroft 1679d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 1680d8aaf121SAndy Whitcroft $realcnt--; 16810a920b5bSAndy Whitcroft } 16820a920b5bSAndy Whitcroft 1683cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 1684cc77cdcaSAndy Whitcroft 16850a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 1686773647a0SAndy Whitcroft $prefix = "$filename:$realline: " if ($emacs && $file); 1687773647a0SAndy Whitcroft $prefix = "$filename:$linenr: " if ($emacs && !$file); 1688773647a0SAndy Whitcroft 16896c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 16906c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 1691773647a0SAndy Whitcroft 1692773647a0SAndy Whitcroft # extract the filename as it passes 16933bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 16943bf9a009SRabin Vincent $realfile = $1; 16953bf9a009SRabin Vincent $realfile =~ s@^([^/]*)/@@; 1696270c49a0SJoe Perches $in_commit_log = 0; 16973bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 1698773647a0SAndy Whitcroft $realfile = $1; 16991e855726SWolfram Sang $realfile =~ s@^([^/]*)/@@; 1700270c49a0SJoe Perches $in_commit_log = 0; 17011e855726SWolfram Sang 17021e855726SWolfram Sang $p1_prefix = $1; 1703e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 1704e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 1705000d1cc1SJoe Perches WARN("PATCH_PREFIX", 1706000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 17071e855726SWolfram Sang } 1708773647a0SAndy Whitcroft 1709c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 1710000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 1711000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 1712773647a0SAndy Whitcroft } 1713773647a0SAndy Whitcroft next; 1714773647a0SAndy Whitcroft } 1715773647a0SAndy Whitcroft 1716389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 17170a920b5bSAndy Whitcroft 1718c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 1719c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 1720c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 17210a920b5bSAndy Whitcroft 17226c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 17236c72ffaaSAndy Whitcroft 17243bf9a009SRabin Vincent# Check for incorrect file permissions 17253bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 17263bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 172704db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 172804db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 1729000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 1730000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 17313bf9a009SRabin Vincent } 17323bf9a009SRabin Vincent } 17333bf9a009SRabin Vincent 173420112475SJoe Perches# Check the patch for a signoff: 1735d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 17364a0df2efSAndy Whitcroft $signoff++; 173715662b3eSJoe Perches $in_commit_log = 0; 17380a920b5bSAndy Whitcroft } 173920112475SJoe Perches 174020112475SJoe Perches# Check signature styles 1741270c49a0SJoe Perches if (!$in_header_lines && 1742ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 174320112475SJoe Perches my $space_before = $1; 174420112475SJoe Perches my $sign_off = $2; 174520112475SJoe Perches my $space_after = $3; 174620112475SJoe Perches my $email = $4; 174720112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 174820112475SJoe Perches 1749ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 1750ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 1751ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 1752ce0338dfSJoe Perches } 175320112475SJoe Perches if (defined $space_before && $space_before ne "") { 17543705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 17553705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 17563705ce5bSJoe Perches $fix) { 17573705ce5bSJoe Perches $fixed[$linenr - 1] = 17583705ce5bSJoe Perches "$ucfirst_sign_off $email"; 17593705ce5bSJoe Perches } 176020112475SJoe Perches } 176120112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 17623705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 17633705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 17643705ce5bSJoe Perches $fix) { 17653705ce5bSJoe Perches $fixed[$linenr - 1] = 17663705ce5bSJoe Perches "$ucfirst_sign_off $email"; 17673705ce5bSJoe Perches } 17683705ce5bSJoe Perches 176920112475SJoe Perches } 177020112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 17713705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 17723705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 17733705ce5bSJoe Perches $fix) { 17743705ce5bSJoe Perches $fixed[$linenr - 1] = 17753705ce5bSJoe Perches "$ucfirst_sign_off $email"; 17763705ce5bSJoe Perches } 177720112475SJoe Perches } 177820112475SJoe Perches 177920112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 178020112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 178120112475SJoe Perches if ($suggested_email eq "") { 1782000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 1783000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 178420112475SJoe Perches } else { 178520112475SJoe Perches my $dequoted = $suggested_email; 178620112475SJoe Perches $dequoted =~ s/^"//; 178720112475SJoe Perches $dequoted =~ s/" </ </; 178820112475SJoe Perches # Don't force email to have quotes 178920112475SJoe Perches # Allow just an angle bracketed address 179020112475SJoe Perches if ("$dequoted$comment" ne $email && 179120112475SJoe Perches "<$email_address>$comment" ne $email && 179220112475SJoe Perches "$suggested_email$comment" ne $email) { 1793000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 1794000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 179520112475SJoe Perches } 17960a920b5bSAndy Whitcroft } 17977e51f197SJoe Perches 17987e51f197SJoe Perches# Check for duplicate signatures 17997e51f197SJoe Perches my $sig_nospace = $line; 18007e51f197SJoe Perches $sig_nospace =~ s/\s//g; 18017e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 18027e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 18037e51f197SJoe Perches WARN("BAD_SIGN_OFF", 18047e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 18057e51f197SJoe Perches } else { 18067e51f197SJoe Perches $signatures{$sig_nospace} = 1; 18077e51f197SJoe Perches } 18080a920b5bSAndy Whitcroft } 18090a920b5bSAndy Whitcroft 181000df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 18118905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 1812000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 1813000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 18146c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 1815de7d4f0eSAndy Whitcroft } 1816de7d4f0eSAndy Whitcroft 18176ecd9674SAndy Whitcroft# Check for absolute kernel paths. 18186ecd9674SAndy Whitcroft if ($tree) { 18196ecd9674SAndy Whitcroft while ($line =~ m{(?:^|\s)(/\S*)}g) { 18206ecd9674SAndy Whitcroft my $file = $1; 18216ecd9674SAndy Whitcroft 18226ecd9674SAndy Whitcroft if ($file =~ m{^(.*?)(?::\d+)+:?$} && 18236ecd9674SAndy Whitcroft check_absolute_file($1, $herecurr)) { 18246ecd9674SAndy Whitcroft # 18256ecd9674SAndy Whitcroft } else { 18266ecd9674SAndy Whitcroft check_absolute_file($file, $herecurr); 18276ecd9674SAndy Whitcroft } 18286ecd9674SAndy Whitcroft } 18296ecd9674SAndy Whitcroft } 18306ecd9674SAndy Whitcroft 1831de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1832de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 1833171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 1834171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 1835171ae1a4SAndy Whitcroft 1836171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 1837171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 1838171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 1839171ae1a4SAndy Whitcroft 184034d99219SJoe Perches CHK("INVALID_UTF8", 1841000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 184200df344fSAndy Whitcroft } 18430a920b5bSAndy Whitcroft 184415662b3eSJoe Perches# Check if it's the start of a commit log 184515662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 184615662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 1847270c49a0SJoe Perches $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { 184815662b3eSJoe Perches $in_header_lines = 0; 184915662b3eSJoe Perches $in_commit_log = 1; 185015662b3eSJoe Perches } 185115662b3eSJoe Perches 1852fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 1853fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 1854fa64205dSPasi Savanainen if ($in_header_lines && 1855fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 1856fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 1857fa64205dSPasi Savanainen $non_utf8_charset = 1; 1858fa64205dSPasi Savanainen } 1859fa64205dSPasi Savanainen 1860fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 186115662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 1862fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 186315662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 186415662b3eSJoe Perches } 186515662b3eSJoe Perches 186630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 186730670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 186800df344fSAndy Whitcroft 18690a920b5bSAndy Whitcroft#trailing whitespace 18709c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 1871c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1872d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 1873d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 1874d5e616fcSJoe Perches $fix) { 1875d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/[\s\015]+$//; 1876d5e616fcSJoe Perches } 1877c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1878c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 18793705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 18803705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 18813705ce5bSJoe Perches $fix) { 1882d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\s+$//; 18833705ce5bSJoe Perches } 18843705ce5bSJoe Perches 1885d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 18860a920b5bSAndy Whitcroft } 18875368df20SAndy Whitcroft 18883354957aSAndi Kleen# check for Kconfig help text having a real description 18899fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 18909fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 18913354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 1892a1385803SAndy Whitcroft $line =~ /.\s*config\s+/) { 18933354957aSAndi Kleen my $length = 0; 18949fe287d7SAndy Whitcroft my $cnt = $realcnt; 18959fe287d7SAndy Whitcroft my $ln = $linenr + 1; 18969fe287d7SAndy Whitcroft my $f; 1897a1385803SAndy Whitcroft my $is_start = 0; 18989fe287d7SAndy Whitcroft my $is_end = 0; 1899a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 19009fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 19019fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 19029fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 19039fe287d7SAndy Whitcroft 19049fe287d7SAndy Whitcroft next if ($f =~ /^-/); 1905a1385803SAndy Whitcroft 1906a1385803SAndy Whitcroft if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { 1907a1385803SAndy Whitcroft $is_start = 1; 1908a1385803SAndy Whitcroft } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { 1909a1385803SAndy Whitcroft $length = -1; 1910a1385803SAndy Whitcroft } 1911a1385803SAndy Whitcroft 19129fe287d7SAndy Whitcroft $f =~ s/^.//; 19133354957aSAndi Kleen $f =~ s/#.*//; 19143354957aSAndi Kleen $f =~ s/^\s+//; 19153354957aSAndi Kleen next if ($f =~ /^$/); 19169fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 19179fe287d7SAndy Whitcroft $is_end = 1; 19189fe287d7SAndy Whitcroft last; 19199fe287d7SAndy Whitcroft } 19203354957aSAndi Kleen $length++; 19213354957aSAndi Kleen } 1922000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 1923a1385803SAndy Whitcroft "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); 1924a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 19253354957aSAndi Kleen } 19263354957aSAndi Kleen 19271ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. 19281ba8dfd1SKees Cook if ($realfile =~ /Kconfig/ && 19291ba8dfd1SKees Cook $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { 19301ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 19311ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 19321ba8dfd1SKees Cook } 19331ba8dfd1SKees Cook 1934c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 1935c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 1936c68e5878SArnaud Lacombe my $flag = $1; 1937c68e5878SArnaud Lacombe my $replacement = { 1938c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 1939c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 1940c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 1941c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 1942c68e5878SArnaud Lacombe }; 1943c68e5878SArnaud Lacombe 1944c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 1945c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 1946c68e5878SArnaud Lacombe } 1947c68e5878SArnaud Lacombe 19485368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 19495368df20SAndy Whitcroft next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 19505368df20SAndy Whitcroft 19516cd7f386SJoe Perches#line length limit 1952c45dcabdSAndy Whitcroft if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1953f4c014c0SAndy Whitcroft $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 19540fccc622SJoe Perches !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || 19558bbea968SJoe Perches $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && 19566cd7f386SJoe Perches $length > $max_line_length) 1957c45dcabdSAndy Whitcroft { 1958000d1cc1SJoe Perches WARN("LONG_LINE", 19596cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 19600a920b5bSAndy Whitcroft } 19610a920b5bSAndy Whitcroft 1962ca56dc09SJosh Triplett# Check for user-visible strings broken across lines, which breaks the ability 1963ca56dc09SJosh Triplett# to grep for the string. Limited to strings used as parameters (those 1964ca56dc09SJosh Triplett# following an open parenthesis), which almost completely eliminates false 1965ca56dc09SJosh Triplett# positives, as well as warning only once per parameter rather than once per 1966ca56dc09SJosh Triplett# line of the string. Make an exception when the previous string ends in a 1967ca56dc09SJosh Triplett# newline (multiple lines in one string constant) or \n\t (common in inline 1968ca56dc09SJosh Triplett# assembly to indent the instruction on the following line). 1969ca56dc09SJosh Triplett if ($line =~ /^\+\s*"/ && 1970ca56dc09SJosh Triplett $prevline =~ /"\s*$/ && 1971ca56dc09SJosh Triplett $prevline =~ /\(/ && 1972ca56dc09SJosh Triplett $prevrawline !~ /\\n(?:\\t)*"\s*$/) { 1973ca56dc09SJosh Triplett WARN("SPLIT_STRING", 1974ca56dc09SJosh Triplett "quoted string split across lines\n" . $hereprev); 1975ca56dc09SJosh Triplett } 1976ca56dc09SJosh Triplett 19775e79d96eSJoe Perches# check for spaces before a quoted newline 19785e79d96eSJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 19793705ce5bSJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 19803705ce5bSJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 19813705ce5bSJoe Perches $fix) { 19823705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 19833705ce5bSJoe Perches } 19843705ce5bSJoe Perches 19855e79d96eSJoe Perches } 19865e79d96eSJoe Perches 19878905a67cSAndy Whitcroft# check for adding lines without a newline. 19888905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1989000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 1990000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 19918905a67cSAndy Whitcroft } 19928905a67cSAndy Whitcroft 199342e41c54SMike Frysinger# Blackfin: use hi/lo macros 199442e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 199542e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 199642e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 1997000d1cc1SJoe Perches ERROR("LO_MACRO", 1998000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 199942e41c54SMike Frysinger } 200042e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 200142e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2002000d1cc1SJoe Perches ERROR("HI_MACRO", 2003000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 200442e41c54SMike Frysinger } 200542e41c54SMike Frysinger } 200642e41c54SMike Frysinger 2007b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2008b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c|pl)$/); 20090a920b5bSAndy Whitcroft 20100a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 20110a920b5bSAndy Whitcroft# more than 8 must use tabs. 2012c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2013c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2014c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2015d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 20163705ce5bSJoe Perches if (ERROR("CODE_INDENT", 20173705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 20183705ce5bSJoe Perches $fix) { 20193705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 20203705ce5bSJoe Perches } 20210a920b5bSAndy Whitcroft } 20220a920b5bSAndy Whitcroft 202308e44365SAlberto Panizzo# check for space before tabs. 202408e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 202508e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 20263705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 20273705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 20283705ce5bSJoe Perches $fix) { 20293705ce5bSJoe Perches $fixed[$linenr - 1] =~ 20303705ce5bSJoe Perches s/(^\+.*) +\t/$1\t/; 20313705ce5bSJoe Perches } 203208e44365SAlberto Panizzo } 203308e44365SAlberto Panizzo 2034d1fe9c09SJoe Perches# check for && or || at the start of a line 2035d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2036d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2037d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2038d1fe9c09SJoe Perches } 2039d1fe9c09SJoe Perches 2040d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2041d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 2042d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { 2043d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2044d1fe9c09SJoe Perches my $oldindent = $1; 2045d1fe9c09SJoe Perches my $rest = $2; 2046d1fe9c09SJoe Perches 2047d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2048d1fe9c09SJoe Perches if ($pos >= 0) { 2049b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2050b34a26f3SJoe Perches my $newindent = $2; 2051d1fe9c09SJoe Perches 2052d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2053d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2054d1fe9c09SJoe Perches " " x ($pos % 8); 2055d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2056d1fe9c09SJoe Perches 2057d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2058d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 20593705ce5bSJoe Perches 20603705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 20613705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 20623705ce5bSJoe Perches $fix && $line =~ /^\+/) { 20633705ce5bSJoe Perches $fixed[$linenr - 1] =~ 20643705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 20653705ce5bSJoe Perches } 2066d1fe9c09SJoe Perches } 2067d1fe9c09SJoe Perches } 2068d1fe9c09SJoe Perches } 2069d1fe9c09SJoe Perches 207023f780c9SJoe Perches if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) { 20713705ce5bSJoe Perches if (CHK("SPACING", 20723705ce5bSJoe Perches "No space is necessary after a cast\n" . $hereprev) && 20733705ce5bSJoe Perches $fix) { 20743705ce5bSJoe Perches $fixed[$linenr - 1] =~ 20753705ce5bSJoe Perches s/^(\+.*\*[ \t]*\))[ \t]+/$1/; 20763705ce5bSJoe Perches } 2077aad4f614SJoe Perches } 2078aad4f614SJoe Perches 207905880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2080fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 2081fdb4bcd6SJoe Perches $rawline =~ /^\+[ \t]*\*/) { 208205880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 208305880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 208405880600SJoe Perches } 208505880600SJoe Perches 208605880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2087a605e32eSJoe Perches $prevrawline =~ /^\+[ \t]*\/\*/ && #starting /* 2088a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 2089*61135e96SJoe Perches $rawline =~ /^\+/ && #line is new 2090a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 2091a605e32eSJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 2092a605e32eSJoe Perches "networking block comments start with * on subsequent lines\n" . $hereprev); 2093a605e32eSJoe Perches } 2094a605e32eSJoe Perches 2095a605e32eSJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 2096c24f9f19SJoe Perches $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 2097c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 2098c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 2099c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 210005880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 210105880600SJoe Perches "networking block comments put the trailing */ on a separate line\n" . $herecurr); 210205880600SJoe Perches } 210305880600SJoe Perches 21045f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 21056b4c5bebSAndy Whitcroft# Exceptions: 21066b4c5bebSAndy Whitcroft# 1) within comments 21076b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 21086b4c5bebSAndy Whitcroft# 3) hanging labels 21093705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 21105f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 21113705ce5bSJoe Perches if (WARN("LEADING_SPACE", 21123705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 21133705ce5bSJoe Perches $fix) { 21143705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 21153705ce5bSJoe Perches } 21165f7ddae6SRaffaele Recalcati } 21175f7ddae6SRaffaele Recalcati 2118b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 2119b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 2120b9ea10d6SAndy Whitcroft 21211ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). 21221ba8dfd1SKees Cook if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { 21231ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 21241ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 21251ba8dfd1SKees Cook } 21261ba8dfd1SKees Cook 2127c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 2128cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 2129000d1cc1SJoe Perches WARN("CVS_KEYWORD", 2130000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 2131c2fdda0dSAndy Whitcroft } 213222f2a2efSAndy Whitcroft 213342e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 213442e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 213542e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2136000d1cc1SJoe Perches ERROR("CSYNC", 2137000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 213842e41c54SMike Frysinger } 213942e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 214042e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2141000d1cc1SJoe Perches ERROR("SSYNC", 2142000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 214342e41c54SMike Frysinger } 214442e41c54SMike Frysinger 214556e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 214656e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 214756e77d70SJoe Perches WARN("HOTPLUG_SECTION", 214856e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 214956e77d70SJoe Perches } 215056e77d70SJoe Perches 21519c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 21522b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 21532b474a1aSAndy Whitcroft $realline_next); 21543e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 21553e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 21563e469cdcSAndy Whitcroft $realcnt && $line =~ /.\s*\S/) { 2157170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 2158f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 2159171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 2160171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 2161171ae1a4SAndy Whitcroft 21623e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 21633e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 21643e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 21653e469cdcSAndy Whitcroft # until we hit end of it. 21663e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 21673e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 21683e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 21693e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 21703e469cdcSAndy Whitcroft } 2171f74bd194SAndy Whitcroft 21722b474a1aSAndy Whitcroft # Find the real next line. 21732b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 21742b474a1aSAndy Whitcroft if (defined $realline_next && 21752b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 21762b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 21772b474a1aSAndy Whitcroft $realline_next++; 21782b474a1aSAndy Whitcroft } 21792b474a1aSAndy Whitcroft 2180171ae1a4SAndy Whitcroft my $s = $stat; 2181171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 2182cf655043SAndy Whitcroft 2183c2fdda0dSAndy Whitcroft # Ignore goto labels. 2184171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 2185c2fdda0dSAndy Whitcroft 2186c2fdda0dSAndy Whitcroft # Ignore functions being called 2187171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 2188c2fdda0dSAndy Whitcroft 2189463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 2190463f2864SAndy Whitcroft 2191c45dcabdSAndy Whitcroft # declarations always start with types 2192d2506586SAndy 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) { 2193c45dcabdSAndy Whitcroft my $type = $1; 2194c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 2195c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 2196c45dcabdSAndy Whitcroft 21976c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 2198a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 2199c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 2200c2fdda0dSAndy Whitcroft } 22018905a67cSAndy Whitcroft 22026c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 220365863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 2204c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 22059c0ca6f9SAndy Whitcroft } 22068905a67cSAndy Whitcroft 22078905a67cSAndy Whitcroft # Check for any sort of function declaration. 22088905a67cSAndy Whitcroft # int foo(something bar, other baz); 22098905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 2210171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 22118905a67cSAndy Whitcroft my ($name_len) = length($1); 22128905a67cSAndy Whitcroft 2213cf655043SAndy Whitcroft my $ctx = $s; 2214773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 22158905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 2216cf655043SAndy Whitcroft 22178905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 2218c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 22198905a67cSAndy Whitcroft 2220c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 22218905a67cSAndy Whitcroft } 22228905a67cSAndy Whitcroft } 22238905a67cSAndy Whitcroft } 22248905a67cSAndy Whitcroft 22259c0ca6f9SAndy Whitcroft } 22269c0ca6f9SAndy Whitcroft 222700df344fSAndy Whitcroft# 222800df344fSAndy Whitcroft# Checks which may be anchored in the context. 222900df344fSAndy Whitcroft# 223000df344fSAndy Whitcroft 223100df344fSAndy Whitcroft# Check for switch () and associated case and default 223200df344fSAndy Whitcroft# statements should be at the same indent. 223300df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 223400df344fSAndy Whitcroft my $err = ''; 223500df344fSAndy Whitcroft my $sep = ''; 223600df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 223700df344fSAndy Whitcroft shift(@ctx); 223800df344fSAndy Whitcroft for my $ctx (@ctx) { 223900df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 224000df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 224100df344fSAndy Whitcroft $indent != $cindent) { 224200df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 224300df344fSAndy Whitcroft $sep = ''; 224400df344fSAndy Whitcroft } else { 224500df344fSAndy Whitcroft $sep = "[...]\n"; 224600df344fSAndy Whitcroft } 224700df344fSAndy Whitcroft } 224800df344fSAndy Whitcroft if ($err ne '') { 2249000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 2250000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 2251de7d4f0eSAndy Whitcroft } 2252de7d4f0eSAndy Whitcroft } 2253de7d4f0eSAndy Whitcroft 2254de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 2255de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 2256c45dcabdSAndy Whitcroft if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 2257773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 2258773647a0SAndy Whitcroft 22599c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 22608eef05ddSJoe Perches 22618eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 22628eef05ddSJoe Perches WARN("DEEP_INDENTATION", 22638eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 22648eef05ddSJoe Perches } 22658eef05ddSJoe Perches 2266de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 2267de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 2268de7d4f0eSAndy Whitcroft 2269548596d5SAndy Whitcroft my $ctx_ln = $linenr; 2270548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 2271de7d4f0eSAndy Whitcroft 2272548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 2273548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 2274548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 2275548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 2276548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 2277773647a0SAndy Whitcroft $ctx_ln++; 2278773647a0SAndy Whitcroft } 2279548596d5SAndy Whitcroft 228053210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 228153210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 2282773647a0SAndy Whitcroft 2283773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 2284000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2285000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 228601464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 228700df344fSAndy Whitcroft } 2288773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 2289773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 2290773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 2291773647a0SAndy Whitcroft { 22929c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 22939c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 2294000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 2295000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 229601464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 22979c0ca6f9SAndy Whitcroft } 22989c0ca6f9SAndy Whitcroft } 229900df344fSAndy Whitcroft } 230000df344fSAndy Whitcroft 23014d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 23024d001e4dSAndy Whitcroft if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 23033e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 23043e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 23053e469cdcSAndy Whitcroft if (!defined $stat); 23064d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 23074d001e4dSAndy Whitcroft 23084d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 23094d001e4dSAndy Whitcroft 23104d001e4dSAndy Whitcroft # Make sure we remove the line prefixes as we have 23114d001e4dSAndy Whitcroft # none on the first line, and are going to readd them 23124d001e4dSAndy Whitcroft # where necessary. 23134d001e4dSAndy Whitcroft $s =~ s/\n./\n/gs; 23144d001e4dSAndy Whitcroft 23154d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 23166f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 23176f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 23184d001e4dSAndy Whitcroft 23194d001e4dSAndy Whitcroft # We want to check the first line inside the block 23204d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 23214d001e4dSAndy Whitcroft # 1) any blank line termination 23224d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 23234d001e4dSAndy Whitcroft # 3) any do (...) { 23244d001e4dSAndy Whitcroft my $continuation = 0; 23254d001e4dSAndy Whitcroft my $check = 0; 23264d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 23274d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 23284d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 23294d001e4dSAndy Whitcroft $continuation = 1; 23304d001e4dSAndy Whitcroft } 23319bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 23324d001e4dSAndy Whitcroft $check = 1; 23334d001e4dSAndy Whitcroft $cond_lines++; 23344d001e4dSAndy Whitcroft } 23354d001e4dSAndy Whitcroft 23364d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 23374d001e4dSAndy Whitcroft # preprocessor statement. 23384d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 23394d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 23404d001e4dSAndy Whitcroft $check = 0; 23414d001e4dSAndy Whitcroft } 23424d001e4dSAndy Whitcroft 23439bd49efeSAndy Whitcroft my $cond_ptr = -1; 2344740504c6SAndy Whitcroft $continuation = 0; 23459bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 23469bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 23474d001e4dSAndy Whitcroft 2348f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 2349f16fa28fSAndy Whitcroft # is not linear. 2350f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 2351f16fa28fSAndy Whitcroft $check = 0; 2352f16fa28fSAndy Whitcroft } 2353f16fa28fSAndy Whitcroft 23549bd49efeSAndy Whitcroft # Ignore: 23559bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 23569bd49efeSAndy Whitcroft # 2) preprocessor lines, and 23579bd49efeSAndy Whitcroft # 3) labels. 2358740504c6SAndy Whitcroft if ($continuation || 2359740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 23609bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 23619bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 2362740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 236330dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 23649bd49efeSAndy Whitcroft $cond_lines++; 23659bd49efeSAndy Whitcroft } 23664d001e4dSAndy Whitcroft } 236730dad6ebSAndy Whitcroft } 23684d001e4dSAndy Whitcroft 23694d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 23704d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 23714d001e4dSAndy Whitcroft 23724d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 23734d001e4dSAndy Whitcroft # this is not this patch's fault. 23744d001e4dSAndy Whitcroft if (!defined($stat_real) || 23754d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 23764d001e4dSAndy Whitcroft $check = 0; 23774d001e4dSAndy Whitcroft } 23784d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 23794d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 23804d001e4dSAndy Whitcroft } 23814d001e4dSAndy Whitcroft 23829bd49efeSAndy 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"; 23834d001e4dSAndy Whitcroft 23844d001e4dSAndy Whitcroft if ($check && (($sindent % 8) != 0 || 23854d001e4dSAndy Whitcroft ($sindent <= $indent && $s ne ''))) { 2386000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 2387000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 23884d001e4dSAndy Whitcroft } 23894d001e4dSAndy Whitcroft } 23904d001e4dSAndy Whitcroft 23916c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 23926c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 23931f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 23941f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 23956c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 2396c2fdda0dSAndy Whitcroft if ($dbg_values) { 2397c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 2398cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 2399cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 24001f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 2401c2fdda0dSAndy Whitcroft } 24026c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 24036c72ffaaSAndy Whitcroft 240400df344fSAndy Whitcroft#ignore lines not being added 24053705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 240600df344fSAndy Whitcroft 2407653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 24087429c690SAndy Whitcroft if ($dbg_type) { 24097429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 2410000d1cc1SJoe Perches ERROR("TEST_TYPE", 2411000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 24127429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 2413000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 2414000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 24157429c690SAndy Whitcroft } 2416653d4876SAndy Whitcroft next; 2417653d4876SAndy Whitcroft } 2418a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 2419a1ef277eSAndy Whitcroft if ($dbg_attr) { 24209360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 2421000d1cc1SJoe Perches ERROR("TEST_ATTR", 2422000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 24239360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 2424000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 2425000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 2426a1ef277eSAndy Whitcroft } 2427a1ef277eSAndy Whitcroft next; 2428a1ef277eSAndy Whitcroft } 2429653d4876SAndy Whitcroft 2430f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 243199423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 243299423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 2433000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2434000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . $hereprev); 2435f0a594c1SAndy Whitcroft } 2436f0a594c1SAndy Whitcroft 243700df344fSAndy Whitcroft# 243800df344fSAndy Whitcroft# Checks which are anchored on the added line. 243900df344fSAndy Whitcroft# 244000df344fSAndy Whitcroft 2441653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 2442c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 2443653d4876SAndy Whitcroft my $path = $1; 2444653d4876SAndy Whitcroft if ($path =~ m{//}) { 2445000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 2446495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 2447495e9d84SJoe Perches } 2448495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 2449495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 2450495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 2451653d4876SAndy Whitcroft } 2452653d4876SAndy Whitcroft } 2453653d4876SAndy Whitcroft 245400df344fSAndy Whitcroft# no C99 // comments 245500df344fSAndy Whitcroft if ($line =~ m{//}) { 24563705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 24573705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 24583705ce5bSJoe Perches $fix) { 24593705ce5bSJoe Perches my $line = $fixed[$linenr - 1]; 24603705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 24613705ce5bSJoe Perches my $comment = trim($1); 24623705ce5bSJoe Perches $fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@; 24633705ce5bSJoe Perches } 24643705ce5bSJoe Perches } 246500df344fSAndy Whitcroft } 246600df344fSAndy Whitcroft # Remove C99 comments. 24670a920b5bSAndy Whitcroft $line =~ s@//.*@@; 24686c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 24690a920b5bSAndy Whitcroft 24702b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 24712b474a1aSAndy Whitcroft# the whole statement. 24722b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 24732b474a1aSAndy Whitcroft if (defined $realline_next && 24742b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 24752b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 24762b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 24772b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 24783cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 24793cbf62dfSAndy Whitcroft # a prefix: 24803cbf62dfSAndy Whitcroft # XXX(foo); 24813cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 2482653d4876SAndy Whitcroft my $name = $1; 248387a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 24843cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 24853cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 24863cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 24873cbf62dfSAndy Whitcroft 24883cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 24892b474a1aSAndy Whitcroft \n.}\s*$| 249048012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 249148012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 249248012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 24932b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 24942b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 249548012058SAndy Whitcroft )/x) { 24962b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 24972b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 24982b474a1aSAndy Whitcroft } else { 24992b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 25000a920b5bSAndy Whitcroft } 25010a920b5bSAndy Whitcroft } 25022b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 25032b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 25042b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 25052b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 25062b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 25072b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 25082b474a1aSAndy Whitcroft } 25092b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 25102b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 2511000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 2512000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 25132b474a1aSAndy Whitcroft } 25140a920b5bSAndy Whitcroft 25155150bda4SJoe Eloff# check for global initialisers. 2516d5e616fcSJoe Perches if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) { 2517d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 2518000d1cc1SJoe Perches "do not initialise globals to 0 or NULL\n" . 2519d5e616fcSJoe Perches $herecurr) && 2520d5e616fcSJoe Perches $fix) { 2521d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/; 2522d5e616fcSJoe Perches } 2523f0a594c1SAndy Whitcroft } 25240a920b5bSAndy Whitcroft# check for static initialisers. 2525d5e616fcSJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) { 2526d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 2527000d1cc1SJoe Perches "do not initialise statics to 0 or NULL\n" . 2528d5e616fcSJoe Perches $herecurr) && 2529d5e616fcSJoe Perches $fix) { 2530d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/; 2531d5e616fcSJoe Perches } 25320a920b5bSAndy Whitcroft } 25330a920b5bSAndy Whitcroft 2534cb710ecaSJoe Perches# check for static const char * arrays. 2535cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 2536000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 2537000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 2538cb710ecaSJoe Perches $herecurr); 2539cb710ecaSJoe Perches } 2540cb710ecaSJoe Perches 2541cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 2542cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 2543000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 2544000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 2545cb710ecaSJoe Perches $herecurr); 2546cb710ecaSJoe Perches } 2547cb710ecaSJoe Perches 254893ed0e2dSJoe Perches# check for declarations of struct pci_device_id 254993ed0e2dSJoe Perches if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { 2550000d1cc1SJoe Perches WARN("DEFINE_PCI_DEVICE_TABLE", 2551000d1cc1SJoe Perches "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); 255293ed0e2dSJoe Perches } 255393ed0e2dSJoe Perches 2554653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 2555653d4876SAndy Whitcroft# make sense. 2556653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 25578054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 2558c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 25598ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 2560653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 2561000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 2562000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 25630a920b5bSAndy Whitcroft } 25640a920b5bSAndy Whitcroft 25650a920b5bSAndy Whitcroft# * goes on variable not on type 256665863862SAndy Whitcroft # (char*[ const]) 2567bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 2568bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 25693705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 2570d8aaf121SAndy Whitcroft 257165863862SAndy Whitcroft # Should start with a space. 257265863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 257365863862SAndy Whitcroft # Should not end with a space. 257465863862SAndy Whitcroft $to =~ s/\s+$//; 257565863862SAndy Whitcroft # '*'s should not have spaces between. 2576f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 257765863862SAndy Whitcroft } 2578d8aaf121SAndy Whitcroft 25793705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 258065863862SAndy Whitcroft if ($from ne $to) { 25813705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 25823705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 25833705ce5bSJoe Perches $fix) { 25843705ce5bSJoe Perches my $sub_from = $ident; 25853705ce5bSJoe Perches my $sub_to = $ident; 25863705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 25873705ce5bSJoe Perches $fixed[$linenr - 1] =~ 25883705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 25893705ce5bSJoe Perches } 259065863862SAndy Whitcroft } 2591bfcb2cc7SAndy Whitcroft } 2592bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 2593bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 25943705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 2595d8aaf121SAndy Whitcroft 259665863862SAndy Whitcroft # Should start with a space. 259765863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 259865863862SAndy Whitcroft # Should not end with a space. 259965863862SAndy Whitcroft $to =~ s/\s+$//; 260065863862SAndy Whitcroft # '*'s should not have spaces between. 2601f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 260265863862SAndy Whitcroft } 260365863862SAndy Whitcroft # Modifiers should have spaces. 260465863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 260565863862SAndy Whitcroft 26063705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 2607667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 26083705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 26093705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 26103705ce5bSJoe Perches $fix) { 26113705ce5bSJoe Perches 26123705ce5bSJoe Perches my $sub_from = $match; 26133705ce5bSJoe Perches my $sub_to = $match; 26143705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 26153705ce5bSJoe Perches $fixed[$linenr - 1] =~ 26163705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 26173705ce5bSJoe Perches } 261865863862SAndy Whitcroft } 26190a920b5bSAndy Whitcroft } 26200a920b5bSAndy Whitcroft 26210a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 26220a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 26230a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 26240a920b5bSAndy Whitcroft# print "$herecurr"; 26250a920b5bSAndy Whitcroft# $clean = 0; 26260a920b5bSAndy Whitcroft# } 26270a920b5bSAndy Whitcroft 26288905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 2629000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 2630000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 26318905a67cSAndy Whitcroft } 26328905a67cSAndy Whitcroft 263317441227SJoe Perches# check for uses of printk_ratelimit 263417441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 2635000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 2636000d1cc1SJoe Perches"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 263717441227SJoe Perches } 263817441227SJoe Perches 263900df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 264000df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 264100df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 264225985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 264300df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 2644f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 264500df344fSAndy Whitcroft my $ok = 0; 264600df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 264700df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 264825985edcSLucas De Marchi # we have a preceding printk if it ends 264900df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 265000df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 265100df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 265200df344fSAndy Whitcroft $ok = 1; 265300df344fSAndy Whitcroft } 265400df344fSAndy Whitcroft last; 265500df344fSAndy Whitcroft } 265600df344fSAndy Whitcroft } 265700df344fSAndy Whitcroft if ($ok == 0) { 2658000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 2659000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 26600a920b5bSAndy Whitcroft } 266100df344fSAndy Whitcroft } 26620a920b5bSAndy Whitcroft 2663243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 2664243f3803SJoe Perches my $orig = $1; 2665243f3803SJoe Perches my $level = lc($orig); 2666243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 26678f26b837SJoe Perches my $level2 = $level; 26688f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 2669243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 26708f26b837SJoe Perches "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 2671243f3803SJoe Perches } 2672243f3803SJoe Perches 2673243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 2674d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 2675d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 2676d5e616fcSJoe Perches $fix) { 2677d5e616fcSJoe Perches $fixed[$linenr - 1] =~ 2678d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 2679d5e616fcSJoe Perches } 2680243f3803SJoe Perches } 2681243f3803SJoe Perches 2682dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 2683dc139313SJoe Perches my $orig = $1; 2684dc139313SJoe Perches my $level = lc($orig); 2685dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 2686dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 2687dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 2688dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 2689dc139313SJoe Perches } 2690dc139313SJoe Perches 2691653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 2692653d4876SAndy Whitcroft# or if closed on same line 2693c45dcabdSAndy Whitcroft if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and 2694c45dcabdSAndy Whitcroft !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { 2695000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2696000d1cc1SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr); 26970a920b5bSAndy Whitcroft } 2698653d4876SAndy Whitcroft 26998905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 27008905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 27018905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 2702000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2703000d1cc1SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev); 27048905a67cSAndy Whitcroft } 27058905a67cSAndy Whitcroft 27060c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 27073705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 27083705ce5bSJoe Perches if (WARN("SPACING", 27093705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 27103705ce5bSJoe Perches $fix) { 27113705ce5bSJoe Perches $fixed[$linenr - 1] =~ 27123705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 27133705ce5bSJoe Perches } 27140c73b4ebSAndy Whitcroft } 27150c73b4ebSAndy Whitcroft 27168d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 27178d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 2718fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 2719fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 27208d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 27218d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 27228d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 2723fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 2724daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 27253705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 27263705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 27273705ce5bSJoe Perches $fix) { 27283705ce5bSJoe Perches $fixed[$linenr - 1] =~ 27293705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 27303705ce5bSJoe Perches } 27318d31cfceSAndy Whitcroft } 27328d31cfceSAndy Whitcroft } 27338d31cfceSAndy Whitcroft 2734f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 27356c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 2736c2fdda0dSAndy Whitcroft my $name = $1; 2737773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 2738773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 2739c2fdda0dSAndy Whitcroft 2740c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 2741773647a0SAndy Whitcroft if ($name =~ /^(?: 2742773647a0SAndy Whitcroft if|for|while|switch|return|case| 2743773647a0SAndy Whitcroft volatile|__volatile__| 2744773647a0SAndy Whitcroft __attribute__|format|__extension__| 2745773647a0SAndy Whitcroft asm|__asm__)$/x) 2746773647a0SAndy Whitcroft { 2747c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 2748c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 2749c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 2750c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 2751773647a0SAndy Whitcroft 2752773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 2753c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 2754c2fdda0dSAndy Whitcroft 2755c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 2756c2fdda0dSAndy Whitcroft # likely a typedef for a function. 2757773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 2758c2fdda0dSAndy Whitcroft 2759c2fdda0dSAndy Whitcroft } else { 27603705ce5bSJoe Perches if (WARN("SPACING", 27613705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 27623705ce5bSJoe Perches $fix) { 27633705ce5bSJoe Perches $fixed[$linenr - 1] =~ 27643705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 27653705ce5bSJoe Perches } 2766f0a594c1SAndy Whitcroft } 27676c72ffaaSAndy Whitcroft } 27689a4cad4eSEric Nelson 2769653d4876SAndy Whitcroft# Check operator spacing. 27700a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 27713705ce5bSJoe Perches my $fixed_line = ""; 27723705ce5bSJoe Perches my $line_fixed = 0; 27733705ce5bSJoe Perches 27749c0ca6f9SAndy Whitcroft my $ops = qr{ 27759c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 27769c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 27779c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 27781f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 27791f65f947SAndy Whitcroft \?|: 27809c0ca6f9SAndy Whitcroft }x; 2781cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 27823705ce5bSJoe Perches 27833705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 27843705ce5bSJoe Perches## foreach my $el (@elements) { 27853705ce5bSJoe Perches## print("el: <$el>\n"); 27863705ce5bSJoe Perches## } 27873705ce5bSJoe Perches 27883705ce5bSJoe Perches my @fix_elements = (); 278900df344fSAndy Whitcroft my $off = 0; 27906c72ffaaSAndy Whitcroft 27913705ce5bSJoe Perches foreach my $el (@elements) { 27923705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 27933705ce5bSJoe Perches $off += length($el); 27943705ce5bSJoe Perches } 27953705ce5bSJoe Perches 27963705ce5bSJoe Perches $off = 0; 27973705ce5bSJoe Perches 27986c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 27996c72ffaaSAndy Whitcroft 28000a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 28013705ce5bSJoe Perches 28023705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 28033705ce5bSJoe Perches 28043705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 28053705ce5bSJoe Perches 28064a0df2efSAndy Whitcroft $off += length($elements[$n]); 28074a0df2efSAndy Whitcroft 280825985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 2809773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 2810773647a0SAndy Whitcroft my $cc = ''; 2811773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 2812773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 2813773647a0SAndy Whitcroft } 2814773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 2815773647a0SAndy Whitcroft 28164a0df2efSAndy Whitcroft my $a = ''; 28174a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 28184a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 2819cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 28204a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 28214a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 2822773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 28234a0df2efSAndy Whitcroft 28240a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 28254a0df2efSAndy Whitcroft 28264a0df2efSAndy Whitcroft my $c = ''; 28270a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 28284a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 28294a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 2830cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 28314a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 28324a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 28338b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 28344a0df2efSAndy Whitcroft } else { 28354a0df2efSAndy Whitcroft $c = 'E'; 28360a920b5bSAndy Whitcroft } 28370a920b5bSAndy Whitcroft 28384a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 28394a0df2efSAndy Whitcroft 28404a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 28414a0df2efSAndy Whitcroft 28426c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 2843de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 28440a920b5bSAndy Whitcroft 284574048ed8SAndy Whitcroft # Pull out the value of this operator. 28466c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 28470a920b5bSAndy Whitcroft 28481f65f947SAndy Whitcroft # Get the full operator variant. 28491f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 28501f65f947SAndy Whitcroft 285113214adfSAndy Whitcroft # Ignore operators passed as parameters. 285213214adfSAndy Whitcroft if ($op_type ne 'V' && 285313214adfSAndy Whitcroft $ca =~ /\s$/ && $cc =~ /^\s*,/) { 285413214adfSAndy Whitcroft 2855cf655043SAndy Whitcroft# # Ignore comments 2856cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 285713214adfSAndy Whitcroft 2858d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 285913214adfSAndy Whitcroft } elsif ($op eq ';') { 2860cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 2861cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 28623705ce5bSJoe Perches if (ERROR("SPACING", 28633705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 28643705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 28653705ce5bSJoe Perches $line_fixed = 1; 28663705ce5bSJoe Perches } 2867d8aaf121SAndy Whitcroft } 2868d8aaf121SAndy Whitcroft 2869d8aaf121SAndy Whitcroft # // is a comment 2870d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 28710a920b5bSAndy Whitcroft 28721f65f947SAndy Whitcroft # No spaces for: 28731f65f947SAndy Whitcroft # -> 28741f65f947SAndy Whitcroft # : when part of a bitfield 28751f65f947SAndy Whitcroft } elsif ($op eq '->' || $opv eq ':B') { 28764a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 28773705ce5bSJoe Perches if (ERROR("SPACING", 28783705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 28793705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 28803705ce5bSJoe Perches $line_fixed = 1; 28813705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 28823705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 28833705ce5bSJoe Perches } 28843705ce5bSJoe Perches } 28850a920b5bSAndy Whitcroft } 28860a920b5bSAndy Whitcroft 28870a920b5bSAndy Whitcroft # , must have a space on the right. 28880a920b5bSAndy Whitcroft } elsif ($op eq ',') { 2889cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 28903705ce5bSJoe Perches if (ERROR("SPACING", 28913705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 28923705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " "; 28933705ce5bSJoe Perches $line_fixed = 1; 28943705ce5bSJoe Perches } 28950a920b5bSAndy Whitcroft } 28960a920b5bSAndy Whitcroft 28979c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 289874048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 28999c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 29009c0ca6f9SAndy Whitcroft 29019c0ca6f9SAndy Whitcroft # unary operators should have a space before and 29029c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 29039c0ca6f9SAndy Whitcroft # unary operator, or a cast 29049c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 290574048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 29060d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 2907cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 29083705ce5bSJoe Perches if (ERROR("SPACING", 29093705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 29103705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 29113705ce5bSJoe Perches $line_fixed = 1; 29123705ce5bSJoe Perches } 29130a920b5bSAndy Whitcroft } 2914a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 2915171ae1a4SAndy Whitcroft # A unary '*' may be const 2916171ae1a4SAndy Whitcroft 2917171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 29183705ce5bSJoe Perches if (ERROR("SPACING", 29193705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 29203705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 29213705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 29223705ce5bSJoe Perches $line_fixed = 1; 29233705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 29243705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 29253705ce5bSJoe Perches } 29263705ce5bSJoe Perches } 29270a920b5bSAndy Whitcroft } 29280a920b5bSAndy Whitcroft 29290a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 29300a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 2931773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 29323705ce5bSJoe Perches if (ERROR("SPACING", 29333705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 29343705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 29353705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " "; 29363705ce5bSJoe Perches $line_fixed = 1; 29373705ce5bSJoe Perches } 29380a920b5bSAndy Whitcroft } 2939773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 2940773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 29413705ce5bSJoe Perches if (ERROR("SPACING", 29423705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 29433705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 29443705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 29453705ce5bSJoe Perches $line_fixed = 1; 29463705ce5bSJoe Perches } 2947653d4876SAndy Whitcroft } 2948773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 29493705ce5bSJoe Perches if (ERROR("SPACING", 29503705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 29513705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 29523705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 29533705ce5bSJoe Perches $line_fixed = 1; 29543705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 29553705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 2956773647a0SAndy Whitcroft } 29573705ce5bSJoe Perches } 29583705ce5bSJoe Perches } 29590a920b5bSAndy Whitcroft 29600a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 29619c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 29629c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 29639c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 2964c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 2965c2fdda0dSAndy Whitcroft $op eq '%') 29660a920b5bSAndy Whitcroft { 2967773647a0SAndy Whitcroft if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 29683705ce5bSJoe Perches if (ERROR("SPACING", 29693705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 29703705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 29713705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 29723705ce5bSJoe Perches $line_fixed = 1; 29733705ce5bSJoe Perches } 29740a920b5bSAndy Whitcroft } 29750a920b5bSAndy Whitcroft 29761f65f947SAndy Whitcroft # A colon needs no spaces before when it is 29771f65f947SAndy Whitcroft # terminating a case value or a label. 29781f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 29791f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 29803705ce5bSJoe Perches if (ERROR("SPACING", 29813705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 29823705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 29833705ce5bSJoe Perches $line_fixed = 1; 29843705ce5bSJoe Perches } 29851f65f947SAndy Whitcroft } 29861f65f947SAndy Whitcroft 29870a920b5bSAndy Whitcroft # All the others need spaces both sides. 2988cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 29891f65f947SAndy Whitcroft my $ok = 0; 29901f65f947SAndy Whitcroft 299122f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 29921f65f947SAndy Whitcroft if (($op eq '<' && 29931f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 29941f65f947SAndy Whitcroft ($op eq '>' && 29951f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 29961f65f947SAndy Whitcroft { 29971f65f947SAndy Whitcroft $ok = 1; 29981f65f947SAndy Whitcroft } 29991f65f947SAndy Whitcroft 30001f65f947SAndy Whitcroft # Ignore ?: 30011f65f947SAndy Whitcroft if (($opv eq ':O' && $ca =~ /\?$/) || 30021f65f947SAndy Whitcroft ($op eq '?' && $cc =~ /^:/)) { 30031f65f947SAndy Whitcroft $ok = 1; 30041f65f947SAndy Whitcroft } 30051f65f947SAndy Whitcroft 30061f65f947SAndy Whitcroft if ($ok == 0) { 30073705ce5bSJoe Perches if (ERROR("SPACING", 30083705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 30093705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 30103705ce5bSJoe Perches $good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " "; 30113705ce5bSJoe Perches $line_fixed = 1; 30123705ce5bSJoe Perches } 30130a920b5bSAndy Whitcroft } 301422f2a2efSAndy Whitcroft } 30154a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 30163705ce5bSJoe Perches 30173705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 30183705ce5bSJoe Perches 30193705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 30200a920b5bSAndy Whitcroft } 30213705ce5bSJoe Perches 30223705ce5bSJoe Perches if (($#elements % 2) == 0) { 30233705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 30243705ce5bSJoe Perches } 30253705ce5bSJoe Perches 30263705ce5bSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) { 30273705ce5bSJoe Perches $fixed[$linenr - 1] = $fixed_line; 30283705ce5bSJoe Perches } 30293705ce5bSJoe Perches 30303705ce5bSJoe Perches 30310a920b5bSAndy Whitcroft } 30320a920b5bSAndy Whitcroft 3033786b6326SJoe Perches# check for whitespace before a non-naked semicolon 3034786b6326SJoe Perches if ($line =~ /^\+.*\S\s+;/) { 3035786b6326SJoe Perches if (WARN("SPACING", 3036786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 3037786b6326SJoe Perches $fix) { 3038786b6326SJoe Perches 1 while $fixed[$linenr - 1] =~ 3039786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 3040786b6326SJoe Perches } 3041786b6326SJoe Perches } 3042786b6326SJoe Perches 3043f0a594c1SAndy Whitcroft# check for multiple assignments 3044f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 3045000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 3046000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 3047f0a594c1SAndy Whitcroft } 3048f0a594c1SAndy Whitcroft 304922f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 305022f2a2efSAndy Whitcroft## # continuation. 305122f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 305222f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 305322f2a2efSAndy Whitcroft## 305422f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 305522f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 305622f2a2efSAndy Whitcroft## my $ln = $line; 305722f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 305822f2a2efSAndy Whitcroft## } 305922f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 3060000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 3061000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 306222f2a2efSAndy Whitcroft## } 306322f2a2efSAndy Whitcroft## } 3064f0a594c1SAndy Whitcroft 30650a920b5bSAndy Whitcroft#need space before brace following if, while, etc 306622f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 306722f2a2efSAndy Whitcroft $line =~ /do{/) { 30683705ce5bSJoe Perches if (ERROR("SPACING", 30693705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 30703705ce5bSJoe Perches $fix) { 3071d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/; 30723705ce5bSJoe Perches } 3073de7d4f0eSAndy Whitcroft } 3074de7d4f0eSAndy Whitcroft 3075c4a62ef9SJoe Perches## # check for blank lines before declarations 3076c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 3077c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 3078c4a62ef9SJoe Perches## WARN("SPACING", 3079c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 3080c4a62ef9SJoe Perches## } 3081c4a62ef9SJoe Perches## 3082c4a62ef9SJoe Perches 3083de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 3084de7d4f0eSAndy Whitcroft# on the line 3085de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 3086d5e616fcSJoe Perches if (ERROR("SPACING", 3087d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 3088d5e616fcSJoe Perches $fix) { 3089d5e616fcSJoe Perches $fixed[$linenr - 1] =~ 3090d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 3091d5e616fcSJoe Perches } 30920a920b5bSAndy Whitcroft } 30930a920b5bSAndy Whitcroft 309422f2a2efSAndy Whitcroft# check spacing on square brackets 309522f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 30963705ce5bSJoe Perches if (ERROR("SPACING", 30973705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 30983705ce5bSJoe Perches $fix) { 30993705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31003705ce5bSJoe Perches s/\[\s+/\[/; 31013705ce5bSJoe Perches } 310222f2a2efSAndy Whitcroft } 310322f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 31043705ce5bSJoe Perches if (ERROR("SPACING", 31053705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 31063705ce5bSJoe Perches $fix) { 31073705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31083705ce5bSJoe Perches s/\s+\]/\]/; 31093705ce5bSJoe Perches } 311022f2a2efSAndy Whitcroft } 311122f2a2efSAndy Whitcroft 3112c45dcabdSAndy Whitcroft# check spacing on parentheses 31139c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 31149c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 31153705ce5bSJoe Perches if (ERROR("SPACING", 31163705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 31173705ce5bSJoe Perches $fix) { 31183705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31193705ce5bSJoe Perches s/\(\s+/\(/; 31203705ce5bSJoe Perches } 312122f2a2efSAndy Whitcroft } 312213214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 3123c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 3124c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 31253705ce5bSJoe Perches if (ERROR("SPACING", 31263705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 31273705ce5bSJoe Perches $fix) { 31283705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31293705ce5bSJoe Perches s/\s+\)/\)/; 31303705ce5bSJoe Perches } 313122f2a2efSAndy Whitcroft } 313222f2a2efSAndy Whitcroft 31330a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 31344a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 31350a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 31363705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 31373705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 31383705ce5bSJoe Perches $fix) { 31393705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31403705ce5bSJoe Perches s/^(.)\s+/$1/; 31413705ce5bSJoe Perches } 31420a920b5bSAndy Whitcroft } 31430a920b5bSAndy Whitcroft 3144c45dcabdSAndy Whitcroft# Return is not a function. 3145c45dcabdSAndy Whitcroft if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { 3146c45dcabdSAndy Whitcroft my $spacing = $1; 3147c45dcabdSAndy Whitcroft my $value = $2; 3148c45dcabdSAndy Whitcroft 314986f9d059SAndy Whitcroft # Flatten any parentheses 3150fb2d2c1bSAndy Whitcroft $value =~ s/\(/ \(/g; 3151fb2d2c1bSAndy Whitcroft $value =~ s/\)/\) /g; 3152e01886adSAndy Whitcroft while ($value =~ s/\[[^\[\]]*\]/1/ || 315363f17f89SAndy Whitcroft $value !~ /(?:$Ident|-?$Constant)\s* 315463f17f89SAndy Whitcroft $Compare\s* 315563f17f89SAndy Whitcroft (?:$Ident|-?$Constant)/x && 315663f17f89SAndy Whitcroft $value =~ s/\([^\(\)]*\)/1/) { 3157c45dcabdSAndy Whitcroft } 3158fb2d2c1bSAndy Whitcroft#print "value<$value>\n"; 3159fb2d2c1bSAndy Whitcroft if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { 3160000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 3161000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 3162c45dcabdSAndy Whitcroft 3163c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 3164000d1cc1SJoe Perches ERROR("SPACING", 3165000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 3166c45dcabdSAndy Whitcroft } 3167c45dcabdSAndy Whitcroft } 316853a3c448SAndy Whitcroft# Return of what appears to be an errno should normally be -'ve 316953a3c448SAndy Whitcroft if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { 317053a3c448SAndy Whitcroft my $name = $1; 317153a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 3172000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 3173000d1cc1SJoe Perches "return of an errno should typically be -ve (return -$1)\n" . $herecurr); 317453a3c448SAndy Whitcroft } 317553a3c448SAndy Whitcroft } 3176c45dcabdSAndy Whitcroft 31770a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 31784a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 31793705ce5bSJoe Perches if (ERROR("SPACING", 31803705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 31813705ce5bSJoe Perches $fix) { 31823705ce5bSJoe Perches $fixed[$linenr - 1] =~ 31833705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 31843705ce5bSJoe Perches } 31850a920b5bSAndy Whitcroft } 31860a920b5bSAndy Whitcroft 3187f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 3188f5fe35ddSAndy Whitcroft# statements after the conditional. 3189170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 31903e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 31913e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 31923e469cdcSAndy Whitcroft if (!defined $stat); 3193170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 3194170d3a22SAndy Whitcroft $remain_next, $off_next); 3195170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 3196170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 3197170d3a22SAndy Whitcroft 3198170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 3199170d3a22SAndy Whitcroft # If the statement carries leading newlines, 3200170d3a22SAndy Whitcroft # then count those as offsets. 3201170d3a22SAndy Whitcroft my ($whitespace) = 3202170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 3203170d3a22SAndy Whitcroft my $offset = 3204170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 3205170d3a22SAndy Whitcroft 3206170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 3207170d3a22SAndy Whitcroft $offset} = 1; 3208170d3a22SAndy Whitcroft } 3209170d3a22SAndy Whitcroft } 3210170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 3211170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 3212171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 32138905a67cSAndy Whitcroft 3214b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 3215000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 3216000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 32178905a67cSAndy Whitcroft } 32188905a67cSAndy Whitcroft 32198905a67cSAndy Whitcroft # Find out what is on the end of the line after the 32208905a67cSAndy Whitcroft # conditional. 3221773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 32228905a67cSAndy Whitcroft $s =~ s/\n.*//g; 322313214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 322453210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 322553210168SAndy Whitcroft $c !~ /}\s*while\s*/) 3226773647a0SAndy Whitcroft { 3227bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 3228bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 3229bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 323042bdf74cSHidetoshi Seto my $stat_real = ''; 3231bb44ad39SAndy Whitcroft 323242bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 323342bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 3234bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 3235bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 3236bb44ad39SAndy Whitcroft } 3237bb44ad39SAndy Whitcroft 3238000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3239000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 32408905a67cSAndy Whitcroft } 32418905a67cSAndy Whitcroft } 32428905a67cSAndy Whitcroft 324313214adfSAndy Whitcroft# Check for bitwise tests written as boolean 324413214adfSAndy Whitcroft if ($line =~ / 324513214adfSAndy Whitcroft (?: 324613214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 324713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 324813214adfSAndy Whitcroft (?:\&\&|\|\|) 324913214adfSAndy Whitcroft | 325013214adfSAndy Whitcroft (?:\&\&|\|\|) 325113214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 325213214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 325313214adfSAndy Whitcroft )/x) 325413214adfSAndy Whitcroft { 3255000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 3256000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 325713214adfSAndy Whitcroft } 325813214adfSAndy Whitcroft 32598905a67cSAndy Whitcroft# if and else should not have general statements after it 326013214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 326113214adfSAndy Whitcroft my $s = $1; 326213214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 326313214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 3264000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3265000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 32660a920b5bSAndy Whitcroft } 326713214adfSAndy Whitcroft } 326839667782SAndy Whitcroft# if should not continue a brace 326939667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 3270000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3271000d1cc1SJoe Perches "trailing statements should be on next line\n" . 327239667782SAndy Whitcroft $herecurr); 327339667782SAndy Whitcroft } 3274a1080bf8SAndy Whitcroft# case and default should not have general statements after them 3275a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 3276a1080bf8SAndy Whitcroft $line !~ /\G(?: 32773fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 3278a1080bf8SAndy Whitcroft \s*return\s+ 3279a1080bf8SAndy Whitcroft )/xg) 3280a1080bf8SAndy Whitcroft { 3281000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3282000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 3283a1080bf8SAndy Whitcroft } 32840a920b5bSAndy Whitcroft 32850a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 32860a920b5bSAndy Whitcroft # indent level to be relevant to each other. 32870a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 32880a920b5bSAndy Whitcroft $previndent == $indent) { 3289000d1cc1SJoe Perches ERROR("ELSE_AFTER_BRACE", 3290000d1cc1SJoe Perches "else should follow close brace '}'\n" . $hereprev); 32910a920b5bSAndy Whitcroft } 32920a920b5bSAndy Whitcroft 3293c2fdda0dSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 3294c2fdda0dSAndy Whitcroft $previndent == $indent) { 3295c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 3296c2fdda0dSAndy Whitcroft 3297c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 3298c2fdda0dSAndy Whitcroft # conditional. 3299773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 3300c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 3301c2fdda0dSAndy Whitcroft 3302c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 3303000d1cc1SJoe Perches ERROR("WHILE_AFTER_BRACE", 3304000d1cc1SJoe Perches "while should follow close brace '}'\n" . $hereprev); 3305c2fdda0dSAndy Whitcroft } 3306c2fdda0dSAndy Whitcroft } 3307c2fdda0dSAndy Whitcroft 330895e2c602SJoe Perches#Specific variable tests 3309323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 3310323c1260SJoe Perches my $var = $1; 331195e2c602SJoe Perches 331295e2c602SJoe Perches#gcc binary extension 331395e2c602SJoe Perches if ($var =~ /^$Binary$/) { 3314d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 3315d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 3316d5e616fcSJoe Perches $fix) { 3317d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 3318d5e616fcSJoe Perches $fixed[$linenr - 1] =~ 3319d5e616fcSJoe Perches s/\b$var\b/$hexval/; 3320d5e616fcSJoe Perches } 332195e2c602SJoe Perches } 332295e2c602SJoe Perches 332395e2c602SJoe Perches#CamelCase 3324807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 3325be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 332622735ce8SJoe Perches#Ignore Page<foo> variants 3327807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 332822735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 33293445686aSJoe Perches $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) { 33307e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 33317e781f67SJoe Perches my $word = $1; 33327e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 33333445686aSJoe Perches seed_camelcase_includes() if ($check); 33347e781f67SJoe Perches if (!defined $camelcase{$word}) { 33357e781f67SJoe Perches $camelcase{$word} = 1; 3336be79794bSJoe Perches CHK("CAMELCASE", 33377e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 33387e781f67SJoe Perches } 3339323c1260SJoe Perches } 3340323c1260SJoe Perches } 33413445686aSJoe Perches } 33420a920b5bSAndy Whitcroft 33430a920b5bSAndy Whitcroft#no spaces allowed after \ in define 3344d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 3345d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 3346d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 3347d5e616fcSJoe Perches $fix) { 3348d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\s+$//; 3349d5e616fcSJoe Perches } 33500a920b5bSAndy Whitcroft } 33510a920b5bSAndy Whitcroft 3352653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 3353c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 3354e09dec48SAndy Whitcroft my $file = "$1.h"; 3355e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 3356e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 3357e09dec48SAndy Whitcroft $realfile ne $checkfile && 33587840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 3359c45dcabdSAndy Whitcroft { 3360e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 3361000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 3362000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 3363e09dec48SAndy Whitcroft } else { 3364000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 3365000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 3366e09dec48SAndy Whitcroft } 33670a920b5bSAndy Whitcroft } 33680a920b5bSAndy Whitcroft } 33690a920b5bSAndy Whitcroft 3370653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 3371653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 3372cf655043SAndy Whitcroft# in a known good container 3373b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 3374b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 3375d8aaf121SAndy Whitcroft my $ln = $linenr; 3376d8aaf121SAndy Whitcroft my $cnt = $realcnt; 3377c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 3378c45dcabdSAndy Whitcroft my $ctx = ''; 3379c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 3380f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3381f74bd194SAndy Whitcroft $ctx = $dstat; 3382c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 3383a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 3384c45dcabdSAndy Whitcroft 3385f74bd194SAndy Whitcroft $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; 3386292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 3387c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 3388c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 3389c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 3390c45dcabdSAndy Whitcroft 3391c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 3392bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 3393bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 3394c81769fdSAndy Whitcroft $dstat =~ s/\[[^\[\]]*\]/1/) 3395bf30d6edSAndy Whitcroft { 3396c45dcabdSAndy Whitcroft } 3397c45dcabdSAndy Whitcroft 3398e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 3399e45bab8eSAndy Whitcroft while ($dstat =~ s/("X*")\s*$Ident/$1/ || 3400e45bab8eSAndy Whitcroft $dstat =~ s/$Ident\s*("X*")/$1/) 3401e45bab8eSAndy Whitcroft { 3402e45bab8eSAndy Whitcroft } 3403e45bab8eSAndy Whitcroft 3404c45dcabdSAndy Whitcroft my $exceptions = qr{ 3405c45dcabdSAndy Whitcroft $Declare| 3406c45dcabdSAndy Whitcroft module_param_named| 3407a0a0a7a9SKees Cook MODULE_PARM_DESC| 3408c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 3409c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 3410383099fdSAndy Whitcroft __typeof__\(| 341122fd2d3eSStefani Seibold union| 341222fd2d3eSStefani Seibold struct| 3413ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 3414ea71a0a0SAndy Whitcroft ^\"|\"$ 3415c45dcabdSAndy Whitcroft }x; 34165eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 3417f74bd194SAndy Whitcroft if ($dstat ne '' && 3418f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 3419f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 34203cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 3421b9df76acSAndy Whitcroft $dstat !~ /^'X'$/ && # character constants 3422f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 3423f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 3424e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 342572f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 3426f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 3427f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 3428f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 3429f74bd194SAndy Whitcroft $dstat !~ /^\({/) # ({... 3430c45dcabdSAndy Whitcroft { 3431f74bd194SAndy Whitcroft $ctx =~ s/\n*$//; 3432f74bd194SAndy Whitcroft my $herectx = $here . "\n"; 3433f74bd194SAndy Whitcroft my $cnt = statement_rawlines($ctx); 3434f74bd194SAndy Whitcroft 3435f74bd194SAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 3436f74bd194SAndy Whitcroft $herectx .= raw_line($linenr, $n) . "\n"; 3437c45dcabdSAndy Whitcroft } 3438c45dcabdSAndy Whitcroft 3439f74bd194SAndy Whitcroft if ($dstat =~ /;/) { 3440f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 3441f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 3442f74bd194SAndy Whitcroft } else { 3443000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 3444f74bd194SAndy Whitcroft "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); 3445d8aaf121SAndy Whitcroft } 34460a920b5bSAndy Whitcroft } 34475023d347SJoe Perches 3448481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 34495023d347SJoe Perches 34505023d347SJoe Perches } else { 34515023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 3452481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 3453481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 34545023d347SJoe Perches $line =~ /^\+.*\\$/) { 34555023d347SJoe Perches WARN("LINE_CONTINUATIONS", 34565023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 34575023d347SJoe Perches } 3458653d4876SAndy Whitcroft } 34590a920b5bSAndy Whitcroft 3460b13edf7fSJoe Perches# do {} while (0) macro tests: 3461b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 3462b13edf7fSJoe Perches# macro should not end with a semicolon 3463b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 3464b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 3465b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 3466b13edf7fSJoe Perches my $ln = $linenr; 3467b13edf7fSJoe Perches my $cnt = $realcnt; 3468b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 3469b13edf7fSJoe Perches my $ctx = ''; 3470b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 3471b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 3472b13edf7fSJoe Perches $ctx = $dstat; 3473b13edf7fSJoe Perches 3474b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 3475b13edf7fSJoe Perches 3476b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 3477b13edf7fSJoe Perches my $stmts = $2; 3478b13edf7fSJoe Perches my $semis = $3; 3479b13edf7fSJoe Perches 3480b13edf7fSJoe Perches $ctx =~ s/\n*$//; 3481b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 3482b13edf7fSJoe Perches my $herectx = $here . "\n"; 3483b13edf7fSJoe Perches 3484b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 3485b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 3486b13edf7fSJoe Perches } 3487b13edf7fSJoe Perches 3488ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 3489ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 3490b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 3491b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 3492b13edf7fSJoe Perches } 3493b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 3494b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 3495b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 3496b13edf7fSJoe Perches } 3497b13edf7fSJoe Perches } 3498b13edf7fSJoe Perches } 3499b13edf7fSJoe Perches 3500080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 3501080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 3502080ba929SMike Frysinger# . 3503080ba929SMike Frysinger# ALIGN(...) 3504080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 3505080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 3506000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 3507000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 3508080ba929SMike Frysinger } 3509080ba929SMike Frysinger 3510f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 351113214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 351213214adfSAndy Whitcroft my ($level, $endln, @chunks) = 3513cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 351413214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 3515cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 3516cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 3517aad4f614SJoe Perches my @allowed = (); 3518aad4f614SJoe Perches my $allow = 0; 351913214adfSAndy Whitcroft my $seen = 0; 3520773647a0SAndy Whitcroft my $herectx = $here . "\n"; 3521cf655043SAndy Whitcroft my $ln = $linenr - 1; 352213214adfSAndy Whitcroft for my $chunk (@chunks) { 352313214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 352413214adfSAndy Whitcroft 3525773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 3526773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 3527773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 3528773647a0SAndy Whitcroft 3529aad4f614SJoe Perches $allowed[$allow] = 0; 3530773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 3531773647a0SAndy Whitcroft 3532773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 3533773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 3534773647a0SAndy Whitcroft 3535773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 3536cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 3537cf655043SAndy Whitcroft 3538773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 353913214adfSAndy Whitcroft 354013214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 354113214adfSAndy Whitcroft 3542aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 3543cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 3544cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 3545aad4f614SJoe Perches $allowed[$allow] = 1; 354613214adfSAndy Whitcroft } 354713214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 3548cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 3549aad4f614SJoe Perches $allowed[$allow] = 1; 355013214adfSAndy Whitcroft } 3551cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 3552cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 3553aad4f614SJoe Perches $allowed[$allow] = 1; 355413214adfSAndy Whitcroft } 3555aad4f614SJoe Perches $allow++; 355613214adfSAndy Whitcroft } 3557aad4f614SJoe Perches if ($seen) { 3558aad4f614SJoe Perches my $sum_allowed = 0; 3559aad4f614SJoe Perches foreach (@allowed) { 3560aad4f614SJoe Perches $sum_allowed += $_; 3561aad4f614SJoe Perches } 3562aad4f614SJoe Perches if ($sum_allowed == 0) { 3563000d1cc1SJoe Perches WARN("BRACES", 3564000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 3565aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 3566aad4f614SJoe Perches $seen != $allow) { 3567aad4f614SJoe Perches CHK("BRACES", 3568aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 3569aad4f614SJoe Perches } 357013214adfSAndy Whitcroft } 357113214adfSAndy Whitcroft } 357213214adfSAndy Whitcroft } 3573773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 357413214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 3575cf655043SAndy Whitcroft my $allowed = 0; 3576f0a594c1SAndy Whitcroft 3577cf655043SAndy Whitcroft # Check the pre-context. 3578cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 3579cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 3580cf655043SAndy Whitcroft $allowed = 1; 3581f0a594c1SAndy Whitcroft } 3582773647a0SAndy Whitcroft 3583773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 3584773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 3585773647a0SAndy Whitcroft 3586cf655043SAndy Whitcroft # Check the condition. 3587cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 3588773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 3589cf655043SAndy Whitcroft if (defined $cond) { 3590773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 3591cf655043SAndy Whitcroft } 3592cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 3593cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 3594cf655043SAndy Whitcroft $allowed = 1; 3595cf655043SAndy Whitcroft } 3596cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 3597cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 3598cf655043SAndy Whitcroft $allowed = 1; 3599cf655043SAndy Whitcroft } 3600cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 3601cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 3602cf655043SAndy Whitcroft $allowed = 1; 3603cf655043SAndy Whitcroft } 3604cf655043SAndy Whitcroft # Check the post-context. 3605cf655043SAndy Whitcroft if (defined $chunks[1]) { 3606cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 3607cf655043SAndy Whitcroft if (defined $cond) { 3608773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 3609cf655043SAndy Whitcroft } 3610cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 3611cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 3612cf655043SAndy Whitcroft $allowed = 1; 3613cf655043SAndy Whitcroft } 3614cf655043SAndy Whitcroft } 3615cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 361669932487SJustin P. Mattock my $herectx = $here . "\n"; 3617f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 3618cf655043SAndy Whitcroft 3619f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 362069932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 3621cf655043SAndy Whitcroft } 3622cf655043SAndy Whitcroft 3623000d1cc1SJoe Perches WARN("BRACES", 3624000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 3625f0a594c1SAndy Whitcroft } 3626f0a594c1SAndy Whitcroft } 3627f0a594c1SAndy Whitcroft 36280979ae66SJoe Perches# check for unnecessary blank lines around braces 362977b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 36300979ae66SJoe Perches CHK("BRACES", 36310979ae66SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); 36320979ae66SJoe Perches } 363377b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 36340979ae66SJoe Perches CHK("BRACES", 36350979ae66SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); 36360979ae66SJoe Perches } 36370979ae66SJoe Perches 36384a0df2efSAndy Whitcroft# no volatiles please 36396c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 36406c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 3641000d1cc1SJoe Perches WARN("VOLATILE", 3642000d1cc1SJoe Perches "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 36434a0df2efSAndy Whitcroft } 36444a0df2efSAndy Whitcroft 364500df344fSAndy Whitcroft# warn about #if 0 3646c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 3647000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 3648000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 3649de7d4f0eSAndy Whitcroft $herecurr); 36504a0df2efSAndy Whitcroft } 36514a0df2efSAndy Whitcroft 365203df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 365303df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 365403df4b51SAndy Whitcroft my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; 365503df4b51SAndy Whitcroft if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { 365603df4b51SAndy Whitcroft WARN('NEEDLESS_IF', 365703df4b51SAndy Whitcroft "$1(NULL) is safe this check is probably not required\n" . $hereprev); 36584c432a8fSGreg Kroah-Hartman } 36594c432a8fSGreg Kroah-Hartman } 3660f0a594c1SAndy Whitcroft 36611a15a250SPatrick Pannuto# prefer usleep_range over udelay 366237581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 36631a15a250SPatrick Pannuto # ignore udelay's < 10, however 366437581c28SBruce Allan if (! ($1 < 10) ) { 3665000d1cc1SJoe Perches CHK("USLEEP_RANGE", 3666000d1cc1SJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); 36671a15a250SPatrick Pannuto } 36681a15a250SPatrick Pannuto } 36691a15a250SPatrick Pannuto 367009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 367109ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 367209ef8725SPatrick Pannuto if ($1 < 20) { 3673000d1cc1SJoe Perches WARN("MSLEEP", 3674000d1cc1SJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); 367509ef8725SPatrick Pannuto } 367609ef8725SPatrick Pannuto } 367709ef8725SPatrick Pannuto 367836ec1939SJoe Perches# check for comparisons of jiffies 367936ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 368036ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 368136ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 368236ec1939SJoe Perches } 368336ec1939SJoe Perches 36849d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 36859d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 36869d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 36879d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 36889d7a34a5SJoe Perches } 36899d7a34a5SJoe Perches 369000df344fSAndy Whitcroft# warn about #ifdefs in C files 3691c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 369200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 369300df344fSAndy Whitcroft# print "$herecurr"; 369400df344fSAndy Whitcroft# $clean = 0; 369500df344fSAndy Whitcroft# } 369600df344fSAndy Whitcroft 369722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 3698c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 36993705ce5bSJoe Perches if (ERROR("SPACING", 37003705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 37013705ce5bSJoe Perches $fix) { 37023705ce5bSJoe Perches $fixed[$linenr - 1] =~ 37033705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 37043705ce5bSJoe Perches } 37053705ce5bSJoe Perches 370622f2a2efSAndy Whitcroft } 370722f2a2efSAndy Whitcroft 37084a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 3709171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 3710171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 37114a0df2efSAndy Whitcroft my $which = $1; 37124a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 3713000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 3714000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 37154a0df2efSAndy Whitcroft } 37164a0df2efSAndy Whitcroft } 37174a0df2efSAndy Whitcroft# check for memory barriers without a comment. 37184a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 37194a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 3720000d1cc1SJoe Perches CHK("MEMORY_BARRIER", 3721000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 37224a0df2efSAndy Whitcroft } 37234a0df2efSAndy Whitcroft } 37244a0df2efSAndy Whitcroft# check of hardware specific defines 3725c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 3726000d1cc1SJoe Perches CHK("ARCH_DEFINES", 3727000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 37280a920b5bSAndy Whitcroft } 3729653d4876SAndy Whitcroft 3730d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 3731d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 3732000d1cc1SJoe Perches WARN("STORAGE_CLASS", 3733000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 3734d4977c78STobias Klauser } 3735d4977c78STobias Klauser 3736de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 3737de7d4f0eSAndy Whitcroft# storage class and type. 37389c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 37399c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 3740000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 3741000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 3742de7d4f0eSAndy Whitcroft } 3743de7d4f0eSAndy Whitcroft 37448905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 37458905a67cSAndy Whitcroft if ($line =~ /\b(__inline__|__inline)\b/) { 3746d5e616fcSJoe Perches if (WARN("INLINE", 3747d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 3748d5e616fcSJoe Perches $fix) { 3749d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/; 3750d5e616fcSJoe Perches 3751d5e616fcSJoe Perches } 37528905a67cSAndy Whitcroft } 37538905a67cSAndy Whitcroft 37543d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 37553d130fd0SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 3756000d1cc1SJoe Perches WARN("PREFER_PACKED", 3757000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 37583d130fd0SJoe Perches } 37593d130fd0SJoe Perches 376039b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 376139b7e287SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 3762000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 3763000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 376439b7e287SJoe Perches } 376539b7e287SJoe Perches 37665f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 37675f14d3bdSJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 3768d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 3769d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 3770d5e616fcSJoe Perches $fix) { 3771d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 3772d5e616fcSJoe Perches 3773d5e616fcSJoe Perches } 37745f14d3bdSJoe Perches } 37755f14d3bdSJoe Perches 37766061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 37776061d949SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 3778d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 3779d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 3780d5e616fcSJoe Perches $fix) { 3781d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 3782d5e616fcSJoe Perches } 37836061d949SJoe Perches } 37846061d949SJoe Perches 37858f53a9b8SJoe Perches# check for sizeof(&) 37868f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 3787000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 3788000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 37898f53a9b8SJoe Perches } 37908f53a9b8SJoe Perches 379166c80b60SJoe Perches# check for sizeof without parenthesis 379266c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 3793d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 3794d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 3795d5e616fcSJoe Perches $fix) { 3796d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 3797d5e616fcSJoe Perches } 379866c80b60SJoe Perches } 379966c80b60SJoe Perches 3800428e2fdcSJoe Perches# check for line continuations in quoted strings with odd counts of " 3801428e2fdcSJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 3802000d1cc1SJoe Perches WARN("LINE_CONTINUATIONS", 3803000d1cc1SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 3804428e2fdcSJoe Perches } 3805428e2fdcSJoe Perches 380688982feaSJoe Perches# check for struct spinlock declarations 380788982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 380888982feaSJoe Perches WARN("USE_SPINLOCK_T", 380988982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 381088982feaSJoe Perches } 381188982feaSJoe Perches 3812a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 3813a6962d72SJoe Perches if ($line =~ /\bseq_printf\s*\(/) { 3814a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 3815a6962d72SJoe Perches if ($fmt !~ /[^\\]\%/) { 3816d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 3817d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 3818d5e616fcSJoe Perches $fix) { 3819d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\bseq_printf\b/seq_puts/; 3820d5e616fcSJoe Perches } 3821a6962d72SJoe Perches } 3822a6962d72SJoe Perches } 3823a6962d72SJoe Perches 3824554e165cSAndy Whitcroft# Check for misused memsets 3825d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 3826d1fe9c09SJoe Perches defined $stat && 3827d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { 3828554e165cSAndy Whitcroft 3829d7c76ba7SJoe Perches my $ms_addr = $2; 3830d1fe9c09SJoe Perches my $ms_val = $7; 3831d1fe9c09SJoe Perches my $ms_size = $12; 3832d7c76ba7SJoe Perches 3833554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 3834554e165cSAndy Whitcroft ERROR("MEMSET", 3835d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 3836554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 3837554e165cSAndy Whitcroft WARN("MEMSET", 3838d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 3839d7c76ba7SJoe Perches } 3840d7c76ba7SJoe Perches } 3841d7c76ba7SJoe Perches 3842d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 3843d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 3844d1fe9c09SJoe Perches defined $stat && 3845d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 3846d1fe9c09SJoe Perches if (defined $2 || defined $7) { 3847d7c76ba7SJoe Perches my $call = $1; 3848d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 3849d7c76ba7SJoe Perches my $arg1 = $3; 3850d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 3851d1fe9c09SJoe Perches my $arg2 = $8; 3852d7c76ba7SJoe Perches my $cast; 3853d7c76ba7SJoe Perches 3854d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 3855d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 3856d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 3857d7c76ba7SJoe Perches $cast = $cast1; 3858d7c76ba7SJoe Perches } else { 3859d7c76ba7SJoe Perches $cast = $cast2; 3860d7c76ba7SJoe Perches } 3861d7c76ba7SJoe Perches WARN("MINMAX", 3862d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 3863554e165cSAndy Whitcroft } 3864554e165cSAndy Whitcroft } 3865554e165cSAndy Whitcroft 38664a273195SJoe Perches# check usleep_range arguments 38674a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 38684a273195SJoe Perches defined $stat && 38694a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 38704a273195SJoe Perches my $min = $1; 38714a273195SJoe Perches my $max = $7; 38724a273195SJoe Perches if ($min eq $max) { 38734a273195SJoe Perches WARN("USLEEP_RANGE", 38744a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 38754a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 38764a273195SJoe Perches $min > $max) { 38774a273195SJoe Perches WARN("USLEEP_RANGE", 38784a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 38794a273195SJoe Perches } 38804a273195SJoe Perches } 38814a273195SJoe Perches 388270dc8a48SJoe Perches# check for new externs in .h files. 388370dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 388470dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 388570dc8a48SJoe Perches if (WARN("AVOID_EXTERNS", 388670dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 388770dc8a48SJoe Perches $fix) { 388870dc8a48SJoe Perches $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 388970dc8a48SJoe Perches } 389070dc8a48SJoe Perches } 389170dc8a48SJoe Perches 3892de7d4f0eSAndy Whitcroft# check for new externs in .c files. 3893171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 3894c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 3895171ae1a4SAndy Whitcroft { 3896c45dcabdSAndy Whitcroft my $function_name = $1; 3897c45dcabdSAndy Whitcroft my $paren_space = $2; 3898171ae1a4SAndy Whitcroft 3899171ae1a4SAndy Whitcroft my $s = $stat; 3900171ae1a4SAndy Whitcroft if (defined $cond) { 3901171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 3902171ae1a4SAndy Whitcroft } 3903c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 3904c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 3905c45dcabdSAndy Whitcroft { 3906000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 3907000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 3908de7d4f0eSAndy Whitcroft } 3909de7d4f0eSAndy Whitcroft 3910171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 3911000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 3912000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 3913171ae1a4SAndy Whitcroft } 39149c9ba34eSAndy Whitcroft 39159c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 39169c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 39179c9ba34eSAndy Whitcroft { 3918000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 3919000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 3920171ae1a4SAndy Whitcroft } 3921171ae1a4SAndy Whitcroft 3922de7d4f0eSAndy Whitcroft# checks for new __setup's 3923de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 3924de7d4f0eSAndy Whitcroft my $name = $1; 3925de7d4f0eSAndy Whitcroft 3926de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 3927000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 3928000d1cc1SJoe Perches "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 3929de7d4f0eSAndy Whitcroft } 3930653d4876SAndy Whitcroft } 39319c0ca6f9SAndy Whitcroft 39329c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 3933caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 3934000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 3935000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 39369c0ca6f9SAndy Whitcroft } 393713214adfSAndy Whitcroft 3938a640d25cSJoe Perches# alloc style 3939a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 3940a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 3941a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 3942a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 3943a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 3944a640d25cSJoe Perches } 3945a640d25cSJoe Perches 3946972fdea2SJoe Perches# check for krealloc arg reuse 3947972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 3948972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 3949972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 3950972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 3951972fdea2SJoe Perches } 3952972fdea2SJoe Perches 39535ce59ae0SJoe Perches# check for alloc argument mismatch 39545ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 39555ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 39565ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 39575ce59ae0SJoe Perches } 39585ce59ae0SJoe Perches 3959caf2a54fSJoe Perches# check for multiple semicolons 3960caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 3961d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 3962d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 3963d5e616fcSJoe Perches $fix) { 3964d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g; 3965d5e616fcSJoe Perches } 3966d1e2ad07SJoe Perches } 3967d1e2ad07SJoe Perches 3968d1e2ad07SJoe Perches# check for switch/default statements without a break; 3969d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 3970d1e2ad07SJoe Perches defined $stat && 3971d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 3972d1e2ad07SJoe Perches my $ctx = ''; 3973d1e2ad07SJoe Perches my $herectx = $here . "\n"; 3974d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 3975d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 3976d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 3977d1e2ad07SJoe Perches } 3978d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 3979d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 3980caf2a54fSJoe Perches } 3981caf2a54fSJoe Perches 398213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 3983d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 3984d5e616fcSJoe Perches if (WARN("USE_FUNC", 3985d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 3986d5e616fcSJoe Perches $fix) { 3987d5e616fcSJoe Perches $fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g; 3988d5e616fcSJoe Perches } 398913214adfSAndy Whitcroft } 3990773647a0SAndy Whitcroft 39912c92488aSJoe Perches# check for use of yield() 39922c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 39932c92488aSJoe Perches WARN("YIELD", 39942c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 39952c92488aSJoe Perches } 39962c92488aSJoe Perches 3997179f8f40SJoe Perches# check for comparisons against true and false 3998179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 3999179f8f40SJoe Perches my $lead = $1; 4000179f8f40SJoe Perches my $arg = $2; 4001179f8f40SJoe Perches my $test = $3; 4002179f8f40SJoe Perches my $otype = $4; 4003179f8f40SJoe Perches my $trail = $5; 4004179f8f40SJoe Perches my $op = "!"; 4005179f8f40SJoe Perches 4006179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 4007179f8f40SJoe Perches 4008179f8f40SJoe Perches my $type = lc($otype); 4009179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 4010179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 4011179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 4012179f8f40SJoe Perches $op = ""; 4013179f8f40SJoe Perches } 4014179f8f40SJoe Perches 4015179f8f40SJoe Perches CHK("BOOL_COMPARISON", 4016179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 4017179f8f40SJoe Perches 4018179f8f40SJoe Perches## maybe suggesting a correct construct would better 4019179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 4020179f8f40SJoe Perches 4021179f8f40SJoe Perches } 4022179f8f40SJoe Perches } 4023179f8f40SJoe Perches 40244882720bSThomas Gleixner# check for semaphores initialized locked 40254882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 4026000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 4027000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 4028773647a0SAndy Whitcroft } 40296712d858SJoe Perches 403067d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 403167d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 4032000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 403367d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 4034773647a0SAndy Whitcroft } 40356712d858SJoe Perches 4036f3db6639SMichael Ellerman# check for __initcall(), use device_initcall() explicitly please 4037f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 4038000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 4039000d1cc1SJoe Perches "please use device_initcall() instead of __initcall()\n" . $herecurr); 4040f3db6639SMichael Ellerman } 40416712d858SJoe Perches 404279404849SEmese Revfy# check for various ops structs, ensure they are const. 404379404849SEmese Revfy my $struct_ops = qr{acpi_dock_ops| 404479404849SEmese Revfy address_space_operations| 404579404849SEmese Revfy backlight_ops| 404679404849SEmese Revfy block_device_operations| 404779404849SEmese Revfy dentry_operations| 404879404849SEmese Revfy dev_pm_ops| 404979404849SEmese Revfy dma_map_ops| 405079404849SEmese Revfy extent_io_ops| 405179404849SEmese Revfy file_lock_operations| 405279404849SEmese Revfy file_operations| 405379404849SEmese Revfy hv_ops| 405479404849SEmese Revfy ide_dma_ops| 405579404849SEmese Revfy intel_dvo_dev_ops| 405679404849SEmese Revfy item_operations| 405779404849SEmese Revfy iwl_ops| 405879404849SEmese Revfy kgdb_arch| 405979404849SEmese Revfy kgdb_io| 406079404849SEmese Revfy kset_uevent_ops| 406179404849SEmese Revfy lock_manager_operations| 406279404849SEmese Revfy microcode_ops| 406379404849SEmese Revfy mtrr_ops| 406479404849SEmese Revfy neigh_ops| 406579404849SEmese Revfy nlmsvc_binding| 406679404849SEmese Revfy pci_raw_ops| 406779404849SEmese Revfy pipe_buf_operations| 406879404849SEmese Revfy platform_hibernation_ops| 406979404849SEmese Revfy platform_suspend_ops| 407079404849SEmese Revfy proto_ops| 407179404849SEmese Revfy rpc_pipe_ops| 407279404849SEmese Revfy seq_operations| 407379404849SEmese Revfy snd_ac97_build_ops| 407479404849SEmese Revfy soc_pcmcia_socket_ops| 407579404849SEmese Revfy stacktrace_ops| 407679404849SEmese Revfy sysfs_ops| 407779404849SEmese Revfy tty_operations| 407879404849SEmese Revfy usb_mon_operations| 407979404849SEmese Revfy wd_ops}x; 40806903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 408179404849SEmese Revfy $line =~ /\bstruct\s+($struct_ops)\b/) { 4082000d1cc1SJoe Perches WARN("CONST_STRUCT", 4083000d1cc1SJoe Perches "struct $1 should normally be const\n" . 40846903ffb2SAndy Whitcroft $herecurr); 40852b6db5cbSAndy Whitcroft } 4086773647a0SAndy Whitcroft 4087773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 4088773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 4089773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 4090c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 4091c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 4092171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 4093171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 4094171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 4095773647a0SAndy Whitcroft { 4096000d1cc1SJoe Perches WARN("NR_CPUS", 4097000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 4098773647a0SAndy Whitcroft } 40999c9ba34eSAndy Whitcroft 41009c9ba34eSAndy Whitcroft# check for %L{u,d,i} in strings 41019c9ba34eSAndy Whitcroft my $string; 41029c9ba34eSAndy Whitcroft while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 41039c9ba34eSAndy Whitcroft $string = substr($rawline, $-[1], $+[1] - $-[1]); 41042a1bc5d5SAndy Whitcroft $string =~ s/%%/__/g; 41059c9ba34eSAndy Whitcroft if ($string =~ /(?<!%)%L[udi]/) { 4106000d1cc1SJoe Perches WARN("PRINTF_L", 4107000d1cc1SJoe Perches "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 41089c9ba34eSAndy Whitcroft last; 41099c9ba34eSAndy Whitcroft } 41109c9ba34eSAndy Whitcroft } 4111691d77b6SAndy Whitcroft 4112691d77b6SAndy Whitcroft# whine mightly about in_atomic 4113691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 4114691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 4115000d1cc1SJoe Perches ERROR("IN_ATOMIC", 4116000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 4117f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 4118000d1cc1SJoe Perches WARN("IN_ATOMIC", 4119000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 4120691d77b6SAndy Whitcroft } 4121691d77b6SAndy Whitcroft } 41221704f47bSPeter Zijlstra 41231704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 41241704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 41251704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 41261704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 41271704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 41281704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 4129000d1cc1SJoe Perches ERROR("LOCKDEP", 4130000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 41311704f47bSPeter Zijlstra } 41321704f47bSPeter Zijlstra } 413388f8831cSDave Jones 413488f8831cSDave Jones if ($line =~ /debugfs_create_file.*S_IWUGO/ || 413588f8831cSDave Jones $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { 4136000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 4137000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 413888f8831cSDave Jones } 413913214adfSAndy Whitcroft } 414013214adfSAndy Whitcroft 414113214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 414213214adfSAndy Whitcroft # so just keep quiet. 414313214adfSAndy Whitcroft if ($#rawlines == -1) { 414413214adfSAndy Whitcroft exit(0); 41450a920b5bSAndy Whitcroft } 41460a920b5bSAndy Whitcroft 41478905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 41488905a67cSAndy Whitcroft # things that appear to be patches. 41498905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 41508905a67cSAndy Whitcroft exit(0); 41518905a67cSAndy Whitcroft } 41528905a67cSAndy Whitcroft 41538905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 41548905a67cSAndy Whitcroft # just keep quiet. 41558905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 41568905a67cSAndy Whitcroft exit(0); 41578905a67cSAndy Whitcroft } 41588905a67cSAndy Whitcroft 41598905a67cSAndy Whitcroft if (!$is_patch) { 4160000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 4161000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 41620a920b5bSAndy Whitcroft } 41630a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 4164000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 4165000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 41660a920b5bSAndy Whitcroft } 41670a920b5bSAndy Whitcroft 4168f0a594c1SAndy Whitcroft print report_dump(); 416913214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 417013214adfSAndy Whitcroft print "$filename " if ($summary_file); 41716c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 41726c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 41736c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 41748905a67cSAndy Whitcroft print "\n" if ($quiet == 0); 41756c72ffaaSAndy Whitcroft } 41768905a67cSAndy Whitcroft 4177d2c0a235SAndy Whitcroft if ($quiet == 0) { 4178d1fe9c09SJoe Perches 4179d1fe9c09SJoe Perches if ($^V lt 5.10.0) { 4180d1fe9c09SJoe Perches print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); 4181d1fe9c09SJoe Perches print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); 4182d1fe9c09SJoe Perches } 4183d1fe9c09SJoe Perches 4184d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 4185d2c0a235SAndy Whitcroft # then suggest that. 4186d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 4187d2c0a235SAndy Whitcroft print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 4188d2c0a235SAndy Whitcroft print " scripts/cleanfile\n\n"; 4189b0781216SMike Frysinger $rpt_cleaners = 0; 4190d2c0a235SAndy Whitcroft } 4191d2c0a235SAndy Whitcroft } 4192d2c0a235SAndy Whitcroft 419311232688SArtem Bityutskiy if ($quiet == 0 && keys %ignore_type) { 4194000d1cc1SJoe Perches print "NOTE: Ignored message types:"; 4195000d1cc1SJoe Perches foreach my $ignore (sort keys %ignore_type) { 4196000d1cc1SJoe Perches print " $ignore"; 4197000d1cc1SJoe Perches } 419811232688SArtem Bityutskiy print "\n\n"; 4199000d1cc1SJoe Perches } 4200000d1cc1SJoe Perches 42013705ce5bSJoe Perches if ($clean == 0 && $fix && "@rawlines" ne "@fixed") { 42023705ce5bSJoe Perches my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes"; 42033705ce5bSJoe Perches my $linecount = 0; 42043705ce5bSJoe Perches my $f; 42053705ce5bSJoe Perches 42063705ce5bSJoe Perches open($f, '>', $newfile) 42073705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 42083705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 42093705ce5bSJoe Perches $linecount++; 42103705ce5bSJoe Perches if ($file) { 42113705ce5bSJoe Perches if ($linecount > 3) { 42123705ce5bSJoe Perches $fixed_line =~ s/^\+//; 42133705ce5bSJoe Perches print $f $fixed_line. "\n"; 42143705ce5bSJoe Perches } 42153705ce5bSJoe Perches } else { 42163705ce5bSJoe Perches print $f $fixed_line . "\n"; 42173705ce5bSJoe Perches } 42183705ce5bSJoe Perches } 42193705ce5bSJoe Perches close($f); 42203705ce5bSJoe Perches 42213705ce5bSJoe Perches if (!$quiet) { 42223705ce5bSJoe Perches print << "EOM"; 42233705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 42243705ce5bSJoe Perches 42253705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 42263705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 42273705ce5bSJoe Perches 42283705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 42293705ce5bSJoe PerchesNo warranties, expressed or implied... 42303705ce5bSJoe Perches 42313705ce5bSJoe PerchesEOM 42323705ce5bSJoe Perches } 42333705ce5bSJoe Perches } 42343705ce5bSJoe Perches 42350a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 4236c2fdda0dSAndy Whitcroft print "$vname has no obvious style problems and is ready for submission.\n" 42370a920b5bSAndy Whitcroft } 42380a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 4239000d1cc1SJoe Perches print << "EOM"; 4240000d1cc1SJoe Perches$vname has style problems, please review. 4241000d1cc1SJoe Perches 4242000d1cc1SJoe PerchesIf any of these errors are false positives, please report 4243000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS. 4244000d1cc1SJoe PerchesEOM 42450a920b5bSAndy Whitcroft } 424613214adfSAndy Whitcroft 42470a920b5bSAndy Whitcroft return $clean; 42480a920b5bSAndy Whitcroft} 4249