1#!/usr/bin/env perl 2# (c) 2001, Dave Jones. (the file handling bit) 3# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 4# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 5# (c) 2008-2010 Andy Whitcroft <apw@canonical.com> 6# Licensed under the terms of the GNU GPL License version 2 7 8use strict; 9use warnings; 10use Term::ANSIColor qw(:constants); 11 12my $P = $0; 13$P =~ s@.*/@@g; 14 15our $SrcFile = qr{\.(?:h|c|cpp|s|S|pl|py|sh)$}; 16 17my $V = '0.31'; 18 19use Getopt::Long qw(:config no_auto_abbrev); 20 21my $quiet = 0; 22my $tree = 1; 23my $chk_signoff = 1; 24my $chk_patch = undef; 25my $chk_branch = undef; 26my $tst_only; 27my $emacs = 0; 28my $terse = 0; 29my $file = undef; 30my $color = "auto"; 31my $no_warnings = 0; 32my $summary = 1; 33my $mailback = 0; 34my $summary_file = 0; 35my $root; 36my %debug; 37my $help = 0; 38 39sub help { 40 my ($exitcode) = @_; 41 42 print << "EOM"; 43Usage: 44 45 $P [OPTION]... [FILE]... 46 $P [OPTION]... [GIT-REV-LIST] 47 48Version: $V 49 50Options: 51 -q, --quiet quiet 52 --patch treat FILE as patchfile 53 --branch treat args as GIT revision list 54 --emacs emacs compile window format 55 --terse one line per report 56 -f, --file treat FILE as regular source file 57 --strict fail if only warnings are found 58 --no-summary suppress the per-file summary 59 --mailback only produce a report in case of warnings/errors 60 --summary-file include the filename in summary 61 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 62 'values', 'possible', 'type', and 'attr' (default 63 is all off) 64 --test-only=WORD report only warnings/errors containing WORD 65 literally 66 --color[=WHEN] Use colors 'always', 'never', or only when output 67 is a terminal ('auto'). Default is 'auto'. 68 -h, --help, --version display this help and exit 69 70When FILE is - read standard input. 71EOM 72 73 exit($exitcode); 74} 75 76# Use at your own risk 77print "\n", MAGENTA, "WARNING:", RESET, " This code is highly experimental ... likely isn't a great style(9) match yet\n\n"; 78 79# Perl's Getopt::Long allows options to take optional arguments after a space. 80# Prevent --color by itself from consuming other arguments 81foreach (@ARGV) { 82 if ($_ eq "--color" || $_ eq "-color") { 83 $_ = "--color=$color"; 84 } 85} 86 87GetOptions( 88 'q|quiet+' => \$quiet, 89 'tree!' => \$tree, 90 'signoff!' => \$chk_signoff, 91 'patch!' => \$chk_patch, 92 'branch!' => \$chk_branch, 93 'emacs!' => \$emacs, 94 'terse!' => \$terse, 95 'f|file!' => \$file, 96 'strict!' => \$no_warnings, 97 'root=s' => \$root, 98 'summary!' => \$summary, 99 'mailback!' => \$mailback, 100 'summary-file!' => \$summary_file, 101 102 'debug=s' => \%debug, 103 'test-only=s' => \$tst_only, 104 'color=s' => \$color, 105 'no-color' => sub { $color = 'never'; }, 106 'h|help' => \$help, 107 'version' => \$help 108) or help(1); 109 110help(0) if ($help); 111 112my $exit = 0; 113 114if ($#ARGV < 0) { 115 print "$P: no input files\n"; 116 exit(1); 117} 118 119if (!defined $chk_branch && !defined $chk_patch && !defined $file) { 120 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 121 $file = $ARGV[0] =~ /$SrcFile/ ? 1 : 0; 122 $chk_patch = $chk_branch || $file ? 0 : 1; 123} elsif (!defined $chk_branch && !defined $chk_patch) { 124 if ($file) { 125 $chk_branch = $chk_patch = 0; 126 } else { 127 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 128 $chk_patch = $chk_branch ? 0 : 1; 129 } 130} elsif (!defined $chk_branch && !defined $file) { 131 if ($chk_patch) { 132 $chk_branch = $file = 0; 133 } else { 134 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 135 $file = $chk_branch ? 0 : 1; 136 } 137} elsif (!defined $chk_patch && !defined $file) { 138 if ($chk_branch) { 139 $chk_patch = $file = 0; 140 } else { 141 $file = $ARGV[0] =~ /$SrcFile/ ? 1 : 0; 142 $chk_patch = $file ? 0 : 1; 143 } 144} elsif (!defined $chk_branch) { 145 $chk_branch = $chk_patch || $file ? 0 : 1; 146} elsif (!defined $chk_patch) { 147 $chk_patch = $chk_branch || $file ? 0 : 1; 148} elsif (!defined $file) { 149 $file = $chk_patch || $chk_branch ? 0 : 1; 150} 151 152if (($chk_patch && $chk_branch) || 153 ($chk_patch && $file) || 154 ($chk_branch && $file)) { 155 die "Only one of --file, --branch, --patch is permitted\n"; 156} 157if (!$chk_patch && !$chk_branch && !$file) { 158 die "One of --file, --branch, --patch is required\n"; 159} 160 161if ($color =~ /^always$/i) { 162 $color = 1; 163} elsif ($color =~ /^never$/i) { 164 $color = 0; 165} elsif ($color =~ /^auto$/i) { 166 $color = (-t STDOUT); 167} else { 168 die "Invalid color mode: $color\n"; 169} 170 171my $dbg_values = 0; 172my $dbg_possible = 0; 173my $dbg_type = 0; 174my $dbg_attr = 0; 175my $dbg_adv_dcs = 0; 176my $dbg_adv_checking = 0; 177my $dbg_adv_apw = 0; 178for my $key (keys %debug) { 179 ## no critic 180 eval "\${dbg_$key} = '$debug{$key}';"; 181 die "$@" if ($@); 182} 183 184my $rpt_cleaners = 0; 185 186if ($terse) { 187 $emacs = 1; 188 $quiet++; 189} 190 191my $emitted_corrupt = 0; 192 193our $Ident = qr{ 194 [A-Za-z_][A-Za-z\d_]* 195 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 196 }x; 197our $Storage = qr{extern|static|asmlinkage}; 198our $Sparse = qr{ 199 __force 200 }x; 201 202# Notes to $Attribute: 203our $Attribute = qr{ 204 const| 205 volatile| 206 QEMU_NORETURN| 207 QEMU_WARN_UNUSED_RESULT| 208 QEMU_SENTINEL| 209 QEMU_PACKED| 210 GCC_FMT_ATTR 211 }x; 212our $Modifier; 213our $Inline = qr{inline}; 214our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 215our $Lval = qr{$Ident(?:$Member)*}; 216 217our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; 218our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; 219our $Compare = qr{<=|>=|==|!=|<|>}; 220our $Operators = qr{ 221 <=|>=|==|!=| 222 =>|->|<<|>>|<|>|!|~| 223 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% 224 }x; 225 226our $NonptrType; 227our $Type; 228our $Declare; 229 230our $NON_ASCII_UTF8 = qr{ 231 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 232 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 233 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 234 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 235 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 236 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 237 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 238}x; 239 240our $UTF8 = qr{ 241 [\x09\x0A\x0D\x20-\x7E] # ASCII 242 | $NON_ASCII_UTF8 243}x; 244 245# some readers default to ISO-8859-1 when showing email source. detect 246# when UTF-8 is incorrectly interpreted as ISO-8859-1 and reencoded back. 247# False positives are possible but very unlikely. 248our $UTF8_MOJIBAKE = qr{ 249 \xC3[\x82-\x9F] \xC2[\x80-\xBF] # c2-df 80-bf 250 | \xC3\xA0 \xC2[\xA0-\xBF] \xC2[\x80-\xBF] # e0 a0-bf 80-bf 251 | \xC3[\xA1-\xAC\xAE\xAF] (?: \xC2[\x80-\xBF]){2} # e1-ec/ee/ef 80-bf 80-bf 252 | \xC3\xAD \xC2[\x80-\x9F] \xC2[\x80-\xBF] # ed 80-9f 80-bf 253 | \xC3\xB0 \xC2[\x90-\xBF] (?: \xC2[\x80-\xBF]){2} # f0 90-bf 80-bf 80-bf 254 | \xC3[\xB1-\xB3] (?: \xC2[\x80-\xBF]){3} # f1-f3 80-bf 80-bf 80-bf 255 | \xC3\xB4 \xC2[\x80-\x8F] (?: \xC2[\x80-\xBF]){2} # f4 80-b8 80-bf 80-bf 256}x; 257 258# There are still some false positives, but this catches most 259# common cases. 260our $typeTypedefs = qr{(?x: 261 (?![KMGTPE]iB) # IEC binary prefix (do not match) 262 [A-Z][A-Z\d_]*[a-z][A-Za-z\d_]* # camelcase 263 | [A-Z][A-Z\d_]*AIOCB # all uppercase 264 | [A-Z][A-Z\d_]*CPU # all uppercase 265 | QEMUBH # all uppercase 266)}; 267 268our @typeList = ( 269 qr{void}, 270 qr{(?:unsigned\s+)?char}, 271 qr{(?:unsigned\s+)?short}, 272 qr{(?:unsigned\s+)?int}, 273 qr{(?:unsigned\s+)?long}, 274 qr{(?:unsigned\s+)?long\s+int}, 275 qr{(?:unsigned\s+)?long\s+long}, 276 qr{(?:unsigned\s+)?long\s+long\s+int}, 277 qr{unsigned}, 278 qr{float}, 279 qr{double}, 280 qr{bool}, 281 qr{struct\s+$Ident}, 282 qr{union\s+$Ident}, 283 qr{enum\s+$Ident}, 284 qr{${Ident}_t}, 285 qr{${Ident}_handler}, 286 qr{${Ident}_handler_fn}, 287 qr{target_(?:u)?long}, 288 qr{hwaddr}, 289); 290 291# This can be modified by sub possible. Since it can be empty, be careful 292# about regexes that always match, because they can cause infinite loops. 293our @modifierList = ( 294); 295 296sub build_types { 297 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 298 if (@modifierList > 0) { 299 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 300 $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 301 } else { 302 $Modifier = qr{(?:$Attribute|$Sparse)}; 303 } 304 $NonptrType = qr{ 305 (?:$Modifier\s+|const\s+)* 306 (?: 307 (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| 308 (?:$typeTypedefs\b)| 309 (?:${all}\b) 310 ) 311 (?:\s+$Modifier|\s+const)* 312 }x; 313 $Type = qr{ 314 $NonptrType 315 (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)? 316 (?:\s+$Inline|\s+$Modifier)* 317 }x; 318 $Declare = qr{(?:$Storage\s+)?$Type}; 319} 320build_types(); 321 322$chk_signoff = 0 if ($file); 323 324my @rawlines = (); 325my @lines = (); 326my $vname; 327if ($chk_branch) { 328 my @patches; 329 my %git_commits = (); 330 my $HASH; 331 open($HASH, "-|", "git", "log", "--reverse", "--no-merges", "--format=%H %s", $ARGV[0]) || 332 die "$P: git log --reverse --no-merges --format='%H %s' $ARGV[0] failed - $!\n"; 333 334 for my $line (<$HASH>) { 335 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 336 next if (!defined($1) || !defined($2)); 337 my $sha1 = $1; 338 my $subject = $2; 339 push(@patches, $sha1); 340 $git_commits{$sha1} = $subject; 341 } 342 343 close $HASH; 344 345 die "$P: no revisions returned for revlist '$ARGV[0]'\n" 346 unless @patches; 347 348 my $i = 1; 349 my $num_patches = @patches; 350 for my $hash (@patches) { 351 my $FILE; 352 open($FILE, '-|', "git", "show", "--patch-with-stat", $hash) || 353 die "$P: git show $hash - $!\n"; 354 while (<$FILE>) { 355 chomp; 356 push(@rawlines, $_); 357 } 358 close($FILE); 359 $vname = substr($hash, 0, 12) . ' (' . $git_commits{$hash} . ')'; 360 if ($num_patches > 1 && $quiet == 0) { 361 my $prefix = "$i/$num_patches"; 362 $prefix = BLUE . BOLD . $prefix . RESET if $color; 363 print "$prefix Checking commit $vname\n"; 364 $vname = "Patch $i/$num_patches"; 365 } else { 366 $vname = "Commit " . $vname; 367 } 368 if (!process($hash)) { 369 $exit = 1; 370 print "\n" if ($num_patches > 1 && $quiet == 0); 371 } 372 @rawlines = (); 373 @lines = (); 374 $i++; 375 } 376} else { 377 for my $filename (@ARGV) { 378 my $FILE; 379 if ($file) { 380 open($FILE, '-|', "diff -u /dev/null $filename") || 381 die "$P: $filename: diff failed - $!\n"; 382 } elsif ($filename eq '-') { 383 open($FILE, '<&STDIN'); 384 } else { 385 open($FILE, '<', "$filename") || 386 die "$P: $filename: open failed - $!\n"; 387 } 388 if ($filename eq '-') { 389 $vname = 'Your patch'; 390 } else { 391 $vname = $filename; 392 } 393 print "Checking $filename...\n" if @ARGV > 1 && $quiet == 0; 394 while (<$FILE>) { 395 chomp; 396 push(@rawlines, $_); 397 } 398 close($FILE); 399 if (!process($filename)) { 400 $exit = 1; 401 } 402 @rawlines = (); 403 @lines = (); 404 } 405} 406 407exit($exit); 408 409sub top_of_kernel_tree { 410 my ($root) = @_; 411 412 my @tree_check = ( 413 "Makefile.inc1", "README.md", "sys", 414 "usr.sbin" 415 ); 416 417 foreach my $check (@tree_check) { 418 if (! -e $root . '/' . $check) { 419 return 0; 420 } 421 } 422 return 1; 423} 424 425sub expand_tabs { 426 my ($str) = @_; 427 428 my $res = ''; 429 my $n = 0; 430 for my $c (split(//, $str)) { 431 if ($c eq "\t") { 432 $res .= ' '; 433 $n++; 434 for (; ($n % 8) != 0; $n++) { 435 $res .= ' '; 436 } 437 next; 438 } 439 $res .= $c; 440 $n++; 441 } 442 443 return $res; 444} 445sub copy_spacing { 446 (my $res = shift) =~ tr/\t/ /c; 447 return $res; 448} 449 450sub line_stats { 451 my ($line) = @_; 452 453 # Drop the diff line leader and expand tabs 454 $line =~ s/^.//; 455 $line = expand_tabs($line); 456 457 # Pick the indent from the front of the line. 458 my ($white) = ($line =~ /^(\s*)/); 459 460 return (length($line), length($white)); 461} 462 463my $sanitise_quote = ''; 464 465sub sanitise_line_reset { 466 my ($in_comment) = @_; 467 468 if ($in_comment) { 469 $sanitise_quote = '*/'; 470 } else { 471 $sanitise_quote = ''; 472 } 473} 474sub sanitise_line { 475 my ($line) = @_; 476 477 my $res = ''; 478 my $l = ''; 479 480 my $qlen = 0; 481 my $off = 0; 482 my $c; 483 484 # Always copy over the diff marker. 485 $res = substr($line, 0, 1); 486 487 for ($off = 1; $off < length($line); $off++) { 488 $c = substr($line, $off, 1); 489 490 # Comments we are wacking completely including the begin 491 # and end, all to $;. 492 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 493 $sanitise_quote = '*/'; 494 495 substr($res, $off, 2, "$;$;"); 496 $off++; 497 next; 498 } 499 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 500 $sanitise_quote = ''; 501 substr($res, $off, 2, "$;$;"); 502 $off++; 503 next; 504 } 505 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 506 $sanitise_quote = '//'; 507 508 substr($res, $off, 2, $sanitise_quote); 509 $off++; 510 next; 511 } 512 513 # A \ in a string means ignore the next character. 514 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 515 $c eq "\\") { 516 substr($res, $off, 2, 'XX'); 517 $off++; 518 next; 519 } 520 # Regular quotes. 521 if ($c eq "'" || $c eq '"') { 522 if ($sanitise_quote eq '') { 523 $sanitise_quote = $c; 524 525 substr($res, $off, 1, $c); 526 next; 527 } elsif ($sanitise_quote eq $c) { 528 $sanitise_quote = ''; 529 } 530 } 531 532 #print "c<$c> SQ<$sanitise_quote>\n"; 533 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 534 substr($res, $off, 1, $;); 535 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 536 substr($res, $off, 1, $;); 537 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 538 substr($res, $off, 1, 'X'); 539 } else { 540 substr($res, $off, 1, $c); 541 } 542 } 543 544 if ($sanitise_quote eq '//') { 545 $sanitise_quote = ''; 546 } 547 548 # The pathname on a #include may be surrounded by '<' and '>'. 549 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 550 my $clean = 'X' x length($1); 551 $res =~ s@\<.*\>@<$clean>@; 552 553 # The whole of a #error is a string. 554 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 555 my $clean = 'X' x length($1); 556 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 557 } 558 559 return $res; 560} 561 562sub ctx_statement_block { 563 my ($linenr, $remain, $off) = @_; 564 my $line = $linenr - 1; 565 my $blk = ''; 566 my $soff = $off; 567 my $coff = $off - 1; 568 my $coff_set = 0; 569 570 my $loff = 0; 571 572 my $type = ''; 573 my $level = 0; 574 my @stack = (); 575 my $p; 576 my $c; 577 my $len = 0; 578 579 my $remainder; 580 while (1) { 581 @stack = (['', 0]) if ($#stack == -1); 582 583 #warn "CSB: blk<$blk> remain<$remain>\n"; 584 # If we are about to drop off the end, pull in more 585 # context. 586 if ($off >= $len) { 587 for (; $remain > 0; $line++) { 588 last if (!defined $lines[$line]); 589 next if ($lines[$line] =~ /^-/); 590 $remain--; 591 $loff = $len; 592 $blk .= $lines[$line] . "\n"; 593 $len = length($blk); 594 $line++; 595 last; 596 } 597 # Bail if there is no further context. 598 #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 599 if ($off >= $len) { 600 last; 601 } 602 } 603 $p = $c; 604 $c = substr($blk, $off, 1); 605 $remainder = substr($blk, $off); 606 607 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 608 609 # Handle nested #if/#else. 610 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 611 push(@stack, [ $type, $level ]); 612 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 613 ($type, $level) = @{$stack[$#stack - 1]}; 614 } elsif ($remainder =~ /^#\s*endif\b/) { 615 ($type, $level) = @{pop(@stack)}; 616 } 617 618 # Statement ends at the ';' or a close '}' at the 619 # outermost level. 620 if ($level == 0 && $c eq ';') { 621 last; 622 } 623 624 # An else is really a conditional as long as its not else if 625 if ($level == 0 && $coff_set == 0 && 626 (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 627 $remainder =~ /^(else)(?:\s|{)/ && 628 $remainder !~ /^else\s+if\b/) { 629 $coff = $off + length($1) - 1; 630 $coff_set = 1; 631 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 632 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 633 } 634 635 if (($type eq '' || $type eq '(') && $c eq '(') { 636 $level++; 637 $type = '('; 638 } 639 if ($type eq '(' && $c eq ')') { 640 $level--; 641 $type = ($level != 0)? '(' : ''; 642 643 if ($level == 0 && $coff < $soff) { 644 $coff = $off; 645 $coff_set = 1; 646 #warn "CSB: mark coff<$coff>\n"; 647 } 648 } 649 if (($type eq '' || $type eq '{') && $c eq '{') { 650 $level++; 651 $type = '{'; 652 } 653 if ($type eq '{' && $c eq '}') { 654 $level--; 655 $type = ($level != 0)? '{' : ''; 656 657 if ($level == 0) { 658 if (substr($blk, $off + 1, 1) eq ';') { 659 $off++; 660 } 661 last; 662 } 663 } 664 $off++; 665 } 666 # We are truly at the end, so shuffle to the next line. 667 if ($off == $len) { 668 $loff = $len + 1; 669 $line++; 670 $remain--; 671 } 672 673 my $statement = substr($blk, $soff, $off - $soff + 1); 674 my $condition = substr($blk, $soff, $coff - $soff + 1); 675 676 #warn "STATEMENT<$statement>\n"; 677 #warn "CONDITION<$condition>\n"; 678 679 #print "coff<$coff> soff<$off> loff<$loff>\n"; 680 681 return ($statement, $condition, 682 $line, $remain + 1, $off - $loff + 1, $level); 683} 684 685sub statement_lines { 686 my ($stmt) = @_; 687 688 # Strip the diff line prefixes and rip blank lines at start and end. 689 $stmt =~ s/(^|\n)./$1/g; 690 $stmt =~ s/^\s*//; 691 $stmt =~ s/\s*$//; 692 693 my @stmt_lines = ($stmt =~ /\n/g); 694 695 return $#stmt_lines + 2; 696} 697 698sub statement_rawlines { 699 my ($stmt) = @_; 700 701 my @stmt_lines = ($stmt =~ /\n/g); 702 703 return $#stmt_lines + 2; 704} 705 706sub statement_block_size { 707 my ($stmt) = @_; 708 709 $stmt =~ s/(^|\n)./$1/g; 710 $stmt =~ s/^\s*\{//; 711 $stmt =~ s/}\s*$//; 712 $stmt =~ s/^\s*//; 713 $stmt =~ s/\s*$//; 714 715 my @stmt_lines = ($stmt =~ /\n/g); 716 my @stmt_statements = ($stmt =~ /;/g); 717 718 my $stmt_lines = $#stmt_lines + 2; 719 my $stmt_statements = $#stmt_statements + 1; 720 721 if ($stmt_lines > $stmt_statements) { 722 return $stmt_lines; 723 } else { 724 return $stmt_statements; 725 } 726} 727 728sub ctx_statement_full { 729 my ($linenr, $remain, $off) = @_; 730 my ($statement, $condition, $level); 731 732 my (@chunks); 733 734 # Grab the first conditional/block pair. 735 ($statement, $condition, $linenr, $remain, $off, $level) = 736 ctx_statement_block($linenr, $remain, $off); 737 #print "F: c<$condition> s<$statement> remain<$remain>\n"; 738 push(@chunks, [ $condition, $statement ]); 739 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 740 return ($level, $linenr, @chunks); 741 } 742 743 # Pull in the following conditional/block pairs and see if they 744 # could continue the statement. 745 for (;;) { 746 ($statement, $condition, $linenr, $remain, $off, $level) = 747 ctx_statement_block($linenr, $remain, $off); 748 #print "C: c<$condition> s<$statement> remain<$remain>\n"; 749 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 750 #print "C: push\n"; 751 push(@chunks, [ $condition, $statement ]); 752 } 753 754 return ($level, $linenr, @chunks); 755} 756 757sub ctx_block_get { 758 my ($linenr, $remain, $outer, $open, $close, $off) = @_; 759 my $line; 760 my $start = $linenr - 1; 761 my $blk = ''; 762 my @o; 763 my @c; 764 my @res = (); 765 766 my $level = 0; 767 my @stack = ($level); 768 for ($line = $start; $remain > 0; $line++) { 769 next if ($rawlines[$line] =~ /^-/); 770 $remain--; 771 772 $blk .= $rawlines[$line]; 773 774 # Handle nested #if/#else. 775 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 776 push(@stack, $level); 777 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 778 $level = $stack[$#stack - 1]; 779 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 780 $level = pop(@stack); 781 } 782 783 foreach my $c (split(//, $lines[$line])) { 784 ##print "C<$c>L<$level><$open$close>O<$off>\n"; 785 if ($off > 0) { 786 $off--; 787 next; 788 } 789 790 if ($c eq $close && $level > 0) { 791 $level--; 792 last if ($level == 0); 793 } elsif ($c eq $open) { 794 $level++; 795 } 796 } 797 798 if (!$outer || $level <= 1) { 799 push(@res, $rawlines[$line]); 800 } 801 802 last if ($level == 0); 803 } 804 805 return ($level, @res); 806} 807sub ctx_block_outer { 808 my ($linenr, $remain) = @_; 809 810 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 811 return @r; 812} 813sub ctx_block { 814 my ($linenr, $remain) = @_; 815 816 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 817 return @r; 818} 819sub ctx_statement { 820 my ($linenr, $remain, $off) = @_; 821 822 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 823 return @r; 824} 825sub ctx_block_level { 826 my ($linenr, $remain) = @_; 827 828 return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 829} 830sub ctx_statement_level { 831 my ($linenr, $remain, $off) = @_; 832 833 return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 834} 835 836sub ctx_locate_comment { 837 my ($first_line, $end_line) = @_; 838 839 # Catch a comment on the end of the line itself. 840 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 841 return $current_comment if (defined $current_comment); 842 843 # Look through the context and try and figure out if there is a 844 # comment. 845 my $in_comment = 0; 846 $current_comment = ''; 847 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 848 my $line = $rawlines[$linenr - 1]; 849 #warn " $line\n"; 850 if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 851 $in_comment = 1; 852 } 853 if ($line =~ m@/\*@) { 854 $in_comment = 1; 855 } 856 if (!$in_comment && $current_comment ne '') { 857 $current_comment = ''; 858 } 859 $current_comment .= $line . "\n" if ($in_comment); 860 if ($line =~ m@\*/@) { 861 $in_comment = 0; 862 } 863 } 864 865 chomp($current_comment); 866 return($current_comment); 867} 868sub ctx_has_comment { 869 my ($first_line, $end_line) = @_; 870 my $cmt = ctx_locate_comment($first_line, $end_line); 871 872 ##print "LINE: $rawlines[$end_line - 1 ]\n"; 873 ##print "CMMT: $cmt\n"; 874 875 return ($cmt ne ''); 876} 877 878sub raw_line { 879 my ($linenr, $cnt) = @_; 880 881 my $offset = $linenr - 1; 882 $cnt++; 883 884 my $line; 885 while ($cnt) { 886 $line = $rawlines[$offset++]; 887 next if (defined($line) && $line =~ /^-/); 888 $cnt--; 889 } 890 891 return $line; 892} 893 894sub cat_vet { 895 my ($vet) = @_; 896 my ($res, $coded); 897 898 $res = ''; 899 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 900 $res .= $1; 901 if ($2 ne '') { 902 $coded = sprintf("^%c", unpack('C', $2) + 64); 903 $res .= $coded; 904 } 905 } 906 $res =~ s/$/\$/; 907 908 return $res; 909} 910 911my $av_preprocessor = 0; 912my $av_pending; 913my @av_paren_type; 914my $av_pend_colon; 915 916sub annotate_reset { 917 $av_preprocessor = 0; 918 $av_pending = '_'; 919 @av_paren_type = ('E'); 920 $av_pend_colon = 'O'; 921} 922 923sub annotate_values { 924 my ($stream, $type) = @_; 925 926 my $res; 927 my $var = '_' x length($stream); 928 my $cur = $stream; 929 930 print "$stream\n" if ($dbg_values > 1); 931 932 while (length($cur)) { 933 @av_paren_type = ('E') if ($#av_paren_type < 0); 934 print " <" . join('', @av_paren_type) . 935 "> <$type> <$av_pending>" if ($dbg_values > 1); 936 if ($cur =~ /^(\s+)/o) { 937 print "WS($1)\n" if ($dbg_values > 1); 938 if ($1 =~ /\n/ && $av_preprocessor) { 939 $type = pop(@av_paren_type); 940 $av_preprocessor = 0; 941 } 942 943 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 944 print "CAST($1)\n" if ($dbg_values > 1); 945 push(@av_paren_type, $type); 946 $type = 'C'; 947 948 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 949 print "DECLARE($1)\n" if ($dbg_values > 1); 950 $type = 'T'; 951 952 } elsif ($cur =~ /^($Modifier)\s*/) { 953 print "MODIFIER($1)\n" if ($dbg_values > 1); 954 $type = 'T'; 955 956 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 957 print "DEFINE($1,$2)\n" if ($dbg_values > 1); 958 $av_preprocessor = 1; 959 push(@av_paren_type, $type); 960 if ($2 ne '') { 961 $av_pending = 'N'; 962 } 963 $type = 'E'; 964 965 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 966 print "UNDEF($1)\n" if ($dbg_values > 1); 967 $av_preprocessor = 1; 968 push(@av_paren_type, $type); 969 970 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 971 print "PRE_START($1)\n" if ($dbg_values > 1); 972 $av_preprocessor = 1; 973 974 push(@av_paren_type, $type); 975 push(@av_paren_type, $type); 976 $type = 'E'; 977 978 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 979 print "PRE_RESTART($1)\n" if ($dbg_values > 1); 980 $av_preprocessor = 1; 981 982 push(@av_paren_type, $av_paren_type[$#av_paren_type]); 983 984 $type = 'E'; 985 986 } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 987 print "PRE_END($1)\n" if ($dbg_values > 1); 988 989 $av_preprocessor = 1; 990 991 # Assume all arms of the conditional end as this 992 # one does, and continue as if the #endif was not here. 993 pop(@av_paren_type); 994 push(@av_paren_type, $type); 995 $type = 'E'; 996 997 } elsif ($cur =~ /^(\\\n)/o) { 998 print "PRECONT($1)\n" if ($dbg_values > 1); 999 1000 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1001 print "ATTR($1)\n" if ($dbg_values > 1); 1002 $av_pending = $type; 1003 $type = 'N'; 1004 1005 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1006 print "SIZEOF($1)\n" if ($dbg_values > 1); 1007 if (defined $2) { 1008 $av_pending = 'V'; 1009 } 1010 $type = 'N'; 1011 1012 } elsif ($cur =~ /^(if|while|for)\b/o) { 1013 print "COND($1)\n" if ($dbg_values > 1); 1014 $av_pending = 'E'; 1015 $type = 'N'; 1016 1017 } elsif ($cur =~/^(case)/o) { 1018 print "CASE($1)\n" if ($dbg_values > 1); 1019 $av_pend_colon = 'C'; 1020 $type = 'N'; 1021 1022 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1023 print "KEYWORD($1)\n" if ($dbg_values > 1); 1024 $type = 'N'; 1025 1026 } elsif ($cur =~ /^(\()/o) { 1027 print "PAREN('$1')\n" if ($dbg_values > 1); 1028 push(@av_paren_type, $av_pending); 1029 $av_pending = '_'; 1030 $type = 'N'; 1031 1032 } elsif ($cur =~ /^(\))/o) { 1033 my $new_type = pop(@av_paren_type); 1034 if ($new_type ne '_') { 1035 $type = $new_type; 1036 print "PAREN('$1') -> $type\n" 1037 if ($dbg_values > 1); 1038 } else { 1039 print "PAREN('$1')\n" if ($dbg_values > 1); 1040 } 1041 1042 } elsif ($cur =~ /^($Ident)\s*\(/o) { 1043 print "FUNC($1)\n" if ($dbg_values > 1); 1044 $type = 'V'; 1045 $av_pending = 'V'; 1046 1047 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 1048 if (defined $2 && $type eq 'C' || $type eq 'T') { 1049 $av_pend_colon = 'B'; 1050 } elsif ($type eq 'E') { 1051 $av_pend_colon = 'L'; 1052 } 1053 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 1054 $type = 'V'; 1055 1056 } elsif ($cur =~ /^($Ident|$Constant)/o) { 1057 print "IDENT($1)\n" if ($dbg_values > 1); 1058 $type = 'V'; 1059 1060 } elsif ($cur =~ /^($Assignment)/o) { 1061 print "ASSIGN($1)\n" if ($dbg_values > 1); 1062 $type = 'N'; 1063 1064 } elsif ($cur =~/^(;|{|})/) { 1065 print "END($1)\n" if ($dbg_values > 1); 1066 $type = 'E'; 1067 $av_pend_colon = 'O'; 1068 1069 } elsif ($cur =~/^(,)/) { 1070 print "COMMA($1)\n" if ($dbg_values > 1); 1071 $type = 'C'; 1072 1073 } elsif ($cur =~ /^(\?)/o) { 1074 print "QUESTION($1)\n" if ($dbg_values > 1); 1075 $type = 'N'; 1076 1077 } elsif ($cur =~ /^(:)/o) { 1078 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 1079 1080 substr($var, length($res), 1, $av_pend_colon); 1081 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 1082 $type = 'E'; 1083 } else { 1084 $type = 'N'; 1085 } 1086 $av_pend_colon = 'O'; 1087 1088 } elsif ($cur =~ /^(\[)/o) { 1089 print "CLOSE($1)\n" if ($dbg_values > 1); 1090 $type = 'N'; 1091 1092 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 1093 my $variant; 1094 1095 print "OPV($1)\n" if ($dbg_values > 1); 1096 if ($type eq 'V') { 1097 $variant = 'B'; 1098 } else { 1099 $variant = 'U'; 1100 } 1101 1102 substr($var, length($res), 1, $variant); 1103 $type = 'N'; 1104 1105 } elsif ($cur =~ /^($Operators)/o) { 1106 print "OP($1)\n" if ($dbg_values > 1); 1107 if ($1 ne '++' && $1 ne '--') { 1108 $type = 'N'; 1109 } 1110 1111 } elsif ($cur =~ /(^.)/o) { 1112 print "C($1)\n" if ($dbg_values > 1); 1113 } 1114 if (defined $1) { 1115 $cur = substr($cur, length($1)); 1116 $res .= $type x length($1); 1117 } 1118 } 1119 1120 return ($res, $var); 1121} 1122 1123sub possible { 1124 my ($possible, $line) = @_; 1125 my $notPermitted = qr{(?: 1126 ^(?: 1127 $Modifier| 1128 $Storage| 1129 $Type| 1130 DEFINE_\S+ 1131 )$| 1132 ^(?: 1133 goto| 1134 return| 1135 case| 1136 else| 1137 asm|__asm__| 1138 do 1139 )(?:\s|$)| 1140 ^(?:typedef|struct|enum)\b| 1141 ^\# 1142 )}x; 1143 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 1144 if ($possible !~ $notPermitted) { 1145 # Check for modifiers. 1146 $possible =~ s/\s*$Storage\s*//g; 1147 $possible =~ s/\s*$Sparse\s*//g; 1148 if ($possible =~ /^\s*$/) { 1149 1150 } elsif ($possible =~ /\s/) { 1151 $possible =~ s/\s*(?:$Type|\#\#)\s*//g; 1152 for my $modifier (split(' ', $possible)) { 1153 if ($modifier !~ $notPermitted) { 1154 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1155 push(@modifierList, $modifier); 1156 } 1157 } 1158 1159 } else { 1160 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1161 push(@typeList, $possible); 1162 } 1163 build_types(); 1164 } else { 1165 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 1166 } 1167} 1168 1169my $prefix = ''; 1170 1171sub report { 1172 my ($level, $msg) = @_; 1173 if (defined $tst_only && $msg !~ /\Q$tst_only\E/) { 1174 return 0; 1175 } 1176 1177 my $output = ''; 1178 $output .= BOLD if $color; 1179 $output .= $prefix; 1180 $output .= RED if $color && $level eq 'ERROR'; 1181 $output .= MAGENTA if $color && $level eq 'WARNING'; 1182 $output .= $level . ':'; 1183 $output .= RESET if $color; 1184 $output .= ' ' . $msg . "\n"; 1185 1186 $output = (split('\n', $output))[0] . "\n" if ($terse); 1187 1188 push(our @report, $output); 1189 1190 return 1; 1191} 1192sub report_dump { 1193 our @report; 1194} 1195sub ERROR { 1196 if (report("ERROR", $_[0])) { 1197 our $clean = 0; 1198 our $cnt_error++; 1199 } 1200} 1201sub WARN { 1202 if (report("WARNING", $_[0])) { 1203 our $clean = 0; 1204 our $cnt_warn++; 1205 } 1206} 1207 1208# According to tests/qtest/bios-tables-test.c: do not 1209# change expected file in the same commit with adding test 1210sub checkfilename { 1211 my ($name, $acpi_testexpected, $acpi_nontestexpected) = @_; 1212 1213 # Note: shell script that rebuilds the expected files is in the same 1214 # directory as files themselves. 1215 # Note: allowed diff list can be changed both when changing expected 1216 # files and when changing tests. 1217 if ($name =~ m#^tests/data/acpi/# and not $name =~ m#^\.sh$#) { 1218 $$acpi_testexpected = $name; 1219 } elsif ($name !~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) { 1220 $$acpi_nontestexpected = $name; 1221 } 1222 if (defined $$acpi_testexpected and defined $$acpi_nontestexpected) { 1223 ERROR("Do not add expected files together with tests, " . 1224 "follow instructions in " . 1225 "tests/qtest/bios-tables-test.c: both " . 1226 $$acpi_testexpected . " and " . 1227 $$acpi_nontestexpected . " found\n"); 1228 } 1229} 1230 1231sub process { 1232 my $filename = shift; 1233 1234 my $linenr=0; 1235 my $prevline=""; 1236 my $prevrawline=""; 1237 my $stashline=""; 1238 my $stashrawline=""; 1239 1240 my $length; 1241 my $indent; 1242 my $previndent=0; 1243 my $stashindent=0; 1244 1245 our $clean = 1; 1246 my $signoff = 0; 1247 my $is_patch = 0; 1248 1249 my $in_header_lines = $file ? 0 : 1; 1250 my $in_commit_log = 0; #Scanning lines before patch 1251 my $non_utf8_charset = 0; 1252 1253 our @report = (); 1254 our $cnt_lines = 0; 1255 our $cnt_error = 0; 1256 our $cnt_warn = 0; 1257 our $cnt_chk = 0; 1258 1259 # Trace the real file/line as we go. 1260 my $realfile = ''; 1261 my $realline = 0; 1262 my $realcnt = 0; 1263 my $here = ''; 1264 my $in_comment = 0; 1265 my $comment_edge = 0; 1266 my $first_line = 0; 1267 my $p1_prefix = ''; 1268 1269 my $prev_values = 'E'; 1270 1271 # suppression flags 1272 my %suppress_ifbraces; 1273 my %suppress_whiletrailers; 1274 my %suppress_export; 1275 1276 my $acpi_testexpected; 1277 my $acpi_nontestexpected; 1278 1279 # Pre-scan the patch sanitizing the lines. 1280 1281 sanitise_line_reset(); 1282 my $line; 1283 foreach my $rawline (@rawlines) { 1284 $linenr++; 1285 $line = $rawline; 1286 1287 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1288 $realline=$1-1; 1289 if (defined $2) { 1290 $realcnt=$3+1; 1291 } else { 1292 $realcnt=1+1; 1293 } 1294 $in_comment = 0; 1295 1296 # Guestimate if this is a continuing comment. Run 1297 # the context looking for a comment "edge". If this 1298 # edge is a close comment then we must be in a comment 1299 # at context start. 1300 my $edge; 1301 my $cnt = $realcnt; 1302 for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 1303 next if (defined $rawlines[$ln - 1] && 1304 $rawlines[$ln - 1] =~ /^-/); 1305 $cnt--; 1306 #print "RAW<$rawlines[$ln - 1]>\n"; 1307 last if (!defined $rawlines[$ln - 1]); 1308 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1309 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1310 ($edge) = $1; 1311 last; 1312 } 1313 } 1314 if (defined $edge && $edge eq '*/') { 1315 $in_comment = 1; 1316 } 1317 1318 # Guestimate if this is a continuing comment. If this 1319 # is the start of a diff block and this line starts 1320 # ' *' then it is very likely a comment. 1321 if (!defined $edge && 1322 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 1323 { 1324 $in_comment = 1; 1325 } 1326 1327 ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 1328 sanitise_line_reset($in_comment); 1329 1330 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 1331 # Standardise the strings and chars within the input to 1332 # simplify matching -- only bother with positive lines. 1333 $line = sanitise_line($rawline); 1334 } 1335 push(@lines, $line); 1336 1337 if ($realcnt > 1) { 1338 $realcnt-- if ($line =~ /^(?:\+| |$)/); 1339 } else { 1340 $realcnt = 0; 1341 } 1342 1343 #print "==>$rawline\n"; 1344 #print "-->$line\n"; 1345 } 1346 1347 $prefix = ''; 1348 1349 $realcnt = 0; 1350 $linenr = 0; 1351 foreach my $line (@lines) { 1352 $linenr++; 1353 1354 my $rawline = $rawlines[$linenr - 1]; 1355 1356#extract the line range in the file after the patch is applied 1357 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1358 $is_patch = 1; 1359 $first_line = $linenr + 1; 1360 $realline=$1-1; 1361 if (defined $2) { 1362 $realcnt=$3+1; 1363 } else { 1364 $realcnt=1+1; 1365 } 1366 annotate_reset(); 1367 $prev_values = 'E'; 1368 1369 %suppress_ifbraces = (); 1370 %suppress_whiletrailers = (); 1371 %suppress_export = (); 1372 next; 1373 1374# track the line number as we move through the hunk, note that 1375# new versions of GNU diff omit the leading space on completely 1376# blank context lines so we need to count that too. 1377 } elsif ($line =~ /^( |\+|$)/) { 1378 $realline++; 1379 $realcnt-- if ($realcnt != 0); 1380 1381 # Measure the line length and indent. 1382 ($length, $indent) = line_stats($rawline); 1383 1384 # Track the previous line. 1385 ($prevline, $stashline) = ($stashline, $line); 1386 ($previndent, $stashindent) = ($stashindent, $indent); 1387 ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 1388 1389 #warn "line<$line>\n"; 1390 1391 } elsif ($realcnt == 1) { 1392 $realcnt--; 1393 } 1394 1395 my $hunk_line = ($realcnt != 0); 1396 1397#make up the handle for any error we report on this line 1398 $prefix = "$filename:$realline: " if ($emacs && $file); 1399 $prefix = "$filename:$linenr: " if ($emacs && !$file); 1400 1401 $here = "#$linenr: " if (!$file); 1402 $here = "#$realline: " if ($file); 1403 1404 # extract the filename as it passes 1405 if ($line =~ /^diff --git.*?(\S+)$/) { 1406 $realfile = $1; 1407 $realfile =~ s@^([^/]*)/@@ if (!$file); 1408 checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); 1409 } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 1410 $realfile = $1; 1411 $realfile =~ s@^([^/]*)/@@ if (!$file); 1412 checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); 1413 1414 $p1_prefix = $1; 1415 if (!$file && $tree && $p1_prefix ne '' && 1416 -e "$root/$p1_prefix") { 1417 WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 1418 } 1419 1420 next; 1421 } 1422 1423 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 1424 1425 my $hereline = "$here\n$rawline\n"; 1426 my $herecurr = "$here\n$rawline\n"; 1427 my $hereprev = "$here\n$prevrawline\n$rawline\n"; 1428 1429 $cnt_lines++ if ($realcnt != 0); 1430 1431# Check for incorrect file permissions 1432 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 1433 my $permhere = $here . "FILE: $realfile\n"; 1434 if ($realfile =~ /(\bMakefile(?:\.objs)?|\.c|\.cc|\.cpp|\.h|\.mak|\.[sS])$/) { 1435 ERROR("do not set execute permissions for source files\n" . $permhere); 1436 } 1437 } 1438 1439# Only allow Python 3 interpreter 1440 if ($realline == 1 && 1441 $line =~ /^\+#!\ *\/usr\/bin\/(?:env )?python$/) { 1442 ERROR("please use python3 interpreter\n" . $herecurr); 1443 } 1444 1445# Accept git diff extended headers as valid patches 1446 if ($line =~ /^(?:rename|copy) (?:from|to) [\w\/\.\-]+\s*$/) { 1447 $is_patch = 1; 1448 } 1449 1450 if ($line =~ /^(Author|From): .*noreply.*/) { 1451 ERROR("Real email adress is needed\n" . $herecurr); 1452 } 1453 1454#check the patch for a signoff: 1455 if ($line =~ /^\s*signed-off-by:/i) { 1456 # This is a signoff, if ugly, so do not double report. 1457 $in_commit_log = 0; 1458 1459 if (!($line =~ /^\s*Signed-off-by:/)) { 1460 ERROR("The correct form is \"Signed-off-by\"\n" . 1461 $herecurr); 1462 } 1463 if ($line =~ /^\s*signed-off-by:\S/i) { 1464 ERROR("space required after Signed-off-by:\n" . 1465 $herecurr); 1466 } 1467 } 1468 1469# Check for wrappage within a valid hunk of the file 1470 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 1471 ERROR("patch seems to be corrupt (line wrapped?)\n" . 1472 $herecurr) if (!$emitted_corrupt++); 1473 } 1474 1475# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1476 if (($realfile =~ /^$/ || $line =~ /^\+/) && 1477 $rawline !~ m/^$UTF8*$/) { 1478 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 1479 1480 my $blank = copy_spacing($rawline); 1481 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 1482 my $hereptr = "$hereline$ptr\n"; 1483 1484 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 1485 } 1486 1487 if ($rawline =~ m/$UTF8_MOJIBAKE/) { 1488 ERROR("Doubly-encoded UTF-8\n" . $herecurr); 1489 } 1490# Check if it's the start of a commit log 1491# (not a header line and we haven't seen the patch filename) 1492 if ($in_header_lines && $realfile =~ /^$/ && 1493 !($rawline =~ /^\s+\S/ || 1494 $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) { 1495 $in_header_lines = 0; 1496 $in_commit_log = 1; 1497 } 1498 1499# Check if there is UTF-8 in a commit log when a mail header has explicitly 1500# declined it, i.e defined some charset where it is missing. 1501 if ($in_header_lines && 1502 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 1503 $1 !~ /utf-8/i) { 1504 $non_utf8_charset = 1; 1505 } 1506 1507 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 1508 $rawline =~ /$NON_ASCII_UTF8/) { 1509 WARN("8-bit UTF-8 used in possible commit log\n" . $herecurr); 1510 } 1511 1512# ignore non-hunk lines and lines being removed 1513 next if (!$hunk_line || $line =~ /^-/); 1514 1515# ignore files that are being periodically imported from Linux 1516 next if ($realfile =~ /^(linux-headers|include\/standard-headers)\//); 1517 1518#trailing whitespace 1519 if ($line =~ /^\+.*\015/) { 1520 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1521 ERROR("DOS line endings\n" . $herevet); 1522 1523 } elsif ($realfile =~ /^docs\/.+\.txt/ || 1524 $realfile =~ /^docs\/.+\.md/) { 1525 if ($rawline =~ /^\+\s+$/ && $rawline !~ /^\+ {4}$/) { 1526 # TODO: properly check we're in a code block 1527 # (surrounding text is 4-column aligned) 1528 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1529 ERROR("code blocks in documentation should have " . 1530 "empty lines with exactly 4 columns of " . 1531 "whitespace\n" . $herevet); 1532 } 1533 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1534 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1535 ERROR("trailing whitespace\n" . $herevet); 1536 $rpt_cleaners = 1; 1537 } 1538 1539# checks for trace-events files 1540 if ($realfile =~ /trace-events$/ && $line =~ /^\+/) { 1541 if ($rawline =~ /%[-+ 0]*#/) { 1542 ERROR("Don't use '#' flag of printf format ('%#') in " . 1543 "trace-events, use '0x' prefix instead\n" . $herecurr); 1544 } else { 1545 my $hex = 1546 qr/%[-+ *.0-9]*([hljztL]|ll|hh)?(x|X|"\s*PRI[xX][^"]*"?)/; 1547 1548 # don't consider groups splitted by [.:/ ], like 2A.20:12ab 1549 my $tmpline = $rawline; 1550 $tmpline =~ s/($hex[.:\/ ])+$hex//g; 1551 1552 if ($tmpline =~ /(?<!0x)$hex/) { 1553 ERROR("Hex numbers must be prefixed with '0x'\n" . 1554 $herecurr); 1555 } 1556 } 1557 } 1558 1559# check we are in a valid source file if not then ignore this hunk 1560 next if ($realfile !~ /$SrcFile/); 1561 1562#120 column limit; exempt URLs, if no other words on line 1563 if ($line =~ /^\+/ && 1564 !($line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && 1565 !($rawline =~ /^[^[:alnum:]]*https?:\S*$/) && 1566 $length > 80 && 1567 $realfile !~ /\/tests\//) 1568 { 1569 if ($length > 120) { 1570 ERROR("line over 120 characters\n" . $herecurr); 1571 } else { 1572 WARN("line over 80 characters\n" . $herecurr); 1573 } 1574 } 1575 1576# check for spaces before a quoted newline 1577 if ($rawline =~ /^.*\".*\s\\n/) { 1578 ERROR("unnecessary whitespace before a quoted newline\n" . $herecurr); 1579 } 1580 1581# check for adding lines without a newline. 1582 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1583 ERROR("adding a line without newline at end of file\n" . $herecurr); 1584 } 1585 1586# check for RCS/CVS revision markers 1587 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|\b)/) { 1588 ERROR("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 1589 } 1590 1591# check we are in a valid C source file if not then ignore this hunk 1592 next if ($realfile !~ /\.(h|c|cpp)$/); 1593 1594# Block comment styles 1595 1596 # Block comments use /* on a line of its own 1597 if ($rawline !~ m@^\+.*/\*.*\*/[ \t)}]*$@ && #inline /*...*/ 1598 $rawline =~ m@^\+.*/\*[*-]?+[ \t]*[^ \t]@) { # /* or /** or /*- non-blank 1599 WARN("Block comments use a leading /* on a separate line\n" . $herecurr); 1600 } 1601 1602# Block comments use * on subsequent lines 1603 if ($prevline =~ /$;[ \t]*$/ && #ends in comment 1604 $prevrawline =~ /^\+.*?\/\*/ && #starting /* 1605 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 1606 $rawline =~ /^\+/ && #line is new 1607 $rawline !~ /^\+[ \t]*\*/) { #no leading * 1608 WARN("Block comments use * on subsequent lines\n" . $hereprev); 1609 } 1610 1611# Block comments use */ on trailing lines 1612 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 1613 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 1614 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 1615 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 1616 WARN("Block comments use a trailing */ on a separate line\n" . $herecurr); 1617 } 1618 1619# Block comment * alignment 1620 if ($prevline =~ /$;[ \t]*$/ && #ends in comment 1621 $line =~ /^\+[ \t]*$;/ && #leading comment 1622 $rawline =~ /^\+[ \t]*\*/ && #leading * 1623 (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 1624 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 1625 $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 1626 my $oldindent; 1627 $prevrawline =~ m@^\+([ \t]*/?)\*@; 1628 if (defined($1)) { 1629 $oldindent = expand_tabs($1); 1630 } else { 1631 $prevrawline =~ m@^\+(.*/?)\*@; 1632 $oldindent = expand_tabs($1); 1633 } 1634 $rawline =~ m@^\+([ \t]*)\*@; 1635 my $newindent = $1; 1636 $newindent = expand_tabs($newindent); 1637 if (length($oldindent) ne length($newindent)) { 1638 WARN("Block comments should align the * on each line\n" . $hereprev); 1639 } 1640 } 1641 1642# Check for potential 'bare' types 1643 my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 1644 $realline_next); 1645 if ($realcnt && $line =~ /.\s*\S/) { 1646 ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 1647 ctx_statement_block($linenr, $realcnt, 0); 1648 $stat =~ s/\n./\n /g; 1649 $cond =~ s/\n./\n /g; 1650 1651 # Find the real next line. 1652 $realline_next = $line_nr_next; 1653 if (defined $realline_next && 1654 (!defined $lines[$realline_next - 1] || 1655 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 1656 $realline_next++; 1657 } 1658 1659 my $s = $stat; 1660 $s =~ s/{.*$//s; 1661 1662 # Ignore goto labels. 1663 if ($s =~ /$Ident:\*$/s) { 1664 1665 # Ignore functions being called 1666 } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 1667 1668 } elsif ($s =~ /^.\s*else\b/s) { 1669 1670 # declarations always start with types 1671 } 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) { 1672 my $type = $1; 1673 $type =~ s/\s+/ /g; 1674 possible($type, "A:" . $s); 1675 1676 # definitions in global scope can only start with types 1677 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 1678 possible($1, "B:" . $s); 1679 } 1680 1681 # any (foo ... *) is a pointer cast, and foo is a type 1682 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 1683 possible($1, "C:" . $s); 1684 } 1685 1686 # Check for any sort of function declaration. 1687 # int foo(something bar, other baz); 1688 # void (*store_gdt)(x86_descr_ptr *); 1689 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 1690 my ($name_len) = length($1); 1691 1692 my $ctx = $s; 1693 substr($ctx, 0, $name_len + 1, ''); 1694 $ctx =~ s/\)[^\)]*$//; 1695 1696 for my $arg (split(/\s*,\s*/, $ctx)) { 1697 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 1698 1699 possible($1, "D:" . $s); 1700 } 1701 } 1702 } 1703 1704 } 1705 1706# 1707# Checks which may be anchored in the context. 1708# 1709 1710# Check for switch () and associated case and default 1711# statements should be at the same indent. 1712 if ($line=~/\bswitch\s*\(.*\)/) { 1713 my $err = ''; 1714 my $sep = ''; 1715 my @ctx = ctx_block_outer($linenr, $realcnt); 1716 shift(@ctx); 1717 for my $ctx (@ctx) { 1718 my ($clen, $cindent) = line_stats($ctx); 1719 if ($ctx =~ /^\+\s*(case\s+|default:)/ && 1720 $indent != $cindent) { 1721 $err .= "$sep$ctx\n"; 1722 $sep = ''; 1723 } else { 1724 $sep = "[...]\n"; 1725 } 1726 } 1727 if ($err ne '') { 1728 ERROR("switch and case should be at the same indent\n$hereline$err"); 1729 } 1730 } 1731 1732# if/while/etc brace do not go on next line, unless defining a do while loop, 1733# or if that brace on the next line is for something else 1734 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 1735 my $pre_ctx = "$1$2"; 1736 1737 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 1738 my $ctx_cnt = $realcnt - $#ctx - 1; 1739 my $ctx = join("\n", @ctx); 1740 1741 my $ctx_ln = $linenr; 1742 my $ctx_skip = $realcnt; 1743 1744 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 1745 defined $lines[$ctx_ln - 1] && 1746 $lines[$ctx_ln - 1] =~ /^-/)) { 1747 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 1748 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 1749 $ctx_ln++; 1750 } 1751 1752 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 1753 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 1754 1755 # The length of the "previous line" is checked against 80 because it 1756 # includes the + at the beginning of the line (if the actual line has 1757 # 79 or 80 characters, it is no longer possible to add a space and an 1758 # opening brace there) 1759 if ($#ctx == 0 && $ctx !~ /{\s*/ && 1760 defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*\{/ && 1761 defined($lines[$ctx_ln - 2]) && length($lines[$ctx_ln - 2]) < 80) { 1762 ERROR("that open brace { should be on the previous line\n" . 1763 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 1764 } 1765 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 1766 $ctx =~ /\)\s*\;\s*$/ && 1767 defined $lines[$ctx_ln - 1]) 1768 { 1769 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 1770 if ($nindent > $indent) { 1771 ERROR("trailing semicolon indicates no statements, indent implies otherwise\n" . 1772 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 1773 } 1774 } 1775 } 1776 1777# 'do ... while (0/false)' only makes sense in macros, without trailing ';' 1778 if ($line =~ /while\s*\((0|false)\);/) { 1779 ERROR("suspicious ; after while (0)\n" . $herecurr); 1780 } 1781 1782# Check superfluous trailing ';' 1783 if ($line =~ /;;$/) { 1784 ERROR("superfluous trailing semicolon\n" . $herecurr); 1785 } 1786 1787# Check relative indent for conditionals and blocks. 1788 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 1789 my ($s, $c) = ($stat, $cond); 1790 1791 substr($s, 0, length($c), ''); 1792 1793 # Make sure we remove the line prefixes as we have 1794 # none on the first line, and are going to re-add them 1795 # where necessary. 1796 $s =~ s/\n./\n/gs; 1797 1798 # Find out how long the conditional actually is. 1799 my @newlines = ($c =~ /\n/gs); 1800 my $cond_lines = 1 + $#newlines; 1801 1802 # We want to check the first line inside the block 1803 # starting at the end of the conditional, so remove: 1804 # 1) any blank line termination 1805 # 2) any opening brace { on end of the line 1806 # 3) any do (...) { 1807 my $continuation = 0; 1808 my $check = 0; 1809 $s =~ s/^.*\bdo\b//; 1810 $s =~ s/^\s*\{//; 1811 if ($s =~ s/^\s*\\//) { 1812 $continuation = 1; 1813 } 1814 if ($s =~ s/^\s*?\n//) { 1815 $check = 1; 1816 $cond_lines++; 1817 } 1818 1819 # Also ignore a loop construct at the end of a 1820 # preprocessor statement. 1821 if (($prevline =~ /^.\s*#\s*define\s/ || 1822 $prevline =~ /\\\s*$/) && $continuation == 0) { 1823 $check = 0; 1824 } 1825 1826 my $cond_ptr = -1; 1827 $continuation = 0; 1828 while ($cond_ptr != $cond_lines) { 1829 $cond_ptr = $cond_lines; 1830 1831 # If we see an #else/#elif then the code 1832 # is not linear. 1833 if ($s =~ /^\s*\#\s*(?:else|elif)/) { 1834 $check = 0; 1835 } 1836 1837 # Ignore: 1838 # 1) blank lines, they should be at 0, 1839 # 2) preprocessor lines, and 1840 # 3) labels. 1841 if ($continuation || 1842 $s =~ /^\s*?\n/ || 1843 $s =~ /^\s*#\s*?/ || 1844 $s =~ /^\s*$Ident\s*:/) { 1845 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 1846 if ($s =~ s/^.*?\n//) { 1847 $cond_lines++; 1848 } 1849 } 1850 } 1851 1852 my (undef, $sindent) = line_stats("+" . $s); 1853 my $stat_real = raw_line($linenr, $cond_lines); 1854 1855 # Check if either of these lines are modified, else 1856 # this is not this patch's fault. 1857 if (!defined($stat_real) || 1858 $stat !~ /^\+/ && $stat_real !~ /^\+/) { 1859 $check = 0; 1860 } 1861 if (defined($stat_real) && $cond_lines > 1) { 1862 $stat_real = "[...]\n$stat_real"; 1863 } 1864 1865 #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"; 1866 1867 if ($check && (($sindent % 4) != 0 || 1868 ($sindent <= $indent && $s ne ''))) { 1869 ERROR("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 1870 } 1871 } 1872 1873 # Track the 'values' across context and added lines. 1874 my $opline = $line; $opline =~ s/^./ /; 1875 my ($curr_values, $curr_vars) = 1876 annotate_values($opline . "\n", $prev_values); 1877 $curr_values = $prev_values . $curr_values; 1878 if ($dbg_values) { 1879 my $outline = $opline; $outline =~ s/\t/ /g; 1880 print "$linenr > .$outline\n"; 1881 print "$linenr > $curr_values\n"; 1882 print "$linenr > $curr_vars\n"; 1883 } 1884 $prev_values = substr($curr_values, -1); 1885 1886#ignore lines not being added 1887 if ($line=~/^[^\+]/) {next;} 1888 1889# TEST: allow direct testing of the type matcher. 1890 if ($dbg_type) { 1891 if ($line =~ /^.\s*$Declare\s*$/) { 1892 ERROR("TEST: is type\n" . $herecurr); 1893 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 1894 ERROR("TEST: is not type ($1 is)\n". $herecurr); 1895 } 1896 next; 1897 } 1898# TEST: allow direct testing of the attribute matcher. 1899 if ($dbg_attr) { 1900 if ($line =~ /^.\s*$Modifier\s*$/) { 1901 ERROR("TEST: is attr\n" . $herecurr); 1902 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 1903 ERROR("TEST: is not attr ($1 is)\n". $herecurr); 1904 } 1905 next; 1906 } 1907 1908# check for initialisation to aggregates open brace on the next line 1909 if ($line =~ /^.\s*\{/ && 1910 $prevline =~ /(?:^|[^=])=\s*$/) { 1911 ERROR("that open brace { should be on the previous line\n" . $hereprev); 1912 } 1913 1914# 1915# Checks which are anchored on the added line. 1916# 1917 1918# check for malformed paths in #include statements (uses RAW line) 1919 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 1920 my $path = $1; 1921 if ($path =~ m{//}) { 1922 ERROR("malformed #include filename\n" . 1923 $herecurr); 1924 } 1925 } 1926 1927# Remove C99 comments. 1928 $line =~ s@//.*@@; 1929 $opline =~ s@//.*@@; 1930 1931# check for global initialisers. 1932# if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 1933# ERROR("do not initialise globals to 0 or NULL\n" . 1934# $herecurr); 1935# } 1936# check for static initialisers. 1937# if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { 1938# ERROR("do not initialise statics to 0 or NULL\n" . 1939# $herecurr); 1940# } 1941 1942# * goes on variable not on type 1943 # (char*[ const]) 1944 if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { 1945 my ($from, $to) = ($1, $1); 1946 1947 # Should start with a space. 1948 $to =~ s/^(\S)/ $1/; 1949 # Should not end with a space. 1950 $to =~ s/\s+$//; 1951 # '*'s should not have spaces between. 1952 while ($to =~ s/\*\s+\*/\*\*/) { 1953 } 1954 1955 #print "from<$from> to<$to>\n"; 1956 if ($from ne $to) { 1957 ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); 1958 } 1959 } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { 1960 my ($from, $to, $ident) = ($1, $1, $2); 1961 1962 # Should start with a space. 1963 $to =~ s/^(\S)/ $1/; 1964 # Should not end with a space. 1965 $to =~ s/\s+$//; 1966 # '*'s should not have spaces between. 1967 while ($to =~ s/\*\s+\*/\*\*/) { 1968 } 1969 # Modifiers should have spaces. 1970 $to =~ s/(\b$Modifier$)/$1 /; 1971 1972 #print "from<$from> to<$to> ident<$ident>\n"; 1973 if ($from ne $to && $ident !~ /^$Modifier$/) { 1974 ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); 1975 } 1976 } 1977 1978# function brace can't be on same line, except for #defines of do while, 1979# or if closed on same line 1980 if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and 1981 !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 1982 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 1983 } 1984 1985# missing space after union, struct or enum definition 1986 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { 1987 ERROR("missing space after $1 definition\n" . $herecurr); 1988 } 1989 1990# check for spacing round square brackets; allowed: 1991# 1. with a type on the left -- int [] a; 1992# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 1993# 3. inside a curly brace -- = { [0...10] = 5 } 1994# 4. after a comma -- [1] = 5, [2] = 6 1995# 5. in a macro definition -- #define abc(x) [x] = y 1996 while ($line =~ /(.*?\s)\[/g) { 1997 my ($where, $prefix) = ($-[1], $1); 1998 if ($prefix !~ /$Type\s+$/ && 1999 ($where != 0 || $prefix !~ /^.\s+$/) && 2000 $prefix !~ /\#\s*define[^(]*\([^)]*\)\s+$/ && 2001 $prefix !~ /[,{:]\s+$/) { 2002 ERROR("space prohibited before open square bracket '['\n" . $herecurr); 2003 } 2004 } 2005 2006# check for spaces between functions and their parentheses. 2007 while ($line =~ /($Ident)\s+\(/g) { 2008 my $name = $1; 2009 my $ctx_before = substr($line, 0, $-[1]); 2010 my $ctx = "$ctx_before$name"; 2011 2012 # Ignore those directives where spaces _are_ permitted. 2013 if ($name =~ /^(?: 2014 if|for|while|switch|return|case| 2015 volatile|__volatile__|coroutine_fn| 2016 __attribute__|format|__extension__| 2017 asm|__asm__)$/x) 2018 { 2019 2020 # Ignore 'catch (...)' in C++ 2021 } elsif ($name =~ /^catch$/ && $realfile =~ /(\.cpp|\.h)$/) { 2022 2023 # cpp #define statements have non-optional spaces, ie 2024 # if there is a space between the name and the open 2025 # parenthesis it is simply not a parameter group. 2026 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 2027 2028 # cpp #elif statement condition may start with a ( 2029 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 2030 2031 # If this whole things ends with a type its most 2032 # likely a typedef for a function. 2033 } elsif ($ctx =~ /$Type$/) { 2034 2035 } else { 2036 ERROR("space prohibited between function name and open parenthesis '('\n" . $herecurr); 2037 } 2038 } 2039# Check operator spacing. 2040 if (!($line=~/\#\s*include/)) { 2041 my $ops = qr{ 2042 <<=|>>=|<=|>=|==|!=| 2043 \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 2044 =>|->|<<|>>|<|>|=|!|~| 2045 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 2046 \?|::|: 2047 }x; 2048 my @elements = split(/($ops|;)/, $opline); 2049 my $off = 0; 2050 2051 my $blank = copy_spacing($opline); 2052 2053 for (my $n = 0; $n < $#elements; $n += 2) { 2054 $off += length($elements[$n]); 2055 2056 # Pick up the preceding and succeeding characters. 2057 my $ca = substr($opline, 0, $off); 2058 my $cc = ''; 2059 if (length($opline) >= ($off + length($elements[$n + 1]))) { 2060 $cc = substr($opline, $off + length($elements[$n + 1])); 2061 } 2062 my $cb = "$ca$;$cc"; 2063 2064 my $a = ''; 2065 $a = 'V' if ($elements[$n] ne ''); 2066 $a = 'W' if ($elements[$n] =~ /\s$/); 2067 $a = 'C' if ($elements[$n] =~ /$;$/); 2068 $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 2069 $a = 'O' if ($elements[$n] eq ''); 2070 $a = 'E' if ($ca =~ /^\s*$/); 2071 2072 my $op = $elements[$n + 1]; 2073 2074 my $c = ''; 2075 if (defined $elements[$n + 2]) { 2076 $c = 'V' if ($elements[$n + 2] ne ''); 2077 $c = 'W' if ($elements[$n + 2] =~ /^\s/); 2078 $c = 'C' if ($elements[$n + 2] =~ /^$;/); 2079 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 2080 $c = 'O' if ($elements[$n + 2] eq ''); 2081 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 2082 } else { 2083 $c = 'E'; 2084 } 2085 2086 my $ctx = "${a}x${c}"; 2087 2088 my $at = "(ctx:$ctx)"; 2089 2090 my $ptr = substr($blank, 0, $off) . "^"; 2091 my $hereptr = "$hereline$ptr\n"; 2092 2093 # Pull out the value of this operator. 2094 my $op_type = substr($curr_values, $off + 1, 1); 2095 2096 # Get the full operator variant. 2097 my $opv = $op . substr($curr_vars, $off, 1); 2098 2099 # Ignore operators passed as parameters. 2100 if ($op_type ne 'V' && 2101 $ca =~ /\s$/ && $cc =~ /^\s*,/) { 2102 2103# # Ignore comments 2104# } elsif ($op =~ /^$;+$/) { 2105 2106 # ; should have either the end of line or a space or \ after it 2107 } elsif ($op eq ';') { 2108 if ($ctx !~ /.x[WEBC]/ && 2109 $cc !~ /^\\/ && $cc !~ /^;/) { 2110 ERROR("space required after that '$op' $at\n" . $hereptr); 2111 } 2112 2113 # // is a comment 2114 } elsif ($op eq '//') { 2115 2116 # Ignore : used in class declaration in C++ 2117 } elsif ($opv eq ':B' && $ctx =~ /Wx[WE]/ && 2118 $line =~ /class/ && $realfile =~ /(\.cpp|\.h)$/) { 2119 2120 # No spaces for: 2121 # -> 2122 # : when part of a bitfield 2123 } elsif ($op eq '->' || $opv eq ':B') { 2124 if ($ctx =~ /Wx.|.xW/) { 2125 ERROR("spaces prohibited around that '$op' $at\n" . $hereptr); 2126 } 2127 2128 # , must have a space on the right. 2129 # not required when having a single },{ on one line 2130 } elsif ($op eq ',') { 2131 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && 2132 ($elements[$n] . $elements[$n + 2]) !~ " *}\\{") { 2133 ERROR("space required after that '$op' $at\n" . $hereptr); 2134 } 2135 2136 # '*' as part of a type definition -- reported already. 2137 } elsif ($opv eq '*_') { 2138 #warn "'*' is part of type\n"; 2139 2140 # unary operators should have a space before and 2141 # none after. May be left adjacent to another 2142 # unary operator, or a cast 2143 } elsif ($op eq '!' || $op eq '~' || 2144 $opv eq '*U' || $opv eq '-U' || 2145 $opv eq '&U' || $opv eq '&&U') { 2146 if ($op eq '~' && $ca =~ /::$/ && $realfile =~ /(\.cpp|\.h)$/) { 2147 # '~' used as a name of Destructor 2148 2149 } elsif ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 2150 ERROR("space required before that '$op' $at\n" . $hereptr); 2151 } 2152 if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 2153 # A unary '*' may be const 2154 2155 } elsif ($ctx =~ /.xW/) { 2156 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2157 } 2158 2159 # unary ++ and unary -- are allowed no space on one side. 2160 } elsif ($op eq '++' or $op eq '--') { 2161 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 2162 ERROR("space required one side of that '$op' $at\n" . $hereptr); 2163 } 2164 if ($ctx =~ /Wx[BE]/ || 2165 ($ctx =~ /Wx./ && $cc =~ /^;/)) { 2166 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2167 } 2168 if ($ctx =~ /ExW/) { 2169 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2170 } 2171 2172 # A colon needs no spaces before when it is 2173 # terminating a case value or a label. 2174 } elsif ($opv eq ':C' || $opv eq ':L') { 2175 if ($ctx =~ /Wx./) { 2176 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2177 } 2178 2179 # All the others need spaces both sides. 2180 } elsif ($ctx !~ /[EWC]x[CWE]/) { 2181 my $ok = 0; 2182 2183 if ($realfile =~ /\.cpp|\.h$/) { 2184 # Ignore template arguments <...> in C++ 2185 if (($op eq '<' || $op eq '>') && $line =~ /<.*>/) { 2186 $ok = 1; 2187 } 2188 2189 # Ignore :: in C++ 2190 if ($op eq '::') { 2191 $ok = 1; 2192 } 2193 } 2194 2195 # Ignore email addresses <foo@bar> 2196 if (($op eq '<' && 2197 $cc =~ /^\S+\@\S+>/) || 2198 ($op eq '>' && 2199 $ca =~ /<\S+\@\S+$/)) 2200 { 2201 $ok = 1; 2202 } 2203 2204 # Ignore ?: 2205 if (($opv eq ':O' && $ca =~ /\?$/) || 2206 ($op eq '?' && $cc =~ /^:/)) { 2207 $ok = 1; 2208 } 2209 2210 if ($ok == 0) { 2211 ERROR("spaces required around that '$op' $at\n" . $hereptr); 2212 } 2213 } 2214 $off += length($elements[$n + 1]); 2215 } 2216 } 2217 2218#need space before brace following if, while, etc 2219 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 2220 $line =~ /do\{/) { 2221 ERROR("space required before the open brace '{'\n" . $herecurr); 2222 } 2223 2224# closing brace should have a space following it when it has anything 2225# on the line 2226 if ($line =~ /}(?!(?:,|;|\)))\S/) { 2227 ERROR("space required after that close brace '}'\n" . $herecurr); 2228 } 2229 2230# check spacing on square brackets 2231 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 2232 ERROR("space prohibited after that open square bracket '['\n" . $herecurr); 2233 } 2234 if ($line =~ /\s\]/) { 2235 ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); 2236 } 2237 2238# check spacing on parentheses 2239 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 2240 $line !~ /for\s*\(\s+;/) { 2241 ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); 2242 } 2243 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 2244 $line !~ /for\s*\(.*;\s+\)/ && 2245 $line !~ /:\s+\)/) { 2246 ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); 2247 } 2248 2249 if ($line =~ /^.\s*(Q(?:S?LIST|SIMPLEQ|TAILQ)_HEAD)\s*\(\s*[^,]/ && 2250 $line !~ /^.typedef/) { 2251 ERROR("named $1 should be typedefed separately\n" . $herecurr); 2252 } 2253 2254# Return needs parens 2255 if ($line =~ /^.\s*return [^(]/) { 2256 ERROR("parentheses required on return\n" . $herecurr); 2257 } 2258 2259# Need a space before open parenthesis after if, while etc 2260 if ($line=~/\b(if|while|for|switch|return)\(/) { 2261 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2262 } 2263 2264# Check for illegal assignment in if conditional -- and check for trailing 2265# statements after the conditional. 2266 if ($line =~ /do\s*(?!{)/) { 2267 my ($stat_next) = ctx_statement_block($line_nr_next, 2268 $remain_next, $off_next); 2269 $stat_next =~ s/\n./\n /g; 2270 ##print "stat<$stat> stat_next<$stat_next>\n"; 2271 2272 if ($stat_next =~ /^\s*while\b/) { 2273 # If the statement carries leading newlines, 2274 # then count those as offsets. 2275 my ($whitespace) = 2276 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 2277 my $offset = 2278 statement_rawlines($whitespace) - 1; 2279 2280 $suppress_whiletrailers{$line_nr_next + 2281 $offset} = 1; 2282 } 2283 } 2284 if (!defined $suppress_whiletrailers{$linenr} && 2285 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 2286 my ($s, $c) = ($stat, $cond); 2287 2288# if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 2289# ERROR("do not use assignment in if condition\n" . $herecurr); 2290# } 2291 2292 # Find out what is on the end of the line after the 2293 # conditional. 2294 substr($s, 0, length($c), ''); 2295 $s =~ s/\n.*//g; 2296 $s =~ s/$;//g; # Remove any comments 2297 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 2298 $c !~ /}\s*while\s*/) 2299 { 2300 # Find out how long the conditional actually is. 2301 my @newlines = ($c =~ /\n/gs); 2302 my $cond_lines = 1 + $#newlines; 2303 my $stat_real = ''; 2304 2305 $stat_real = raw_line($linenr, $cond_lines) 2306 . "\n" if ($cond_lines); 2307 if (defined($stat_real) && $cond_lines > 1) { 2308 $stat_real = "[...]\n$stat_real"; 2309 } 2310 2311 ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real); 2312 } 2313 } 2314 2315# Check for bitwise tests written as boolean 2316 if ($line =~ / 2317 (?: 2318 (?:\[|\(|\&\&|\|\|) 2319 \s*0[xX][0-9]+\s* 2320 (?:\&\&|\|\|) 2321 | 2322 (?:\&\&|\|\|) 2323 \s*0[xX][0-9]+\s* 2324 (?:\&\&|\|\||\)|\]) 2325 )/x) 2326 { 2327 ERROR("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 2328 } 2329 2330# if and else should not have general statements after it 2331 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 2332 my $s = $1; 2333 $s =~ s/$;//g; # Remove any comments 2334 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 2335 ERROR("trailing statements should be on next line\n" . $herecurr); 2336 } 2337 } 2338# if should not continue a brace 2339 if ($line =~ /}\s*if\b/) { 2340 ERROR("trailing statements should be on next line\n" . 2341 $herecurr); 2342 } 2343# case and default should not have general statements after them 2344 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 2345 $line !~ /\G(?: 2346 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 2347 \s*return\s+ 2348 )/xg) 2349 { 2350 ERROR("trailing statements should be on next line\n" . $herecurr); 2351 } 2352 2353 # Check for }<nl>else {, these must be at the same 2354 # indent level to be relevant to each other. 2355 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 2356 $previndent == $indent) { 2357 ERROR("else should follow close brace '}'\n" . $hereprev); 2358 } 2359 2360 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 2361 $previndent == $indent) { 2362 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 2363 2364 # Find out what is on the end of the line after the 2365 # conditional. 2366 substr($s, 0, length($c), ''); 2367 $s =~ s/\n.*//g; 2368 2369 if ($s =~ /^\s*;/) { 2370 ERROR("while should follow close brace '}'\n" . $hereprev); 2371 } 2372 } 2373 2374#no spaces allowed after \ in define 2375 if ($line=~/\#\s*define.*\\\s$/) { 2376 ERROR("Whitespace after \\ makes next lines useless\n" . $herecurr); 2377 } 2378 2379# multi-statement macros should be enclosed in a do while loop, grab the 2380# first statement and ensure its the whole macro if its not enclosed 2381# in a known good container 2382 if ($realfile !~ m@/vmlinux.lds.h$@ && 2383 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 2384 my $ln = $linenr; 2385 my $cnt = $realcnt; 2386 my ($off, $dstat, $dcond, $rest); 2387 my $ctx = ''; 2388 2389 my $args = defined($1); 2390 2391 # Find the end of the macro and limit our statement 2392 # search to that. 2393 while ($cnt > 0 && defined $lines[$ln - 1] && 2394 $lines[$ln - 1] =~ /^(?:-|..*\\$)/) 2395 { 2396 $ctx .= $rawlines[$ln - 1] . "\n"; 2397 $cnt-- if ($lines[$ln - 1] !~ /^-/); 2398 $ln++; 2399 } 2400 $ctx .= $rawlines[$ln - 1]; 2401 2402 ($dstat, $dcond, $ln, $cnt, $off) = 2403 ctx_statement_block($linenr, $ln - $linenr + 1, 0); 2404 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 2405 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 2406 2407 # Extract the remainder of the define (if any) and 2408 # rip off surrounding spaces, and trailing \'s. 2409 $rest = ''; 2410 while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { 2411 #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; 2412 if ($off != 0 || $lines[$ln - 1] !~ /^-/) { 2413 $rest .= substr($lines[$ln - 1], $off) . "\n"; 2414 $cnt--; 2415 } 2416 $ln++; 2417 $off = 0; 2418 } 2419 $rest =~ s/\\\n.//g; 2420 $rest =~ s/^\s*//s; 2421 $rest =~ s/\s*$//s; 2422 2423 # Clean up the original statement. 2424 if ($args) { 2425 substr($dstat, 0, length($dcond), ''); 2426 } else { 2427 $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; 2428 } 2429 $dstat =~ s/$;//g; 2430 $dstat =~ s/\\\n.//g; 2431 $dstat =~ s/^\s*//s; 2432 $dstat =~ s/\s*$//s; 2433 2434 # Flatten any parentheses and braces 2435 while ($dstat =~ s/\([^\(\)]*\)/1/ || 2436 $dstat =~ s/\{[^\{\}]*\}/1/ || 2437 $dstat =~ s/\[[^\{\}]*\]/1/) 2438 { 2439 } 2440 2441 my $exceptions = qr{ 2442 $Declare| 2443 module_param_named| 2444 MODULE_PARAM_DESC| 2445 DECLARE_PER_CPU| 2446 DEFINE_PER_CPU| 2447 __typeof__\(| 2448 union| 2449 struct| 2450 \.$Ident\s*=\s*| 2451 ^\"|\"$ 2452 }x; 2453 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 2454 if ($rest ne '' && $rest ne ',') { 2455 if ($rest !~ /while\s*\(/ && 2456 $dstat !~ /$exceptions/) 2457 { 2458 ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 2459 } 2460 2461 } elsif ($ctx !~ /;/) { 2462 if ($dstat ne '' && 2463 $dstat !~ /^(?:$Ident|-?$Constant)$/ && 2464 $dstat !~ /$exceptions/ && 2465 $dstat !~ /^\.$Ident\s*=/ && 2466 $dstat =~ /$Operators/) 2467 { 2468 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 2469 } 2470 } 2471 } 2472 2473# check for missing bracing around if etc 2474 if ($line =~ /(^.*)\b(?:if|while|for)\b/ && 2475 $line !~ /\#\s*if/) { 2476 my $allowed = 0; 2477 2478 # Check the pre-context. 2479 if ($line =~ /(\}.*?)$/) { 2480 my $pre = $1; 2481 2482 if ($line !~ /else/) { 2483 print "APW: ALLOWED: pre<$pre> line<$line>\n" 2484 if $dbg_adv_apw; 2485 $allowed = 1; 2486 } 2487 } 2488 my ($level, $endln, @chunks) = 2489 ctx_statement_full($linenr, $realcnt, 1); 2490 if ($dbg_adv_apw) { 2491 print "APW: chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 2492 print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n" 2493 if $#chunks >= 1; 2494 } 2495 if ($#chunks >= 0 && $level == 0) { 2496 my $seen = 0; 2497 my $herectx = $here . "\n"; 2498 my $ln = $linenr - 1; 2499 for my $chunk (@chunks) { 2500 my ($cond, $block) = @{$chunk}; 2501 2502 # If the condition carries leading newlines, then count those as offsets. 2503 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 2504 my $offset = statement_rawlines($whitespace) - 1; 2505 2506 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 2507 2508 # We have looked at and allowed this specific line. 2509 $suppress_ifbraces{$ln + $offset} = 1; 2510 2511 $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 2512 $ln += statement_rawlines($block) - 1; 2513 2514 substr($block, 0, length($cond), ''); 2515 2516 my $spaced_block = $block; 2517 $spaced_block =~ s/\n\+/ /g; 2518 2519 $seen++ if ($spaced_block =~ /^\s*\{/); 2520 2521 print "APW: cond<$cond> block<$block> allowed<$allowed>\n" 2522 if $dbg_adv_apw; 2523 if (statement_lines($cond) > 1) { 2524 print "APW: ALLOWED: cond<$cond>\n" 2525 if $dbg_adv_apw; 2526 $allowed = 1; 2527 } 2528 if ($block =~/\b(?:if|for|while)\b/) { 2529 print "APW: ALLOWED: block<$block>\n" 2530 if $dbg_adv_apw; 2531 $allowed = 1; 2532 } 2533 if (statement_block_size($block) > 1) { 2534 print "APW: ALLOWED: lines block<$block>\n" 2535 if $dbg_adv_apw; 2536 $allowed = 1; 2537 } 2538 } 2539 $allowed=1; # disable for now. 2540 if ($seen != ($#chunks + 1) && !$allowed) { 2541 ERROR("braces {} are necessary for all arms of this statement\n" . $herectx); 2542 } 2543 } 2544 } 2545 if (!defined $suppress_ifbraces{$linenr - 1} && 2546 $line =~ /\b(if|while|for|else)\b/ && 2547 $line !~ /\#\s*if/ && 2548 $line !~ /\#\s*else/) { 2549 my $allowed = 0; 2550 2551 # Check the pre-context. 2552 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 2553 my $pre = $1; 2554 2555 if ($line !~ /else/) { 2556 print "APW: ALLOWED: pre<$pre> line<$line>\n" 2557 if $dbg_adv_apw; 2558 $allowed = 1; 2559 } 2560 } 2561 2562 my ($level, $endln, @chunks) = 2563 ctx_statement_full($linenr, $realcnt, $-[0]); 2564 2565 # Check the condition. 2566 my ($cond, $block) = @{$chunks[0]}; 2567 print "CHECKING<$linenr> cond<$cond> block<$block>\n" 2568 if $dbg_adv_checking; 2569 if (defined $cond) { 2570 substr($block, 0, length($cond), ''); 2571 } 2572 if (statement_lines($cond) > 1) { 2573 print "APW: ALLOWED: cond<$cond>\n" 2574 if $dbg_adv_apw; 2575 $allowed = 1; 2576 } 2577 if ($block =~/\b(?:if|for|while)\b/) { 2578 print "APW: ALLOWED: block<$block>\n" 2579 if $dbg_adv_apw; 2580 $allowed = 1; 2581 } 2582 if (statement_block_size($block) > 1) { 2583 print "APW: ALLOWED: lines block<$block>\n" 2584 if $dbg_adv_apw; 2585 $allowed = 1; 2586 } 2587 # Check the post-context. 2588 if (defined $chunks[1]) { 2589 my ($cond, $block) = @{$chunks[1]}; 2590 if (defined $cond) { 2591 substr($block, 0, length($cond), ''); 2592 } 2593 if ($block =~ /^\s*\{/) { 2594 print "APW: ALLOWED: chunk-1 block<$block>\n" 2595 if $dbg_adv_apw; 2596 $allowed = 1; 2597 } 2598 } 2599 print "DCS: level=$level block<$block> allowed=$allowed\n" 2600 if $dbg_adv_dcs; 2601 if ($level == 0 && $block !~ /^\s*\{/ && !$allowed) { 2602 my $herectx = $here . "\n";; 2603 my $cnt = statement_rawlines($block); 2604 2605 for (my $n = 0; $n < $cnt; $n++) { 2606 $herectx .= raw_line($linenr, $n) . "\n";; 2607 } 2608 2609 ERROR("braces {} are necessary even for single statement blocks\n" . $herectx); 2610 } 2611 } 2612 2613# warn about #if 0 2614 if ($line =~ /^.\s*\#\s*if\s+0\b/) { 2615 ERROR("if this code is redundant consider removing it\n" . 2616 $herecurr); 2617 } 2618 2619# Check that the storage class is at the beginning of a declaration 2620 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 2621 ERROR("storage class should be at the beginning of the declaration\n" . $herecurr) 2622 } 2623 2624# check the location of the inline attribute, that it is between 2625# storage class and type. 2626 if ($line =~ /\b$Type\s+$Inline\b/ || 2627 $line =~ /\b$Inline\s+$Storage\b/) { 2628 ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 2629 } 2630 2631# check for sizeof(&) 2632 if ($line =~ /\bsizeof\s*\(\s*\&/) { 2633 ERROR("sizeof(& should be avoided\n" . $herecurr); 2634 } 2635 2636# check for new externs in .c files. 2637 if ($realfile =~ /\.c$/ && defined $stat && 2638 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 2639 { 2640 my $function_name = $1; 2641 my $paren_space = $2; 2642 2643 my $s = $stat; 2644 if (defined $cond) { 2645 substr($s, 0, length($cond), ''); 2646 } 2647 if ($s =~ /^\s*;/ && 2648 $function_name ne 'uninitialized_var') 2649 { 2650 ERROR("externs should be avoided in .c files\n" . $herecurr); 2651 } 2652 2653 if ($paren_space =~ /\n/) { 2654 ERROR("arguments for function declarations should follow identifier\n" . $herecurr); 2655 } 2656 2657 } elsif ($realfile =~ /\.c$/ && defined $stat && 2658 $stat =~ /^.\s*extern\s+/) 2659 { 2660 ERROR("externs should be avoided in .c files\n" . $herecurr); 2661 } 2662 2663# check for gcc specific __FUNCTION__ 2664 if ($line =~ /__FUNCTION__/) { 2665 ERROR("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 2666 } 2667 2668# recommend sigaction over signal for portability, when establishing a handler 2669 if ($line =~ /\bsignal\s*\(/ && !($line =~ /SIG_(?:IGN|DFL)/)) { 2670 ERROR("use sigaction to establish signal handlers; signal is not portable\n" . $herecurr); 2671 } 2672 2673# format strings checks 2674 my $string; 2675 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 2676 $string = substr($rawline, $-[1], $+[1] - $-[1]); 2677 $string =~ s/%%/__/g; 2678 # check for %L{u,d,i} in strings 2679 if ($string =~ /(?<!%)%L[udi]/) { 2680 ERROR("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 2681 } 2682 } 2683 2684 # Continue checking for error messages that contains newlines. This 2685 # check handles cases where string literals are spread over multiple lines. 2686 # Example: 2687 # error_report("Error msg line #1" 2688 # "Error msg line #2\n"); 2689 my $quoted_newline_regex = qr{\+\s*\".*\\n.*\"}; 2690 my $continued_str_literal = qr{\+\s*\".*\"}; 2691 2692 if ($rawline =~ /$quoted_newline_regex/) { 2693 # Backtrack to first line that does not contain only a quoted literal 2694 # and assume that it is the start of the statement. 2695 my $i = $linenr - 2; 2696 2697 while (($i >= 0) & $rawlines[$i] =~ /$continued_str_literal/) { 2698 $i--; 2699 } 2700 } 2701 2702 } 2703 2704 # If we have no input at all, then there is nothing to report on 2705 # so just keep quiet. 2706 if ($#rawlines == -1) { 2707 return 1; 2708 } 2709 2710 # In mailback mode only produce a report in the negative, for 2711 # things that appear to be patches. 2712 if ($mailback && ($clean == 1 || !$is_patch)) { 2713 return 1; 2714 } 2715 2716 # This is not a patch, and we are are in 'no-patch' mode so 2717 # just keep quiet. 2718 if (!$chk_patch && !$is_patch) { 2719 return 1; 2720 } 2721 2722 if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 2723 ERROR("Does not appear to be a unified-diff format patch\n"); 2724 } 2725 2726 print report_dump(); 2727 if ($summary && !($clean == 1 && $quiet == 1)) { 2728 print "$filename " if ($summary_file); 2729 print "total: $cnt_error errors, $cnt_warn warnings, " . 2730 "$cnt_lines lines checked\n"; 2731 print "\n" if ($quiet == 0); 2732 } 2733 2734 if ($quiet == 0) { 2735 # If there were whitespace errors which cleanpatch can fix 2736 # then suggest that. 2737# if ($rpt_cleaners) { 2738# print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 2739# print " scripts/cleanfile\n\n"; 2740# } 2741 } 2742 2743 if ($clean == 1 && $quiet == 0) { 2744 print "$vname has no obvious style problems and is ready for submission.\n" 2745 } 2746 2747 return ($no_warnings ? $clean : $cnt_error == 0); 2748} 2749