scan-build revision 7a334d9ed9ff7426e78a88582207b47b370ec5de
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); 22cd25c13ade3afa829c87ca1ed0ed0d379f426251Ted Kremenekuse Cwd qw/ getcwd abs_path /; 237cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Sys::Hostname; 249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 27f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 28f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 300e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 31c9480dd03522f0bab5fff7d30402cb7ee31117dcTed Kremenekmy $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT 320e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 347cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $UserName = HtmlEscape(getpwuid($<) || 'unknown'); 357cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HostName = HtmlEscape(hostname() || 'unknown'); 367cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDir = HtmlEscape(getcwd()); 377cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDirSuffix = basename($CurrentDir); 387cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 39f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksmy @PluginsToLoad; 407cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CmdArgs; 417cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 427cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HtmlTitle; 437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 447cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $Date = localtime(); 457cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 46b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 47b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 48b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 49b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 5023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 5123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 5323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 5423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 5923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 60991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 61991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 62938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("The analyzer encountered problems on some source files.\n"); 63938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 64991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 65e2c8663ad2b110712401145b866072bb94108058Nico Weber Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") 66991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 67991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 6923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 7023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, RED "$Prog: "; 7123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET, RED @_; 7223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 7323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 7523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: ", @_; 7623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek exit(0); 7823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 7923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 818db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek# Print default checker names 828db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek##----------------------------------------------------------------------------## 838db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek 848db26ce0464c712058ab60b72e2a70c04148020eTed Kremenekif (grep /^--help-checkers$/, @ARGV) { 858db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek my @options = qx($0 -h); 868db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek foreach (@options) { 878db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek next unless /^ \+/; 888db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek s/^\s*//; 898db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek my ($sign, $name, @text) = split ' ', $_; 908db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek print $name, $/ if $sign eq '+'; 918db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek } 928db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek exit 1; 938db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek} 948db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek 958db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek##----------------------------------------------------------------------------## 96810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek# Declaration of Clang options. Populated later. 97b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 98b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 99e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekmy $Clang; 100810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangSB; 101810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangCXX; 102810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangVersion; 103fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek 104b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 105fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 108a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub GetHTMLRunDir { 109fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "Not enough arguments." if (@_ == 0); 1102a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my $Dir = shift @_; 111fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 112fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 1133fa3c44d624d2df9ef2649ca1a7efa97d81b36d8Jordan Rose $Dir = $ENV{'TMPDIR'}; 1143fa3c44d624d2df9ef2649ca1a7efa97d81b36d8Jordan Rose if (!defined $Dir) { $Dir = "/tmp"; } 115fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 116fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 117bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek 118bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek # Chop off any trailing '/' characters. 119bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek while ($Dir =~ /\/$/) { chop $Dir; } 120fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 1222a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my @CurrentTime = localtime(); 1239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 1269d7405fafd5bc08d38bc75579927bf414570bd61Ted Kremenek my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 1279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1282a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek # Determine the run number. 1299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 1309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1312a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek if (-d $Dir) { 1329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 13323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 1342a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek } 1352a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek # Iterate over all files in the specified directory. 1362a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my $max = 0; 1379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 13829da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 1409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1412a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek foreach my $f (@FILES) { 142fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 143fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 144fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 145fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 146fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 147fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1489cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 1499cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 1509cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 1519cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 1529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 1539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($x[3] > $max) { 1559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $max = $x[3]; 1569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 1629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 16423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 1659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 166fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 167fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 168445fa776d2bc9207c33a9b9ab4afb9513f6b81b0Ted Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 169fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 170fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # $Dir does not exist. It will be automatically created by the 1729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # clang driver. Set the run number to 1. 173fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 1759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 177fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 1789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 180fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 181fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 182fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 183fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 184fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 185fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 186fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 187fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek system 'mkdir','-p',$NewDir; 188fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 1899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 1909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 191a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 1929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 1949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 1979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 1999cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2019e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek 2029e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { 2039cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 20723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 21457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 21557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 21657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 21757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 21857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 21923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 220a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 221a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2227ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2237ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 22463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # come bundled on most systems. 22523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 226a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 227a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 228a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 229a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 23063c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Return the digest. 231a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 23257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 23357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 23457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 2357a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 2367a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2377a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2387a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 2397a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2407a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 2417a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 2427a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 2437a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 2447a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2457a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 2467a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 2477a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 2487a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 2497a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 25020b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 2517a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2527a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2537a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 2547a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 2557a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2567a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2577a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2587a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 2597a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2607a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2617a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 2627a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 2637a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 2647a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 26563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2667a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 26763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 26863c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2697a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 2707a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 2717a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 2727a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 27363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2747a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 2757a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 27620161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("mv", "$fname.tmp", $fname); 2777a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2787a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2797a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2804f2b10b24bab0049020d268382eda144e2aa064cTom Care# AddStatLine - Decode and insert a statistics line into the database. 2814f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 2824f2b10b24bab0049020d268382eda144e2aa064cTom Care 2834f2b10b24bab0049020d268382eda144e2aa064cTom Caresub AddStatLine { 2844f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Line = shift; 2854f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 2864f2b10b24bab0049020d268382eda144e2aa064cTom Care 2874f2b10b24bab0049020d268382eda144e2aa064cTom Care print $Line . "\n"; 2884f2b10b24bab0049020d268382eda144e2aa064cTom Care 2894f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Regex = qr/(.*?)\ :\ (.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable 2906bdda82234ff106d561dc8c0ce5ca48b97726bbfTed Kremenek \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: 2914f2b10b24bab0049020d268382eda144e2aa064cTom Care \ (yes|no)/x; 2924f2b10b24bab0049020d268382eda144e2aa064cTom Care 2934f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($Line !~ $Regex) { 2944f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 2954f2b10b24bab0049020d268382eda144e2aa064cTom Care } 2964f2b10b24bab0049020d268382eda144e2aa064cTom Care 2974f2b10b24bab0049020d268382eda144e2aa064cTom Care # Create a hash of the interesting fields 2984f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Row = { 2994f2b10b24bab0049020d268382eda144e2aa064cTom Care Filename => $1, 3004f2b10b24bab0049020d268382eda144e2aa064cTom Care Function => $2, 3014f2b10b24bab0049020d268382eda144e2aa064cTom Care Total => $3, 3024f2b10b24bab0049020d268382eda144e2aa064cTom Care Unreachable => $4, 3034f2b10b24bab0049020d268382eda144e2aa064cTom Care Aborted => $5, 3044f2b10b24bab0049020d268382eda144e2aa064cTom Care Empty => $6 3054f2b10b24bab0049020d268382eda144e2aa064cTom Care }; 3064f2b10b24bab0049020d268382eda144e2aa064cTom Care 3074f2b10b24bab0049020d268382eda144e2aa064cTom Care # Add them to the stats array 3084f2b10b24bab0049020d268382eda144e2aa064cTom Care push @$Stats, $Row; 3094f2b10b24bab0049020d268382eda144e2aa064cTom Care} 3104f2b10b24bab0049020d268382eda144e2aa064cTom Care 3114f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 3125744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3135744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3145744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 31557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 31657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 31757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 31857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 31957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3205744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 3215744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3225744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3235744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3245744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3254f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 3265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 32757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 32857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 32957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 33057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 33157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 332fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 33357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 33420161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-f", "$Dir/$FName"); 33557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 33657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 33757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 33857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 33957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 340809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 34120161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("chmod", "644", "$Dir/$FName"); 342684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek 343684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 34423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3455744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3464f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugType = ""; 3474f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugFile = ""; 3484f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugCategory = ""; 3494f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugDescription = ""; 3504f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugPathLength = 1; 3514f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugLine = 0; 352ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3535744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 354d658e67b438c60fbe3bd1773a3172fd0f082c483Ted Kremenek last if (/<!-- BUGMETAEND -->/); 355ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 356a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek if (/<!-- BUGTYPE (.*) -->$/) { 357a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek $BugType = $1; 3585744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 35922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 360990c2f45e566d8ff097fa90176ba90036892b3cdTed Kremenek $BugFile = abs_path($1); 3617a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 36222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 36322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 36422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 36522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 36622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 36722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugLine = $1; 368ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 369ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek elsif (/<!-- BUGCATEGORY (.*) -->$/) { 370ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = $1; 37122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 3724f2b10b24bab0049020d268382eda144e2aa064cTom Care elsif (/<!-- BUGDESC (.*) -->$/) { 3734f2b10b24bab0049020d268382eda144e2aa064cTom Care $BugDescription = $1; 3744f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3755744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 3765744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3775744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 378ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 379ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $BugCategory) { 380ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = "Other"; 381ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 3824f2b10b24bab0049020d268382eda144e2aa064cTom Care 3834f2b10b24bab0049020d268382eda144e2aa064cTom Care # Don't add internal statistics to the bug reports 3844f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($BugCategory =~ /statistics/i) { 3854f2b10b24bab0049020d268382eda144e2aa064cTom Care AddStatLine($BugDescription, $Stats); 3864f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 3874f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3884f2b10b24bab0049020d268382eda144e2aa064cTom Care 389a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, 39081983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek $BugPathLength ]; 39122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 39222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 39322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 3943ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek# CopyFiles - Copy resource files to target directory. 39522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 39622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 3973ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremeneksub CopyFiles { 39822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 39922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 400e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 401e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $JS = Cwd::realpath("$RealBin/sorttable.js"); 40222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 404e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $JS); 40522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 406e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $JS, "$Dir"); 40722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 40922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 4103ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 411e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $CSS = Cwd::realpath("$RealBin/scanview.css"); 412e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 4133ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Cannot find 'scanview.css'.\n") 414e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4153ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 416e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $CSS, "$Dir"); 4173ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4183ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 419e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4205744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 4215744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4225744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 4234f2b10b24bab0049020d268382eda144e2aa064cTom Care# CalcStats - Calculates visitation statistics and returns the string. 4244f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 4254f2b10b24bab0049020d268382eda144e2aa064cTom Care 4264f2b10b24bab0049020d268382eda144e2aa064cTom Caresub CalcStats { 4274f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 4284f2b10b24bab0049020d268382eda144e2aa064cTom Care 4294f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalBlocks = 0; 4304f2b10b24bab0049020d268382eda144e2aa064cTom Care my $UnreachedBlocks = 0; 4314f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFunctions = scalar(@$Stats); 4324f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BlockAborted = 0; 4334f2b10b24bab0049020d268382eda144e2aa064cTom Care my $WorkListAborted = 0; 4344f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Aborted = 0; 4354f2b10b24bab0049020d268382eda144e2aa064cTom Care 4364f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculate the unique files 4374f2b10b24bab0049020d268382eda144e2aa064cTom Care my $FilesHash = {}; 4384f2b10b24bab0049020d268382eda144e2aa064cTom Care 4394f2b10b24bab0049020d268382eda144e2aa064cTom Care foreach my $Row (@$Stats) { 4404f2b10b24bab0049020d268382eda144e2aa064cTom Care $FilesHash->{$Row->{Filename}} = 1; 4414f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalBlocks += $Row->{Total}; 4424f2b10b24bab0049020d268382eda144e2aa064cTom Care $UnreachedBlocks += $Row->{Unreachable}; 4434f2b10b24bab0049020d268382eda144e2aa064cTom Care $BlockAborted++ if $Row->{Aborted} eq 'yes'; 4444f2b10b24bab0049020d268382eda144e2aa064cTom Care $WorkListAborted++ if $Row->{Empty} eq 'no'; 4454f2b10b24bab0049020d268382eda144e2aa064cTom Care $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; 4464f2b10b24bab0049020d268382eda144e2aa064cTom Care } 4474f2b10b24bab0049020d268382eda144e2aa064cTom Care 4484f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFiles = scalar(keys(%$FilesHash)); 4494f2b10b24bab0049020d268382eda144e2aa064cTom Care 4504f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculations 4514f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); 4524f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions 4534f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4544f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / 4554f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalFunctions * 100); 4564f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks 4574f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4584f2b10b24bab0049020d268382eda144e2aa064cTom Care 4594f2b10b24bab0049020d268382eda144e2aa064cTom Care my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" 4604f2b10b24bab0049020d268382eda144e2aa064cTom Care . " in $TotalFiles files\n" 4614f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$Aborted functions aborted early ($PercentAborted%)\n" 4624f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" 4634f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" 4644f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; 4654f2b10b24bab0049020d268382eda144e2aa064cTom Care 4664f2b10b24bab0049020d268382eda144e2aa064cTom Care return $StatsString; 4674f2b10b24bab0049020d268382eda144e2aa064cTom Care} 4684f2b10b24bab0049020d268382eda144e2aa064cTom Care 4694f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 4709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 4719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 4729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 473a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 4749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4754f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Dir = shift; 4764f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BaseDir = shift; 4774f2b10b24bab0049020d268382eda144e2aa064cTom Care my $AnalyzerStats = shift; 4789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 479fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 4809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 48223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 483363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 487938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @files = grep { /^report-.*\.html$/ } readdir(DIR); 4889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 4899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 490938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar(@files) == 0 and ! -e "$Dir/failures") { 49123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Removing directory '$Dir' because it contains no reports.\n"); 49220161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-fR", $Dir); 493363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4955744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 496991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Scan each report file and build an index. 4974f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Index; 4984f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Stats; 4994f2b10b24bab0049020d268382eda144e2aa064cTom Care foreach my $file (@files) { ScanFile(\@Index, $Dir, $file, \@Stats); } 5005744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 501938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Scan the failures directory and use the information in the .info files 502d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 503938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @failures; 504938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @attributes_ignored; 505938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (-d "$Dir/failures") { 506938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 507938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 508d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 509938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 510938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 511938eef139ad43345248235da31f78a759dd18f13Ted Kremenek closedir(DIR); 512938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (@failures) { 513938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 514d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 515d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 516d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 517d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 518d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 519d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 52063c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Generate an index.html file. 52163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek my $FName = "$Dir/index.html"; 52263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 5235744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 5246e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 5256e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 5275744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 5285744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 5297cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<title>${HtmlTitle}</title> 530f143545ce5ce125e7c1aa6fca9df372bfb604e9cTed Kremenek<link type="text/css" rel="stylesheet" href="scanview.css"/> 53122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 5326e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 5336e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 5346e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 5356e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 5366e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 5376e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 5386e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 5396e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5406e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5416e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 542ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 5432350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenekfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 5442350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek var Inputs = document.getElementsByTagName("input"); 5452350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek for ( var i = 0 ; i < Inputs.length; ++i ) { 5462350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if (Inputs[i].type == "checkbox") { 5472350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if(Inputs[i] != SummaryCheckButton) { 5482350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].checked = SummaryCheckButton.checked; 5492350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].onclick(); 5502350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5512350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5522350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5532350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek} 5542350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek 555999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekfunction returnObjById( id ) { 556999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (document.getElementById) 557999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.getElementById(id); 558999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.all) 559999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.all[id]; 560999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.layers) 561999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.layers[id]; 562999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek return returnVar; 563999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek} 564999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 565999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekvar NumUnchecked = 0; 566999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 5676e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 5686e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 5696e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 570999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (--NumUnchecked == 0) { 571999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = true; 572999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek } 5736e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5746e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 5756e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 576999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek NumUnchecked++; 577999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = false; 5786e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5796e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 5806e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 5811d1abb1dec3d0b7609809d876a16a64a021e96e7Ted Kremenek<!-- SUMMARYENDHEAD --> 5826e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 5836e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 5847cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h1>${HtmlTitle}</h1> 5857cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5867cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<table> 5877cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 5887cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 5897cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 590b4882d50923881d1a01af4d5604b5baaa141cdf9Douglas Gregor<tr><th>Clang Version:</th><td>${ClangVersion}</td></tr> 5917cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Date:</th><td>${Date}</td></tr> 5927cba11262458df05951432b54997eb40a35dbf9eTed KremenekENDTEXT 5937cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5947cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 5957cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (defined($BuildName) && defined($BuildDate)); 5967cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5977cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT <<ENDTEXT; 5987cba11262458df05951432b54997eb40a35dbf9eTed Kremenek</table> 5996e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6006e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 601991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 602991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 603991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 604ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 605991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 606ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_type = ($row->[2]); 607ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_category = ($row->[1]); 608ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $key = "$bug_category:$bug_type"; 609ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 610ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 611ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { $Totals{$key}->[0]++; } 6126e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 613991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6147cba11262458df05951432b54997eb40a35dbf9eTed Kremenek print OUT "<h2>Bug Summary</h2>"; 615991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 616991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 617991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 6186e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 619f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 6202350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek my $TotalBugs = scalar(@Index); 6216e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 622ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table> 623ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 624999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek<tr style="font-weight:bold"><td class="SUMM_DESC">All Bugs</td><td class="Q">$TotalBugs</td><td><center><input type="checkbox" id="AllBugsCheck" onClick="CopyCheckedStateToCheckButtons(this);" checked/></center></td></tr> 6256e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6266e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 627ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $last_category; 628ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 629ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $key ( 630ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek sort { 631ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = $Totals{$a}; 632ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $y = $Totals{$b}; 633ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $res = $x->[1] cmp $y->[1]; 634ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res = $x->[2] cmp $y->[2] if ($res == 0); 635ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res 636ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } keys %Totals ) 637ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek { 638ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $val = $Totals{$key}; 639ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $category = $val->[1]; 640ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $last_category or $last_category ne $category) { 641ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $last_category = $category; 642ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 643ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 644ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = lc $key; 645ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 646ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><td class=\"SUMM_DESC\">"; 647ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[2]; 6482350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek print OUT "</td><td class=\"Q\">"; 649ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[0]; 650ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 651991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6526e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6536e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 6546e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6556e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 6566e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 6577cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Reports</h2> 658ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 659ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table class="sortable" style="table-layout:automatic"> 660ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr> 661ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td>Bug Group</td> 662ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 663bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 664ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="Q">Line</td> 66581983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek <td class="Q">Path Length</td> 6662645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 667ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <!-- REPORTBUGCOL --> 668ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek</tr></thead> 669ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<tbody> 6705744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 6719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 672991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 673991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 674991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 675991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 6767a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 677991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $prefix) { 678991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $regex = qr/^\Q$prefix\E/is; 679991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 680991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6817a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 682ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 683ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = "$row->[1]:$row->[2]"; 684ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x = lc $x; 685ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 6866e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 687991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 688ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 689ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr class=\"bt_$x\">"; 690ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 691991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 692ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 693ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 694ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $row->[2]; 695ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 696ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 697ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Update the file prefix. 698ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $fname = $row->[3]; 699ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 700991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 701991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 702991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 703991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 704ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 70591639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek print OUT "<td>"; 706ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my @fname = split /\//,$fname; 707ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname > 0) { 708ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek while ($#fname >= 0) { 709ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = shift @fname; 710ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $x; 711ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname >= 0) { 712ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<span class=\"W\"> </span>/"; 713ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 714ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 715ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 716ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { 717ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $fname; 71891639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek } 719ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 720ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 721ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Print out the quantities. 72281983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for my $j ( 4 .. 5 ) { 723ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"Q\">$row->[$j]</td>"; 724ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 725ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 726991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 72781983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for (my $j = 6; $j <= $#{$row}; ++$j) { 728ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td>$row->[$j]</td>" 729991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 7307f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 731991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 73268005ddb49b88c2f6cdd88185d72d8b411d2dbc9Ted Kremenek print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 7333cea9ee6b77ac797ebb910bdf45d1d7f8f68e37bTed Kremenek 734e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar # Emit REPORTBUG markers. 735ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 736e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar 737991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 738991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 739991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 740991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 741ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</tbody>\n</table>\n\n"; 742991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 743991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 744938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar (@failures) || scalar(@attributes_ignored)) { 745938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<h2>Analyzer Failures</h2>\n"; 746938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 747938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @attributes_ignored) { 748938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 749938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 750938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 751938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @attributes_ignored) { 752938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 753938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $attribute = $1; 754938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the attribute file to get the first file that failed. 755938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (!open (ATTR, "$Dir/failures/$file")); 756938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile = <ATTR>; 757938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $ppfile; 758938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close ATTR; 759938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (! -e "$Dir/failures/$ppfile"); 760938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the info file and get the name of the source file. 761938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$ppfile.info.txt") or 762938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 763938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $srcfile = <INFO>; 764938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $srcfile; 765938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close (INFO); 766938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Print the information in the table. 767938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $prefix = GetPrefix(); 768938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 769938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<tr><td>$attribute</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; 770938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile_clang = $ppfile; 771938eef139ad43345248235da31f78a759dd18f13Ted Kremenek $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 772938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 773938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 774938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 775938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 776938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 777938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @failures) { 778938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 779938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 780938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 781938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @failures) { 78282a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek $file =~ /(.+).info.txt$/; 783991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 784991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 785991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 786938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$file") or 787938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$file\n"; 788991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 7895d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 7905d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 7915d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 792991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 793991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 794d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 7959f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 796938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; 797ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar my $ppfile_clang = $ppfile; 798ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 799938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 800991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 801938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 802938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 803e2c8663ad2b110712401145b866072bb94108058Nico Weber print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang-analyzer.llvm.org/filing_bugs.html\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n"; 8045744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 8055744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 806991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</body></html>\n"; 8075744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 8083ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek CopyFiles($Dir); 80920161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 81020161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 81120161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("chmod", "755", $Dir); 812fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 81320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 8144f2b10b24bab0049020d268382eda144e2aa064cTom Care # Print statistics 8154f2b10b24bab0049020d268382eda144e2aa064cTom Care print CalcStats(\@Stats) if $AnalyzerStats; 8164f2b10b24bab0049020d268382eda144e2aa064cTom Care 81723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 818150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("$Num bugs found.\n"); 819150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 8205950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 821150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 822363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 823938eef139ad43345248235da31f78a759dd18f13Ted Kremenek DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 824991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 825363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 8269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 829dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 830dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 831dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8326b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 8336b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 8346b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Arg = shift; 8356b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 8366b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8376b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 8386b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 8396b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 8406b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 8416b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8426b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8436b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8446b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 8456b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 8466b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8476b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 8486b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 849cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremeneksub SetEnv { 850cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift @_; 851cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX', 852cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS') { 853cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek die "$opt is undefined\n" if (!defined $opt); 854cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{$opt} = $Options->{$opt}; 855cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 856cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek foreach my $opt ('CCC_ANALYZER_STORE_MODEL', 857cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_PLUGINS', 858cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_INTERNAL_STATS', 859cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_OUTPUT_FORMAT') { 860cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $x = $Options->{$opt}; 861cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if (defined $x) { $ENV{$opt} = $x } 862cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 863cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Verbose = $Options->{'VERBOSE'}; 864cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if ($Verbose >= 2) { 865cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 866cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 867cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if ($Verbose >= 3) { 868cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 869cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 870cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek} 871cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 87238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremeneksub RunXcodebuild { 87338447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $Args = shift; 87438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $IgnoreErrors = shift; 87538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $CCAnalyzer = shift; 87638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $CXXAnalyzer = shift; 877cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift; 878cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 87938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if ($IgnoreErrors) { 88038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 88138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 88238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 883cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek # Default to old behavior where we insert a bogus compiler. 884cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek SetEnv($Options); 885cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 88638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # Check if using iPhone SDK 3.0 (simulator). If so the compiler being 88738447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # used should be gcc-4.2. 88838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if (!defined $ENV{"CCC_CC"}) { 88938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek for (my $i = 0 ; $i < scalar(@$Args); ++$i) { 89038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { 89138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if (@$Args[$i+1] =~ /^iphonesimulator3/) { 89238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek $ENV{"CCC_CC"} = "gcc-4.2"; 893cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{"CCC_CXX"} = "g++-4.2"; 89438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 89538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 89638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 89738447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 89838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 89938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # Disable PCH files until clang supports them. 90038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 90138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 90238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 90338447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 90438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # (via c++-analyzer) when linking such files. 90538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; 90638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 90738447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek return (system(@$Args) >> 8); 90838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek} 90938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 910cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremeneksub RunBuildCommand { 911dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 9127442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 913dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 9146195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 915524c308506e77e173092e87a0724a27817311428Ted Kremenek my $CXXAnalyzer = shift; 916cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift; 917dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 9183301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek # Get only the part of the command after the last '/'. 9193301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek if ($Cmd =~ /\/([^\/]+)$/) { 9203301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek $Cmd = $1; 9213301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek } 9223301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek 92338447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if ($Cmd eq "xcodebuild") { 924cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek return RunXcodebuild($Args, $IgnoreErrors, $CCAnalyzer, $CXXAnalyzer, $Options); 92538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 92638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 927cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek # Setup the environment. 928cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek SetEnv($Options); 929cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 93092548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 93192548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?cc[^\/]*$)/ or 93292548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 93305acf8b689257d8b7349ffdfe309b4d7f7d6ae13Ted Kremenek $Cmd =~ /(.*\/?clang$)/ or 93492548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 93592548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 93692548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 93751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CC"} = $1; 93892548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek } 93992548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 940dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 9416195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 942dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 94351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 94451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or 94551365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or 94605acf8b689257d8b7349ffdfe309b4d7f7d6ae13Ted Kremenek $Cmd =~ /(.*\/?clang\+\+$)/ or 94751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { 94851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { 94951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = $1; 95051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek } 95151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek shift @$Args; 952524c308506e77e173092e87a0724a27817311428Ted Kremenek unshift @$Args, $CXXAnalyzer; 95351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek } 9547442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($IgnoreErrors) { 9557442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek if ($Cmd eq "make" or $Cmd eq "gmake") { 9566fba85dc6509069ff7735283464bd02da2da6eebTed Kremenek AddIfNotPresent($Args, "CC=$CCAnalyzer"); 957524c308506e77e173092e87a0724a27817311428Ted Kremenek AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); 9586b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 9598912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 9607442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 9616b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 96287752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek 9635a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 964dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 965dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 966dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 9679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 9689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 9699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 970a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 9719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9725744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 973a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 9742b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 975f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 976f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 977fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 978f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 979f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 980f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 981f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 9822b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 9832b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 984eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -analyze-headers 9858382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek 986eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Also analyze functions in #included files. By default, such functions 987eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek are skipped unless they are called by functions within the main source file. 988eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 989eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -o <output location> 990eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 991eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specifies the output directory for analyzer reports. Subdirectories will be 992eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek created as needed to represent separate "runs" of the analyzer. If this 993eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X) 994eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek to store the reports. 995eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 996eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -h 997363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 9981262fc4d66584224234691d30d779f8ff004585cTed Kremenek 999eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Display this message. 1000eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1001eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -k 1002eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --keep-going 1003eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1004eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Add a "keep on going" option to the specified build command. This option 1005eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek currently supports make and xcodebuild. This is a convenience option; one 1006eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek can specify this behavior directly using build options. 1007eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1008eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --html-title [title] 1009eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --html-title=[title] 10102b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1011eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specify the title used on generated HTML pages. If not specified, a default 1012eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek title will be used. 10137cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 1014eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -plist 10152c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks 1016eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default the output of scan-build is a set of HTML files. This option 1017eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek outputs the results as a set of .plist files. 10182c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks 1019eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -plist-html 1020eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1021eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default the output of scan-build is a set of HTML files. This option 1022eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek outputs the results as a set of HTML and .plist files. 1023eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1024eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --status-bugs 1025eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1026eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default, the exit status of scan-build is the same as the executed build 1027eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek command. Specifying this option causes the exit status of scan-build to be 1 1028eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek if it found potential bugs and 0 otherwise. 1029386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 1030eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-cc [compiler path] 1031eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-cc=[compiler path] 1032eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1033eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build analyzes a project by interposing a "fake compiler", which 1034eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek executes a real compiler for compilation and the static analyzer for analysis. 1035eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Because of the current implementation of interposition, scan-build does not 1036eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek know what compiler your project normally uses. Instead, it simply overrides 1037eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek the CC environment variable, and guesses your default compiler. 1038eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1039eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek In the future, this interposition mechanism to be improved, but if you need 1040eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build to use a specific compiler for *compilation* then you can use 1041eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek this option to specify a path to that compiler. 1042eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1043eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-c++ [compiler path] 1044eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-c++=[compiler path] 1045eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1046eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek This is the same as "-use-cc" but for C++ code. 1047eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1048eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -v 1049eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1050eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Enable verbose output from scan-build. A second and third '-v' increases 1051eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek verbosity. 1052f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1053eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -V 1054eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --view 1055363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 1056eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek View analysis results in a web browser when the build completes. 10577f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1058be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed KremenekADVANCED OPTIONS: 1059be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1060eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -no-failure-reports 1061eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1062eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Do not create a 'failures' subdirectory that includes analyzer crash reports 1063eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek and preprocessed source files. 1064b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1065eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -stats 1066eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1067eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Generates visitation statistics for the project being analyzed. 10684f2b10b24bab0049020d268382eda144e2aa064cTom Care 1069eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -maxloop <loop count> 10701e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks 1071eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specifiy the number of times a block can be visited before giving up. 1072eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Default is 4. Increase for more comprehensive coverage at a cost of speed. 1073eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1074eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -internal-stats 1075eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1076eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Generate internal analyzer statistics. 1077810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 10785a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek --use-analyzer [Xcode|path to clang] 10795a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek --use-analyzer=[Xcode|path to clang] 1080810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 1081810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek scan-build uses the 'clang' executable relative to itself for static 1082810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek analysis. One can override this behavior with this option by using the 1083810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 'clang' packaged with Xcode (on OS X) or from the PATH. 1084810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 108509fbf297da918760ce33302a3f709a77f43af265Ted KremenekCONTROLLING CHECKERS: 108609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 108709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek A default group of checkers are always run unless explicitly disabled. 108809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek Checkers may be enabled/disabled using the following options: 108909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 109009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -enable-checker [checker name] 109109fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -disable-checker [checker name] 1092f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1093f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna ZaksLOADING CHECKERS: 1094f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1095f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks Loading external checkers using the clang plugin interface: 1096f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1097f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks -load-plugin [plugin library] 1098d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 1099b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1100ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for list of checkers that are enabled. 1101f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1102f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks# create a list to load the plugins via the 'Xclang' command line 1103f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks# argument 1104f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksmy @PluginLoadCommandline_xclang; 1105f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksforeach my $param ( @PluginsToLoad ) { 1106f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push ( @PluginLoadCommandline_xclang, "-Xclang" ); 1107f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push ( @PluginLoadCommandline_xclang, $param ); 1108f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks} 1109ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy %EnabledCheckers; 1110ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekforeach my $lang ("c", "objective-c", "objective-c++", "c++") { 1111ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek pipe(FROM_CHILD, TO_PARENT); 1112ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $pid = fork(); 1113ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($pid == 0) { 1114ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close FROM_CHILD; 1115ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDOUT,">&", \*TO_PARENT); 1116ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDERR,">&", \*TO_PARENT); 1117f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###'); 1118ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1119ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(TO_PARENT); 1120ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 1121ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek foreach my $val (split /\s+/) { 1122ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $val =~ s/\"//g; 1123ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($val =~ /-analyzer-checker\=([^\s]+)/) { 1124ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $EnabledCheckers{$1} = 1; 1125ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1126ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1127ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1128ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek waitpid($pid,0); 1129ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(FROM_CHILD); 1130ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1131ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1132ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for complete list of checkers. 1133a778d710e2c62d62e0b78d120254764142801196Jordan Roseif (defined $Clang && -x $Clang) { 1134a778d710e2c62d62e0b78d120254764142801196Jordan Rose pipe(FROM_CHILD, TO_PARENT); 1135a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $pid = fork(); 1136a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($pid == 0) { 1137a778d710e2c62d62e0b78d120254764142801196Jordan Rose close FROM_CHILD; 1138a778d710e2c62d62e0b78d120254764142801196Jordan Rose open(STDOUT,">&", \*TO_PARENT); 1139a778d710e2c62d62e0b78d120254764142801196Jordan Rose open(STDERR,">&", \*TO_PARENT); 1140a778d710e2c62d62e0b78d120254764142801196Jordan Rose exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help'); 1141ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1142a778d710e2c62d62e0b78d120254764142801196Jordan Rose close(TO_PARENT); 1143a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $foundCheckers = 0; 1144ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 1145a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/CHECKERS:/) { 1146a778d710e2c62d62e0b78d120254764142801196Jordan Rose $foundCheckers = 1; 1147a778d710e2c62d62e0b78d120254764142801196Jordan Rose last; 114873078642d3c32499ee573bd458af6d384fa7f6d8Ted Kremenek } 1149a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1150a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (!$foundCheckers) { 1151a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " *** Could not query Clang for the list of available checkers."; 1152a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1153a778d710e2c62d62e0b78d120254764142801196Jordan Rose else { 1154a778d710e2c62d62e0b78d120254764142801196Jordan Rose print("\nAVAILABLE CHECKERS:\n\n"); 1155a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $skip = 0; 1156a778d710e2c62d62e0b78d120254764142801196Jordan Rose while(<FROM_CHILD>) { 1157a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/experimental/) { 1158a778d710e2c62d62e0b78d120254764142801196Jordan Rose $skip = 1; 1159a778d710e2c62d62e0b78d120254764142801196Jordan Rose next; 1160a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1161a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($skip) { 1162a778d710e2c62d62e0b78d120254764142801196Jordan Rose next if (!/^\s\s[^\s]/); 1163a778d710e2c62d62e0b78d120254764142801196Jordan Rose $skip = 0; 1164ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1165a778d710e2c62d62e0b78d120254764142801196Jordan Rose s/^\s\s//; 1166a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/^([^\s]+)/) { 1167a778d710e2c62d62e0b78d120254764142801196Jordan Rose # Is the checker enabled? 1168a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $checker = $1; 1169a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $enabled = 0; 1170a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $aggregate = ""; 1171a778d710e2c62d62e0b78d120254764142801196Jordan Rose foreach my $domain (split /\./, $checker) { 1172a778d710e2c62d62e0b78d120254764142801196Jordan Rose $aggregate .= $domain; 1173a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($EnabledCheckers{$aggregate}) { 1174a778d710e2c62d62e0b78d120254764142801196Jordan Rose $enabled =1; 1175a778d710e2c62d62e0b78d120254764142801196Jordan Rose last; 1176a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1177a778d710e2c62d62e0b78d120254764142801196Jordan Rose # append a dot, if an additional domain is added in the next iteration 1178a778d710e2c62d62e0b78d120254764142801196Jordan Rose $aggregate .= "."; 1179a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1180ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1181a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($enabled) { 1182a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " + "; 1183a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1184a778d710e2c62d62e0b78d120254764142801196Jordan Rose else { 1185a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " "; 1186a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1187ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1188ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek else { 1189ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " "; 1190ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1191a778d710e2c62d62e0b78d120254764142801196Jordan Rose print $_; 1192ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1193a778d710e2c62d62e0b78d120254764142801196Jordan Rose print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n" 1194a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1195a778d710e2c62d62e0b78d120254764142801196Jordan Rose waitpid($pid,0); 1196a778d710e2c62d62e0b78d120254764142801196Jordan Rose close(FROM_CHILD); 1197ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 11987fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1199b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 1200b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 12012b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 12022b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1203363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 120439eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 12055744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 12062b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1207eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build -o /tmp/myhtmldir make -j4 12082b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1209eaafdfc7b475937ed194ad729407481054b99be9Ted KremenekThe above example causes analysis reports to be deposited into a subdirectory 1210eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenekof "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different 1211eaafdfc7b475937ed194ad729407481054b99be9Ted Kremeneksubdirectory is created each time scan-build analyzes a project. The analyzer 1212eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenekshould support most parallel builds, but not distributed builds. 12132b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 12142b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 12159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 12169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 12187cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# HtmlEscape - HTML entity encode characters that are special in HTML 12197cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 12207cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12217cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub HtmlEscape { 12227cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 12237cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 12247cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 122587f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/&/&/g; 122687f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/</</g; 122787f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/>/>/g; 12287cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 12297cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 12307cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12317cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 12327cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# ShellEscape - backslash escape characters that are special to the shell 12337cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 12347cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12357cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub ShellEscape { 12367cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 12377cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 123887f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 123987f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek return $arg; 12407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 12417cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12427cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 12439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 12449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 12459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1246e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekmy $AnalyzeHeaders = 0; 12479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 12489cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 12497f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 1250363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 1251b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 125207c3767be59472e19183c7b51fae76481465cb51Zhongxing Xumy $StoreModel; 1253be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekmy $ConstraintsModel; 12541e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaksmy $InternalStats; 12558d8bc9157fccab6a4089c41cdad9e12045edd736Ted Kremenekmy $OutputFormat = "html"; 12564f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $AnalyzerStats = 0; 12574f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $MaxLoop = 0; 12589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 12609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1261a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 12629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 12639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1264ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1265ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy $displayHelp = 0; 1266810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $AnalyzerDiscoveryMethod; 1267ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 12689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 12699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 12719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 12739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12742f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 1275ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $displayHelp = 1; 1276ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek shift @ARGV; 1277ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek next; 12789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1280e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if ($arg eq '-analyze-headers') { 1281e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek shift @ARGV; 1282e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek $AnalyzeHeaders = 1; 1283e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek next; 1284e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek } 1285e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 12869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 12879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 12889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 129023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 12919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1293db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # Construct an absolute path. Uses the current working directory 1294db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # as a base if the original path was not absolute. 1295db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek $HtmlDir = abs_path(shift @ARGV); 1296db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek 12979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 12989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12997cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--html-title(=(.+))?$/) { 13017cba11262458df05951432b54997eb40a35dbf9eTed Kremenek shift @ARGV; 13027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 1303278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq '') { 13047cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (!@ARGV) { 13057cba11262458df05951432b54997eb40a35dbf9eTed Kremenek DieDiag("'--html-title' option requires a string.\n"); 13067cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 13077cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13087cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = shift @ARGV; 13097cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } else { 13107cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = $2; 13117cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 13127cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13137cba11262458df05951432b54997eb40a35dbf9eTed Kremenek next; 13147cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 13159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13162b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 13179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 13189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 13199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 13209cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 13217fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1322f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 1323f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 1324f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 1325f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1326278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1327f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 1328f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 1329f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1330f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 1331f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1332f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 1333f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 1334f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1335f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1336f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 1337f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 1338f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1339f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 13407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 1341386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 134251365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek my $cxx; 1343386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 1344278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1345386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 1346386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 1347386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 134851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = shift @ARGV; 1349386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1350386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 135151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = $2; 1352386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 135351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek 135451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = $cxx; 1355386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 1356386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1357386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 13589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 13599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 13609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 13619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 13629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 13639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13647f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 13657f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 13667f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek $ViewResults = 1; 13677f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 13687f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 13697f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1370363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 1371363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 1372363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 1373363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 1374363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 137507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu 137607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu if ($arg eq "-store") { 137707c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu shift @ARGV; 1378be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $StoreModel = shift @ARGV; 1379be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek next; 1380be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek } 1381be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1382be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek if ($arg eq "-constraints") { 1383be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek shift @ARGV; 1384be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ConstraintsModel = shift @ARGV; 138507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu next; 138607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu } 13871e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks 13881e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks if ($arg eq "-internal-stats") { 13891e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks shift @ARGV; 13901e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks $InternalStats = 1; 13911e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks next; 13921e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks } 1393363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 1394db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($arg eq "-plist") { 1395db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek shift @ARGV; 1396db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $OutputFormat = "plist"; 1397db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek next; 1398db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 13997753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($arg eq "-plist-html") { 14007753b352366778d01c5cda4117356f181d3dd468Ted Kremenek shift @ARGV; 14017753b352366778d01c5cda4117356f181d3dd468Ted Kremenek $OutputFormat = "plist-html"; 14027753b352366778d01c5cda4117356f181d3dd468Ted Kremenek next; 14037753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1404e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek 1405e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek if ($arg eq "-no-failure-reports") { 1406e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek $ENV{"CCC_REPORT_FAILURES"} = 0; 1407e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek next; 1408e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek } 14094f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-stats") { 14104f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 14114f2b10b24bab0049020d268382eda144e2aa064cTom Care $AnalyzerStats = 1; 14124f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 14134f2b10b24bab0049020d268382eda144e2aa064cTom Care } 14144f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-maxloop") { 14154f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 14164f2b10b24bab0049020d268382eda144e2aa064cTom Care $MaxLoop = shift @ARGV; 14174f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 14184f2b10b24bab0049020d268382eda144e2aa064cTom Care } 141909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-enable-checker") { 142009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 142109fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-checker", shift @ARGV; 142209fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 142309fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 142409fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-disable-checker") { 142509fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 142609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-disable-checker", shift @ARGV; 142709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 142809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 1429f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks if ($arg eq "-load-plugin") { 1430f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks shift @ARGV; 1431f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push @PluginsToLoad, "-load", shift @ARGV; 1432f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks next; 1433f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks } 14345a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek if ($arg eq "--use-analyzer") { 1435810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek shift @ARGV; 1436810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $AnalyzerDiscoveryMethod = shift @ARGV; 1437810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek next; 1438810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 14395a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek if ($arg =~ /^--use-analyzer=(.+)$/) { 1440810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek shift @ARGV; 1441810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $AnalyzerDiscoveryMethod = $1; 1442810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek next; 1443810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1444f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 144523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 14460062ad4f47d152def1f720878aaf5904b22aefbfTed Kremenek 14479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 14489cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 14499cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1450ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekif (!@ARGV and $displayHelp == 0) { 145123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No build command specified.\n\n"); 1452ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $displayHelp = 1; 1453ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1454ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1455810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek# Find 'clang' 1456810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekif (!defined $AnalyzerDiscoveryMethod) { 1457810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = Cwd::realpath("$RealBin/bin/clang"); 1458810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if (!defined $Clang || ! -x $Clang) { 1459810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = Cwd::realpath("$RealBin/clang"); 1460810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1461810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if (!defined $Clang || ! -x $Clang) { 1462a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (!$displayHelp) { 1463a778d710e2c62d62e0b78d120254764142801196Jordan Rose DieDiag("error: Cannot find an executable 'clang' relative to scan-build." . 1464a778d710e2c62d62e0b78d120254764142801196Jordan Rose " Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n"); 1465a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1466810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1467810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek} 1468810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekelse { 14690d3a3fd7211a1b368d1f8c0d7ca1cfd40d31a0eaTed Kremenek if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) { 1470810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek my $xcrun = `which xcrun`; 1471810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek chomp $xcrun; 1472810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if ($xcrun eq "") { 1473810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n"); 1474810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1475810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = `$xcrun -toolchain XcodeDefault -find clang`; 1476810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek chomp $Clang; 1477810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if ($Clang eq "") { 1478810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek DieDiag("No 'clang' executable found by 'xcrun'\n"); 1479810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1480810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1481810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek else { 1482810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = Cwd::realpath($AnalyzerDiscoveryMethod); 1483810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if (! -x $Clang) { 1484810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek DieDiag("Cannot find an executable clang at '$Clang'\n"); 1485810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1486810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1487810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek} 1488810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 1489a778d710e2c62d62e0b78d120254764142801196Jordan Roseif ($displayHelp) { 1490a778d710e2c62d62e0b78d120254764142801196Jordan Rose DisplayHelp(); 1491a778d710e2c62d62e0b78d120254764142801196Jordan Rose exit 1; 1492a778d710e2c62d62e0b78d120254764142801196Jordan Rose} 1493a778d710e2c62d62e0b78d120254764142801196Jordan Rose 1494810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek$ClangCXX = $Clang; 1495810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek$ClangCXX =~ s/\-\d+\.\d+$//; 1496810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek$ClangCXX .= "++"; 1497810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek$ClangVersion = HtmlEscape(`$Clang --version`); 1498810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 1499ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine where results go. 15007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 15017cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 15027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek unless (defined($HtmlTitle)); 1503386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 15049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 1505684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 1506a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 15079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1508ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine the location of ccc-analyzer. 150951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $AbsRealBin = Cwd::realpath($RealBin); 151051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; 151151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; 151251365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek 1513ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenekif (!defined $Cmd || ! -x $Cmd) { 151451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd = "$AbsRealBin/ccc-analyzer"; 15156b89636db873142f562cf576df9bc195c5b8674bTed Kremenek DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd); 1516ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenek} 151751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekif (!defined $CmdCXX || ! -x $CmdCXX) { 151851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $CmdCXX = "$AbsRealBin/c++-analyzer"; 151951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX); 152051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek} 1521f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 1522810e6229e59796f8109e94e4a469a2dc17cf3e6dTed KremenekDiag("Using '$Clang' for static analysis\n"); 15230b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 1524ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted KremenekSetHtmlEnv(\@ARGV, $HtmlDir); 1525cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekif ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; } 1526cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekif ($AnalyzerStats) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; } 1527be92debbf1e9c38b1ae8a4a9c30377b24196ca73Ted Kremenekif ($MaxLoop > 0) { push @AnalysesToRun, "-analyzer-max-loop $MaxLoop"; } 1528cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 1529cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek# Delay setting up other environment variables in case we can do true 1530cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek# interposition. 1531cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun; 1532cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad; 1533cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy %Options = ( 1534cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CC' => $Cmd, 1535cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CXX' => $CmdCXX, 1536cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CLANG' => $Clang, 1537cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CLANG_CXX' => $ClangCXX, 1538cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'VERBOSE' => $Verbose, 1539cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS, 1540cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS, 1541cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'OUTPUT_DIR' => $HtmlDir 1542cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek); 1543f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 15443cab2b1c3798f2a6aa3526875801a02aebf6fc1dZhongxing Xuif (defined $StoreModel) { 1545cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; 154607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu} 1547be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekif (defined $ConstraintsModel) { 1548cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; 1549be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek} 15501e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaksif (defined $InternalStats) { 1551cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_INTERNAL_STATS'} = 1; 15521e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks} 1553db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekif (defined $OutputFormat) { 1554cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; 1555db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek} 1556db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 15579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 1558cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX, 1559cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek \%Options); 15609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 15617753b352366778d01c5cda4117356f181d3dd468Ted Kremenekif (defined $OutputFormat) { 15621182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar if ($OutputFormat =~ /plist/) { 15631182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis run complete.\n"; 15641182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; 15651182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar } 15667a334d9ed9ff7426e78a88582207b47b370ec5deTed Kremenek if ($OutputFormat =~ /html/) { 15677753b352366778d01c5cda4117356f181d3dd468Ted Kremenek # Postprocess the HTML directory. 15684f2b10b24bab0049020d268382eda144e2aa064cTom Care my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats); 15697753b352366778d01c5cda4117356f181d3dd468Ted Kremenek 15707753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ViewResults and -r "$HtmlDir/index.html") { 15717753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Analysis run complete.\n"; 15727753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 15737753b352366778d01c5cda4117356f181d3dd468Ted Kremenek my $ScanView = Cwd::realpath("$RealBin/scan-view"); 15747753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if (! -x $ScanView) { $ScanView = "scan-view"; } 15757753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exec $ScanView, "$HtmlDir"; 15767753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1577db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 15787753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ExitStatusFoundBugs) { 15797753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 1 if ($NumBugs > 0); 15807753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 0; 15817753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1582db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 1583363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 1584363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 15855656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 15865656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1587