scan-build revision 9f9b1fded49acff77e61b3ed1afc8bbaaefe6f34
19cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek#!/usr/bin/env perl 29cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 39cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# The LLVM Compiler Infrastructure 49cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 59cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# This file is distributed under the University of Illinois Open Source 69cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# License. See LICENSE.TXT for details. 79cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 89cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 99cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# A script designed to wrap a build so that all calls to gcc are intercepted 119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# and piped to the static analyzer. 129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse strict; 169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse warnings; 1722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenekuse FindBin qw($RealBin); 18a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenekuse Digest::MD5; 197a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekuse File::Basename; 2023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor; 2123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor qw(:constants); 229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 25f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 26f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 2795aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekmy $CXX; # Leave undefined initially. 289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 290e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 300e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT 310e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 33b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 34b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 35b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 36b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 3723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 3823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 3923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 4023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 4123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 4223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 4323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 4423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 4523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 4623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 47991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 48991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 49991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("The analyzer crashed on some source files.\n"); 50386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek Diag ("Preprocessed versions of crashed files were deposited in '$Dir/crashes'.\n"); 51991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 52991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n") 53991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 54991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, RED "$Prog: "; 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET, RED @_; 5923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 6023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 6123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 6223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: ", @_; 6323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 6423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek exit(0); 6523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 6623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 68b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Some initial preprocessing of Clang options. 69b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 70b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 71b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $ClangSB = "$RealBin/clang"; 72b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $Clang = $ClangSB; 73b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 74b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekif (! -x $ClangSB) { 75b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $Clang = "clang"; 76b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 77b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 78b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AvailableAnalyses; 79b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 80b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Query clang for analysis options. 8163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenekopen(PIPE, "-|", $Clang, "--help") or 82b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek DieDiag("Cannot execute '$Clang'"); 8363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 84b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $FoundAnalysis = 0; 85b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 86b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekwhile(<PIPE>) { 87b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if ($FoundAnalysis == 0) { 88b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if (/Available Source Code Analyses/) { 89b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $FoundAnalysis = 1; 90b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 91991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 92b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 93b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 94b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 95b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if (/^\s\s\s\s([^\s]+)\s(.+)$/) { 96b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next if ($1 =~ /-dump/ or $1 =~ /-view/ 97b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek or $1 =~ /-checker-simple/ or $1 =~ /-warn-uninit/); 98b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 99b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $AvailableAnalyses{$1} = $2; 100b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 101b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 102b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 103b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek last; 104b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 105b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 106b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekclose (PIPE); 107b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 108b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AnalysesDefaultEnabled = ( 109b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-warn-dead-stores' => 1, 110b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-checker-cfref' => 1, 1119012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek '-warn-objc-methodsigs' => 1, 112bde3a051933b6829ed79d6db0118231c2c01b105Ted Kremenek '-warn-objc-missing-dealloc' => 1, 113bde3a051933b6829ed79d6db0118231c2c01b105Ted Kremenek '-warn-objc-unused-ivars' => 1 114b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek); 115b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 116b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 117fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 120a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub GetHTMLRunDir { 1219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 122fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "Not enough arguments." if (@_ == 0); 1239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift @_; 124fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 125fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 126fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 127fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $Dir = "/tmp"; 128fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 129fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 130fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 1329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @CurrentTime = localtime(); 1349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 1389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1399d7405fafd5bc08d38bc75579927bf414570bd61Ted Kremenek my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 1409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Determine the run number. 1429cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 1449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-d $Dir) { 1469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 14823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 1499cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1509cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1519cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Iterate over all files in the specified directory. 1529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $max = 0; 1549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 15629da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 1589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek foreach my $f (@FILES) { 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 161fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 162fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 163fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 164fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 165fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 166fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 168fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 1709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 1719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 1729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 1739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($x[3] > $max) { 1759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $max = $x[3]; 1769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 1809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 1829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 18423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 1859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 186fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 187fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 188fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed."); 189fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 190fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # $Dir does not exist. It will be automatically created by the 1929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # clang driver. Set the run number to 1. 193fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 1959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 197fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 1989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1999cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 200fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 201fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 202fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 203fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 204fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 205fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 206fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 207fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek system 'mkdir','-p',$NewDir; 208fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 2099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 211a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 2129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 2149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 2169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 2179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 2199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2209cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Cmd =~ /configure/) { 2239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 22723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 23457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 23557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 23657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 23757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 23857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 23923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 240a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 241a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2427ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2437ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 24463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # come bundled on most systems. 24523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 246a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 247a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 248a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 249a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 25063c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Return the digest. 251a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 25257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 25357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 25457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 2557a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 2567a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2577a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2587a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 2597a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2607a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 2617a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 2627a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 2637a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 2647a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2657a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek # Ignore /usr, /Library, /System, /Developer 2667a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return if ( $x =~ /^\/usr/ or $x =~ /^\/Library/ 2677a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek or $x =~ /^\/System/ or $x =~ /^\/Developer/); 2687a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2697a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 2707a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 2717a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 2727a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 2737a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 27420b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 2757a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2767a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2777a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 2787a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 2797a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2807a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2817a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2827a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 2837a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2847a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2857a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 2867a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 2877a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 2887a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 28963c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2907a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 29163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 29263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2937a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 2947a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 2957a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 2967a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 29763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2987a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 2997a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 30020161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("mv", "$fname.tmp", $fname); 3017a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3027a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3037a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3045744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3055744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3065744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 30757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 30857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 30957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 31057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 31157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3125744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 3135744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3145744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3155744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3165744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3175744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 31857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 31957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 32057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 32157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 32257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 323fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 32457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 32520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-f", "$Dir/$FName"); 32657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 32757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 32857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 32957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 33057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 331809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 33220161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("chmod", "644", "$Dir/$FName"); 333684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek 334684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 33523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3365744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3375744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $BugDesc = ""; 33822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugFile = ""; 33922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugPathLength = 1; 34022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugLine = 0; 3415744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3425744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 3435744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3445744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek if (/<!-- BUGDESC (.*) -->$/) { 3455744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek $BugDesc = $1; 3465744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 34722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 34822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugFile = $1; 3497a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 35022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 35122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 35222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 35322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 35422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 35522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugLine = $1; 35622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 3575744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 3585744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3595744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 3605744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 36122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek push @$Index,[ $FName, $BugDesc, $BugFile, $BugLine, $BugPathLength ]; 36222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 36322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 36422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 36522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek# CopyJS - Copy JavaScript code to target directory. 36622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 36722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 36822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremeneksub CopyJS { 36922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 37022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 37122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 37223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 37322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$RealBin/sorttable.js"); 37422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 37520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("cp", "$RealBin/sorttable.js", "$Dir"); 37622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 37723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 37822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 3795744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 3805744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3815744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 3839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 3849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 385a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 3869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 3879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 388684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek my $BaseDir = shift; 3899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 390fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 3919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 3929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 39323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 394363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 3959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 3969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 3979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 398991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Crashes = 0; 399991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @files = grep { if ($_ eq "crashes") { $Crashes++; } 400991c54b9b7409656e5593364e065878b5210d556Ted Kremenek /^report-.*\.html$/; } readdir(DIR); 4019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 4029cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 403991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files) == 0 and $Crashes == 0) { 40423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Removing directory '$Dir' because it contains no reports.\n"); 40520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-fR", $Dir); 406363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4085744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 409991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Scan each report file and build an index. 410991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @Index; 4115744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); } 4125744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 413d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # Scan the crashes directory and use the information in the .info files 414d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 415d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (-d "$Dir/crashes") { 416d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek opendir(DIR, "$Dir/crashes"); 417d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my @files = grep { /[.]info$/; } readdir(DIR); 418d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 419d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek foreach my $file (@files) { 420d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek open IN, "$Dir/crashes/$file" or DieDiag("cannot open $file\n"); 421d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 422d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 423d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 424d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 425d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 426d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 42763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Generate an index.html file. 42863c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek my $FName = "$Dir/index.html"; 42963c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 4305744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4316e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 4326e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 4335744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 4345744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 4355744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 4367f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek<style type="text/css"> 4377f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek body { color:#000000; background-color:#ffffff } 43822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek body { font-family: Helvetica, sans-serif; font-size:9pt } 4397f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek h1 { font-size:12pt } 440991c54b9b7409656e5593364e065878b5210d556Ted Kremenek table thead { 44122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek background-color:#eee; color:#666666; 44222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek font-weight: bold; cursor: default; 443bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek text-align:center; 444bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek border-top: 2px solid #000000; 445bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek border-bottom: 2px solid #000000; 446bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek font-weight: bold; font-family: Verdana 447bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek } 448991c54b9b7409656e5593364e065878b5210d556Ted Kremenek table { border: 1px #000000 solid } 449991c54b9b7409656e5593364e065878b5210d556Ted Kremenek table { border-collapse: collapse; border-spacing: 0px } 4507f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek td { border-bottom: 1px #000000 dotted } 45122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek td { padding:5px; padding-left:8px; padding-right:8px } 452d8c6d0c8a5f970240cc4cbf8eddeae037d1b29eaTed Kremenek td { text-align:left; font-size:9pt } 45322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek td.View { padding-left: 10px } 4547f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek</style> 45522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 4566e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 4576e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 4586e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 4596e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 4606e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 4616e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 4626e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 4636e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4646e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4656e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 4666e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 4676e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 4686e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 4696e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 4706e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4716e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 4726e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 4736e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4746e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 4756e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 4766e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 4776e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 4786e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 4796e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 480991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 481991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 482991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 4836e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 484991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 485991c54b9b7409656e5593364e065878b5210d556Ted Kremenek #my $bug_type = lc($row->[1]); 486991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $bug_type = ($row->[1]); 4876e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 488991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (!defined $Totals{$bug_type}) { $Totals{$bug_type} = 1; } 489991c54b9b7409656e5593364e065878b5210d556Ted Kremenek else { $Totals{$bug_type}++; } 4906e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 491991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 492991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "<h3>Bug Summary</h3>"; 493991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 494991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 495991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 4966e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 497f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 4986e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 4996e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<table class="sortable"> 5006e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<tr> 5016e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek <td>Bug Type</td> 5026e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek <td>Quantity</td> 5032645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort">Display?</td> 5046e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</tr> 5056e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 5066e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 507991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $key ( sort { $a cmp $b } keys %Totals ) { 508991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $x = lc($key); 509991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $x =~ s/[ ,'"]+/_/g; 510991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "<tr><td>$key</td><td>$Totals{$key}</td><td><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></td></tr>\n"; 511991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5126e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5136e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 5146e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5156e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 5166e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 5176e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<h3>Reports</h3> 51822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<table class="sortable"> 5197f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek<tr> 52088a96d6c3fe2b1b9d80b39c21cf7aca4aa9fcf08Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span> 521bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 522bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>Line</td> 523bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>Path Length</td> 5242645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 5257f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek</tr> 5265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 5279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 528991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 529991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 530991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 531991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 5327a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 533991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $prefix) { 534991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $regex = qr/^\Q$prefix\E/is; 535991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 536991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5377a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 538991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( sort { $a->[1] cmp $b->[1] } @Index ) { 5395744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 540991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $x = lc($row->[1]); 541991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $x =~ s/[ ,'"]+/_/g; 5426e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 543991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "<tr class=\"bt_$x\">\n"; 5445744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 545991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 5469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 547991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT " <td class=\"DESC\">"; 548991c54b9b7409656e5593364e065878b5210d556Ted Kremenek #print OUT lc($row->[1]); 549991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 550991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</td>\n"; 5515744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 552991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Update the file prefix. 5537a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 554991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $fname = $row->[2]; 555991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 556991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 557991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 558991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5593e56e0b8b285e86eed4d191b1da93ded7382a847Ted Kremenek 560991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "<td>$fname</td>\n"; 5617a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 562991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 563991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $j ( 3 .. $#{$row} ) { 564991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "<td>$row->[$j]</td>\n" 565991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5667f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 567991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 568991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT " <td class=\"View\"><a href=\"$ReportFile#EndPath\">View</a></td>\n"; 5693cea9ee6b77ac797ebb910bdf45d1d7f8f68e37bTed Kremenek 570991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 571991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 572991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 573991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 574991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</table>\n"; 575991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 576991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 577991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if ($Crashes) { 578991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Read the crash directory for files. 579991c54b9b7409656e5593364e065878b5210d556Ted Kremenek opendir(DIR, "$Dir/crashes"); 580991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @files = grep { /[.]info$/ } readdir(DIR); 581991c54b9b7409656e5593364e065878b5210d556Ted Kremenek closedir(DIR); 582991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 583991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 584991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT <<ENDTEXT; 5855d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek<h3>Analyzer Failures</h3> 586991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 5875d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek<p>The analyzer had problems processing the following files:</p> 588991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 589991c54b9b7409656e5593364e065878b5210d556Ted Kremenek<table> 5909f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead> 591991c54b9b7409656e5593364e065878b5210d556Ted KremenekENDTEXT 592991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 593991c54b9b7409656e5593364e065878b5210d556Ted Kremenek foreach my $file (sort @files) { 594991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $file =~ /(.+).info$/; 595991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 596991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 597991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 598991c54b9b7409656e5593364e065878b5210d556Ted Kremenek open (INFO, "$Dir/crashes/$file") or 599991c54b9b7409656e5593364e065878b5210d556Ted Kremenek die "Cannot open $Dir/crashes/$file\n"; 600991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 6015d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 6025d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 6035d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 604991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 605991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 606d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 6079f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 6089f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"crashes/$ppfile\">$ppfile</a></td><td><a href=\"crashes/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; 609991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 610991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 611991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT <<ENDTEXT; 612991c54b9b7409656e5593364e065878b5210d556Ted Kremenek</table> 613991c54b9b7409656e5593364e065878b5210d556Ted Kremenek<p>Please consider submitting preprocessed files as <a href="http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs">bug reports</a>.</p> 614991c54b9b7409656e5593364e065878b5210d556Ted KremenekENDTEXT 615991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6165744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 6175744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 618991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</body></html>\n"; 6195744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 62022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek CopyJS($Dir); 62120161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 62220161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 62320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("chmod", "755", $Dir); 624fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 62520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 62623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 627150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("$Num bugs found.\n"); 628150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 629150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("Open '$Dir/index.html' to examine bug reports.\n"); 630150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 631363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 632991c54b9b7409656e5593364e065878b5210d556Ted Kremenek DiagCrashes($Dir) if ($Crashes); 633991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 634363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 6359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 6369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 6379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 638dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 639dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 640dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 6416b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 6426b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 6436b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Arg = shift; 6446b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 6456b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 6466b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 6476b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 6486b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 6496b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 6506b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 6516b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 6526b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 6536b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 6546b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 6556b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 6566b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 6576b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 658dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremeneksub RunBuildCommand { 659dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 660dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 6617442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 662dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 6636195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 664dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 6653301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek # Get only the part of the command after the last '/'. 6663301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek if ($Cmd =~ /\/([^\/]+)$/) { 6673301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek $Cmd = $1; 6683301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek } 6693301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek 67063c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek if ($Cmd eq "gcc" or $Cmd eq "cc" or $Cmd eq "llvm-gcc" 67163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek or $Cmd eq "ccc-analyzer") { 672dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 6736195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 674dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 6757442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($IgnoreErrors) { 6767442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek if ($Cmd eq "make" or $Cmd eq "gmake") { 6776b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 6788912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 6797442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 6807442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($Cmd eq "xcodebuild") { 6816b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 6827442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 6836b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 6846b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 6856b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($Cmd eq "xcodebuild") { 686cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable distributed builds for xcodebuild. 6876b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-nodistribute"); 688cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek 689cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable PCH files until clang supports them. 690cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 691915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek 692915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 693915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 694915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # when linking such files. 69595aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek die if (!defined $CXX); 69695aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek my $LDPLUSPLUS = `which $CXX`; 697915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $LDPLUSPLUS =~ s/\015?\012//; # strip newlines 698915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS; 6996b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 700dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 7015a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 702dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 703dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 704dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 7059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 7069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 7079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 708a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 7099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 7105744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 711a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 7122b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 713f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 714f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 715fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 716f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 717f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 718f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 719f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 7202b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 7212b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 722363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -o - Target directory for HTML report files. Subdirectories 723a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop will be created as needed to represent separate "runs" of 7242b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek the analyzer. If this option is not specified, a directory 7252b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek is created in /tmp to store the reports. 7261262fc4d66584224234691d30d779f8ff004585cTed Kremenek 727363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -h - Display this message. 728363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 7291262fc4d66584224234691d30d779f8ff004585cTed Kremenek 730363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -k - Add a "keep on going" option to the specified build command. 731363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --keep-going This option currently supports make and xcodebuild. 732f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek This is a convenience option; one can specify this 733f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek behavior directly using build options. 7342b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 735363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --status-bugs - By default, the exit status of $Prog is the same as the 736363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek executed build command. Specifying this option causes the 737363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit status of $Prog to be 1 if it found potential bugs 738363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek and 0 otherwise. 7392b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 740386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link 741386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc=[compiler path] your C and Objective-C code. Use this option 742386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 743386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 744386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link 745386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option 746386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 747f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 748363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -v - Verbose output from $Prog and the analyzer. 749386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek A second and third '-v' increases verbosity. 750363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 751363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -V - View analysis results in a web browser when the build 752363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --view completes. 7537f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 754b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 755386c69316668b9ea8c2591af56f994be16e3ff62Ted KremenekAVAILABLE ANALYSES (multiple analyses may be specified): 756d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 757d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 758b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 759b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek foreach my $Analysis (sort keys %AvailableAnalyses) { 760fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AnalysesDefaultEnabled{$Analysis}) { 761363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " (+)"; 762b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 763b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek else { 764363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " "; 765b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 766b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 767b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek print " $Analysis $AvailableAnalyses{$Analysis}\n"; 768b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 769b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 770b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 771b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 772363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek NOTE: "(+)" indicates that an analysis is enabled by default unless one 773363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek or more analysis options are specified 774b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 7752b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 7762b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 777363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 77839eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 7795744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 7802b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 781363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $Prog -o /tmp/myhtmldir make -j4 7822b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 783363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The above example causes analysis reports to be deposited into 784363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option. 785363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek A different subdirectory is created each time $Prog analyzes a project. 786363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The analyzer should support most parallel builds, but not distributed builds. 7872b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 7882b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 7899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 7909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 7919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 7929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 7939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 7949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 7959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 7969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 7977f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 798363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 799b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 8009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 8029cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 803a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 8049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 8079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 8099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 8119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8122f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 8139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 814a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 0; 8159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 8169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 817fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AvailableAnalyses{$arg}) { 8181262fc4d66584224234691d30d779f8ff004585cTed Kremenek shift @ARGV; 819b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek push @AnalysesToRun, $arg; 8201262fc4d66584224234691d30d779f8ff004585cTed Kremenek next; 8211262fc4d66584224234691d30d779f8ff004585cTed Kremenek } 8221262fc4d66584224234691d30d779f8ff004585cTed Kremenek 8239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 8249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 8259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 82723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 8289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 8299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $HtmlDir = shift @ARGV; 8319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 8329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 8339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8342b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 8359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 8369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 8379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 8389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 8399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 840f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 841f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 842f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 843f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 844f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($2 eq "") { 845f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 846f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 847f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 848f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 849f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 850f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 851f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 852f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 853f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 854f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 855f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 856f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 857f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 858386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if ($arg =~ /^--use-c[+][+](=(.+))?$/) { 859386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 860386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 861386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if ($2 eq "") { 862386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 863386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 864386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 865386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = shift @ARGV; 866386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 867386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 868386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = $2; 869386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 870386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 871386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 872386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 8739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 8749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 8759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 8769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 8779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 8789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8797f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 8807f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 8817f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek $ViewResults = 1; 8827f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 8837f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 8847f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 885363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 886363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 887363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 888363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 889363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 890363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 89123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 8920062ad4f47d152def1f720878aaf5904b22aefbfTed Kremenek 8939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 8949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 89723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No build command specified.\n\n"); 8989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 899a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 9009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 9019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 902386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 903386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 9049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 905684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 906a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 9079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Set the appropriate environment variables. 909a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopSetHtmlEnv(\@ARGV, $HtmlDir); 9109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9110b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenekmy $Cmd = "$RealBin/ccc-analyzer"; 9120b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 91323cfca3760c482f8543daab62051f5eaa1f98fb4Ted KremenekDieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") 9140b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek if (! -x $Cmd); 915f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 916b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekif (! -x $ClangSB) { 917b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek Diag("'clang' executable not found in '$RealBin'.\n"); 918b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek Diag("Using 'clang' from path.\n"); 919f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek} 9200b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 92195aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekif (defined $CXX) { 92295aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $ENV{'CXX'} = $CXX; 92395aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 92495aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekelse { 92595aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $CXX = 'g++'; # This variable is used by other parts of scan-build 92695aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek # that need to know a default C++ compiler to fall back to. 92795aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 92895aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek 9294f4b17da43d3be87a248e1e10bf0b7d8b5891efdTed Kremenek$ENV{'CC'} = $Cmd; 930f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek$ENV{'CLANG'} = $Clang; 9319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif ($Verbose >= 2) { 9339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 9349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 9359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 936a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenekif ($Verbose >= 3) { 937a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 938a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek} 939a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek 9409012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenekif (scalar(@AnalysesToRun) == 0) { 9419012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek foreach my $key (keys %AnalysesDefaultEnabled) { 9429012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek push @AnalysesToRun,$key; 9439012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek } 94401006786e3760cc48c5e94d731b468b811b976d2Ted Kremenek} 9451262fc4d66584224234691d30d779f8ff004585cTed Kremenek 9469012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun; 9479012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek 9489cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 9495656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd); 9509cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9519cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess the HTML directory. 952363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $NumBugs = Postprocess($HtmlDir, $BaseDir); 9537f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 9547f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekif ($ViewResults and -r "$HtmlDir/index.html") { 9557f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek # Only works on Mac OS X (for now). 9567f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek print "Viewing analysis results: '$HtmlDir/index.html'\n"; 95720161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("open", "$HtmlDir/index.html"); 9587f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek} 9595656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 960363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekif ($ExitStatusFoundBugs) { 961363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit 1 if ($NumBugs > 0); 962363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit 0; 963363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 964363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 9655656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 9665656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 967