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; 209d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenekuse File::Find; 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesuse File::Copy qw(copy); 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesuse File::Path qw( rmtree mkpath ); 2323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor; 2423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor qw(:constants); 25cd25c13ade3afa829c87ca1ed0ed0d379f426251Ted Kremenekuse Cwd qw/ getcwd abs_path /; 267cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Sys::Hostname; 279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 30f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 31f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 330e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 34c9480dd03522f0bab5fff7d30402cb7ee31117dcTed Kremenekmy $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT 350e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines# Portability: getpwuid is not implemented for Win32 (see Perl language 384415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev# reference, perlport), use getlogin instead. 394415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsevmy $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown'); 407cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HostName = HtmlEscape(hostname() || 'unknown'); 417cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDir = HtmlEscape(getcwd()); 427cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDirSuffix = basename($CurrentDir); 437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 44f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksmy @PluginsToLoad; 457cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CmdArgs; 467cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 477cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HtmlTitle; 487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 497cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $Date = localtime(); 507cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 51b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 52b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 53b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 54b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 5923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 6023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 6123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 6323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 6423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 65f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rosesub ErrorDiag { 66f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose if ($UseColor) { 67f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR BOLD, RED "$Prog: "; 68f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR RESET, RED @_; 69f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR RESET; 70f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose } else { 71f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR "$Prog: @_"; 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 73f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose} 74f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose 75991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 76991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 77938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("The analyzer encountered problems on some source files.\n"); 78938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 79991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 80e2c8663ad2b110712401145b866072bb94108058Nico Weber Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") 81991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 82991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 8323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 8423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 85f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR BOLD, RED "$Prog: "; 86f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR RESET, RED @_; 87f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR RESET; 8823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 8923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 90f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose print STDERR "$Prog: ", @_; 9123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 92f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose exit 1; 9323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 9423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 968db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek# Print default checker names 978db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek##----------------------------------------------------------------------------## 988db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek 998db26ce0464c712058ab60b72e2a70c04148020eTed Kremenekif (grep /^--help-checkers$/, @ARGV) { 1008db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek my @options = qx($0 -h); 1018db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek foreach (@options) { 1028db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek next unless /^ \+/; 1038db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek s/^\s*//; 1048db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek my ($sign, $name, @text) = split ' ', $_; 1058db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek print $name, $/ if $sign eq '+'; 1068db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek } 107f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose exit 0; 1088db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek} 1098db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek 1108db26ce0464c712058ab60b72e2a70c04148020eTed Kremenek##----------------------------------------------------------------------------## 111810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek# Declaration of Clang options. Populated later. 112b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 113b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 114e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekmy $Clang; 115810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangSB; 116810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangCXX; 117810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekmy $ClangVersion; 118fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek 119b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 120fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinessub GetHTMLRunDir { 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines die "Not enough arguments." if (@_ == 0); 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my $Dir = shift @_; 126fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 127fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 1284415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev $Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp"; 129fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 130fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 132bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek # Chop off any trailing '/' characters. 133bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek while ($Dir =~ /\/$/) { chop $Dir; } 134fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my @CurrentTime = localtime(); 1379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 140f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose my $hour = $CurrentTime[2]; 141f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose my $min = $CurrentTime[1]; 142f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose my $sec = $CurrentTime[0]; 143f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose 144f55e36a9d88dc2c625c05d6bc560099e2236dfbeJordan Rose my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec); 145f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose my $DateString = sprintf("%d-%02d-%02d-%s-$$", 146f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose $year, $month, $day, $TimeString); 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Determine the run number. 1499cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (-d $Dir) { 1529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 15323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Iterate over all files in the specified directory. 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my $max = 0; 1579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 15829da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1612a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek foreach my $f (@FILES) { 162fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 163fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 164fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 165fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 166fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 167fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 1699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 1709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 1719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 1729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 173f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose next if ($x[3] != $TimeString); 174f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose next if ($x[4] != $$); 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 176f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose if ($x[5] > $max) { 177f8a89ce9f09f04fbb80426f4940f0c601a017b5eJordan Rose $max = $x[5]; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 1829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 18623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 1879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 188fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 189fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 190445fa776d2bc9207c33a9b9ab4afb9513f6b81b0Ted Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 191fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 192fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # $Dir does not exist. It will be automatically created by the 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # clang driver. Set the run number to 1. 195fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 1979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 199fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 202fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 203fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 204fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 205fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 206fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 207fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 208fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 209ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 210ef8225444452a1486bd721f3285301fe84643b00Stephen Hines # Make sure that the directory does not exist in order to avoid hijack. 211ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (-e $NewDir) { 212ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DieDiag("The directory '$NewDir' already exists.\n"); 213ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 214ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines mkpath($NewDir); 216fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 2179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 219a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 2249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2299e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek 2309e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { 2319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 23523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 24257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 24357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 24457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 24557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 24657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 249a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2507ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2517ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # come bundled on most systems. 25323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 254a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 255a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 256a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Return the digest. 259a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 26057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 26157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 26257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 2637a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 2647a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2657a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2667a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 2677a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2687a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 2697a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 2707a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 2717a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 2727a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2737a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 2747a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 2757a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 2767a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 27820b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 2797a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2807a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2817a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 2827a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 2837a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2847a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2857a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2867a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 2877a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2887a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2897a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 2907a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 2917a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 2927a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 29363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2947a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 29563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 29663c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2977a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 2987a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 2997a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 3007a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 30163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3027a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 3037a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines rename("$fname.tmp", $fname) 3057a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3067a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3077a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3084f2b10b24bab0049020d268382eda144e2aa064cTom Care# AddStatLine - Decode and insert a statistics line into the database. 3094f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 3104f2b10b24bab0049020d268382eda144e2aa064cTom Care 3114f2b10b24bab0049020d268382eda144e2aa064cTom Caresub AddStatLine { 3124f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Line = shift; 3134f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 3144a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose my $File = shift; 3154f2b10b24bab0049020d268382eda144e2aa064cTom Care 3164f2b10b24bab0049020d268382eda144e2aa064cTom Care print $Line . "\n"; 3174f2b10b24bab0049020d268382eda144e2aa064cTom Care 3184a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose my $Regex = qr/(.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable 3196bdda82234ff106d561dc8c0ce5ca48b97726bbfTed Kremenek \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: 3204f2b10b24bab0049020d268382eda144e2aa064cTom Care \ (yes|no)/x; 3214f2b10b24bab0049020d268382eda144e2aa064cTom Care 3224f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($Line !~ $Regex) { 3234f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 3244f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3254f2b10b24bab0049020d268382eda144e2aa064cTom Care 3264f2b10b24bab0049020d268382eda144e2aa064cTom Care # Create a hash of the interesting fields 3274f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Row = { 3284a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Filename => $File, 3294a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Function => $1, 3304a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Total => $2, 3314a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Unreachable => $3, 3324a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Aborted => $4, 3334a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose Empty => $5 3344f2b10b24bab0049020d268382eda144e2aa064cTom Care }; 3354f2b10b24bab0049020d268382eda144e2aa064cTom Care 3364f2b10b24bab0049020d268382eda144e2aa064cTom Care # Add them to the stats array 3374f2b10b24bab0049020d268382eda144e2aa064cTom Care push @$Stats, $Row; 3384f2b10b24bab0049020d268382eda144e2aa064cTom Care} 3394f2b10b24bab0049020d268382eda144e2aa064cTom Care 3404f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 3415744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3425744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3435744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 34457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 34557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 34657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 34757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 34857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3495744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3515744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3525744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3535744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3544f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 35657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 35757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 35957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 36057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 361fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 36257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines unlink("$Dir/$FName"); 36457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 36557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 36757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 369809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 3706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines chmod(0644, "$Dir/$FName"); 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 372684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 37323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3745744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3754f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugType = ""; 3764f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugFile = ""; 377ef8225444452a1486bd721f3285301fe84643b00Stephen Hines my $BugFunction = ""; 3784f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugCategory = ""; 3794f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugDescription = ""; 3804f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugPathLength = 1; 3814f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugLine = 0; 382ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3835744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 384d658e67b438c60fbe3bd1773a3172fd0f082c483Ted Kremenek last if (/<!-- BUGMETAEND -->/); 385ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 386a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek if (/<!-- BUGTYPE (.*) -->$/) { 387a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek $BugType = $1; 3885744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 38922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 390990c2f45e566d8ff097fa90176ba90036892b3cdTed Kremenek $BugFile = abs_path($1); 3917a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 39222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 39322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 39422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 39522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 39622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $BugLine = $1; 398ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 399ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek elsif (/<!-- BUGCATEGORY (.*) -->$/) { 400ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = $1; 40122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 4024f2b10b24bab0049020d268382eda144e2aa064cTom Care elsif (/<!-- BUGDESC (.*) -->$/) { 4034f2b10b24bab0049020d268382eda144e2aa064cTom Care $BugDescription = $1; 4044f2b10b24bab0049020d268382eda144e2aa064cTom Care } 405ef8225444452a1486bd721f3285301fe84643b00Stephen Hines elsif (/<!-- FUNCTIONNAME (.*) -->$/) { 406ef8225444452a1486bd721f3285301fe84643b00Stephen Hines $BugFunction = $1; 407ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 408ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 4095744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 4105744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 411ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 4125744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 414ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $BugCategory) { 415ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = "Other"; 416ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 4174f2b10b24bab0049020d268382eda144e2aa064cTom Care 4184f2b10b24bab0049020d268382eda144e2aa064cTom Care # Don't add internal statistics to the bug reports 4194f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($BugCategory =~ /statistics/i) { 4204a374f9a58a5b350ec2e4123b20c9884ed1f5f15Jordan Rose AddStatLine($BugDescription, $Stats, $BugFile); 4214f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 4224f2b10b24bab0049020d268382eda144e2aa064cTom Care } 423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 424ef8225444452a1486bd721f3285301fe84643b00Stephen Hines push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugFunction, $BugLine, 42581983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek $BugPathLength ]; 42622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 42722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 42822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 4293ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek# CopyFiles - Copy resource files to target directory. 43022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 43122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 4323ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremeneksub CopyFiles { 43322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 43422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 435e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 436e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $JS = Cwd::realpath("$RealBin/sorttable.js"); 437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 43823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (! -r $JS); 44022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 4416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines copy($JS, "$Dir"); 44222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 44323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 44422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 446e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $CSS = Cwd::realpath("$RealBin/scanview.css"); 447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4483ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Cannot find 'scanview.css'.\n") 449e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4503ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines copy($CSS, "$Dir"); 4523ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4533ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 454e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4555744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 4565744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4575744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 4584f2b10b24bab0049020d268382eda144e2aa064cTom Care# CalcStats - Calculates visitation statistics and returns the string. 4594f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 4604f2b10b24bab0049020d268382eda144e2aa064cTom Care 4614f2b10b24bab0049020d268382eda144e2aa064cTom Caresub CalcStats { 4624f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 4634f2b10b24bab0049020d268382eda144e2aa064cTom Care 4644f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalBlocks = 0; 4654f2b10b24bab0049020d268382eda144e2aa064cTom Care my $UnreachedBlocks = 0; 4664f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFunctions = scalar(@$Stats); 4674f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BlockAborted = 0; 4684f2b10b24bab0049020d268382eda144e2aa064cTom Care my $WorkListAborted = 0; 4694f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Aborted = 0; 4704f2b10b24bab0049020d268382eda144e2aa064cTom Care 4714f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculate the unique files 4724f2b10b24bab0049020d268382eda144e2aa064cTom Care my $FilesHash = {}; 4734f2b10b24bab0049020d268382eda144e2aa064cTom Care 4744f2b10b24bab0049020d268382eda144e2aa064cTom Care foreach my $Row (@$Stats) { 4754f2b10b24bab0049020d268382eda144e2aa064cTom Care $FilesHash->{$Row->{Filename}} = 1; 4764f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalBlocks += $Row->{Total}; 4774f2b10b24bab0049020d268382eda144e2aa064cTom Care $UnreachedBlocks += $Row->{Unreachable}; 4784f2b10b24bab0049020d268382eda144e2aa064cTom Care $BlockAborted++ if $Row->{Aborted} eq 'yes'; 4794f2b10b24bab0049020d268382eda144e2aa064cTom Care $WorkListAborted++ if $Row->{Empty} eq 'no'; 4804f2b10b24bab0049020d268382eda144e2aa064cTom Care $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; 4814f2b10b24bab0049020d268382eda144e2aa064cTom Care } 4824f2b10b24bab0049020d268382eda144e2aa064cTom Care 4834f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFiles = scalar(keys(%$FilesHash)); 4844f2b10b24bab0049020d268382eda144e2aa064cTom Care 4854f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculations 4864f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); 4874f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions 4884f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4894f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / 4904f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalFunctions * 100); 4914f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks 4924f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4934f2b10b24bab0049020d268382eda144e2aa064cTom Care 4944f2b10b24bab0049020d268382eda144e2aa064cTom Care my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" 4954f2b10b24bab0049020d268382eda144e2aa064cTom Care . " in $TotalFiles files\n" 4964f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$Aborted functions aborted early ($PercentAborted%)\n" 4974f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" 4984f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" 4994f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; 5004f2b10b24bab0049020d268382eda144e2aa064cTom Care 5014f2b10b24bab0049020d268382eda144e2aa064cTom Care return $StatsString; 5024f2b10b24bab0049020d268382eda144e2aa064cTom Care} 5034f2b10b24bab0049020d268382eda144e2aa064cTom Care 5044f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 5059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 5069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 5079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 5089d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenekmy @filesFound; 5099d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenekmy $baseDir; 510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinessub FileWanted { 5119d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek my $baseDirRegEx = quotemeta $baseDir; 5129d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek my $file = $File::Find::name; 513ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 514ef8225444452a1486bd721f3285301fe84643b00Stephen Hines # The name of the file is generated by clang binary (HTMLDiagnostics.cpp) 5159d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek if ($file =~ /report-.*\.html$/) { 5169d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek my $relative_file = $file; 5179d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek $relative_file =~ s/$baseDirRegEx//g; 5189d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek push @filesFound, $relative_file; 5199d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek } 5209d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek} 5219d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek 522a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5244f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Dir = shift; 5254f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BaseDir = shift; 5264f2b10b24bab0049020d268382eda144e2aa064cTom Care my $AnalyzerStats = shift; 52733e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose my $KeepEmpty = shift; 528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 529fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 53223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 533363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 5349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 5359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 5369d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek $baseDir = $Dir . "/"; 5379d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek find({ wanted => \&FileWanted, follow => 0}, $Dir); 5389d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek 5399d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") { 54033e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose if (! $KeepEmpty) { 54133e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose Diag("Removing directory '$Dir' because it contains no reports.\n"); 5426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines rmtree($Dir) or die "Cannot rmtree '$Dir' : $!"; 54333e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose } 544e09b8c41d0eeb17f8cbe73affb213cb7ff8d0718Jordan Rose Diag("No bugs found.\n"); 545363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 5469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Scan each report file and build an index. 5494f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Index; 5504f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Stats; 5519d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); } 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 553938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Scan the failures directory and use the information in the .info files 554d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 555938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @failures; 556938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @attributes_ignored; 557938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (-d "$Dir/failures") { 558938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 559938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 560d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines opendir(DIR, "$Dir/failures"); 562938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 563938eef139ad43345248235da31f78a759dd18f13Ted Kremenek closedir(DIR); 564938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (@failures) { 565938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 566d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 567d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 568d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 570d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Generate an index.html file. 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my $FName = "$Dir/index.html"; 57463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5766e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5785744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 5795744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 5805744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 5817cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<title>${HtmlTitle}</title> 582f143545ce5ce125e7c1aa6fca9df372bfb604e9cTed Kremenek<link type="text/css" rel="stylesheet" href="scanview.css"/> 58322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 5846e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 5856e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 5866e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 5876e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 5886e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 5896e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 5906e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 5916e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5926e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5936e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 594ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 5952350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenekfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 5962350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek var Inputs = document.getElementsByTagName("input"); 5972350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek for ( var i = 0 ; i < Inputs.length; ++i ) { 5982350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if (Inputs[i].type == "checkbox") { 5992350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if(Inputs[i] != SummaryCheckButton) { 6002350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].checked = SummaryCheckButton.checked; 6012350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].onclick(); 6022350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 6032350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 6042350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 6052350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek} 6062350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek 607999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekfunction returnObjById( id ) { 608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (document.getElementById) 609999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.getElementById(id); 610999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.all) 611999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.all[id]; 612651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (document.layers) 613999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.layers[id]; 614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return returnVar; 615999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek} 616999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 617999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekvar NumUnchecked = 0; 618999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 6196e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 6206e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 6216e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 622999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (--NumUnchecked == 0) { 623999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = true; 624999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek } 6256e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 6266e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 6276e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 628999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek NumUnchecked++; 629999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = false; 6306e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 6316e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 6326e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 6331d1abb1dec3d0b7609809d876a16a64a021e96e7Ted Kremenek<!-- SUMMARYENDHEAD --> 6346e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 6356e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 6367cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h1>${HtmlTitle}</h1> 6377cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 6387cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<table> 6397cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 6407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 6417cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 642b4882d50923881d1a01af4d5604b5baaa141cdf9Douglas Gregor<tr><th>Clang Version:</th><td>${ClangVersion}</td></tr> 6437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Date:</th><td>${Date}</td></tr> 6447cba11262458df05951432b54997eb40a35dbf9eTed KremenekENDTEXT 6457cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 6467cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 6477cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (defined($BuildName) && defined($BuildDate)); 6487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 6497cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT <<ENDTEXT; 6507cba11262458df05951432b54997eb40a35dbf9eTed Kremenek</table> 6516e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6526e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6539d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek if (scalar(@filesFound)) { 654991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 655991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 656ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 657991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 658ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_type = ($row->[2]); 659ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_category = ($row->[1]); 660ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $key = "$bug_category:$bug_type"; 661ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 662ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 663ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { $Totals{$key}->[0]++; } 6646e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 665991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6667cba11262458df05951432b54997eb40a35dbf9eTed Kremenek print OUT "<h2>Bug Summary</h2>"; 667991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 668991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 669991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 6706e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6722350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek my $TotalBugs = scalar(@Index); 6736e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 674ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table> 675ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 676999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed 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> 6776e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 679ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $last_category; 680ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 681ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $key ( 682ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek sort { 683ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = $Totals{$a}; 684ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $y = $Totals{$b}; 685ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $res = $x->[1] cmp $y->[1]; 686ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res = $x->[2] cmp $y->[2] if ($res == 0); 687ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } keys %Totals ) 689ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek { 690ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $val = $Totals{$key}; 691ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $category = $val->[1]; 692ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $last_category or $last_category ne $category) { 693ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $last_category = $category; 694ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 696ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = lc $key; 697ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 698ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><td class=\"SUMM_DESC\">"; 699ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[2]; 7002350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek print OUT "</td><td class=\"Q\">"; 701ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[0]; 702ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 703991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 7046e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 7056e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 7066e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 7076e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 7086e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 7097cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Reports</h2> 710ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 711ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table class="sortable" style="table-layout:automatic"> 712ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr> 713ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td>Bug Group</td> 714ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 715bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 716ef8225444452a1486bd721f3285301fe84643b00Stephen Hines <td>Function/Method</td> 717ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="Q">Line</td> 71881983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek <td class="Q">Path Length</td> 7192645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 720ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <!-- REPORTBUGCOL --> 721ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek</tr></thead> 722ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<tbody> 7235744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 7249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 725991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 726991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 727991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 728991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (defined $prefix) { 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $regex = qr/^\Q$prefix\E/is; 732991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 7347a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 735ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 736ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = "$row->[1]:$row->[2]"; 737ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x = lc $x; 738ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 740991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 742ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr class=\"bt_$x\">"; 743ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 744991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 745ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 746ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 747ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $row->[2]; 748ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # Update the file prefix. 751ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $fname = $row->[3]; 752ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 753991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 754991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 755991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 756991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 757651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines print OUT "<td>"; 759ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my @fname = split /\//,$fname; 760ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname > 0) { 761ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek while ($#fname >= 0) { 762ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = shift @fname; 763ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $x; 764ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname >= 0) { 765ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<span class=\"W\"> </span>/"; 766ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 767ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 768ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 769ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { 770ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $fname; 771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 772ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 774ef8225444452a1486bd721f3285301fe84643b00Stephen Hines print OUT "<td class=\"DESC\">"; 775ef8225444452a1486bd721f3285301fe84643b00Stephen Hines print OUT $row->[4]; 776ef8225444452a1486bd721f3285301fe84643b00Stephen Hines print OUT "</td>"; 777ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 778ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Print out the quantities. 779ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for my $j ( 5 .. 6 ) { 780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines print OUT "<td class=\"Q\">$row->[$j]</td>"; 781ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 783991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 784ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (my $j = 7; $j <= $#{$row}; ++$j) { 785ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td>$row->[$j]</td>" 786991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 7877f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 788991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 78968005ddb49b88c2f6cdd88185d72d8b411d2dbc9Ted Kremenek print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 790651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 791e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar # Emit REPORTBUG markers. 792ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 794991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 795991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 796991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 798ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</tbody>\n</table>\n\n"; 799991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 800991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 801938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar (@failures) || scalar(@attributes_ignored)) { 802938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<h2>Analyzer Failures</h2>\n"; 803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 804938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @attributes_ignored) { 805938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 806938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 807938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 808938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @attributes_ignored) { 809938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 810938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $attribute = $1; 811938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the attribute file to get the first file that failed. 812938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (!open (ATTR, "$Dir/failures/$file")); 813938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile = <ATTR>; 814938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $ppfile; 815938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close ATTR; 816938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (! -e "$Dir/failures/$ppfile"); 817938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the info file and get the name of the source file. 818938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$ppfile.info.txt") or 819938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 820938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $srcfile = <INFO>; 821938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $srcfile; 822938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close (INFO); 823938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Print the information in the table. 824938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $prefix = GetPrefix(); 825938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 826938eef139ad43345248235da31f78a759dd18f13Ted 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"; 827938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile_clang = $ppfile; 828938eef139ad43345248235da31f78a759dd18f13Ted Kremenek $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 829938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 830938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 831938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 832938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 833651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 834938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @failures) { 835938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 836938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 837938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 838938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @failures) { 83982a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek $file =~ /(.+).info.txt$/; 840991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 841991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 842991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 843938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$file") or 844938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$file\n"; 845991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 8465d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 8475d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 8485d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 849991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 850991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 851d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 8529f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 853938eef139ad43345248235da31f78a759dd18f13Ted 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"; 854ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar my $ppfile_clang = $ppfile; 855ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 856938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 857991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 858938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 859651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 860e2c8663ad2b110712401145b866072bb94108058Nico 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"; 8615744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 862651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 863651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines print OUT "</body></html>\n"; 8645744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 8653ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek CopyFiles($Dir); 86620161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 86720161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 8686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines chmod(0755, $Dir); 8696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (defined $BaseDir) { chmod(0755, $BaseDir); } 87020161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 8714f2b10b24bab0049020d268382eda144e2aa064cTom Care # Print statistics 8724f2b10b24bab0049020d268382eda144e2aa064cTom Care print CalcStats(\@Stats) if $AnalyzerStats; 8734f2b10b24bab0049020d268382eda144e2aa064cTom Care 87423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 8756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ($Num == 1) { 8766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag("$Num bug found.\n"); 8776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 8786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag("$Num bugs found.\n"); 8796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 880150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 8815950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 882150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 883651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 884938eef139ad43345248235da31f78a759dd18f13Ted Kremenek DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 885651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 886363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 8879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 890dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 891dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 892dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8936b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 8946b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 895651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my $Arg = shift; 8966b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 897651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8986b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 8996b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 9006b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 9016b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 9026b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 9036b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 904651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 9056b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 9066b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 9076b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 9086b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 9096b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 910cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremeneksub SetEnv { 911cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift @_; 912cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX', 913651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS', 914651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 'CCC_ANALYZER_CONFIG') { 915cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek die "$opt is undefined\n" if (!defined $opt); 916cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{$opt} = $Options->{$opt}; 917cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 918cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek foreach my $opt ('CCC_ANALYZER_STORE_MODEL', 919cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_PLUGINS', 920cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_INTERNAL_STATS', 921cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_OUTPUT_FORMAT') { 922cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $x = $Options->{$opt}; 923cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if (defined $x) { $ENV{$opt} = $x } 924cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 925cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Verbose = $Options->{'VERBOSE'}; 926cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if ($Verbose >= 2) { 927cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 928cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 929cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek if ($Verbose >= 3) { 930cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 931cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek } 932cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek} 933cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 9343ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks# The flag corresponding to the --override-compiler command line option. 935651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesmy $OverrideCompiler = 0; 9363ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks 93738447a40795ef140a5d14ce43e31b60276c8d207Ted Kremeneksub RunXcodebuild { 93838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $Args = shift; 93938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $IgnoreErrors = shift; 94038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $CCAnalyzer = shift; 94138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek my $CXXAnalyzer = shift; 942cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift; 943cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 94438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if ($IgnoreErrors) { 94538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 94638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 9471afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek 9481afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek # Detect the version of Xcode. If Xcode 4.6 or higher, use new 9491afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek # in situ support for analyzer interposition without needed to override 9501afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek # the compiler. 951c810bff508f7515dd398e80c1828de1ef773d1caJordan Rose open(DETECT_XCODE, "-|", $Args->[0], "-version") or 9521afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek die "error: cannot detect version of xcodebuild\n"; 9531afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek 9541afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek my $oldBehavior = 1; 9551afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek 9561afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek while(<DETECT_XCODE>) { 9571afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek if (/^Xcode (.+)$/) { 958c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek my $ver = $1; 959c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek if ($ver =~ /^([0-9]+[.][0-9]+)[^0-9]?/) { 960c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek if ($1 >= 4.6) { 961c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek $oldBehavior = 0; 962c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek last; 963c73dcba91872322159b94dc49afb9c86d169425eTed Kremenek } 9641afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek } 9651afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek } 9661afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek } 9671afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek close(DETECT_XCODE); 968651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 969651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines # If --override-compiler is explicitely requested, resort to the old 9703ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks # behavior regardless of Xcode version. 9713ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks if ($OverrideCompiler) { 9723ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks $oldBehavior = 1; 9733ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks } 974651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 9751afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek if ($oldBehavior == 0) { 9761afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek my $OutputDir = $Options->{"OUTPUT_DIR"}; 9771afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek my $CLANG = $Options->{"CLANG"}; 97840ebe3dac227cebd47a0518fa30273cfc98358c7Jordan Rose my $OtherFlags = $Options->{"CCC_ANALYZER_ANALYSIS"}; 9791afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek push @$Args, 9801afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek "RUN_CLANG_STATIC_ANALYZER=YES", 9811afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek "CLANG_ANALYZER_OUTPUT=plist-html", 9821afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek "CLANG_ANALYZER_EXEC=$CLANG", 98340ebe3dac227cebd47a0518fa30273cfc98358c7Jordan Rose "CLANG_ANALYZER_OUTPUT_DIR=$OutputDir", 98440ebe3dac227cebd47a0518fa30273cfc98358c7Jordan Rose "CLANG_ANALYZER_OTHER_FLAGS=$OtherFlags"; 9851afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek 9861afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek return (system(@$Args) >> 8); 9871afc201e644ce6379b115b1fae0608dee1b0ab5fTed Kremenek } 988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 989cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek # Default to old behavior where we insert a bogus compiler. 990cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek SetEnv($Options); 991651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 99238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # Check if using iPhone SDK 3.0 (simulator). If so the compiler being 99338447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # used should be gcc-4.2. 99438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if (!defined $ENV{"CCC_CC"}) { 99538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek for (my $i = 0 ; $i < scalar(@$Args); ++$i) { 99638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { 99738447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek if (@$Args[$i+1] =~ /^iphonesimulator3/) { 99838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek $ENV{"CCC_CC"} = "gcc-4.2"; 999cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $ENV{"CCC_CXX"} = "g++-4.2"; 100038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 100138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 100238447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 100338447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 100438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 100538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # Disable PCH files until clang supports them. 100638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 1007651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 100838447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 100938447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 101038447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek # (via c++-analyzer) when linking such files. 101138447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; 1012651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1013651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return (system(@$Args) >> 8); 101438447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek} 101538447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek 1016651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinessub RunBuildCommand { 1017dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 10187442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 1019dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 10206195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 1021524c308506e77e173092e87a0724a27817311428Ted Kremenek my $CXXAnalyzer = shift; 1022cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek my $Options = shift; 1023c810bff508f7515dd398e80c1828de1ef773d1caJordan Rose 1024c810bff508f7515dd398e80c1828de1ef773d1caJordan Rose if ($Cmd =~ /\bxcodebuild$/) { 1025cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek return RunXcodebuild($Args, $IgnoreErrors, $CCAnalyzer, $CXXAnalyzer, $Options); 102638447a40795ef140a5d14ce43e31b60276c8d207Ted Kremenek } 1027c810bff508f7515dd398e80c1828de1ef773d1caJordan Rose 1028cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek # Setup the environment. 1029cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek SetEnv($Options); 1030651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1031651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 103292548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?cc[^\/]*$)/ or 103392548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 1034651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $Cmd =~ /(.*\/?clang$)/ or 103592548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 103692548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 103792548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 1038651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $ENV{"CCC_CC"} = $1; 103992548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek } 1040651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1041dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 10426195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 1043dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 1044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 104551365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or 104651365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or 104705acf8b689257d8b7349ffdfe309b4d7f7d6ae13Ted Kremenek $Cmd =~ /(.*\/?clang\+\+$)/ or 104851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { 104951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { 1050651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $ENV{"CCC_CXX"} = $1; 1051651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 105251365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek shift @$Args; 1053524c308506e77e173092e87a0724a27817311428Ted Kremenek unshift @$Args, $CXXAnalyzer; 105451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek } 105533881620f4b160f020712f26df57ed39b540fcddJordan Rose elsif ($Cmd eq "make" or $Cmd eq "gmake") { 105633881620f4b160f020712f26df57ed39b540fcddJordan Rose AddIfNotPresent($Args, "CC=$CCAnalyzer"); 105733881620f4b160f020712f26df57ed39b540fcddJordan Rose AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); 105833881620f4b160f020712f26df57ed39b540fcddJordan Rose if ($IgnoreErrors) { 10596b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 10608912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 10617442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 1062651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 106387752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek 10645a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 1065dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 1066dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 1067dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 10689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 10699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 10709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1071a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 1072651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10735744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 1074a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 10752b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1076f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 1077f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 1078fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 1079f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 1080f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 1081f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 1082f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 10832b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 10842b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1085eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -analyze-headers 1086651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1087eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Also analyze functions in #included files. By default, such functions 1088eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek are skipped unless they are called by functions within the main source file. 1089651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1090eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -o <output location> 1091651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1092eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specifies the output directory for analyzer reports. Subdirectories will be 1093eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek created as needed to represent separate "runs" of the analyzer. If this 1094eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X) 1095eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek to store the reports. 1096eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1097651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines -h 1098363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 10991262fc4d66584224234691d30d779f8ff004585cTed Kremenek 1100eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Display this message. 1101eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1102eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -k 1103eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --keep-going 1104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1105eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Add a "keep on going" option to the specified build command. This option 1106eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek currently supports make and xcodebuild. This is a convenience option; one 1107eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek can specify this behavior directly using build options. 1108eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1109eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --html-title [title] 1110eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --html-title=[title] 11112b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1112eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specify the title used on generated HTML pages. If not specified, a default 1113eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek title will be used. 11147cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 1115eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -plist 1116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1117eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default the output of scan-build is a set of HTML files. This option 1118eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek outputs the results as a set of .plist files. 1119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1120eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -plist-html 1121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1122eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default the output of scan-build is a set of HTML files. This option 1123eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek outputs the results as a set of HTML and .plist files. 1124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1125eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --status-bugs 1126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1127eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek By default, the exit status of scan-build is the same as the executed build 1128eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek command. Specifying this option causes the exit status of scan-build to be 1 1129eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek if it found potential bugs and 0 otherwise. 1130386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 1131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines --use-cc [compiler path] 1132eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-cc=[compiler path] 1133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1134eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build analyzes a project by interposing a "fake compiler", which 1135eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek executes a real compiler for compilation and the static analyzer for analysis. 1136eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Because of the current implementation of interposition, scan-build does not 1137eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek know what compiler your project normally uses. Instead, it simply overrides 1138eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek the CC environment variable, and guesses your default compiler. 1139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1140eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek In the future, this interposition mechanism to be improved, but if you need 1141eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build to use a specific compiler for *compilation* then you can use 1142eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek this option to specify a path to that compiler. 1143eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek 1144eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-c++ [compiler path] 1145eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --use-c++=[compiler path] 1146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1147eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek This is the same as "-use-cc" but for C++ code. 1148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1149eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -v 1150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1151eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Enable verbose output from scan-build. A second and third '-v' increases 1152eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek verbosity. 1153f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1154eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -V 1155eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek --view 1156363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 1157eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek View analysis results in a web browser when the build completes. 11587f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1159be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed KremenekADVANCED OPTIONS: 1160be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1161eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -no-failure-reports 1162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1163eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Do not create a 'failures' subdirectory that includes analyzer crash reports 1164eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek and preprocessed source files. 1165b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1166eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -stats 1167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1168eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Generates visitation statistics for the project being analyzed. 11694f2b10b24bab0049020d268382eda144e2aa064cTom Care 1170eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -maxloop <loop count> 1171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1172eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Specifiy the number of times a block can be visited before giving up. 1173eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Default is 4. Increase for more comprehensive coverage at a cost of speed. 1174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1175eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek -internal-stats 1176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1177eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek Generate internal analyzer statistics. 1178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines --use-analyzer [Xcode|path to clang] 11805a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek --use-analyzer=[Xcode|path to clang] 1181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1182810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek scan-build uses the 'clang' executable relative to itself for static 1183810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek analysis. One can override this behavior with this option by using the 1184810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 'clang' packaged with Xcode (on OS X) or from the PATH. 118533e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose 118633e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose --keep-empty 118733e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose 118833e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose Don't remove the build results directory even if no issues were reported. 118933e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose 1190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines --override-compiler 1191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Always resort to the ccc-analyzer even when better interposition methods 11923ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks are available. 1193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines -analyzer-config <options> 1195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Provide options to pass through to the analyzer's -analyzer-config flag. 1197ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Several options are separated with comma: 'key1=val1,key2=val2' 1198ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 1199ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Available options: 1200ef8225444452a1486bd721f3285301fe84643b00Stephen Hines * stable-report-filename=true or false (default) 1201ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Switch the page naming to: 1202ef8225444452a1486bd721f3285301fe84643b00Stephen Hines report-<filename>-<function/method name>-<id>.html 1203ef8225444452a1486bd721f3285301fe84643b00Stephen Hines instead of report-XXXXXX.html 1204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 120509fbf297da918760ce33302a3f709a77f43af265Ted KremenekCONTROLLING CHECKERS: 120609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 120709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek A default group of checkers are always run unless explicitly disabled. 120809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek Checkers may be enabled/disabled using the following options: 120909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 121009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -enable-checker [checker name] 121109fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -disable-checker [checker name] 1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1213f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna ZaksLOADING CHECKERS: 1214f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1215f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks Loading external checkers using the clang plugin interface: 1216f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1217f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks -load-plugin [plugin library] 1218d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 1219b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1220ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for list of checkers that are enabled. 1221f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 1222f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks# create a list to load the plugins via the 'Xclang' command line 1223f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks# argument 1224f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksmy @PluginLoadCommandline_xclang; 1225f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaksforeach my $param ( @PluginsToLoad ) { 1226f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push ( @PluginLoadCommandline_xclang, "-Xclang" ); 1227f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push ( @PluginLoadCommandline_xclang, $param ); 1228f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks} 1229ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy %EnabledCheckers; 1230ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekforeach my $lang ("c", "objective-c", "objective-c++", "c++") { 1231ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek pipe(FROM_CHILD, TO_PARENT); 1232ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $pid = fork(); 1233ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($pid == 0) { 1234ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close FROM_CHILD; 1235ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDOUT,">&", \*TO_PARENT); 1236ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDERR,">&", \*TO_PARENT); 1237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###'); 1238ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1239ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(TO_PARENT); 1240ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 1241ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek foreach my $val (split /\s+/) { 1242ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $val =~ s/\"//g; 1243ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($val =~ /-analyzer-checker\=([^\s]+)/) { 1244ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $EnabledCheckers{$1} = 1; 1245ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1246ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1247ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1248ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek waitpid($pid,0); 1249ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(FROM_CHILD); 1250ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1251ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1252ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for complete list of checkers. 1253a778d710e2c62d62e0b78d120254764142801196Jordan Roseif (defined $Clang && -x $Clang) { 1254a778d710e2c62d62e0b78d120254764142801196Jordan Rose pipe(FROM_CHILD, TO_PARENT); 1255a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $pid = fork(); 1256a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($pid == 0) { 1257a778d710e2c62d62e0b78d120254764142801196Jordan Rose close FROM_CHILD; 1258a778d710e2c62d62e0b78d120254764142801196Jordan Rose open(STDOUT,">&", \*TO_PARENT); 1259a778d710e2c62d62e0b78d120254764142801196Jordan Rose open(STDERR,">&", \*TO_PARENT); 1260a778d710e2c62d62e0b78d120254764142801196Jordan Rose exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help'); 1261ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1262a778d710e2c62d62e0b78d120254764142801196Jordan Rose close(TO_PARENT); 1263a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $foundCheckers = 0; 1264ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 1265a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/CHECKERS:/) { 1266a778d710e2c62d62e0b78d120254764142801196Jordan Rose $foundCheckers = 1; 1267a778d710e2c62d62e0b78d120254764142801196Jordan Rose last; 126873078642d3c32499ee573bd458af6d384fa7f6d8Ted Kremenek } 1269a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1270a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (!$foundCheckers) { 1271a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " *** Could not query Clang for the list of available checkers."; 1272a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1273a778d710e2c62d62e0b78d120254764142801196Jordan Rose else { 1274a778d710e2c62d62e0b78d120254764142801196Jordan Rose print("\nAVAILABLE CHECKERS:\n\n"); 1275a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $skip = 0; 1276a778d710e2c62d62e0b78d120254764142801196Jordan Rose while(<FROM_CHILD>) { 1277a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/experimental/) { 1278a778d710e2c62d62e0b78d120254764142801196Jordan Rose $skip = 1; 1279a778d710e2c62d62e0b78d120254764142801196Jordan Rose next; 1280a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1281a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($skip) { 1282a778d710e2c62d62e0b78d120254764142801196Jordan Rose next if (!/^\s\s[^\s]/); 1283a778d710e2c62d62e0b78d120254764142801196Jordan Rose $skip = 0; 1284ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1285a778d710e2c62d62e0b78d120254764142801196Jordan Rose s/^\s\s//; 1286a778d710e2c62d62e0b78d120254764142801196Jordan Rose if (/^([^\s]+)/) { 1287a778d710e2c62d62e0b78d120254764142801196Jordan Rose # Is the checker enabled? 1288a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $checker = $1; 1289a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $enabled = 0; 1290a778d710e2c62d62e0b78d120254764142801196Jordan Rose my $aggregate = ""; 1291a778d710e2c62d62e0b78d120254764142801196Jordan Rose foreach my $domain (split /\./, $checker) { 1292a778d710e2c62d62e0b78d120254764142801196Jordan Rose $aggregate .= $domain; 1293a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($EnabledCheckers{$aggregate}) { 1294a778d710e2c62d62e0b78d120254764142801196Jordan Rose $enabled =1; 1295a778d710e2c62d62e0b78d120254764142801196Jordan Rose last; 1296a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1297a778d710e2c62d62e0b78d120254764142801196Jordan Rose # append a dot, if an additional domain is added in the next iteration 1298a778d710e2c62d62e0b78d120254764142801196Jordan Rose $aggregate .= "."; 1299a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1301a778d710e2c62d62e0b78d120254764142801196Jordan Rose if ($enabled) { 1302a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " + "; 1303a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1304a778d710e2c62d62e0b78d120254764142801196Jordan Rose else { 1305a778d710e2c62d62e0b78d120254764142801196Jordan Rose print " "; 1306a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1307ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1308ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek else { 1309ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " "; 1310ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1311a778d710e2c62d62e0b78d120254764142801196Jordan Rose print $_; 1312ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1313a778d710e2c62d62e0b78d120254764142801196Jordan Rose print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n" 1314a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1315a778d710e2c62d62e0b78d120254764142801196Jordan Rose waitpid($pid,0); 1316a778d710e2c62d62e0b78d120254764142801196Jordan Rose close(FROM_CHILD); 1317ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 13187fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1319b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 1320b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 13212b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 13222b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1323363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 132439eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 13255744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 13262b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1327eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenek scan-build -o /tmp/myhtmldir make -j4 1328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1329eaafdfc7b475937ed194ad729407481054b99be9Ted KremenekThe above example causes analysis reports to be deposited into a subdirectory 1330eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenekof "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different 1331eaafdfc7b475937ed194ad729407481054b99be9Ted Kremeneksubdirectory is created each time scan-build analyzes a project. The analyzer 1332eaafdfc7b475937ed194ad729407481054b99be9Ted Kremenekshould support most parallel builds, but not distributed builds. 13332b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 13342b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 13359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 13369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 13387cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# HtmlEscape - HTML entity encode characters that are special in HTML 13397cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 13407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13417cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub HtmlEscape { 13427cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 13437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 13447cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 134587f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/&/&/g; 134687f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/</</g; 134787f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/>/>/g; 13487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 13497cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 13507cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13517cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 13527cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# ShellEscape - backslash escape characters that are special to the shell 13537cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 13547cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13557cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub ShellEscape { 13567cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 13577cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 135887f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 135987f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek return $arg; 13607cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 13617cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 13627cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 13639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 13649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 13659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1366e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekmy $AnalyzeHeaders = 0; 13679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 13689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 13697f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 1370363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 137133e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rosemy $KeepEmpty = 0; # Don't remove output directory even with 0 results. 1372b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 137307c3767be59472e19183c7b51fae76481465cb51Zhongxing Xumy $StoreModel; 1374be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekmy $ConstraintsModel; 13751e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaksmy $InternalStats; 1376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesmy @ConfigOptions; 13778d8bc9157fccab6a4089c41cdad9e12045edd736Ted Kremenekmy $OutputFormat = "html"; 13784f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $AnalyzerStats = 0; 13794f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $MaxLoop = 0; 1380f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rosemy $RequestDisplayHelp = 0; 1381f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rosemy $ForceDisplayHelp = 0; 1382f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rosemy $AnalyzerDiscoveryMethod; 13839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 1385f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose $ForceDisplayHelp = 1 13869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 13879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 1389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 1391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 13939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 13942f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 1395f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose $RequestDisplayHelp = 1; 1396ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek shift @ARGV; 1397ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek next; 13989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1400e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if ($arg eq '-analyze-headers') { 1401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines shift @ARGV; 1402e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek $AnalyzeHeaders = 1; 1403e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek next; 1404e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek } 1405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 14079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 1408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 141023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 14119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1413db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # Construct an absolute path. Uses the current working directory 1414db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # as a base if the original path was not absolute. 1415db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek $HtmlDir = abs_path(shift @ARGV); 1416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 14189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 14197cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 14207cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--html-title(=(.+))?$/) { 14217cba11262458df05951432b54997eb40a35dbf9eTed Kremenek shift @ARGV; 14227cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 1423278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq '') { 14247cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (!@ARGV) { 14257cba11262458df05951432b54997eb40a35dbf9eTed Kremenek DieDiag("'--html-title' option requires a string.\n"); 14267cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 14277cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 14287cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = shift @ARGV; 14297cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } else { 14307cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = $2; 14317cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 14327cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 14337cba11262458df05951432b54997eb40a35dbf9eTed Kremenek next; 14347cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 1435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14362b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 14379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 14389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 14399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 14409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 14417fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1442f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 1443f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 1444f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 1445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1446278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1447f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 1448f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 1449f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1450f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 1451f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1452f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 1453f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 1454f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1456f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 1457f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 1458f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14607cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 1461386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 1462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines my $cxx; 1463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1464278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1465386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 1466386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 1467386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 146851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = shift @ARGV; 1469386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1470386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 147151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = $2; 1472386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 147451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = $cxx; 1475386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 1476386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 14799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 14809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 14819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 14829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14847f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 14857f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 1486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines $ViewResults = 1; 14877f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 14887f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 1489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1490363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 1491363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 1492363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 1493363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 1494363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 149507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu 149607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu if ($arg eq "-store") { 149707c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu shift @ARGV; 1498be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $StoreModel = shift @ARGV; 1499be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek next; 1500be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek } 1501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1502be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek if ($arg eq "-constraints") { 1503be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek shift @ARGV; 1504be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ConstraintsModel = shift @ARGV; 150507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu next; 150607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu } 15071e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks 15081e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks if ($arg eq "-internal-stats") { 15091e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks shift @ARGV; 15101e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks $InternalStats = 1; 15111e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks next; 15121e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks } 1513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1514db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($arg eq "-plist") { 1515db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek shift @ARGV; 1516db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $OutputFormat = "plist"; 1517db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek next; 1518db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 15197753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($arg eq "-plist-html") { 15207753b352366778d01c5cda4117356f181d3dd468Ted Kremenek shift @ARGV; 15217753b352366778d01c5cda4117356f181d3dd468Ted Kremenek $OutputFormat = "plist-html"; 15227753b352366778d01c5cda4117356f181d3dd468Ted Kremenek next; 15237753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if ($arg eq "-analyzer-config") { 1526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines shift @ARGV; 1527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines push @ConfigOptions, "-analyzer-config", shift @ARGV; 1528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines next; 1529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1531e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek if ($arg eq "-no-failure-reports") { 1532e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek $ENV{"CCC_REPORT_FAILURES"} = 0; 1533e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek next; 1534e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek } 15354f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-stats") { 15364f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 15374f2b10b24bab0049020d268382eda144e2aa064cTom Care $AnalyzerStats = 1; 15384f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 15394f2b10b24bab0049020d268382eda144e2aa064cTom Care } 15404f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-maxloop") { 15414f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 15424f2b10b24bab0049020d268382eda144e2aa064cTom Care $MaxLoop = shift @ARGV; 15434f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 15444f2b10b24bab0049020d268382eda144e2aa064cTom Care } 154509fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-enable-checker") { 154609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 154709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-checker", shift @ARGV; 154809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 154909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 155009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-disable-checker") { 155109fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 155209fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-disable-checker", shift @ARGV; 155309fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 155409fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 1555f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks if ($arg eq "-load-plugin") { 1556f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks shift @ARGV; 1557f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks push @PluginsToLoad, "-load", shift @ARGV; 1558f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks next; 1559f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks } 15605a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek if ($arg eq "--use-analyzer") { 1561810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek shift @ARGV; 1562810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $AnalyzerDiscoveryMethod = shift @ARGV; 1563810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek next; 1564810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 15655a3581daf22f9b9d0025093b07c35a08cceeae6cTed Kremenek if ($arg =~ /^--use-analyzer=(.+)$/) { 1566810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek shift @ARGV; 1567810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $AnalyzerDiscoveryMethod = $1; 1568810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek next; 1569810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 157033e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose if ($arg eq "--keep-empty") { 157133e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose shift @ARGV; 157233e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose $KeepEmpty = 1; 157333e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose next; 157433e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose } 15753ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks 15763ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks if ($arg eq "--override-compiler") { 15773ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks shift @ARGV; 15783ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks $OverrideCompiler = 1; 15793ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks next; 15803ee2ad876a7ffc093cecb220916b0cfa1b4cc3c3Anna Zaks } 1581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 158223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 1583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 15849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 15859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 15869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1587f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Roseif (!@ARGV and !$RequestDisplayHelp) { 1588f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose ErrorDiag("No build command specified.\n\n"); 1589f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose $ForceDisplayHelp = 1; 1590ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1591ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1592810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek# Find 'clang' 1593810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenekif (!defined $AnalyzerDiscoveryMethod) { 1594810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = Cwd::realpath("$RealBin/bin/clang"); 1595810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if (!defined $Clang || ! -x $Clang) { 1596810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = Cwd::realpath("$RealBin/clang"); 1597810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1598810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if (!defined $Clang || ! -x $Clang) { 1599f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose if (!$RequestDisplayHelp && !$ForceDisplayHelp) { 1600a778d710e2c62d62e0b78d120254764142801196Jordan Rose DieDiag("error: Cannot find an executable 'clang' relative to scan-build." . 1601a778d710e2c62d62e0b78d120254764142801196Jordan Rose " Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n"); 1602a778d710e2c62d62e0b78d120254764142801196Jordan Rose } 1603810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1605651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineselse { 16060d3a3fd7211a1b368d1f8c0d7ca1cfd40d31a0eaTed Kremenek if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) { 1607810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek my $xcrun = `which xcrun`; 1608810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek chomp $xcrun; 1609810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if ($xcrun eq "") { 1610810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n"); 1611810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1612810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek $Clang = `$xcrun -toolchain XcodeDefault -find clang`; 1613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines chomp $Clang; 1614810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek if ($Clang eq "") { 1615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DieDiag("No 'clang' executable found by 'xcrun'\n"); 1616810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1617810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1618810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek else { 16196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines $Clang = $AnalyzerDiscoveryMethod; 16209d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek if (!defined $Clang or not -x $Clang) { 16219d9f254f7781c157256dbde4d4d961a2d89e8599Ted Kremenek DieDiag("Cannot find an executable clang at '$AnalyzerDiscoveryMethod'\n"); 1622810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1623810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek } 1624810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek} 1625810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 1626f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Roseif ($ForceDisplayHelp || $RequestDisplayHelp) { 1627a778d710e2c62d62e0b78d120254764142801196Jordan Rose DisplayHelp(); 1628f190f6b88e0648ebb5f49bab3c788e03e13b9069Jordan Rose exit $ForceDisplayHelp; 1629a778d710e2c62d62e0b78d120254764142801196Jordan Rose} 1630a778d710e2c62d62e0b78d120254764142801196Jordan Rose 1631810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek$ClangCXX = $Clang; 1632ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev# Determine operating system under which this copy of Perl was built. 1633ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsevmy $IsWinBuild = ($^O =~/msys|cygwin|MSWin32/); 1634ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsevif($IsWinBuild) { 1635ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev $ClangCXX =~ s/.exe$/++.exe/; 1636ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev} 1637ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsevelse { 1638ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev $ClangCXX =~ s/\-\d+\.\d+$//; 1639ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev $ClangCXX .= "++"; 1640ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev} 1641ceb791ccd25b7395bdd9a6d01c30740ad42c09a0Anton Yartsev 164247135fe346b101c9bfb15c7309423fb57ec533f0Ted Kremenek# Make sure to use "" to handle paths with spaces. 164347135fe346b101c9bfb15c7309423fb57ec533f0Ted Kremenek$ClangVersion = HtmlEscape(`"$Clang" --version`); 1644810e6229e59796f8109e94e4a469a2dc17cf3e6dTed Kremenek 1645ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine where results go. 16467cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 16477cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 16487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek unless (defined($HtmlTitle)); 1649386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 16509cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 1651684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 1652a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 16539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1654ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine the location of ccc-analyzer. 165551365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $AbsRealBin = Cwd::realpath($RealBin); 165651365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; 165751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; 165851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek 1659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines# Portability: use less strict but portable check -e (file exists) instead of 16604415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev# non-portable -x (file is executable). On some windows ports -x just checks 1661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines# file extension to determine if a file is executable (see Perl language 16624415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev# reference, perlport) 16634415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsevif (!defined $Cmd || ! -e $Cmd) { 166451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd = "$AbsRealBin/ccc-analyzer"; 16654415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev DieDiag("'ccc-analyzer' does not exist at '$Cmd'\n") if(! -e $Cmd); 1666ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenek} 16674415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsevif (!defined $CmdCXX || ! -e $CmdCXX) { 166851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $CmdCXX = "$AbsRealBin/c++-analyzer"; 16694415a4b58bd561d85a7dff84f62778b675a98a09Anton Yartsev DieDiag("'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -e $CmdCXX); 167051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek} 1671f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 1672810e6229e59796f8109e94e4a469a2dc17cf3e6dTed KremenekDiag("Using '$Clang' for static analysis\n"); 16730b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 1674ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted KremenekSetHtmlEnv(\@ARGV, $HtmlDir); 1675cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekif ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; } 1676cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekif ($AnalyzerStats) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; } 1677be92debbf1e9c38b1ae8a4a9c30377b24196ca73Ted Kremenekif ($MaxLoop > 0) { push @AnalysesToRun, "-analyzer-max-loop $MaxLoop"; } 1678cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 1679cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek# Delay setting up other environment variables in case we can do true 1680cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek# interposition. 1681cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun; 1682cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad; 1683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesmy $CCC_ANALYZER_CONFIG = join ' ',@ConfigOptions; 1684cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy %Options = ( 1685cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CC' => $Cmd, 1686cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CXX' => $CmdCXX, 1687cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CLANG' => $Clang, 1688cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CLANG_CXX' => $ClangCXX, 1689cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'VERBOSE' => $Verbose, 1690cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS, 1691cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS, 1692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 'CCC_ANALYZER_CONFIG' => $CCC_ANALYZER_CONFIG, 1693cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek 'OUTPUT_DIR' => $HtmlDir 1694cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek); 1695f8e8a3eeff891d1c056c96b6d6be404533741ba7Anna Zaks 16963cab2b1c3798f2a6aa3526875801a02aebf6fc1dZhongxing Xuif (defined $StoreModel) { 1697cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; 169807c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu} 1699be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekif (defined $ConstraintsModel) { 1700cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; 1701be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek} 17021e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaksif (defined $InternalStats) { 1703cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_INTERNAL_STATS'} = 1; 17041e548f12f7cd6631a3e688a9580ede92898d9e69Anna Zaks} 1705db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekif (defined $OutputFormat) { 1706cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek $Options{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; 1707db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek} 1708db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 17099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 1710cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX, 1711cbea860417eea485be5bc34e6a61f267cf180a56Ted Kremenek \%Options); 17129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 17137753b352366778d01c5cda4117356f181d3dd468Ted Kremenekif (defined $OutputFormat) { 17141182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar if ($OutputFormat =~ /plist/) { 17151182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis run complete.\n"; 17161182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; 17171182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar } 17187a334d9ed9ff7426e78a88582207b47b370ec5deTed Kremenek if ($OutputFormat =~ /html/) { 17197753b352366778d01c5cda4117356f181d3dd468Ted Kremenek # Postprocess the HTML directory. 172033e9500784a6b8dc7f01ae5c85ebf0883fbc6662Jordan Rose my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats, $KeepEmpty); 17217753b352366778d01c5cda4117356f181d3dd468Ted Kremenek 17227753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ViewResults and -r "$HtmlDir/index.html") { 17237753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Analysis run complete.\n"; 17247753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 17257753b352366778d01c5cda4117356f181d3dd468Ted Kremenek my $ScanView = Cwd::realpath("$RealBin/scan-view"); 17267753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if (! -x $ScanView) { $ScanView = "scan-view"; } 17277753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exec $ScanView, "$HtmlDir"; 17287753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1729db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 17307753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ExitStatusFoundBugs) { 17317753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 1 if ($NumBugs > 0); 17327753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 0; 17337753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1734db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 1735363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 1736363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 17375656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 1738