scan-build revision fd9df0eddd7d2b190f740f33a3d08f611c0be3f0
19cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek#!/usr/bin/env perl 29cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 39cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# The LLVM Compiler Infrastructure 49cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 59cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# This file is distributed under the University of Illinois Open Source 69cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# License. See LICENSE.TXT for details. 79cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 89cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 99cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# A script designed to wrap a build so that all calls to gcc are intercepted 119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# and piped to the static analyzer. 129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse strict; 169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse warnings; 1722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenekuse FindBin qw($RealBin); 18a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenekuse Digest::MD5; 197a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekuse File::Basename; 2023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor; 2123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor qw(:constants); 22cd25c13ade3afa829c87ca1ed0ed0d379f426251Ted Kremenekuse Cwd qw/ getcwd abs_path /; 237cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Sys::Hostname; 249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 27f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 28f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 2995aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekmy $CXX; # Leave undefined initially. 309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 310e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 320e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT 330e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 357cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $UserName = HtmlEscape(getpwuid($<) || 'unknown'); 367cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HostName = HtmlEscape(hostname() || 'unknown'); 377cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDir = HtmlEscape(getcwd()); 387cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDirSuffix = basename($CurrentDir); 397cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 407cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CmdArgs; 417cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 427cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HtmlTitle; 437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 447cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $Date = localtime(); 457cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 46b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 47b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 48b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 49b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 5023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 5123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 5323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 5423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 5923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 60991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 61991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 62938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("The analyzer encountered problems on some source files.\n"); 63938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 64991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 65991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n") 66991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 67991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 6923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 7023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, RED "$Prog: "; 7123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET, RED @_; 7223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 7323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 7523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: ", @_; 7623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek exit(0); 7823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 7923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 81b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Some initial preprocessing of Clang options. 82b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 83b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 84833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenek# First, look for 'clang-cc' in libexec. 85fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekmy $ClangCCSB = Cwd::realpath("$RealBin/libexec/clang-cc"); 86833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenek# Second, look for 'clang-cc' in the same directory as scan-build. 87fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangCCSB || ! -x $ClangCCSB) { 88fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangCCSB = Cwd::realpath("$RealBin/clang-cc"); 8943b7bd31f906f4020090ffb4f64a09d35fb13680Ted Kremenek} 90833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenek# Third, look for 'clang-cc' in ../libexec 91fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangCCSB || ! -x $ClangCCSB) { 92fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangCCSB = Cwd::realpath("$RealBin/../libexec/clang-cc"); 93fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 94fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek# Finally, default to looking for 'clang-cc' in the path. 95fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangCCSB || ! -x $ClangCCSB) { 96fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangCCSB = "clang-cc"; 97fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 98fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekmy $ClangCC = $ClangCCSB; 99fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek 100fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek# Now find 'clang' 101fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekmy $ClangSB = Cwd::realpath("$RealBin/bin/clang"); 1028d10cdd9aa1d58f1898adf7752a7026f151ebc04Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 103fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangSB = Cwd::realpath("$RealBin/clang"); 104fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 105fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek# Third, look for 'clang' in ../bin 106fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 107fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangSB = Cwd::realpath("$RealBin/../bin/clang"); 108b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 109833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenek# Finally, default to looking for 'clang-cc' in the path. 110833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 111fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangSB = "clang"; 112833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenek} 113833da0235676a111d6192b0b182a8c16c27cceeeTed Kremenekmy $Clang = $ClangSB; 114b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 115fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek 116b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AvailableAnalyses; 117b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 118b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Query clang for analysis options. 119fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekopen(PIPE, "-|", $ClangCC, "--help") or 120fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek DieDiag("Cannot execute '$ClangCC'\n"); 12163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 122b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy $FoundAnalysis = 0; 123b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 124b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekwhile(<PIPE>) { 125b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if ($FoundAnalysis == 0) { 126938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (/Checks and Analyses/) { 127b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $FoundAnalysis = 1; 128b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 129b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 130b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 131b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 132b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek if (/^\s\s\s\s([^\s]+)\s(.+)$/) { 133b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next if ($1 =~ /-dump/ or $1 =~ /-view/ 134b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek or $1 =~ /-checker-simple/ or $1 =~ /-warn-uninit/); 135b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 136b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek $AvailableAnalyses{$1} = $2; 137b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek next; 138938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 139b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek last; 140b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek} 141b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 142b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekclose (PIPE); 143b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 144b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy %AnalysesDefaultEnabled = ( 145b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-warn-dead-stores' => 1, 146b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek '-checker-cfref' => 1, 1479012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek '-warn-objc-methodsigs' => 1, 148d76c6a38b8080b3255c37f787bcaf4a4724f330cTed Kremenek # Do not enable the missing -dealloc check by default. 149d76c6a38b8080b3255c37f787bcaf4a4724f330cTed Kremenek # '-warn-objc-missing-dealloc' => 1, 1505d443490cd6fb8c772957b7df728f71189d9c55bTed Kremenek '-warn-objc-unused-ivars' => 1, 151b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek); 152b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 153b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 154fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 157a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub GetHTMLRunDir { 1589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 159fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "Not enough arguments." if (@_ == 0); 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift @_; 161fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 162fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 163fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 164ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek if (`uname` =~ /Darwin/) { 165ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek $Dir = $ENV{'TMPDIR'}; 166ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek if (!defined $Dir) { $Dir = "/tmp"; } 167ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek } 168ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek else { 169ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek $Dir = "/tmp"; 170ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek } 171ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek 172fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 173fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 174bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek 175bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek # Chop off any trailing '/' characters. 176bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek while ($Dir =~ /\/$/) { chop $Dir; } 177fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 1799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @CurrentTime = localtime(); 1819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 1859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1869d7405fafd5bc08d38bc75579927bf414570bd61Ted Kremenek my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 1879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Determine the run number. 1899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 1919cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-d $Dir) { 1939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 19523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Iterate over all files in the specified directory. 1999cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $max = 0; 2019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2029cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 20329da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 2049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 2059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek foreach my $f (@FILES) { 2079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 208fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 209fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 210fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 211fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 212fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 213fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 214ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 2159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 2169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 2179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 2189cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 2199cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 2209cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2219cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($x[3] > $max) { 2229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $max = $x[3]; 2239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 2279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 2299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 23123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 2329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 233fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 234fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 235445fa776d2bc9207c33a9b9ab4afb9513f6b81b0Ted Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 236fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 237fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 2389cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # $Dir does not exist. It will be automatically created by the 2399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # clang driver. Set the run number to 1. 240fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 2419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 2429cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 244fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 2459cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 247fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 248fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 249fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 250fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 251fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 252fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 253fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 254fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek system 'mkdir','-p',$NewDir; 255fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 2569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 258a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 2599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 2619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 2639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 2649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 2669cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Cmd =~ /configure/) { 2709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 27423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 28157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 28257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 28357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 28457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 28557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 28623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 287a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 288a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2897ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2907ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 29163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # come bundled on most systems. 29223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 293a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 294a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 295a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 296a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 29763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Return the digest. 298a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 29957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 30057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 30157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 3027a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 3037a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3047a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3057a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 3067a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3077a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 3087a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 3097a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 3107a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 3117a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3127a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 3137a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 3147a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 3157a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 3167a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 31720b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 3187a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3197a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3207a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 3217a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 3227a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3237a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3247a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3257a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 3267a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3277a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3287a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 3297a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 3307a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 3317a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 33263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3337a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 33463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 33563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3367a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 3377a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 3387a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 3397a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 34063c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 3417a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 3427a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 34320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("mv", "$fname.tmp", $fname); 3447a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 3457a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 3467a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 3475744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3485744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3495744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 35057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 35157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 35257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 35357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 35457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3555744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 3565744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3575744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3585744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3595744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3605744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 36157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 36257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 36357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 36457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 36557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 366fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 36757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 36820161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-f", "$Dir/$FName"); 36957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 37057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 37157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 37257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 37357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 374809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 37520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("chmod", "644", "$Dir/$FName"); 376684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek 377684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 37823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3795744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 380a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek my $BugType = ""; 38122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugFile = ""; 382ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $BugCategory; 38322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugPathLength = 1; 38422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $BugLine = 0; 385ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $found = 0; 386ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3875744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 388ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 389ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek last if ($found == 5); 390ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 391a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek if (/<!-- BUGTYPE (.*) -->$/) { 392a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek $BugType = $1; 393ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 3945744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 39522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 396990c2f45e566d8ff097fa90176ba90036892b3cdTed Kremenek $BugFile = abs_path($1); 3977a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 398ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 39922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 40022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 40122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 402ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 40322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 40422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 40522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugLine = $1; 406ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 407ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 408ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek elsif (/<!-- BUGCATEGORY (.*) -->$/) { 409ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = $1; 410ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek ++$found; 41122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 4125744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 4135744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4145744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 415ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 416ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $BugCategory) { 417ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = "Other"; 418ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 4195744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 420a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, 42181983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek $BugPathLength ]; 42222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 42322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 42422d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 4253ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek# CopyFiles - Copy resource files to target directory. 42622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 42722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 4283ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremeneksub CopyFiles { 42922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 43022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 431e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 432e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $JS = Cwd::realpath("$RealBin/sorttable.js"); 43322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 43423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 435e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $JS); 43622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 437e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $JS, "$Dir"); 43822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 43923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 44022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 4413ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 442e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $CSS = Cwd::realpath("$RealBin/scanview.css"); 443e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 4443ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Cannot find 'scanview.css'.\n") 445e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4463ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 447e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $CSS, "$Dir"); 4483ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4493ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 450e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4515744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 4525744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4535744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 4549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 4559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 4569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 457a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 4589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 460684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek my $BaseDir = shift; 4619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 462fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 4639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 46523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 466363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 470938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @files = grep { /^report-.*\.html$/ } readdir(DIR); 4719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 4729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 473938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar(@files) == 0 and ! -e "$Dir/failures") { 47423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Removing directory '$Dir' because it contains no reports.\n"); 47520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-fR", $Dir); 476363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4785744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 479991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Scan each report file and build an index. 480991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my @Index; 4815744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); } 4825744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 483938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Scan the failures directory and use the information in the .info files 484d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 485938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @failures; 486938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @attributes_ignored; 487938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (-d "$Dir/failures") { 488938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 489938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 490d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 491938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 492938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 493938eef139ad43345248235da31f78a759dd18f13Ted Kremenek closedir(DIR); 494938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (@failures) { 495938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 496d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 497d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 498d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 499d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 500d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 501d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 50263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Generate an index.html file. 50363c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek my $FName = "$Dir/index.html"; 50463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 5055744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 5066e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 5076e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5085744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 5095744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 5105744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 5117cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<title>${HtmlTitle}</title> 512f143545ce5ce125e7c1aa6fca9df372bfb604e9cTed Kremenek<link type="text/css" rel="stylesheet" href="scanview.css"/> 51322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 5146e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 5156e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 5166e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 5176e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 5186e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 5196e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 5206e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 5216e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5226e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5236e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 524ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 5252350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenekfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 5262350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek var Inputs = document.getElementsByTagName("input"); 5272350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek for ( var i = 0 ; i < Inputs.length; ++i ) { 5282350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if (Inputs[i].type == "checkbox") { 5292350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if(Inputs[i] != SummaryCheckButton) { 5302350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].checked = SummaryCheckButton.checked; 5312350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].onclick(); 5322350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5332350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5342350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5352350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek} 5362350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek 537999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekfunction returnObjById( id ) { 538999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (document.getElementById) 539999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.getElementById(id); 540999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.all) 541999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.all[id]; 542999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.layers) 543999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.layers[id]; 544999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek return returnVar; 545999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek} 546999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 547999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekvar NumUnchecked = 0; 548999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 5496e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 5506e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 5516e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 552999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (--NumUnchecked == 0) { 553999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = true; 554999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek } 5556e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5566e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 5576e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 558999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek NumUnchecked++; 559999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = false; 5606e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5616e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 5626e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 5631d1abb1dec3d0b7609809d876a16a64a021e96e7Ted Kremenek<!-- SUMMARYENDHEAD --> 5646e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 5656e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 5667cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h1>${HtmlTitle}</h1> 5677cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5687cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<table> 5697cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 5707cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 5717cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 5727cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Date:</th><td>${Date}</td></tr> 5737cba11262458df05951432b54997eb40a35dbf9eTed KremenekENDTEXT 5747cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5757cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 5767cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (defined($BuildName) && defined($BuildDate)); 5777cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5787cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT <<ENDTEXT; 5797cba11262458df05951432b54997eb40a35dbf9eTed Kremenek</table> 5806e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 5816e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 582991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 583991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 584991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 585ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 586991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 587ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_type = ($row->[2]); 588ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_category = ($row->[1]); 589ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $key = "$bug_category:$bug_type"; 590ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 591ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 592ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { $Totals{$key}->[0]++; } 5936e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 594991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 5957cba11262458df05951432b54997eb40a35dbf9eTed Kremenek print OUT "<h2>Bug Summary</h2>"; 596991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 597991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 598991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 5996e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 600f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 6012350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek my $TotalBugs = scalar(@Index); 6026e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 603ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table> 604ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 605999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed 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> 6066e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6076e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 608ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $last_category; 609ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 610ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $key ( 611ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek sort { 612ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = $Totals{$a}; 613ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $y = $Totals{$b}; 614ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $res = $x->[1] cmp $y->[1]; 615ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res = $x->[2] cmp $y->[2] if ($res == 0); 616ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res 617ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } keys %Totals ) 618ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek { 619ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $val = $Totals{$key}; 620ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $category = $val->[1]; 621ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $last_category or $last_category ne $category) { 622ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $last_category = $category; 623ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 624ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 625ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = lc $key; 626ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 627ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><td class=\"SUMM_DESC\">"; 628ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[2]; 6292350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek print OUT "</td><td class=\"Q\">"; 630ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[0]; 631ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 632991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6336e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6346e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 6356e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6366e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 6376e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 6387cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Reports</h2> 639ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 640ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table class="sortable" style="table-layout:automatic"> 641ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr> 642ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td>Bug Group</td> 643ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 644bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 645ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="Q">Line</td> 64681983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek <td class="Q">Path Length</td> 6472645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 648ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <!-- REPORTBUGCOL --> 649ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek</tr></thead> 650ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<tbody> 6515744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 6529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 653991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 654991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 655991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 656991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 6577a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 658991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $prefix) { 659991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $regex = qr/^\Q$prefix\E/is; 660991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 661991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6627a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 663ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 664ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = "$row->[1]:$row->[2]"; 665ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x = lc $x; 666ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 6676e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 668991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 669ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 670ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr class=\"bt_$x\">"; 671ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 672991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 673ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 674ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 675ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $row->[2]; 676ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 677ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 678ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Update the file prefix. 679ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $fname = $row->[3]; 680ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 681991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 682991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 683991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 684991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 685ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 68691639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek print OUT "<td>"; 687ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my @fname = split /\//,$fname; 688ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname > 0) { 689ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek while ($#fname >= 0) { 690ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = shift @fname; 691ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $x; 692ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname >= 0) { 693ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<span class=\"W\"> </span>/"; 694ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 695ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 696ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 697ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { 698ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $fname; 69991639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek } 700ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 701ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 702ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Print out the quantities. 70381983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for my $j ( 4 .. 5 ) { 704ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"Q\">$row->[$j]</td>"; 705ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 706ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 707991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 70881983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for (my $j = 6; $j <= $#{$row}; ++$j) { 709ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td>$row->[$j]</td>" 710991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 7117f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 712991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 71368005ddb49b88c2f6cdd88185d72d8b411d2dbc9Ted Kremenek print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 7143cea9ee6b77ac797ebb910bdf45d1d7f8f68e37bTed Kremenek 715e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar # Emit REPORTBUG markers. 716ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 717e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar 718991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 719991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 720991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 721991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 722ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</tbody>\n</table>\n\n"; 723991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 724991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 725938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar (@failures) || scalar(@attributes_ignored)) { 726938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<h2>Analyzer Failures</h2>\n"; 727938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 728938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @attributes_ignored) { 729938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 730938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 731938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 732938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @attributes_ignored) { 733938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 734938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $attribute = $1; 735938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the attribute file to get the first file that failed. 736938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (!open (ATTR, "$Dir/failures/$file")); 737938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile = <ATTR>; 738938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $ppfile; 739938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close ATTR; 740938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (! -e "$Dir/failures/$ppfile"); 741938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the info file and get the name of the source file. 742938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$ppfile.info.txt") or 743938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 744938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $srcfile = <INFO>; 745938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $srcfile; 746938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close (INFO); 747938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Print the information in the table. 748938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $prefix = GetPrefix(); 749938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 750938eef139ad43345248235da31f78a759dd18f13Ted 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"; 751938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile_clang = $ppfile; 752938eef139ad43345248235da31f78a759dd18f13Ted Kremenek $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 753938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 754938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 755938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 756938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 757938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 758938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @failures) { 759938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 760938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 761938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 762938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @failures) { 76382a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek $file =~ /(.+).info.txt$/; 764991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 765991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 766991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 767938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$file") or 768938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$file\n"; 769991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 7705d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 7715d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 7725d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 773991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 774991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 775d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 7769f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 777938eef139ad43345248235da31f78a759dd18f13Ted 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"; 778ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar my $ppfile_clang = $ppfile; 779ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 780938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 781991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 782938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 783938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 784938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n"; 7855744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 7865744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 787991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</body></html>\n"; 7885744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 7893ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek CopyFiles($Dir); 79020161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 79120161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 79220161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("chmod", "755", $Dir); 793fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 79420161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 79523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 796150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("$Num bugs found.\n"); 797150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 7985950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 799150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 800363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 801938eef139ad43345248235da31f78a759dd18f13Ted Kremenek DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 802991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 803363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 8049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 807dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 808dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 809dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8106b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 8116b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 8126b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Arg = shift; 8136b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 8146b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8156b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 8166b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 8176b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 8186b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 8196b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8206b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8216b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8226b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 8236b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 8246b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8256b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 8266b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 827dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremeneksub RunBuildCommand { 828dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 829dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 8307442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 831dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 8326195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 833dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8343301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek # Get only the part of the command after the last '/'. 8353301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek if ($Cmd =~ /\/([^\/]+)$/) { 8363301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek $Cmd = $1; 8373301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek } 8383301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek 83992548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 84092548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?cc[^\/]*$)/ or 84192548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 84292548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 84392548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 84492548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 84592548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $ENV{"CCC_CC"} = $1; 84692548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek } 84792548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 848dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 8496195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 850dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 8517442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($IgnoreErrors) { 8527442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek if ($Cmd eq "make" or $Cmd eq "gmake") { 8536b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 8548912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 8557442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 8567442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($Cmd eq "xcodebuild") { 8576b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 8587442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 8596b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8606b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8616b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($Cmd eq "xcodebuild") { 862cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable distributed builds for xcodebuild. 8636b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-nodistribute"); 864cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek 865cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable PCH files until clang supports them. 866cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 867915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek 868915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 869915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 870915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # when linking such files. 87195aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek die if (!defined $CXX); 87295aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek my $LDPLUSPLUS = `which $CXX`; 873915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $LDPLUSPLUS =~ s/\015?\012//; # strip newlines 874915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS; 8756b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 876dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8775a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 878dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 879dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 880dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 8819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 8829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 8839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 884a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 8859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8865744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 887a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 8882b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 889f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 890f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 891fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 892f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 893f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 894f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 895f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 8962b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 8972b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 898e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek -analyze-headers - Also analyze functions in #included files. 899e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 900363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -o - Target directory for HTML report files. Subdirectories 901a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop will be created as needed to represent separate "runs" of 9022b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek the analyzer. If this option is not specified, a directory 903ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek is created in /tmp (TMPDIR on Mac OS X) to store the reports. 904db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 905363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -h - Display this message. 906363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 9071262fc4d66584224234691d30d779f8ff004585cTed Kremenek 908363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -k - Add a "keep on going" option to the specified build command. 909363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --keep-going This option currently supports make and xcodebuild. 910f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek This is a convenience option; one can specify this 911f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek behavior directly using build options. 9122b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 9137cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title [title] - Specify the title used on generated HTML pages. 9147cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title=[title] If not specified, a default title will be used. 9157cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 916db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek -plist - By default the output of scan-build is a set of HTML files. 917db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek This option outputs the results as a set of .plist files. 918db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 919363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --status-bugs - By default, the exit status of $Prog is the same as the 920363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek executed build command. Specifying this option causes the 921363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit status of $Prog to be 1 if it found potential bugs 922363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek and 0 otherwise. 9232b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 924386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link 925386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc=[compiler path] your C and Objective-C code. Use this option 926386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 927386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 928386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link 929386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option 930386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 931f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 932363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -v - Verbose output from $Prog and the analyzer. 933386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek A second and third '-v' increases verbosity. 934363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 935363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -V - View analysis results in a web browser when the build 936363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --view completes. 9377f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 938be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed KremenekADVANCED OPTIONS: 939be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 9409f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek -constraints [model] - Specify the contraint engine used by the analyzer. 9419f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek By default the 'range' model is used. Specifying 9429f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek 'basic' uses a simpler, less powerful constraint model 943d4c7684f19703d75b989364da80727d635f99b53Ted Kremenek used by checker-0.160 and earlier. 944be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 945be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek -store [model] - Specify the store model used by the analyzer. By default, 946be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek the 'basic' store model is used. 'region' specifies a field- 947be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek sensitive store model. Be warned that the 'region' model 948be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek is still in very early testing phase and may often crash. 949b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 950386c69316668b9ea8c2591af56f994be16e3ff62Ted KremenekAVAILABLE ANALYSES (multiple analyses may be specified): 951d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 952d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 953b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 954b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek foreach my $Analysis (sort keys %AvailableAnalyses) { 955fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AnalysesDefaultEnabled{$Analysis}) { 956363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " (+)"; 957b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 958b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek else { 959363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek print " "; 960b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 961b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 962b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek print " $Analysis $AvailableAnalyses{$Analysis}\n"; 963b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek } 964b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 965b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 966b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 967363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek NOTE: "(+)" indicates that an analysis is enabled by default unless one 968363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek or more analysis options are specified 969b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 9702b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 9712b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 972363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 97339eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 9745744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 9752b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 976363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $Prog -o /tmp/myhtmldir make -j4 9772b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 978363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The above example causes analysis reports to be deposited into 979363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option. 980363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek A different subdirectory is created each time $Prog analyzes a project. 981363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The analyzer should support most parallel builds, but not distributed builds. 9822b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 9832b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 9849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 9859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 9877cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# HtmlEscape - HTML entity encode characters that are special in HTML 9887cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 9897cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 9907cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub HtmlEscape { 9917cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 9927cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 9937cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 99487f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/&/&/g; 99587f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/</</g; 99687f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/>/>/g; 9977cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 9987cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 9997cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 10017cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# ShellEscape - backslash escape characters that are special to the shell 10027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 10037cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10047cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub ShellEscape { 10057cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 10067cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 100787f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 100887f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek return $arg; 10097cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 10107cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10117cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 10129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 10139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 10149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1015e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekmy $AnalyzeHeaders = 0; 10169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 10179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 10187f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 1019363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 1020b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 102107c3767be59472e19183c7b51fae76481465cb51Zhongxing Xumy $StoreModel; 1022be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekmy $ConstraintsModel; 1023db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekmy $OutputFormat; 10249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 10269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1027a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 10289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 10299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 10319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 10339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 10359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10362f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 10379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1038a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 0; 10399cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 10409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1041e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if ($arg eq '-analyze-headers') { 1042e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek shift @ARGV; 1043e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek $AnalyzeHeaders = 1; 1044e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek next; 1045e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek } 1046e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 1047fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AvailableAnalyses{$arg}) { 10481262fc4d66584224234691d30d779f8ff004585cTed Kremenek shift @ARGV; 1049b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek push @AnalysesToRun, $arg; 10501262fc4d66584224234691d30d779f8ff004585cTed Kremenek next; 10511262fc4d66584224234691d30d779f8ff004585cTed Kremenek } 10521262fc4d66584224234691d30d779f8ff004585cTed Kremenek 10539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 10549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 10559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 105723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 10589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 10599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1060db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # Construct an absolute path. Uses the current working directory 1061db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # as a base if the original path was not absolute. 1062db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek $HtmlDir = abs_path(shift @ARGV); 1063db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek 10649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 10659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 10667cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10677cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--html-title(=(.+))?$/) { 10687cba11262458df05951432b54997eb40a35dbf9eTed Kremenek shift @ARGV; 10697cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10707cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($2 eq '') { 10717cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (!@ARGV) { 10727cba11262458df05951432b54997eb40a35dbf9eTed Kremenek DieDiag("'--html-title' option requires a string.\n"); 10737cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 10747cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10757cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = shift @ARGV; 10767cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } else { 10777cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = $2; 10787cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 10797cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 10807cba11262458df05951432b54997eb40a35dbf9eTed Kremenek next; 10817cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 10829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 10832b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 10849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 10859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 10869cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 10879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 10889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1089f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 1090f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 1091f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 1092f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1093f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($2 eq "") { 1094f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 1095f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 1096f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1097f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 1098f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1099f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 1100f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 1101f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1102f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1103f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 1104f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 1105f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1106f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 11077cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 1108386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 1109386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 1110386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if ($2 eq "") { 1111386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 1112386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 1113386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1114386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = shift @ARGV; 1115386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1116386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 1117386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek $CXX = $2; 1118386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1119386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 1120386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1121386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 11229cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 11239cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 11249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 11259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 11269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 11279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11287f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 11297f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 11307f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek $ViewResults = 1; 11317f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 11327f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 11337f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1134363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 1135363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 1136363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 1137363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 1138363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 113907c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu 114007c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu if ($arg eq "-store") { 114107c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu shift @ARGV; 1142be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $StoreModel = shift @ARGV; 1143be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek next; 1144be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek } 1145be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1146be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek if ($arg eq "-constraints") { 1147be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek shift @ARGV; 1148be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ConstraintsModel = shift @ARGV; 114907c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu next; 115007c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu } 1151363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 1152db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($arg eq "-plist") { 1153db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek shift @ARGV; 1154db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $OutputFormat = "plist"; 1155db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek next; 1156db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 1157db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 115823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 11590062ad4f47d152def1f720878aaf5904b22aefbfTed Kremenek 11609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 11619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 11629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 116423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No build command specified.\n\n"); 11659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1166a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 11679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 11689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11697cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 11707cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 11717cba11262458df05951432b54997eb40a35dbf9eTed Kremenek unless (defined($HtmlTitle)); 1172386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 11739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 1174684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 1175a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 11769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Set the appropriate environment variables. 1178a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopSetHtmlEnv(\@ARGV, $HtmlDir); 11799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 118091ea79dd3fdf0c3275cf2159c6a01c83e55bcdd3Ted Kremenekmy $Cmd = Cwd::realpath("$RealBin/libexec/ccc-analyzer"); 1181ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenekif (!defined $Cmd || ! -x $Cmd) { 1182ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenek $Cmd = Cwd::realpath("$RealBin/ccc-analyzer"); 11836b89636db873142f562cf576df9bc195c5b8674bTed Kremenek DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd); 1184ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenek} 1185f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 1186fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangCCSB || ! -x $ClangCCSB) { 118791ea79dd3fdf0c3275cf2159c6a01c83e55bcdd3Ted Kremenek Diag("'clang-cc' executable not found in '$RealBin/libexec'.\n"); 1188318e6a65ff6105b0121b49dfc9d47363843a1185Ted Kremenek Diag("Using 'clang-cc' from path.\n"); 1189f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek} 1190fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 1191fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek Diag("'clang' executable not found in '$RealBin/bin'.\n"); 1192fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek Diag("Using 'clang' from path.\n"); 1193fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 11940b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 119595aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekif (defined $CXX) { 119695aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $ENV{'CXX'} = $CXX; 119795aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 119895aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenekelse { 119995aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek $CXX = 'g++'; # This variable is used by other parts of scan-build 120095aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek # that need to know a default C++ compiler to fall back to. 120195aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek} 120295aa1050cd170f9729ca66a1b2e2f0219458671eTed Kremenek 12034f4b17da43d3be87a248e1e10bf0b7d8b5891efdTed Kremenek$ENV{'CC'} = $Cmd; 1204fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek$ENV{'CLANG_CC'} = $ClangCC; 1205f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek$ENV{'CLANG'} = $Clang; 12069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif ($Verbose >= 2) { 12089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 12099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 12109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1211a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenekif ($Verbose >= 3) { 1212a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 1213a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek} 1214a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek 12159012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenekif (scalar(@AnalysesToRun) == 0) { 12169012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek foreach my $key (keys %AnalysesDefaultEnabled) { 12179012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek push @AnalysesToRun,$key; 12189012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek } 121901006786e3760cc48c5e94d731b468b811b976d2Ted Kremenek} 12201262fc4d66584224234691d30d779f8ff004585cTed Kremenek 1221e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekif ($AnalyzeHeaders) { 1222e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek push @AnalysesToRun,"-analyzer-opt-analyze-headers"; 1223e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek} 1224e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 12259012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun; 12269012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek 12273cab2b1c3798f2a6aa3526875801a02aebf6fc1dZhongxing Xuif (defined $StoreModel) { 122807c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; 122907c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu} 123007c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu 1231be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekif (defined $ConstraintsModel) { 1232be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; 1233be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek} 1234be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1235db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekif (defined $OutputFormat) { 1236db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; 1237db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek} 1238db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 1239db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 12409cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 12415656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd); 12429cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1243655aba727e2a5f7f4e4952d35d35faa6ad4ec6e5Ted Kremenekif (defined $OutputFormat and $OutputFormat eq "plist") { 124450534dc3ab0737224f9ce739821e1486219c686bTed Kremenek Diag "Analysis run complete.\n"; 1245db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; 12467f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek} 1247db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekelse { 1248db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek # Postprocess the HTML directory. 1249db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek my $NumBugs = Postprocess($HtmlDir, $BaseDir); 1250db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 1251db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($ViewResults and -r "$HtmlDir/index.html") { 1252db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek Diag "Analysis run complete.\n"; 1253db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 1254db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek my $ScanView = Cwd::realpath("$RealBin/scan-view"); 1255db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if (! -x $ScanView) { $ScanView = "scan-view"; } 1256db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek exec $ScanView, "$HtmlDir"; 1257db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 12585656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1259db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($ExitStatusFoundBugs) { 1260db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek exit 1 if ($NumBugs > 0); 1261db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek exit 0; 1262db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 1263363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 1264363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 12655656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 12665656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1267