scan-build revision ce723ce2346fccb102d4dc93b80356824544d1af
19cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek#!/usr/bin/env perl 29cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 39cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# The LLVM Compiler Infrastructure 49cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 59cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# This file is distributed under the University of Illinois Open Source 69cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# License. See LICENSE.TXT for details. 79cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 89cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 99cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# A script designed to wrap a build so that all calls to gcc are intercepted 119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# and piped to the static analyzer. 129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse strict; 169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse warnings; 1722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenekuse FindBin qw($RealBin); 18a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenekuse Digest::MD5; 197a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekuse File::Basename; 2023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor; 2123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor qw(:constants); 227cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Cwd; 237cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Sys::Hostname; 247cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse File::Basename; 259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 28f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 29f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 3095aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekmy $CXX; # Leave undefined initially. 319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 320e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 330e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT 340e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 367cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $UserName = HtmlEscape(getpwuid($<) || 'unknown'); 377cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HostName = HtmlEscape(hostname() || 'unknown'); 387cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDir = HtmlEscape(getcwd()); 397cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDirSuffix = basename($CurrentDir); 407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 417cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CmdArgs; 427cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 437cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HtmlTitle; 447cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 457cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $Date = localtime(); 467cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 47b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 48b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 49b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 50b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 5123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 5223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 5423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 6023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 61991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 62991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 63991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("The analyzer crashed on some source files.\n"); 64386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek Diag ("Preprocessed versions of crashed files were deposited in '$Dir/crashes'.\n"); 65991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 66991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n") 67991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 68991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 7023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 7123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, RED "$Prog: "; 7223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET, RED @_; 7323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 7423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 7623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: ", @_; 7723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek exit(0); 7923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 8023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 82b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Some initial preprocessing of Clang options. 83b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 84b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 85b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $ClangSB = "$RealBin/clang"; 86b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $Clang = $ClangSB; 87b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 88b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekif (! -x $ClangSB) { 89b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $Clang = "clang"; 90b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 91b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 92b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AvailableAnalyses; 93b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 94b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Query clang for analysis options. 9563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenekopen(PIPE, "-|", $Clang, "--help") or 96b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek DieDiag("Cannot execute '$Clang'"); 9763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 98b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $FoundAnalysis = 0; 99b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 100b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekwhile(<PIPE>) { 101b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if ($FoundAnalysis == 0) { 102b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if (/Available Source Code Analyses/) { 103b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $FoundAnalysis = 1; 104b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 105991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 106b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 107b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 108b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 109b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if (/^\s\s\s\s([^\s]+)\s(.+)$/) { 110b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next if ($1 =~ /-dump/ or $1 =~ /-view/ 111b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek or $1 =~ /-checker-simple/ or $1 =~ /-warn-uninit/); 112b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 113b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $AvailableAnalyses{$1} = $2; 114b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 115b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 116b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 117b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek last; 118b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 119b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 120b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekclose (PIPE); 121b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 122b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AnalysesDefaultEnabled = ( 123b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-warn-dead-stores' => 1, 124b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-checker-cfref' => 1, 1259012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek '-warn-objc-methodsigs' => 1, 126bde3a051933b6829ed79d6db0118231c2c01b105Ted Kremenek '-warn-objc-missing-dealloc' => 1, 1275d443490cd6fb8c772957b7df728f71189d9c55bTed Kremenek '-warn-objc-unused-ivars' => 1, 128b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek); 129b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 130b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 131fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 134a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub GetHTMLRunDir { 1359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 136fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "Not enough arguments." if (@_ == 0); 1379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift @_; 138fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 139fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 140fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 141fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $Dir = "/tmp"; 142fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 143fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 144fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 1469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @CurrentTime = localtime(); 1489cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1499cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1509cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1519cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 1529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1539d7405fafd5bc08d38bc75579927bf414570bd61Ted Kremenek my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 1549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Determine the run number. 1569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 1589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-d $Dir) { 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 16223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 1639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Iterate over all files in the specified directory. 1669cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $max = 0; 1689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 17029da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 1729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek foreach my $f (@FILES) { 1749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 175fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 176fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 177fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 178fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 179fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 180fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 181ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 1829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 1839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 1849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 1859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 1869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 1879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($x[3] > $max) { 1899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $max = $x[3]; 1909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 1949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 19823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 1999cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 200fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 201fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 202fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed."); 203fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 204fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 2059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # $Dir does not exist. It will be automatically created by the 2069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # clang driver. Set the run number to 1. 207fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 2089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 2099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 211fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 2129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 214fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 215fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 216fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 217fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 218fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 219fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 220fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 221fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek system 'mkdir','-p',$NewDir; 222fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 2239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 225a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 2269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 2289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 2309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 2319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 2339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Cmd =~ /configure/) { 2379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 24123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2429cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 24857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 24957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 25057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 25157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 25257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 25323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 254a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 255a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2567ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2577ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 25863c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # come bundled on most systems. 25923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 260a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 261a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 262a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 263a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 26463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Return the digest. 265a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 26657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 26757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 26857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 2697a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 2707a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2717a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2727a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 2737a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2747a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 2757a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 2767a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 2777a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 2787a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2797a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek # Ignore /usr, /Library, /System, /Developer 2807a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return if ( $x =~ /^\/usr/ or $x =~ /^\/Library/ 2817a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek or $x =~ /^\/System/ or $x =~ /^\/Developer/); 2827a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2837a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 2847a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 2857a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 2867a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 2877a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 28820b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 2897a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2907a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2917a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 2927a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 2937a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2947a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2957a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2967a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 2977a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2987a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2997a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 3007a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 3017a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 3027a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 30363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3047a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 30563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 30663c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3077a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 3087a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 3097a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 3107a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 31163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3127a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 3137a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 31420161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("mv", "$fname.tmp", $fname); 3157a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3167a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3177a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3185744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3195744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3205744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 32157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 32257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 32357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 32457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 32557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 3275744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3285744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3295744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3305744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3315744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 33257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 33357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 33457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 33557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 33657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 337fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 33857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 33920161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-f", "$Dir/$FName"); 34057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 34157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 34257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 34357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 34457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 345809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 34620161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("chmod", "644", "$Dir/$FName"); 347684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek 348684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 34923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3505744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3515744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $BugDesc = ""; 35222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugFile = ""; 353ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $BugCategory; 35422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugPathLength = 1; 35522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugLine = 0; 356ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $found = 0; 357ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3585744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 359ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 360ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek last if ($found == 5); 361ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3625744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek if (/<!-- BUGDESC (.*) -->$/) { 3635744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek $BugDesc = $1; 364ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 3655744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 36622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 36722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugFile = $1; 3687a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 369ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 37022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 37122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 37222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 373ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 37422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 37522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 37622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugLine = $1; 377ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 378ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 379ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek elsif (/<!-- BUGCATEGORY (.*) -->$/) { 380ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = $1; 381ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 38222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 3835744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 3845744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3855744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 386ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 387ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $BugCategory) { 388ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = "Other"; 389ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 3905744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 39150534dc3ab0737224f9ce739821e1486219c686bTed Kremenek push @$Index,[ $FName, $BugCategory, $BugDesc, $BugFile, $BugLine ]; 39222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 39322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 39422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 3953ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek# CopyFiles - Copy resource files to target directory. 39622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 39722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 3983ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremeneksub CopyFiles { 39922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 40122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 40322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$RealBin/sorttable.js"); 40422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("cp", "$RealBin/sorttable.js", "$Dir"); 40622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 40822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 4093ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4103ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Cannot find 'scanview.css'.\n") 4113ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek if (! -r "$RealBin/scanview.css"); 4123ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4133ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek system ("cp", "$RealBin/scanview.css", "$Dir"); 4143ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4153ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 4163ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek if (! -r "$Dir/scanview.css"); 4175744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 4185744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4195744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 4209cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 4219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 4229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 423a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 4249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 426684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek my $BaseDir = shift; 4279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 428fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 4299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 43123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 432363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 436991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Crashes = 0; 437991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @files = grep { if ($_ eq "crashes") { $Crashes++; } 438991c54b9b7409656e5593364e065878b5210d556Ted Kremenek /^report-.*\.html$/; } readdir(DIR); 4399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 4409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 441991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files) == 0 and $Crashes == 0) { 44223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Removing directory '$Dir' because it contains no reports.\n"); 44320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-fR", $Dir); 444363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4465744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 447991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Scan each report file and build an index. 448991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @Index; 4495744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); } 4505744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 451d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # Scan the crashes directory and use the information in the .info files 452d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 453d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (-d "$Dir/crashes") { 454d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek opendir(DIR, "$Dir/crashes"); 45582a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek my @files = grep { /[.]info.txt$/; } readdir(DIR); 456d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 457d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek foreach my $file (@files) { 458d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek open IN, "$Dir/crashes/$file" or DieDiag("cannot open $file\n"); 459d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 460d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 461d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 462d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 463d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 464d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 46563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Generate an index.html file. 46663c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek my $FName = "$Dir/index.html"; 46763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 4685744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4696e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 4706e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 4715744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 4725744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 4735744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 4747cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<title>${HtmlTitle}</title> 475f143545ce5ce125e7c1aa6fca9df372bfb604e9cTed Kremenek<link type="text/css" rel="stylesheet" href="scanview.css"/> 47622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 4776e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 4786e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 4796e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 4806e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 4816e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 4826e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 4836e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 4846e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4856e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4866e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 487ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 4886e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 4896e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 4906e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 4916e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4926e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 4936e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 4946e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 4956e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 4966e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 4971d1abb1dec3d0b7609809d876a16a64a021e96e7Ted Kremenek<!-- SUMMARYENDHEAD --> 4986e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 4996e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 5007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h1>${HtmlTitle}</h1> 5017cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<table> 5037cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 5047cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 5057cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 5067cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Date:</th><td>${Date}</td></tr> 5077cba11262458df05951432b54997eb40a35dbf9eTed KremenekENDTEXT 5087cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5097cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 5107cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (defined($BuildName) && defined($BuildDate)); 5117cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5127cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT <<ENDTEXT; 5137cba11262458df05951432b54997eb40a35dbf9eTed Kremenek</table> 5146e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 5156e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 516991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 517991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 518991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 519ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 520991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 521ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_type = ($row->[2]); 522ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_category = ($row->[1]); 523ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $key = "$bug_category:$bug_type"; 524ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 525ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 526ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { $Totals{$key}->[0]++; } 5276e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 528991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 5297cba11262458df05951432b54997eb40a35dbf9eTed Kremenek print OUT "<h2>Bug Summary</h2>"; 530991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 531991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 532991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 5336e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 534f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 5356e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 536ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table> 537ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 5386e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 5396e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 540ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $last_category; 541ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 542ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $key ( 543ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek sort { 544ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = $Totals{$a}; 545ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $y = $Totals{$b}; 546ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $res = $x->[1] cmp $y->[1]; 547ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res = $x->[2] cmp $y->[2] if ($res == 0); 548ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res 549ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } keys %Totals ) 550ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek { 551ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $val = $Totals{$key}; 552ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $category = $val->[1]; 553ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $last_category or $last_category ne $category) { 554ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $last_category = $category; 555ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 556ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 557ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = lc $key; 558ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 559ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><td class=\"SUMM_DESC\">"; 560ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[2]; 561ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td>"; 562ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[0]; 563ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 564991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5656e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5666e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 5676e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5686e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 5696e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 5707cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Reports</h2> 571ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 572ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table class="sortable" style="table-layout:automatic"> 573ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr> 574ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td>Bug Group</td> 575ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 576bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 577ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="Q">Line</td> 5782645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 579ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <!-- REPORTBUGCOL --> 580ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek</tr></thead> 581ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<tbody> 5825744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 5839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 584991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 585991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 586991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 587991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 5887a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 589991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $prefix) { 590991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $regex = qr/^\Q$prefix\E/is; 591991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 592991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 5937a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 594ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 595ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = "$row->[1]:$row->[2]"; 596ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x = lc $x; 597ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 5986e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 599991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 600ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 601ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr class=\"bt_$x\">"; 602ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 603991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 604ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 605ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 606ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $row->[2]; 607ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 608ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 609ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Update the file prefix. 610ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $fname = $row->[3]; 611ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 612991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 613991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 614991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 615991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 616ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 61791639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek print OUT "<td>"; 618ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my @fname = split /\//,$fname; 619ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname > 0) { 620ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek while ($#fname >= 0) { 621ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = shift @fname; 622ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $x; 623ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname >= 0) { 624ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<span class=\"W\"> </span>/"; 625ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 626ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 627ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 628ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { 629ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $fname; 63091639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek } 631ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 632ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 633ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Print out the quantities. 63450534dc3ab0737224f9ce739821e1486219c686bTed Kremenek for my $j ( 4 .. 4 ) { 635ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"Q\">$row->[$j]</td>"; 636ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 637ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 638991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 63950534dc3ab0737224f9ce739821e1486219c686bTed Kremenek for (my $j = 5; $j <= $#{$row}; ++$j) { 640ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td>$row->[$j]</td>" 641991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6427f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 643991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 64468005ddb49b88c2f6cdd88185d72d8b411d2dbc9Ted Kremenek print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 6453cea9ee6b77ac797ebb910bdf45d1d7f8f68e37bTed Kremenek 646e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar # Emit REPORTBUG markers. 647ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 648e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar 649991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 650991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 651991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 652991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 653ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</tbody>\n</table>\n\n"; 654991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 655991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 656991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if ($Crashes) { 657991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Read the crash directory for files. 658991c54b9b7409656e5593364e065878b5210d556Ted Kremenek opendir(DIR, "$Dir/crashes"); 65982a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek my @files = grep { /[.]info.txt$/ } readdir(DIR); 660991c54b9b7409656e5593364e065878b5210d556Ted Kremenek closedir(DIR); 661991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 662991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 663991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT <<ENDTEXT; 6647cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Analyzer Failures</h2> 665991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6665d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek<p>The analyzer had problems processing the following files:</p> 667991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 668991c54b9b7409656e5593364e065878b5210d556Ted Kremenek<table> 6699f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead> 670991c54b9b7409656e5593364e065878b5210d556Ted KremenekENDTEXT 671991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 672991c54b9b7409656e5593364e065878b5210d556Ted Kremenek foreach my $file (sort @files) { 67382a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek $file =~ /(.+).info.txt$/; 674991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 675991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 676991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 677991c54b9b7409656e5593364e065878b5210d556Ted Kremenek open (INFO, "$Dir/crashes/$file") or 678991c54b9b7409656e5593364e065878b5210d556Ted Kremenek die "Cannot open $Dir/crashes/$file\n"; 679991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 6805d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 6815d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 6825d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 683991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 684991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 685d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 6869f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 6879f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"crashes/$ppfile\">$ppfile</a></td><td><a href=\"crashes/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; 688ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar my $ppfile_clang = $ppfile; 689ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 690ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar print OUT " <!-- REPORTPROBLEM file=\"crashes/$ppfile\" clangfile=\"crashes/$ppfile_clang\" stderr=\"crashes/$ppfile.stderr.txt\" info=\"crashes/$ppfile.info\" -->\n"; 691991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 692991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 693991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT <<ENDTEXT; 694991c54b9b7409656e5593364e065878b5210d556Ted Kremenek</table> 695ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar<p>Please consider submitting preprocessed files as <a href="http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs">bug reports</a>. <!-- REPORTCRASHES --> </p> 696991c54b9b7409656e5593364e065878b5210d556Ted KremenekENDTEXT 697991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6985744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 6995744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 700991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</body></html>\n"; 7015744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 7023ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek CopyFiles($Dir); 70320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 70420161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 70520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("chmod", "755", $Dir); 706fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 70720161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 70823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 709150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("$Num bugs found.\n"); 710150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 7115950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 712150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 713363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 714991c54b9b7409656e5593364e065878b5210d556Ted Kremenek DiagCrashes($Dir) if ($Crashes); 715991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 716363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 7179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 7189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 7199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 720dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 721dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 722dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 7236b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 7246b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 7256b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Arg = shift; 7266b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 7276b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 7286b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 7296b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 7306b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 7316b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 7326b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 7336b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 7346b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 7356b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 7366b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 7376b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 7386b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 7396b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 740dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremeneksub RunBuildCommand { 741dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 742dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 7437442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 744dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 7456195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 746dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 7473301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek # Get only the part of the command after the last '/'. 7483301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek if ($Cmd =~ /\/([^\/]+)$/) { 7493301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek $Cmd = $1; 7503301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek } 7513301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek 75263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek if ($Cmd eq "gcc" or $Cmd eq "cc" or $Cmd eq "llvm-gcc" 75363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek or $Cmd eq "ccc-analyzer") { 754dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 7556195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 756dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 7577442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($IgnoreErrors) { 7587442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek if ($Cmd eq "make" or $Cmd eq "gmake") { 7596b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 7608912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 7617442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 7627442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($Cmd eq "xcodebuild") { 7636b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 7647442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 7656b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 7666b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 7676b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($Cmd eq "xcodebuild") { 768cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable distributed builds for xcodebuild. 7696b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-nodistribute"); 770cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek 771cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable PCH files until clang supports them. 772cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 773915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek 774915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 775915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 776915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # when linking such files. 77795aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek die if (!defined $CXX); 77895aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek my $LDPLUSPLUS = `which $CXX`; 779915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $LDPLUSPLUS =~ s/\015?\012//; # strip newlines 780915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS; 7816b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 782dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 7835a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 784dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 785dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 786dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 7879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 7889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 7899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 790a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 7919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 7925744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 793a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 7942b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 795f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 796f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 797fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 798f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 799f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 800f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 801f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 8022b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 8032b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 804363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -o - Target directory for HTML report files. Subdirectories 805a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop will be created as needed to represent separate "runs" of 8062b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek the analyzer. If this option is not specified, a directory 8072b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek is created in /tmp to store the reports. 8081262fc4d66584224234691d30d779f8ff004585cTed Kremenek 809363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -h - Display this message. 810363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 8111262fc4d66584224234691d30d779f8ff004585cTed Kremenek 812363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -k - Add a "keep on going" option to the specified build command. 813363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --keep-going This option currently supports make and xcodebuild. 814f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek This is a convenience option; one can specify this 815f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek behavior directly using build options. 8162b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 8177cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title [title] - Specify the title used on generated HTML pages. 8187cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title=[title] If not specified, a default title will be used. 8197cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 820363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --status-bugs - By default, the exit status of $Prog is the same as the 821363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek executed build command. Specifying this option causes the 822363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit status of $Prog to be 1 if it found potential bugs 823363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek and 0 otherwise. 8242b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 825386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link 826386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc=[compiler path] your C and Objective-C code. Use this option 827386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 828386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 829386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link 830386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option 831386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 832f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 833363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -v - Verbose output from $Prog and the analyzer. 834386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek A second and third '-v' increases verbosity. 835363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 836363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -V - View analysis results in a web browser when the build 837363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --view completes. 8387f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 839b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 840386c69316668b9ea8c2591af56f994be16e3ff62Ted KremenekAVAILABLE ANALYSES (multiple analyses may be specified): 841d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 842d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 843b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 844b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek foreach my $Analysis (sort keys %AvailableAnalyses) { 845fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AnalysesDefaultEnabled{$Analysis}) { 846363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " (+)"; 847b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 848b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek else { 849363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " "; 850b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 851b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 852b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek print " $Analysis $AvailableAnalyses{$Analysis}\n"; 853b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 854b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 855b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 856b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 857363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek NOTE: "(+)" indicates that an analysis is enabled by default unless one 858363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek or more analysis options are specified 859b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 8602b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 8612b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 862363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 86339eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 8645744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 8652b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 866363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $Prog -o /tmp/myhtmldir make -j4 8672b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 868363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The above example causes analysis reports to be deposited into 869363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option. 870363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek A different subdirectory is created each time $Prog analyzes a project. 871363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The analyzer should support most parallel builds, but not distributed builds. 8722b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 8732b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 8749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 8777cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# HtmlEscape - HTML entity encode characters that are special in HTML 8787cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 8797cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8807cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub HtmlEscape { 8817cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 8827cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 8837cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 8847cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8857cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $tmp =~ s/([\<\>\'\"])/sprintf("&#%02x;", chr($1))/ge; 8867cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8877cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 8887cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 8897cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8907cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 8917cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# ShellEscape - backslash escape characters that are special to the shell 8927cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 8937cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8947cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub ShellEscape { 8957cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 8967cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 8977cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 8987cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 8997cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $tmp =~ s/([\!\;\\\'\"\`\<\>\|\s\(\)\[\]\?\#\$\^\&\*\=])/\\$1/g; 9007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9017cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 9027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 9037cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9047cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 9059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 9069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 9079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 9099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 9107f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 911363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 912b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 9139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 9159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 916a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 9179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 9189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 9209cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 9229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 9249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9252f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 9269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 927a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 0; 9289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 9299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 930fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AvailableAnalyses{$arg}) { 9311262fc4d66584224234691d30d779f8ff004585cTed Kremenek shift @ARGV; 932b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek push @AnalysesToRun, $arg; 9331262fc4d66584224234691d30d779f8ff004585cTed Kremenek next; 9341262fc4d66584224234691d30d779f8ff004585cTed Kremenek } 9351262fc4d66584224234691d30d779f8ff004585cTed Kremenek 9369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 9379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 9389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 94023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 9419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 9429cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $HtmlDir = shift @ARGV; 9449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 9459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 9467cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9477cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--html-title(=(.+))?$/) { 9487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek shift @ARGV; 9497cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9507cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($2 eq '') { 9517cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (!@ARGV) { 9527cba11262458df05951432b54997eb40a35dbf9eTed Kremenek DieDiag("'--html-title' option requires a string.\n"); 9537cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 9547cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9557cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = shift @ARGV; 9567cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } else { 9577cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = $2; 9587cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 9597cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9607cba11262458df05951432b54997eb40a35dbf9eTed Kremenek next; 9617cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 9629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9632b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 9649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 9659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 9669cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 9679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 9689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 969f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 970f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 971f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 972f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 973f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($2 eq "") { 974f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 975f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 976f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 977f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 978f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 979f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 980f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 981f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 982f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 983f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 984f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 985f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 986f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 9877cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 988386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 989386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 990386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if ($2 eq "") { 991386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 992386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 993386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 994386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = shift @ARGV; 995386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 996386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 997386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = $2; 998386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 999386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 1000386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1001386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 10029cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 10039cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 10049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 10059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 10069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 10079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10087f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 10097f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 10107f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek $ViewResults = 1; 10117f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 10127f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 10137f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1014363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 1015363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 1016363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 1017363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 1018363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 1019363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 102023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 10210062ad4f47d152def1f720878aaf5904b22aefbfTed Kremenek 10229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 10239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 10249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 102623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No build command specified.\n\n"); 10279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1028a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 10299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 10309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10317cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 10327cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 10337cba11262458df05951432b54997eb40a35dbf9eTed Kremenek unless (defined($HtmlTitle)); 1034386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 10359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 1036684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 1037a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 10389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Set the appropriate environment variables. 1040a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopSetHtmlEnv(\@ARGV, $HtmlDir); 10419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10420b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenekmy $Cmd = "$RealBin/ccc-analyzer"; 10430b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 104423cfca3760c482f8543daab62051f5eaa1f98fb4Ted KremenekDieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") 10450b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek if (! -x $Cmd); 1046f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 1047b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekif (! -x $ClangSB) { 1048b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek Diag("'clang' executable not found in '$RealBin'.\n"); 1049b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek Diag("Using 'clang' from path.\n"); 1050f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek} 10510b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 105295aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekif (defined $CXX) { 105395aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $ENV{'CXX'} = $CXX; 105495aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 105595aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekelse { 105695aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $CXX = 'g++'; # This variable is used by other parts of scan-build 105795aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek # that need to know a default C++ compiler to fall back to. 105895aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 105995aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek 10604f4b17da43d3be87a248e1e10bf0b7d8b5891efdTed Kremenek$ENV{'CC'} = $Cmd; 1061f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek$ENV{'CLANG'} = $Clang; 10629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif ($Verbose >= 2) { 10649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 10659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 10669cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1067a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenekif ($Verbose >= 3) { 1068a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 1069a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek} 1070a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek 10719012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenekif (scalar(@AnalysesToRun) == 0) { 10729012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek foreach my $key (keys %AnalysesDefaultEnabled) { 10739012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek push @AnalysesToRun,$key; 10749012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek } 107501006786e3760cc48c5e94d731b468b811b976d2Ted Kremenek} 10761262fc4d66584224234691d30d779f8ff004585cTed Kremenek 10779012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun; 10789012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek 10799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 10805656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd); 10819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess the HTML directory. 1083363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $NumBugs = Postprocess($HtmlDir, $BaseDir); 10847f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 10857f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekif ($ViewResults and -r "$HtmlDir/index.html") { 108650534dc3ab0737224f9ce739821e1486219c686bTed Kremenek Diag "Analysis run complete.\n"; 10875950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 10885950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek my $ScanView = "$RealBin/scan-view"; 10895950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek if (! -x $ScanView) { $ScanView = "scan-view"; } 10905950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek exec $ScanView, "$HtmlDir"; 10917f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek} 10925656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1093363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekif ($ExitStatusFoundBugs) { 1094363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit 1 if ($NumBugs > 0); 1095363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit 0; 1096363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 1097363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 10985656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 10995656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1100