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 $github = 0; 29my $terse = 0; 30my $file = undef; 31my $color = "auto"; 32my $no_warnings = 0; 33my $summary = 1; 34my $mailback = 0; 35my $summary_file = 0; 36my $root; 37my %debug; 38my $help = 0; 39 40sub help { 41 my ($exitcode) = @_; 42 43 print << "EOM"; 44Usage: 45 46 $P [OPTION]... [FILE]... 47 $P [OPTION]... [GIT-REV-LIST] 48 49Version: $V 50 51Options: 52 -q, --quiet quiet 53 --patch treat FILE as patchfile 54 --branch treat args as GIT revision list 55 --emacs emacs compile window format 56 --terse one line per report 57 -f, --file treat FILE as regular source file 58 --strict fail if only warnings are found 59 --no-summary suppress the per-file summary 60 --mailback only produce a report in case of warnings/errors 61 --summary-file include the filename in summary 62 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 63 'values', 'possible', 'type', and 'attr' (default 64 is all off) 65 --test-only=WORD report only warnings/errors containing WORD 66 literally 67 --color[=WHEN] Use colors 'always', 'never', or only when output 68 is a terminal ('auto'). Default is 'auto'. 69 -h, --help, --version display this help and exit 70 71When FILE is - read standard input. 72EOM 73 74 exit($exitcode); 75} 76 77# Use at your own risk 78print "\n", MAGENTA, "WARNING:", RESET, " This code is highly experimental ... likely isn't a great style(9) match yet\n\n"; 79 80# Perl's Getopt::Long allows options to take optional arguments after a space. 81# Prevent --color by itself from consuming other arguments 82foreach (@ARGV) { 83 if ($_ eq "--color" || $_ eq "-color") { 84 $_ = "--color=$color"; 85 } 86} 87 88GetOptions( 89 'q|quiet+' => \$quiet, 90 'tree!' => \$tree, 91 'signoff!' => \$chk_signoff, 92 'patch!' => \$chk_patch, 93 'branch!' => \$chk_branch, 94 'emacs!' => \$emacs, 95 'github!' => \$github, 96 'terse!' => \$terse, 97 'f|file!' => \$file, 98 'strict!' => \$no_warnings, 99 'root=s' => \$root, 100 'summary!' => \$summary, 101 'mailback!' => \$mailback, 102 'summary-file!' => \$summary_file, 103 104 'debug=s' => \%debug, 105 'test-only=s' => \$tst_only, 106 'color=s' => \$color, 107 'no-color' => sub { $color = 'never'; }, 108 'h|help' => \$help, 109 'version' => \$help 110) or help(1); 111 112help(0) if ($help); 113 114my $exit = 0; 115 116if ($#ARGV < 0) { 117 print "$P: no input files\n"; 118 exit(1); 119} 120 121if (!defined $chk_branch && !defined $chk_patch && !defined $file) { 122 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 123 $file = $ARGV[0] =~ /$SrcFile/ ? 1 : 0; 124 $chk_patch = $chk_branch || $file ? 0 : 1; 125} elsif (!defined $chk_branch && !defined $chk_patch) { 126 if ($file) { 127 $chk_branch = $chk_patch = 0; 128 } else { 129 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 130 $chk_patch = $chk_branch ? 0 : 1; 131 } 132} elsif (!defined $chk_branch && !defined $file) { 133 if ($chk_patch) { 134 $chk_branch = $file = 0; 135 } else { 136 $chk_branch = $ARGV[0] =~ /.\.\./ ? 1 : 0; 137 $file = $chk_branch ? 0 : 1; 138 } 139} elsif (!defined $chk_patch && !defined $file) { 140 if ($chk_branch) { 141 $chk_patch = $file = 0; 142 } else { 143 $file = $ARGV[0] =~ /$SrcFile/ ? 1 : 0; 144 $chk_patch = $file ? 0 : 1; 145 } 146} elsif (!defined $chk_branch) { 147 $chk_branch = $chk_patch || $file ? 0 : 1; 148} elsif (!defined $chk_patch) { 149 $chk_patch = $chk_branch || $file ? 0 : 1; 150} elsif (!defined $file) { 151 $file = $chk_patch || $chk_branch ? 0 : 1; 152} 153 154if (($chk_patch && $chk_branch) || 155 ($chk_patch && $file) || 156 ($chk_branch && $file)) { 157 die "Only one of --file, --branch, --patch is permitted\n"; 158} 159if (!$chk_patch && !$chk_branch && !$file) { 160 die "One of --file, --branch, --patch is required\n"; 161} 162 163if ($color =~ /^always$/i) { 164 $color = 1; 165} elsif ($color =~ /^never$/i) { 166 $color = 0; 167} elsif ($color =~ /^auto$/i) { 168 $color = (-t STDOUT); 169} else { 170 die "Invalid color mode: $color\n"; 171} 172 173my $dbg_values = 0; 174my $dbg_possible = 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 my $do_color = $color && !$github; 1179 $output .= BOLD if $do_color; 1180 $output .= "::error " if $github && $level eq 'ERROR'; 1181 $output .= "::warning " if $github && $level eq 'WARNING'; 1182 $output .= $prefix; 1183 $output .= RED if $do_color && $level eq 'ERROR'; 1184 $output .= MAGENTA if $do_color && $level eq 'WARNING'; 1185 $output .= $level . ':' if !$github; 1186 $output .= RESET if $do_color; 1187 $output .= ' ' if (!$github); 1188 $output .= $msg . "\n"; 1189 1190 $output = (split('\n', $output))[0] . "\n" if ($terse); 1191 1192 push(our @report, $output); 1193 1194 return 1; 1195} 1196sub report_dump { 1197 our @report; 1198} 1199sub ERROR { 1200 if (report("ERROR", $_[0])) { 1201 our $clean = 0; 1202 our $cnt_error++; 1203 } 1204} 1205sub WARN { 1206 if (report("WARNING", $_[0])) { 1207 our $clean = 0; 1208 our $cnt_warn++; 1209 } 1210} 1211 1212# According to tests/qtest/bios-tables-test.c: do not 1213# change expected file in the same commit with adding test 1214sub checkfilename { 1215 my ($name, $acpi_testexpected, $acpi_nontestexpected) = @_; 1216 1217 # Note: shell script that rebuilds the expected files is in the same 1218 # directory as files themselves. 1219 # Note: allowed diff list can be changed both when changing expected 1220 # files and when changing tests. 1221 if ($name =~ m#^tests/data/acpi/# and not $name =~ m#^\.sh$#) { 1222 $$acpi_testexpected = $name; 1223 } elsif ($name !~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) { 1224 $$acpi_nontestexpected = $name; 1225 } 1226 if (defined $$acpi_testexpected and defined $$acpi_nontestexpected) { 1227 ERROR("Do not add expected files together with tests, " . 1228 "follow instructions in " . 1229 "tests/qtest/bios-tables-test.c: both " . 1230 $$acpi_testexpected . " and " . 1231 $$acpi_nontestexpected . " found\n"); 1232 } 1233} 1234 1235sub process { 1236 my $filename = shift; 1237 1238 my $linenr=0; 1239 my $prevline=""; 1240 my $prevrawline=""; 1241 my $stashline=""; 1242 my $stashrawline=""; 1243 1244 my $length; 1245 my $indent; 1246 my $previndent=0; 1247 my $stashindent=0; 1248 1249 our $clean = 1; 1250 my $signoff = 0; 1251 my $is_patch = 0; 1252 1253 my $in_header_lines = $file ? 0 : 1; 1254 my $in_commit_log = 0; #Scanning lines before patch 1255 my $non_utf8_charset = 0; 1256 1257 our @report = (); 1258 our $cnt_lines = 0; 1259 our $cnt_error = 0; 1260 our $cnt_warn = 0; 1261 our $cnt_chk = 0; 1262 1263 # Trace the real file/line as we go. 1264 my $realfile = ''; 1265 my $realline = 0; 1266 my $realcnt = 0; 1267 my $here = ''; 1268 my $in_comment = 0; 1269 my $comment_edge = 0; 1270 my $first_line = 0; 1271 my $p1_prefix = ''; 1272 1273 my $prev_values = 'E'; 1274 1275 # suppression flags 1276 my %suppress_ifbraces; 1277 my %suppress_whiletrailers; 1278 my %suppress_export; 1279 1280 my $acpi_testexpected; 1281 my $acpi_nontestexpected; 1282 1283 # Pre-scan the patch sanitizing the lines. 1284 1285 sanitise_line_reset(); 1286 my $line; 1287 foreach my $rawline (@rawlines) { 1288 $linenr++; 1289 $line = $rawline; 1290 1291 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1292 $realline=$1-1; 1293 if (defined $2) { 1294 $realcnt=$3+1; 1295 } else { 1296 $realcnt=1+1; 1297 } 1298 $in_comment = 0; 1299 1300 # Guestimate if this is a continuing comment. Run 1301 # the context looking for a comment "edge". If this 1302 # edge is a close comment then we must be in a comment 1303 # at context start. 1304 my $edge; 1305 my $cnt = $realcnt; 1306 for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 1307 next if (defined $rawlines[$ln - 1] && 1308 $rawlines[$ln - 1] =~ /^-/); 1309 $cnt--; 1310 #print "RAW<$rawlines[$ln - 1]>\n"; 1311 last if (!defined $rawlines[$ln - 1]); 1312 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1313 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1314 ($edge) = $1; 1315 last; 1316 } 1317 } 1318 if (defined $edge && $edge eq '*/') { 1319 $in_comment = 1; 1320 } 1321 1322 # Guestimate if this is a continuing comment. If this 1323 # is the start of a diff block and this line starts 1324 # ' *' then it is very likely a comment. 1325 if (!defined $edge && 1326 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 1327 { 1328 $in_comment = 1; 1329 } 1330 1331 ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 1332 sanitise_line_reset($in_comment); 1333 1334 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 1335 # Standardise the strings and chars within the input to 1336 # simplify matching -- only bother with positive lines. 1337 $line = sanitise_line($rawline); 1338 } 1339 push(@lines, $line); 1340 1341 if ($realcnt > 1) { 1342 $realcnt-- if ($line =~ /^(?:\+| |$)/); 1343 } else { 1344 $realcnt = 0; 1345 } 1346 1347 #print "==>$rawline\n"; 1348 #print "-->$line\n"; 1349 } 1350 1351 $prefix = ''; 1352 1353 $realcnt = 0; 1354 $linenr = 0; 1355 foreach my $line (@lines) { 1356 $linenr++; 1357 1358 my $rawline = $rawlines[$linenr - 1]; 1359 1360#extract the line range in the file after the patch is applied 1361 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1362 $is_patch = 1; 1363 $first_line = $linenr + 1; 1364 $realline=$1-1; 1365 if (defined $2) { 1366 $realcnt=$3+1; 1367 } else { 1368 $realcnt=1+1; 1369 } 1370 annotate_reset(); 1371 $prev_values = 'E'; 1372 1373 %suppress_ifbraces = (); 1374 %suppress_whiletrailers = (); 1375 %suppress_export = (); 1376 next; 1377 1378# track the line number as we move through the hunk, note that 1379# new versions of GNU diff omit the leading space on completely 1380# blank context lines so we need to count that too. 1381 } elsif ($line =~ /^( |\+|$)/) { 1382 $realline++; 1383 $realcnt-- if ($realcnt != 0); 1384 1385 # Measure the line length and indent. 1386 ($length, $indent) = line_stats($rawline); 1387 1388 # Track the previous line. 1389 ($prevline, $stashline) = ($stashline, $line); 1390 ($previndent, $stashindent) = ($stashindent, $indent); 1391 ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 1392 1393 #warn "line<$line>\n"; 1394 1395 } elsif ($realcnt == 1) { 1396 $realcnt--; 1397 } 1398 1399 my $hunk_line = ($realcnt != 0); 1400 1401#make up the handle for any error we report on this line 1402 $prefix = "$filename:$realline: " if ($emacs && $file); 1403 $prefix = "$filename:$linenr: " if ($emacs && !$file); 1404 $prefix = "file=$filename,line=$realline:\:" if ($github && $file); 1405 $prefix = "file=$realfile,line=$realline:\:" if ($github && !$file); 1406 1407 $here = "#$linenr: " if (!$file); 1408 $here = "#$realline: " if ($file); 1409 1410 # extract the filename as it passes 1411 if ($line =~ /^diff --git.*?(\S+)$/) { 1412 $realfile = $1; 1413 $realfile =~ s@^([^/]*)/@@ if (!$file); 1414 checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); 1415 } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 1416 $realfile = $1; 1417 $realfile =~ s@^([^/]*)/@@ if (!$file); 1418 checkfilename($realfile, \$acpi_testexpected, \$acpi_nontestexpected); 1419 1420 $p1_prefix = $1; 1421 if (!$file && $tree && $p1_prefix ne '' && defined $root && 1422 -e "$root/$p1_prefix") { 1423 WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 1424 } 1425 1426 next; 1427 } 1428 1429 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 1430 1431 my $hereline = "$here\n$rawline\n"; 1432 my $herecurr = "$here\n$rawline\n"; 1433 my $hereprev = "$here\n$prevrawline\n$rawline\n"; 1434 1435 $cnt_lines++ if ($realcnt != 0); 1436 1437# Check for incorrect file permissions 1438 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 1439 my $permhere = $here . "FILE: $realfile\n"; 1440 if ($realfile =~ /(\bMakefile(?:\.objs)?|\.c|\.cc|\.cpp|\.h|\.mak|\.[sS])$/) { 1441 ERROR("do not set execute permissions for source files\n" . $permhere); 1442 } 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# Filter out bad email addresses. 1451 if ($line =~ /^(Author|From): .*noreply.*/) { 1452 ERROR("Real email adress is needed\n" . $herecurr); 1453 } 1454 1455#check the patch for a signoff: 1456 if ($line =~ /^\s*signed-off-by:/i) { 1457 # This is a signoff, if ugly, so do not double report. 1458 $in_commit_log = 0; 1459 1460 if (!($line =~ /^\s*Signed-off-by:/)) { 1461 ERROR("The correct form is \"Signed-off-by\"\n" . 1462 $herecurr); 1463 } 1464 if ($line =~ /^\s*signed-off-by:\S/i) { 1465 ERROR("space required after Signed-off-by:\n" . 1466 $herecurr); 1467 } 1468 } 1469 1470# Check for wrappage within a valid hunk of the file 1471 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 1472 ERROR("patch seems to be corrupt (line wrapped?)\n" . 1473 $herecurr) if (!$emitted_corrupt++); 1474 } 1475 1476# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1477 if (($realfile =~ /^$/ || $line =~ /^\+/) && 1478 $rawline !~ m/^$UTF8*$/) { 1479 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 1480 1481 my $blank = copy_spacing($rawline); 1482 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 1483 my $hereptr = "$hereline$ptr\n"; 1484 1485 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 1486 } 1487 1488 if ($rawline =~ m/$UTF8_MOJIBAKE/) { 1489 ERROR("Doubly-encoded UTF-8\n" . $herecurr); 1490 } 1491# Check if it's the start of a commit log 1492# (not a header line and we haven't seen the patch filename) 1493 if ($in_header_lines && $realfile =~ /^$/ && 1494 !($rawline =~ /^\s+\S/ || 1495 $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) { 1496 $in_header_lines = 0; 1497 $in_commit_log = 1; 1498 } 1499 1500# Check if there is UTF-8 in a commit log when a mail header has explicitly 1501# declined it, i.e defined some charset where it is missing. 1502 if ($in_header_lines && 1503 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 1504 $1 !~ /utf-8/i) { 1505 $non_utf8_charset = 1; 1506 } 1507 1508 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 1509 $rawline =~ /$NON_ASCII_UTF8/) { 1510 WARN("8-bit UTF-8 used in possible commit log\n" . $herecurr); 1511 } 1512 1513# ignore non-hunk lines and lines being removed 1514 next if (!$hunk_line || $line =~ /^-/); 1515 1516#trailing whitespace 1517 if ($line =~ /^\+.*\015/) { 1518 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1519 ERROR("DOS line endings\n" . $herevet); 1520 1521 } elsif ($realfile =~ /^docs\/.+\.txt/ || 1522 $realfile =~ /^docs\/.+\.md/) { 1523 if ($rawline =~ /^\+\s+$/ && $rawline !~ /^\+ {4}$/) { 1524 # TODO: properly check we're in a code block 1525 # (surrounding text is 4-column aligned) 1526 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1527 ERROR("code blocks in documentation should have " . 1528 "empty lines with exactly 4 columns of " . 1529 "whitespace\n" . $herevet); 1530 } 1531 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1532 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1533 ERROR("trailing whitespace\n" . $herevet); 1534 $rpt_cleaners = 1; 1535 } 1536 1537# check we are in a valid source file if not then ignore this hunk 1538 next if ($realfile !~ /$SrcFile/); 1539 1540#120 column limit; exempt URLs, if no other words on line 1541 if ($line =~ /^\+/ && 1542 !($line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && 1543 !($rawline =~ /^[^[:alnum:]]*https?:\S*$/) && 1544 $length > 80 && 1545 $realfile !~ /\/tests\//) 1546 { 1547 if ($length > 120) { 1548 ERROR("line over 120 characters\n" . $herecurr); 1549 } else { 1550 WARN("line over 80 characters\n" . $herecurr); 1551 } 1552 } 1553 1554# check for spaces before a quoted newline 1555 if ($rawline =~ /^.*\".*\s\\n/) { 1556 ERROR("unnecessary whitespace before a quoted newline\n" . $herecurr); 1557 } 1558 1559# check for adding lines without a newline. 1560 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1561 ERROR("adding a line without newline at end of file\n" . $herecurr); 1562 } 1563 1564# check for RCS/CVS revision markers 1565 if ($rawline =~ /^\+.*\$(FreeBSD|Revision|Log|Id)(?:\$|\b)/) { 1566 ERROR("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 1567 } 1568 1569# check we are in a valid C source file if not then ignore this hunk 1570 next if ($realfile !~ /\.(h|c|cpp)$/); 1571 1572# Block comment styles 1573 1574 # Block comments use /* on a line of its own 1575 if ($rawline !~ m@^\+.*/\*.*\*/[ \t)}]*$@ && #inline /*...*/ 1576 $rawline =~ m@^\+.*/\*[*-]?+[ \t]*[^ \t]@) { # /* or /** or /*- non-blank 1577 WARN("Block comments use a leading /* on a separate line\n" . $herecurr); 1578 } 1579 1580# Block comments use * on subsequent lines 1581 if ($prevline =~ /$;[ \t]*$/ && #ends in comment 1582 $prevrawline =~ /^\+.*?\/\*/ && #starting /* 1583 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 1584 $rawline =~ /^\+/ && #line is new 1585 $rawline !~ /^\+[ \t]*\*/) { #no leading * 1586 WARN("Block comments use * on subsequent lines\n" . $hereprev); 1587 } 1588 1589# Block comments use */ on trailing lines 1590 if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 1591 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 1592 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 1593 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 1594 WARN("Block comments use a trailing */ on a separate line\n" . $herecurr); 1595 } 1596 1597# Block comment * alignment 1598 if ($prevline =~ /$;[ \t]*$/ && #ends in comment 1599 $line =~ /^\+[ \t]*$;/ && #leading comment 1600 $rawline =~ /^\+[ \t]*\*/ && #leading * 1601 (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 1602 $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 1603 $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 1604 my $oldindent; 1605 $prevrawline =~ m@^\+([ \t]*/?)\*@; 1606 if (defined($1)) { 1607 $oldindent = expand_tabs($1); 1608 } else { 1609 $prevrawline =~ m@^\+(.*/?)\*@; 1610 $oldindent = expand_tabs($1); 1611 } 1612 $rawline =~ m@^\+([ \t]*)\*@; 1613 my $newindent = $1; 1614 $newindent = expand_tabs($newindent); 1615 if (length($oldindent) ne length($newindent)) { 1616 WARN("Block comments should align the * on each line\n" . $hereprev); 1617 } 1618 } 1619 1620# Check for potential 'bare' types 1621 my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 1622 $realline_next); 1623 if ($realcnt && $line =~ /.\s*\S/) { 1624 ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 1625 ctx_statement_block($linenr, $realcnt, 0); 1626 $stat =~ s/\n./\n /g; 1627 $cond =~ s/\n./\n /g; 1628 1629 # Find the real next line. 1630 $realline_next = $line_nr_next; 1631 if (defined $realline_next && 1632 (!defined $lines[$realline_next - 1] || 1633 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 1634 $realline_next++; 1635 } 1636 1637 my $s = $stat; 1638 $s =~ s/{.*$//s; 1639 1640 # Ignore goto labels. 1641 if ($s =~ /$Ident:\*$/s) { 1642 1643 # Ignore functions being called 1644 } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 1645 1646 } elsif ($s =~ /^.\s*else\b/s) { 1647 1648 # declarations always start with types 1649 } 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) { 1650 my $type = $1; 1651 $type =~ s/\s+/ /g; 1652 possible($type, "A:" . $s); 1653 1654 # definitions in global scope can only start with types 1655 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 1656 possible($1, "B:" . $s); 1657 } 1658 1659 # any (foo ... *) is a pointer cast, and foo is a type 1660 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 1661 possible($1, "C:" . $s); 1662 } 1663 1664 # Check for any sort of function declaration. 1665 # int foo(something bar, other baz); 1666 # void (*store_gdt)(x86_descr_ptr *); 1667 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 1668 my ($name_len) = length($1); 1669 1670 my $ctx = $s; 1671 substr($ctx, 0, $name_len + 1, ''); 1672 $ctx =~ s/\)[^\)]*$//; 1673 1674 for my $arg (split(/\s*,\s*/, $ctx)) { 1675 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 1676 1677 possible($1, "D:" . $s); 1678 } 1679 } 1680 } 1681 1682 } 1683 1684# 1685# Checks which may be anchored in the context. 1686# 1687 1688# Check for switch () and associated case and default 1689# statements should be at the same indent. 1690 if ($line=~/\bswitch\s*\(.*\)/) { 1691 my $err = ''; 1692 my $sep = ''; 1693 my @ctx = ctx_block_outer($linenr, $realcnt); 1694 shift(@ctx); 1695 for my $ctx (@ctx) { 1696 my ($clen, $cindent) = line_stats($ctx); 1697 if ($ctx =~ /^\+\s*(case\s+|default:)/ && 1698 $indent != $cindent) { 1699 $err .= "$sep$ctx\n"; 1700 $sep = ''; 1701 } else { 1702 $sep = "[...]\n"; 1703 } 1704 } 1705 if ($err ne '') { 1706 ERROR("switch and case should be at the same indent\n$hereline$err"); 1707 } 1708 } 1709 1710# if/while/etc brace do not go on next line, unless defining a do while loop, 1711# or if that brace on the next line is for something else 1712 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 1713 my $pre_ctx = "$1$2"; 1714 1715 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 1716 my $ctx_cnt = $realcnt - $#ctx - 1; 1717 my $ctx = join("\n", @ctx); 1718 1719 my $ctx_ln = $linenr; 1720 my $ctx_skip = $realcnt; 1721 1722 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 1723 defined $lines[$ctx_ln - 1] && 1724 $lines[$ctx_ln - 1] =~ /^-/)) { 1725 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 1726 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 1727 $ctx_ln++; 1728 } 1729 1730 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 1731 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 1732 1733 # The length of the "previous line" is checked against 80 because it 1734 # includes the + at the beginning of the line (if the actual line has 1735 # 79 or 80 characters, it is no longer possible to add a space and an 1736 # opening brace there) 1737 if ($#ctx == 0 && $ctx !~ /{\s*/ && 1738 defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*\{/ && 1739 defined($lines[$ctx_ln - 2]) && length($lines[$ctx_ln - 2]) < 80) { 1740 ERROR("that open brace { should be on the previous line\n" . 1741 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 1742 } 1743 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 1744 $ctx =~ /\)\s*\;\s*$/ && 1745 defined $lines[$ctx_ln - 1]) 1746 { 1747 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 1748 if ($nindent > $indent) { 1749 ERROR("trailing semicolon indicates no statements, indent implies otherwise\n" . 1750 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 1751 } 1752 } 1753 } 1754 1755# 'do ... while (0/false)' only makes sense in macros, without trailing ';' 1756 if ($line =~ /while\s*\((0|false)\);/) { 1757 ERROR("suspicious ; after while (0)\n" . $herecurr); 1758 } 1759 1760# Check superfluous trailing ';' 1761 if ($line =~ /;;$/) { 1762 ERROR("superfluous trailing semicolon\n" . $herecurr); 1763 } 1764 1765# Check relative indent for conditionals and blocks. 1766 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 1767 my ($s, $c) = ($stat, $cond); 1768 1769 substr($s, 0, length($c), ''); 1770 1771 # Make sure we remove the line prefixes as we have 1772 # none on the first line, and are going to re-add them 1773 # where necessary. 1774 $s =~ s/\n./\n/gs; 1775 1776 # Find out how long the conditional actually is. 1777 my @newlines = ($c =~ /\n/gs); 1778 my $cond_lines = 1 + $#newlines; 1779 1780 # We want to check the first line inside the block 1781 # starting at the end of the conditional, so remove: 1782 # 1) any blank line termination 1783 # 2) any opening brace { on end of the line 1784 # 3) any do (...) { 1785 my $continuation = 0; 1786 my $check = 0; 1787 $s =~ s/^.*\bdo\b//; 1788 $s =~ s/^\s*\{//; 1789 if ($s =~ s/^\s*\\//) { 1790 $continuation = 1; 1791 } 1792 if ($s =~ s/^\s*?\n//) { 1793 $check = 1; 1794 $cond_lines++; 1795 } 1796 1797 # Also ignore a loop construct at the end of a 1798 # preprocessor statement. 1799 if (($prevline =~ /^.\s*#\s*define\s/ || 1800 $prevline =~ /\\\s*$/) && $continuation == 0) { 1801 $check = 0; 1802 } 1803 1804 my $cond_ptr = -1; 1805 $continuation = 0; 1806 while ($cond_ptr != $cond_lines) { 1807 $cond_ptr = $cond_lines; 1808 1809 # If we see an #else/#elif then the code 1810 # is not linear. 1811 if ($s =~ /^\s*\#\s*(?:else|elif)/) { 1812 $check = 0; 1813 } 1814 1815 # Ignore: 1816 # 1) blank lines, they should be at 0, 1817 # 2) preprocessor lines, and 1818 # 3) labels. 1819 if ($continuation || 1820 $s =~ /^\s*?\n/ || 1821 $s =~ /^\s*#\s*?/ || 1822 $s =~ /^\s*$Ident\s*:/) { 1823 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 1824 if ($s =~ s/^.*?\n//) { 1825 $cond_lines++; 1826 } 1827 } 1828 } 1829 1830 my (undef, $sindent) = line_stats("+" . $s); 1831 my $stat_real = raw_line($linenr, $cond_lines); 1832 1833 # Check if either of these lines are modified, else 1834 # this is not this patch's fault. 1835 if (!defined($stat_real) || 1836 $stat !~ /^\+/ && $stat_real !~ /^\+/) { 1837 $check = 0; 1838 } 1839 if (defined($stat_real) && $cond_lines > 1) { 1840 $stat_real = "[...]\n$stat_real"; 1841 } 1842 1843 #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"; 1844 1845 if ($check && (($sindent % 4) != 0 || 1846 ($sindent <= $indent && $s ne ''))) { 1847 ERROR("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 1848 } 1849 } 1850 1851 # Track the 'values' across context and added lines. 1852 my $opline = $line; $opline =~ s/^./ /; 1853 my ($curr_values, $curr_vars) = 1854 annotate_values($opline . "\n", $prev_values); 1855 $curr_values = $prev_values . $curr_values; 1856 if ($dbg_values) { 1857 my $outline = $opline; $outline =~ s/\t/ /g; 1858 print "$linenr > .$outline\n"; 1859 print "$linenr > $curr_values\n"; 1860 print "$linenr > $curr_vars\n"; 1861 } 1862 $prev_values = substr($curr_values, -1); 1863 1864#ignore lines not being added 1865 if ($line=~/^[^\+]/) {next;} 1866 1867# check for initialisation to aggregates open brace on the next line 1868 if ($line =~ /^.\s*\{/ && 1869 $prevline =~ /(?:^|[^=])=\s*$/) { 1870 ERROR("that open brace { should be on the previous line\n" . $hereprev); 1871 } 1872 1873# 1874# Checks which are anchored on the added line. 1875# 1876 1877# check for malformed paths in #include statements (uses RAW line) 1878 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 1879 my $path = $1; 1880 if ($path =~ m{//}) { 1881 ERROR("malformed #include filename\n" . 1882 $herecurr); 1883 } 1884 } 1885 1886# Remove C99 comments. 1887 $line =~ s@//.*@@; 1888 $opline =~ s@//.*@@; 1889 1890# * goes on variable not on type 1891 # (char*[ const]) 1892 if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { 1893 my ($from, $to) = ($1, $1); 1894 1895 # Should start with a space. 1896 $to =~ s/^(\S)/ $1/; 1897 # Should not end with a space. 1898 $to =~ s/\s+$//; 1899 # '*'s should not have spaces between. 1900 while ($to =~ s/\*\s+\*/\*\*/) { 1901 } 1902 1903 #print "from<$from> to<$to>\n"; 1904 if ($from ne $to) { 1905 ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); 1906 } 1907 } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { 1908 my ($from, $to, $ident) = ($1, $1, $2); 1909 1910 # Should start with a space. 1911 $to =~ s/^(\S)/ $1/; 1912 # Should not end with a space. 1913 $to =~ s/\s+$//; 1914 # '*'s should not have spaces between. 1915 while ($to =~ s/\*\s+\*/\*\*/) { 1916 } 1917 # Modifiers should have spaces. 1918 $to =~ s/(\b$Modifier$)/$1 /; 1919 1920 #print "from<$from> to<$to> ident<$ident>\n"; 1921 if ($from ne $to && $ident !~ /^$Modifier$/) { 1922 ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); 1923 } 1924 } 1925 1926# function brace can't be on same line, except for #defines of do while, 1927# or if closed on same line 1928 if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and 1929 !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 1930 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 1931 } 1932 1933# missing space after union, struct or enum definition 1934 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { 1935 ERROR("missing space after $1 definition\n" . $herecurr); 1936 } 1937 1938# check for spacing round square brackets; allowed: 1939# 1. with a type on the left -- int [] a; 1940# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 1941# 3. inside a curly brace -- = { [0...10] = 5 } 1942# 4. after a comma -- [1] = 5, [2] = 6 1943# 5. in a macro definition -- #define abc(x) [x] = y 1944 while ($line =~ /(.*?\s)\[/g) { 1945 my ($where, $prefix) = ($-[1], $1); 1946 if ($prefix !~ /$Type\s+$/ && 1947 ($where != 0 || $prefix !~ /^.\s+$/) && 1948 $prefix !~ /\#\s*define[^(]*\([^)]*\)\s+$/ && 1949 $prefix !~ /[,{:]\s+$/) { 1950 ERROR("space prohibited before open square bracket '['\n" . $herecurr); 1951 } 1952 } 1953 1954# check for spaces between functions and their parentheses. 1955 while ($line =~ /($Ident)\s+\(/g) { 1956 my $name = $1; 1957 my $ctx_before = substr($line, 0, $-[1]); 1958 my $ctx = "$ctx_before$name"; 1959 1960 # Ignore those directives where spaces _are_ permitted. 1961 if ($name =~ /^(?: 1962 if|for|while|switch|return|case| 1963 volatile|__volatile__|coroutine_fn| 1964 __attribute__|format|__extension__| 1965 asm|__asm__)$/x) 1966 { 1967 1968 # Ignore 'catch (...)' in C++ 1969 } elsif ($name =~ /^catch$/ && $realfile =~ /(\.cpp|\.h)$/) { 1970 1971 # cpp #define statements have non-optional spaces, ie 1972 # if there is a space between the name and the open 1973 # parenthesis it is simply not a parameter group. 1974 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 1975 1976 # cpp #elif statement condition may start with a ( 1977 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 1978 1979 # If this whole things ends with a type its most 1980 # likely a typedef for a function. 1981 } elsif ($ctx =~ /$Type$/) { 1982 1983 } else { 1984 ERROR("space prohibited between function name and open parenthesis '('\n" . $herecurr); 1985 } 1986 } 1987# Check operator spacing. 1988 if (!($line=~/\#\s*include/)) { 1989 my $ops = qr{ 1990 <<=|>>=|<=|>=|==|!=| 1991 \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 1992 =>|->|<<|>>|<|>|=|!|~| 1993 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 1994 \?|::|: 1995 }x; 1996 my @elements = split(/($ops|;)/, $opline); 1997 my $off = 0; 1998 1999 my $blank = copy_spacing($opline); 2000 2001 for (my $n = 0; $n < $#elements; $n += 2) { 2002 $off += length($elements[$n]); 2003 2004 # Pick up the preceding and succeeding characters. 2005 my $ca = substr($opline, 0, $off); 2006 my $cc = ''; 2007 if (length($opline) >= ($off + length($elements[$n + 1]))) { 2008 $cc = substr($opline, $off + length($elements[$n + 1])); 2009 } 2010 my $cb = "$ca$;$cc"; 2011 2012 my $a = ''; 2013 $a = 'V' if ($elements[$n] ne ''); 2014 $a = 'W' if ($elements[$n] =~ /\s$/); 2015 $a = 'C' if ($elements[$n] =~ /$;$/); 2016 $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 2017 $a = 'O' if ($elements[$n] eq ''); 2018 $a = 'E' if ($ca =~ /^\s*$/); 2019 2020 my $op = $elements[$n + 1]; 2021 2022 my $c = ''; 2023 if (defined $elements[$n + 2]) { 2024 $c = 'V' if ($elements[$n + 2] ne ''); 2025 $c = 'W' if ($elements[$n + 2] =~ /^\s/); 2026 $c = 'C' if ($elements[$n + 2] =~ /^$;/); 2027 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 2028 $c = 'O' if ($elements[$n + 2] eq ''); 2029 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 2030 } else { 2031 $c = 'E'; 2032 } 2033 2034 my $ctx = "${a}x${c}"; 2035 2036 my $at = "(ctx:$ctx)"; 2037 2038 my $ptr = substr($blank, 0, $off) . "^"; 2039 my $hereptr = "$hereline$ptr\n"; 2040 2041 # Pull out the value of this operator. 2042 my $op_type = substr($curr_values, $off + 1, 1); 2043 2044 # Get the full operator variant. 2045 my $opv = $op . substr($curr_vars, $off, 1); 2046 2047 # Ignore operators passed as parameters. 2048 if ($op_type ne 'V' && 2049 $ca =~ /\s$/ && $cc =~ /^\s*,/) { 2050 2051# # Ignore comments 2052# } elsif ($op =~ /^$;+$/) { 2053 2054 # ; should have either the end of line or a space or \ after it 2055 } elsif ($op eq ';') { 2056 if ($ctx !~ /.x[WEBC]/ && 2057 $cc !~ /^\\/ && $cc !~ /^;/) { 2058 ERROR("space required after that '$op' $at\n" . $hereptr); 2059 } 2060 2061 # // is a comment 2062 } elsif ($op eq '//') { 2063 2064 # Ignore : used in class declaration in C++ 2065 } elsif ($opv eq ':B' && $ctx =~ /Wx[WE]/ && 2066 $line =~ /class/ && $realfile =~ /(\.cpp|\.h)$/) { 2067 2068 # No spaces for: 2069 # -> 2070 # : when part of a bitfield 2071 } elsif ($op eq '->' || $opv eq ':B') { 2072 if ($ctx =~ /Wx.|.xW/) { 2073 ERROR("spaces prohibited around that '$op' $at\n" . $hereptr); 2074 } 2075 2076 # , must have a space on the right. 2077 # not required when having a single },{ on one line 2078 } elsif ($op eq ',') { 2079 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && 2080 ($elements[$n] . $elements[$n + 2]) !~ " *}\\{") { 2081 ERROR("space required after that '$op' $at\n" . $hereptr); 2082 } 2083 2084 # '*' as part of a type definition -- reported already. 2085 } elsif ($opv eq '*_') { 2086 #warn "'*' is part of type\n"; 2087 2088 # unary operators should have a space before and 2089 # none after. May be left adjacent to another 2090 # unary operator, or a cast 2091 } elsif ($op eq '!' || $op eq '~' || 2092 $opv eq '*U' || $opv eq '-U' || 2093 $opv eq '&U' || $opv eq '&&U') { 2094 if ($op eq '~' && $ca =~ /::$/ && $realfile =~ /(\.cpp|\.h)$/) { 2095 # '~' used as a name of Destructor 2096 2097 } elsif ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 2098 ERROR("space required before that '$op' $at\n" . $hereptr); 2099 } 2100 if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 2101 # A unary '*' may be const 2102 2103 } elsif ($ctx =~ /.xW/) { 2104 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2105 } 2106 2107 # unary ++ and unary -- are allowed no space on one side. 2108 } elsif ($op eq '++' or $op eq '--') { 2109 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 2110 ERROR("space required one side of that '$op' $at\n" . $hereptr); 2111 } 2112 if ($ctx =~ /Wx[BE]/ || 2113 ($ctx =~ /Wx./ && $cc =~ /^;/)) { 2114 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2115 } 2116 if ($ctx =~ /ExW/) { 2117 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2118 } 2119 2120 # A colon needs no spaces before when it is 2121 # terminating a case value or a label. 2122 } elsif ($opv eq ':C' || $opv eq ':L') { 2123 if ($ctx =~ /Wx./) { 2124 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2125 } 2126 2127 # All the others need spaces both sides. 2128 } elsif ($ctx !~ /[EWC]x[CWE]/) { 2129 my $ok = 0; 2130 2131 if ($realfile =~ /\.cpp|\.h$/) { 2132 # Ignore template arguments <...> in C++ 2133 if (($op eq '<' || $op eq '>') && $line =~ /<.*>/) { 2134 $ok = 1; 2135 } 2136 2137 # Ignore :: in C++ 2138 if ($op eq '::') { 2139 $ok = 1; 2140 } 2141 } 2142 2143 # Ignore email addresses <foo@bar> 2144 if (($op eq '<' && 2145 $cc =~ /^\S+\@\S+>/) || 2146 ($op eq '>' && 2147 $ca =~ /<\S+\@\S+$/)) 2148 { 2149 $ok = 1; 2150 } 2151 2152 # Ignore ?: 2153 if (($opv eq ':O' && $ca =~ /\?$/) || 2154 ($op eq '?' && $cc =~ /^:/)) { 2155 $ok = 1; 2156 } 2157 2158 if ($ok == 0) { 2159 ERROR("spaces required around that '$op' $at\n" . $hereptr); 2160 } 2161 } 2162 $off += length($elements[$n + 1]); 2163 } 2164 } 2165 2166#need space before brace following if, while, etc 2167 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 2168 $line =~ /do\{/) { 2169 ERROR("space required before the open brace '{'\n" . $herecurr); 2170 } 2171 2172# closing brace should have a space following it when it has anything 2173# on the line 2174 if ($line =~ /}(?!(?:,|;|\)))\S/) { 2175 ERROR("space required after that close brace '}'\n" . $herecurr); 2176 } 2177 2178# check spacing on square brackets 2179 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 2180 ERROR("space prohibited after that open square bracket '['\n" . $herecurr); 2181 } 2182 if ($line =~ /\s\]/) { 2183 ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); 2184 } 2185 2186# check spacing on parentheses 2187 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 2188 $line !~ /for\s*\(\s+;/) { 2189 ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); 2190 } 2191 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 2192 $line !~ /for\s*\(.*;\s+\)/ && 2193 $line !~ /:\s+\)/) { 2194 ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); 2195 } 2196 2197 if ($line =~ /^.\s*(Q(?:S?LIST|SIMPLEQ|TAILQ)_HEAD)\s*\(\s*[^,]/ && 2198 $line !~ /^.typedef/) { 2199 ERROR("named $1 should be typedefed separately\n" . $herecurr); 2200 } 2201 2202# Return needs parens 2203 if ($line =~ /^.\s*return [^(]/) { 2204 ERROR("parentheses required on return\n" . $herecurr); 2205 } 2206 2207# Need a space before open parenthesis after if, while etc 2208 if ($line=~/\b(if|while|for|switch|return)\(/) { 2209 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2210 } 2211 2212# Check for illegal assignment in if conditional -- and check for trailing 2213# statements after the conditional. 2214 if ($line =~ /do\s*(?!{)/) { 2215 my ($stat_next) = ctx_statement_block($line_nr_next, 2216 $remain_next, $off_next); 2217 $stat_next =~ s/\n./\n /g; 2218 ##print "stat<$stat> stat_next<$stat_next>\n"; 2219 2220 if ($stat_next =~ /^\s*while\b/) { 2221 # If the statement carries leading newlines, 2222 # then count those as offsets. 2223 my ($whitespace) = 2224 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 2225 my $offset = 2226 statement_rawlines($whitespace) - 1; 2227 2228 $suppress_whiletrailers{$line_nr_next + 2229 $offset} = 1; 2230 } 2231 } 2232 if (!defined $suppress_whiletrailers{$linenr} && 2233 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 2234 my ($s, $c) = ($stat, $cond); 2235 2236# if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 2237# ERROR("do not use assignment in if condition\n" . $herecurr); 2238# } 2239 2240 # Find out what is on the end of the line after the 2241 # conditional. 2242 substr($s, 0, length($c), ''); 2243 $s =~ s/\n.*//g; 2244 $s =~ s/$;//g; # Remove any comments 2245 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 2246 $c !~ /}\s*while\s*/) 2247 { 2248 # Find out how long the conditional actually is. 2249 my @newlines = ($c =~ /\n/gs); 2250 my $cond_lines = 1 + $#newlines; 2251 my $stat_real = ''; 2252 2253 $stat_real = raw_line($linenr, $cond_lines) 2254 . "\n" if ($cond_lines); 2255 if (defined($stat_real) && $cond_lines > 1) { 2256 $stat_real = "[...]\n$stat_real"; 2257 } 2258 2259 ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real); 2260 } 2261 } 2262 2263# Check for bitwise tests written as boolean 2264 if ($line =~ / 2265 (?: 2266 (?:\[|\(|\&\&|\|\|) 2267 \s*0[xX][0-9]+\s* 2268 (?:\&\&|\|\|) 2269 | 2270 (?:\&\&|\|\|) 2271 \s*0[xX][0-9]+\s* 2272 (?:\&\&|\|\||\)|\]) 2273 )/x) 2274 { 2275 ERROR("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 2276 } 2277 2278# if and else should not have general statements after it 2279 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 2280 my $s = $1; 2281 $s =~ s/$;//g; # Remove any comments 2282 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 2283 ERROR("trailing statements should be on next line\n" . $herecurr); 2284 } 2285 } 2286# if should not continue a brace 2287 if ($line =~ /}\s*if\b/) { 2288 ERROR("trailing statements should be on next line\n" . 2289 $herecurr); 2290 } 2291# case and default should not have general statements after them 2292 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 2293 $line !~ /\G(?: 2294 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 2295 \s*return\s+ 2296 )/xg) 2297 { 2298 ERROR("trailing statements should be on next line\n" . $herecurr); 2299 } 2300 2301 # Check for }<nl>else {, these must be at the same 2302 # indent level to be relevant to each other. 2303 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 2304 $previndent == $indent) { 2305 ERROR("else should follow close brace '}'\n" . $hereprev); 2306 } 2307 2308 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 2309 $previndent == $indent) { 2310 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 2311 2312 # Find out what is on the end of the line after the 2313 # conditional. 2314 substr($s, 0, length($c), ''); 2315 $s =~ s/\n.*//g; 2316 2317 if ($s =~ /^\s*;/) { 2318 ERROR("while should follow close brace '}'\n" . $hereprev); 2319 } 2320 } 2321 2322#no spaces allowed after \ in define 2323 if ($line=~/\#\s*define.*\\\s$/) { 2324 ERROR("Whitespace after \\ makes next lines useless\n" . $herecurr); 2325 } 2326 2327# multi-statement macros should be enclosed in a do while loop, grab the 2328# first statement and ensure its the whole macro if its not enclosed 2329# in a known good container 2330 if ($realfile !~ m@/vmlinux.lds.h$@ && 2331 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 2332 my $ln = $linenr; 2333 my $cnt = $realcnt; 2334 my ($off, $dstat, $dcond, $rest); 2335 my $ctx = ''; 2336 2337 my $args = defined($1); 2338 2339 # Find the end of the macro and limit our statement 2340 # search to that. 2341 while ($cnt > 0 && defined $lines[$ln - 1] && 2342 $lines[$ln - 1] =~ /^(?:-|..*\\$)/) 2343 { 2344 $ctx .= $rawlines[$ln - 1] . "\n"; 2345 $cnt-- if ($lines[$ln - 1] !~ /^-/); 2346 $ln++; 2347 } 2348 $ctx .= $rawlines[$ln - 1]; 2349 2350 ($dstat, $dcond, $ln, $cnt, $off) = 2351 ctx_statement_block($linenr, $ln - $linenr + 1, 0); 2352 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 2353 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 2354 2355 # Extract the remainder of the define (if any) and 2356 # rip off surrounding spaces, and trailing \'s. 2357 $rest = ''; 2358 while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { 2359 #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; 2360 if ($off != 0 || $lines[$ln - 1] !~ /^-/) { 2361 $rest .= substr($lines[$ln - 1], $off) . "\n"; 2362 $cnt--; 2363 } 2364 $ln++; 2365 $off = 0; 2366 } 2367 $rest =~ s/\\\n.//g; 2368 $rest =~ s/^\s*//s; 2369 $rest =~ s/\s*$//s; 2370 2371 # Clean up the original statement. 2372 if ($args) { 2373 substr($dstat, 0, length($dcond), ''); 2374 } else { 2375 $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; 2376 } 2377 $dstat =~ s/$;//g; 2378 $dstat =~ s/\\\n.//g; 2379 $dstat =~ s/^\s*//s; 2380 $dstat =~ s/\s*$//s; 2381 2382 # Flatten any parentheses and braces 2383 while ($dstat =~ s/\([^\(\)]*\)/1/ || 2384 $dstat =~ s/\{[^\{\}]*\}/1/ || 2385 $dstat =~ s/\[[^\{\}]*\]/1/) 2386 { 2387 } 2388 2389 my $exceptions = qr{ 2390 $Declare| 2391 module_param_named| 2392 MODULE_PARAM_DESC| 2393 DECLARE_PER_CPU| 2394 DEFINE_PER_CPU| 2395 __typeof__\(| 2396 union| 2397 struct| 2398 \.$Ident\s*=\s*| 2399 ^\"|\"$ 2400 }x; 2401 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 2402 if ($rest ne '' && $rest ne ',') { 2403 if ($rest !~ /while\s*\(/ && 2404 $dstat !~ /$exceptions/) 2405 { 2406 ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 2407 } 2408 2409 } elsif ($ctx !~ /;/) { 2410 if ($dstat ne '' && 2411 $dstat !~ /^(?:$Ident|-?$Constant)$/ && 2412 $dstat !~ /$exceptions/ && 2413 $dstat !~ /^\.$Ident\s*=/ && 2414 $dstat =~ /$Operators/) 2415 { 2416 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 2417 } 2418 } 2419 } 2420 2421# check for missing bracing around if etc 2422 if ($line =~ /(^.*)\b(?:if|while|for)\b/ && 2423 $line !~ /\#\s*if/) { 2424 my $allowed = 0; 2425 2426 # Check the pre-context. 2427 if ($line =~ /(\}.*?)$/) { 2428 my $pre = $1; 2429 2430 if ($line !~ /else/) { 2431 print "APW: ALLOWED: pre<$pre> line<$line>\n" 2432 if $dbg_adv_apw; 2433 $allowed = 1; 2434 } 2435 } 2436 my ($level, $endln, @chunks) = 2437 ctx_statement_full($linenr, $realcnt, 1); 2438 if ($dbg_adv_apw) { 2439 print "APW: chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 2440 print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n" 2441 if $#chunks >= 1; 2442 } 2443 if ($#chunks >= 0 && $level == 0) { 2444 my $seen = 0; 2445 my $herectx = $here . "\n"; 2446 my $ln = $linenr - 1; 2447 for my $chunk (@chunks) { 2448 my ($cond, $block) = @{$chunk}; 2449 2450 # If the condition carries leading newlines, then count those as offsets. 2451 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 2452 my $offset = statement_rawlines($whitespace) - 1; 2453 2454 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 2455 2456 # We have looked at and allowed this specific line. 2457 $suppress_ifbraces{$ln + $offset} = 1; 2458 2459 $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 2460 $ln += statement_rawlines($block) - 1; 2461 2462 substr($block, 0, length($cond), ''); 2463 2464 my $spaced_block = $block; 2465 $spaced_block =~ s/\n\+/ /g; 2466 2467 $seen++ if ($spaced_block =~ /^\s*\{/); 2468 2469 print "APW: cond<$cond> block<$block> allowed<$allowed>\n" 2470 if $dbg_adv_apw; 2471 if (statement_lines($cond) > 1) { 2472 print "APW: ALLOWED: cond<$cond>\n" 2473 if $dbg_adv_apw; 2474 $allowed = 1; 2475 } 2476 if ($block =~/\b(?:if|for|while)\b/) { 2477 print "APW: ALLOWED: block<$block>\n" 2478 if $dbg_adv_apw; 2479 $allowed = 1; 2480 } 2481 if (statement_block_size($block) > 1) { 2482 print "APW: ALLOWED: lines block<$block>\n" 2483 if $dbg_adv_apw; 2484 $allowed = 1; 2485 } 2486 } 2487 $allowed=1; # disable for now. 2488 if ($seen != ($#chunks + 1) && !$allowed) { 2489 ERROR("braces {} are necessary for all arms of this statement\n" . $herectx); 2490 } 2491 } 2492 } 2493 if (!defined $suppress_ifbraces{$linenr - 1} && 2494 $line =~ /\b(if|while|for|else)\b/ && 2495 $line !~ /\#\s*if/ && 2496 $line !~ /\#\s*else/) { 2497 my $allowed = 0; 2498 2499 # Check the pre-context. 2500 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 2501 my $pre = $1; 2502 2503 if ($line !~ /else/) { 2504 print "APW: ALLOWED: pre<$pre> line<$line>\n" 2505 if $dbg_adv_apw; 2506 $allowed = 1; 2507 } 2508 } 2509 2510 my ($level, $endln, @chunks) = 2511 ctx_statement_full($linenr, $realcnt, $-[0]); 2512 2513 # Check the condition. 2514 my ($cond, $block) = @{$chunks[0]}; 2515 print "CHECKING<$linenr> cond<$cond> block<$block>\n" 2516 if $dbg_adv_checking; 2517 if (defined $cond) { 2518 substr($block, 0, length($cond), ''); 2519 } 2520 if (statement_lines($cond) > 1) { 2521 print "APW: ALLOWED: cond<$cond>\n" 2522 if $dbg_adv_apw; 2523 $allowed = 1; 2524 } 2525 if ($block =~/\b(?:if|for|while)\b/) { 2526 print "APW: ALLOWED: block<$block>\n" 2527 if $dbg_adv_apw; 2528 $allowed = 1; 2529 } 2530 if (statement_block_size($block) > 1) { 2531 print "APW: ALLOWED: lines block<$block>\n" 2532 if $dbg_adv_apw; 2533 $allowed = 1; 2534 } 2535 # Check the post-context. 2536 if (defined $chunks[1]) { 2537 my ($cond, $block) = @{$chunks[1]}; 2538 if (defined $cond) { 2539 substr($block, 0, length($cond), ''); 2540 } 2541 if ($block =~ /^\s*\{/) { 2542 print "APW: ALLOWED: chunk-1 block<$block>\n" 2543 if $dbg_adv_apw; 2544 $allowed = 1; 2545 } 2546 } 2547 print "DCS: level=$level block<$block> allowed=$allowed\n" 2548 if $dbg_adv_dcs; 2549 if ($level == 0 && $block !~ /^\s*\{/ && !$allowed) { 2550 my $herectx = $here . "\n";; 2551 my $cnt = statement_rawlines($block); 2552 2553 for (my $n = 0; $n < $cnt; $n++) { 2554 $herectx .= raw_line($linenr, $n) . "\n";; 2555 } 2556 2557 WARN("braces {} are encouraged even for single statement blocks\n" . $herectx); 2558 } 2559 } 2560 2561# warn about #if 0 2562 if ($line =~ /^.\s*\#\s*if\s+0\b/) { 2563 ERROR("if this code is redundant consider removing it\n" . 2564 $herecurr); 2565 } 2566 2567# Check that the storage class is at the beginning of a declaration 2568 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 2569 ERROR("storage class should be at the beginning of the declaration\n" . $herecurr) 2570 } 2571 2572# check the location of the inline attribute, that it is between 2573# storage class and type. 2574 if ($line =~ /\b$Type\s+$Inline\b/ || 2575 $line =~ /\b$Inline\s+$Storage\b/) { 2576 ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 2577 } 2578 2579# check for sizeof(&) 2580 if ($line =~ /\bsizeof\s*\(\s*\&/) { 2581 ERROR("sizeof(& should be avoided\n" . $herecurr); 2582 } 2583 2584# check for new externs in .c files. 2585 if ($realfile =~ /\.c$/ && defined $stat && 2586 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 2587 { 2588 my $function_name = $1; 2589 my $paren_space = $2; 2590 2591 my $s = $stat; 2592 if (defined $cond) { 2593 substr($s, 0, length($cond), ''); 2594 } 2595 if ($s =~ /^\s*;/ && 2596 $function_name ne 'uninitialized_var') 2597 { 2598 ERROR("externs should be avoided in .c files\n" . $herecurr); 2599 } 2600 2601 if ($paren_space =~ /\n/) { 2602 ERROR("arguments for function declarations should follow identifier\n" . $herecurr); 2603 } 2604 2605 } elsif ($realfile =~ /\.c$/ && defined $stat && 2606 $stat =~ /^.\s*extern\s+/) 2607 { 2608 ERROR("externs should be avoided in .c files\n" . $herecurr); 2609 } 2610 2611# check for gcc specific __FUNCTION__ 2612 if ($line =~ /__FUNCTION__/) { 2613 ERROR("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 2614 } 2615 2616# recommend sigaction over signal for portability, when establishing a handler 2617 if ($line =~ /\bsignal\s*\(/ && !($line =~ /SIG_(?:IGN|DFL)/)) { 2618 ERROR("use sigaction to establish signal handlers; signal is not portable\n" . $herecurr); 2619 } 2620 2621# format strings checks 2622 my $string; 2623 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 2624 $string = substr($rawline, $-[1], $+[1] - $-[1]); 2625 $string =~ s/%%/__/g; 2626 # check for %L{u,d,i} in strings 2627 if ($string =~ /(?<!%)%L[udi]/) { 2628 ERROR("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 2629 } 2630 } 2631 2632 # Continue checking for error messages that contains newlines. This 2633 # check handles cases where string literals are spread over multiple lines. 2634 # Example: 2635 # error_report("Error msg line #1" 2636 # "Error msg line #2\n"); 2637 my $quoted_newline_regex = qr{\+\s*\".*\\n.*\"}; 2638 my $continued_str_literal = qr{\+\s*\".*\"}; 2639 2640 if ($rawline =~ /$quoted_newline_regex/) { 2641 # Backtrack to first line that does not contain only a quoted literal 2642 # and assume that it is the start of the statement. 2643 my $i = $linenr - 2; 2644 2645 while (($i >= 0) & $rawlines[$i] =~ /$continued_str_literal/) { 2646 $i--; 2647 } 2648 } 2649 2650 } 2651 2652 # If we have no input at all, then there is nothing to report on 2653 # so just keep quiet. 2654 if ($#rawlines == -1) { 2655 return 1; 2656 } 2657 2658 # In mailback mode only produce a report in the negative, for 2659 # things that appear to be patches. 2660 if ($mailback && ($clean == 1 || !$is_patch)) { 2661 return 1; 2662 } 2663 2664 # This is not a patch, and we are are in 'no-patch' mode so 2665 # just keep quiet. 2666 if (!$chk_patch && !$is_patch) { 2667 return 1; 2668 } 2669 2670 if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 2671 ERROR("Does not appear to be a unified-diff format patch\n"); 2672 } 2673 2674 print report_dump(); 2675 if ($summary && !($clean == 1 && $quiet == 1)) { 2676 print "$filename " if ($summary_file); 2677 print "total: $cnt_error errors, $cnt_warn warnings, " . 2678 "$cnt_lines lines checked\n"; 2679 print "\n" if ($quiet == 0); 2680 } 2681 2682 if ($quiet == 0) { 2683 # If there were whitespace errors which cleanpatch can fix 2684 # then suggest that. 2685# if ($rpt_cleaners) { 2686# print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 2687# print " scripts/cleanfile\n\n"; 2688# } 2689 } 2690 2691 if ($clean == 1 && $quiet == 0) { 2692 print "$vname has no obvious style problems and is ready for submission.\n" 2693 } 2694 2695 return ($no_warnings ? $clean : $cnt_error == 0); 2696} 2697