scan-build revision b4882d50923881d1a01af4d5604b5baaa141cdf9
19cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek#!/usr/bin/env perl 29cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 39cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# The LLVM Compiler Infrastructure 49cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 59cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# This file is distributed under the University of Illinois Open Source 69cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# License. See LICENSE.TXT for details. 79cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 89cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 99cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# A script designed to wrap a build so that all calls to gcc are intercepted 119cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# and piped to the static analyzer. 129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# 139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##===----------------------------------------------------------------------===## 149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse strict; 169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekuse warnings; 1722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenekuse FindBin qw($RealBin); 18a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenekuse Digest::MD5; 197a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekuse File::Basename; 2023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor; 2123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenekuse Term::ANSIColor qw(:constants); 22cd25c13ade3afa829c87ca1ed0ed0d379f426251Ted Kremenekuse Cwd qw/ getcwd abs_path /; 237cba11262458df05951432b54997eb40a35dbf9eTed Kremenekuse Sys::Hostname; 249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Verbose = 0; # Verbose output from this script. 269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $Prog = "scan-build"; 27f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildName; 28f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekmy $BuildDate; 299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 300e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $TERM = $ENV{'TERM'}; 310e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenekmy $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT 320e6893840fdd69a8a4d6561663a5a29af237ae08Ted Kremenek and defined $ENV{'SCAN_BUILD_COLOR'}); 3323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 347cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $UserName = HtmlEscape(getpwuid($<) || 'unknown'); 357cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HostName = HtmlEscape(hostname() || 'unknown'); 367cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDir = HtmlEscape(getcwd()); 377cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CurrentDirSuffix = basename($CurrentDir); 387cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 397cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $CmdArgs; 407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 417cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $HtmlTitle; 427cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 437cba11262458df05951432b54997eb40a35dbf9eTed Kremenekmy $Date = localtime(); 447cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 45b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 46b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Diagnostics 47b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 48b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 4923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub Diag { 5023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 5123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, MAGENTA "$Prog: @_"; 5223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 5323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 5523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: @_"; 5623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 5723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 5823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 59991c54b9b7409656e5593364e065878b5210d556Ted Kremeneksub DiagCrashes { 60991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $Dir = shift; 61938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("The analyzer encountered problems on some source files.\n"); 62938eef139ad43345248235da31f78a759dd18f13Ted Kremenek Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 63991c54b9b7409656e5593364e065878b5210d556Ted Kremenek Diag ("Please consider submitting a bug report using these files:\n"); 64e2c8663ad2b110712401145b866072bb94108058Nico Weber Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") 65991c54b9b7409656e5593364e065878b5210d556Ted Kremenek} 66991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremeneksub DieDiag { 6823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek if ($UseColor) { 6923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print BOLD, RED "$Prog: "; 7023cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET, RED @_; 7123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print RESET; 7223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek else { 7423cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek print "$Prog: ", @_; 7523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek } 7623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek exit(0); 7723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek} 7823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek 799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 80b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek# Some initial preprocessing of Clang options. 81b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 82b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 832a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek# Find 'clang' 84fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekmy $ClangSB = Cwd::realpath("$RealBin/bin/clang"); 858d10cdd9aa1d58f1898adf7752a7026f151ebc04Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 86fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek $ClangSB = Cwd::realpath("$RealBin/clang"); 87fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 88e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekmy $Clang; 89e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 90e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenek # Default to looking for 'clang' in the path. 916492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek $Clang = `which clang`; 926492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek chomp $Clang; 936492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek if ($Clang eq "") { 946492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek DieDiag("No 'clang' executable found in path."); 956492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek } 962a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek} 97e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekelse { 98e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenek $Clang = $ClangSB; 99e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenek} 100e01ca51f4167b5a7fd1d6230f2e2f1f177fd68e3Ted Kremenekmy $ClangCXX = $Clang . "++"; 101b4882d50923881d1a01af4d5604b5baaa141cdf9Douglas Gregormy $ClangVersion = HtmlEscape(`$Clang --version`); 102fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek 103b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek##----------------------------------------------------------------------------## 104fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1059cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 1069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 107a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub GetHTMLRunDir { 108fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "Not enough arguments." if (@_ == 0); 1092a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my $Dir = shift @_; 110fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek my $TmpMode = 0; 111fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (!defined $Dir) { 112ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek if (`uname` =~ /Darwin/) { 113ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek $Dir = $ENV{'TMPDIR'}; 114ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek if (!defined $Dir) { $Dir = "/tmp"; } 115ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek } 116ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek else { 117ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek $Dir = "/tmp"; 1182a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek } 119fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $TmpMode = 1; 120fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 121bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek 122bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek # Chop off any trailing '/' characters. 123bf762c9b48673e9686a97fe6ca144d891316164eTed Kremenek while ($Dir =~ /\/$/) { chop $Dir; } 124fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1259cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Get current date and time. 1262a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my @CurrentTime = localtime(); 1279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $year = $CurrentTime[5] + 1900; 1289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $day = $CurrentTime[3]; 1299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $month = $CurrentTime[4] + 1; 1309d7405fafd5bc08d38bc75579927bf414570bd61Ted Kremenek my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 1319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1322a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek # Determine the run number. 1339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $RunNumber; 1349cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1352a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek if (-d $Dir) { 1369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -r $Dir) { 13723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("directory '$Dir' exists but is not readable.\n"); 1382a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek } 1392a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek # Iterate over all files in the specified directory. 1402a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek my $max = 0; 1419cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 14229da6c59df7ca994e75139303a9230b24e2abaadTed Kremenek my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1439cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 1449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1452a3a8b9f47b0a8f3fdd57bc4fbd08684feb4fa85Ted Kremenek foreach my $f (@FILES) { 146fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek # Strip the prefix '$Prog-' if we are dumping files to /tmp. 147fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 148fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek next if (!($f =~ /^$Prog-(.+)/)); 149fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek $f = $1; 150fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 151fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1529cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my @x = split/-/, $f; 1539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if (scalar(@x) != 4); 1549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[0] != $year); 1559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[1] != $month); 1569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next if ($x[2] != $day); 1579cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($x[3] > $max) { 1599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $max = $x[3]; 1609cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1619cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1629cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1639cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = $max + 1; 1649cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1659cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek else { 1669cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (-x $Dir) { 16823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'$Dir' exists but is not a directory.\n"); 1699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 170fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 171fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 172445fa776d2bc9207c33a9b9ab4afb9513f6b81b0Ted Kremenek DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 173fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 174fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # $Dir does not exist. It will be automatically created by the 1769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # clang driver. Set the run number to 1. 177fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek 1789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $RunNumber = 1; 1799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 1809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 181fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "RunNumber must be defined!" if (!defined $RunNumber); 1829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Append the run number. 184fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek my $NewDir; 185fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if ($TmpMode) { 186fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 187fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 188fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek else { 189fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek $NewDir = "$Dir/$DateString-$RunNumber"; 190fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek } 191fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek system 'mkdir','-p',$NewDir; 192fc0898a6529f3d6bc9a4effdb3202aee13170fe3Ted Kremenek return $NewDir; 1939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 1949cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 195a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub SetHtmlEnv { 1969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "Wrong number of arguments." if (scalar(@_) != 2); 1989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1999cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Args = shift; 2009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Dir = shift; 2019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2029cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek die "No build command." if (scalar(@$Args) == 0); 2039cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2049cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $Cmd = $$Args[0]; 2059e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek 2069e4a1bb0084bf3bf64595f57effe496cb2cf1863Ted Kremenek if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { 2079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek return; 2089cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2099cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($Verbose) { 21123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Emitting reports for this run to '$Dir'.\n"); 2129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 2139cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2149cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2159cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 2169cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 2179cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 21857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# ComputeDigest - Compute a digest of the specified file. 21957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 22057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 22157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremeneksub ComputeDigest { 22257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $FName = shift; 22323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 224a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 225a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek # Use Digest::MD5. We don't have to be cryptographically secure. We're 2267ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # just looking for duplicate files that come from a non-malicious source. 2277ea02e6822fadcda31014c55f58cbc04e24d5abfTed Kremenek # We use Digest::MD5 because it is a standard Perl module that should 22863c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # come bundled on most systems. 22923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 230a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek binmode FILE; 231a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 232a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek close(FILE); 233a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek 23463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Return the digest. 235a6e24811207ad2179b0dabe3d7e6ec551e6686dfTed Kremenek return $Result; 23657cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek} 23757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 23857cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek##----------------------------------------------------------------------------## 2397a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdatePrefix - Compute the common prefix of files. 2407a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2417a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2427a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenekmy $Prefix; 2437a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2447a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdatePrefix { 2457a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $x = shift; 2467a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $y = basename($x); 2477a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $x =~ s/\Q$y\E$//; 2487a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2497a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek if (!defined $Prefix) { 2507a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek $Prefix = $x; 2517a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return; 2527a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 2537a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 25420b2bae90c102f405ba70f602c45660ce1cd0c4eTed Kremenek chop $Prefix while (!($x =~ /^\Q$Prefix/)); 2557a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2567a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2577a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub GetPrefix { 2587a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek return $Prefix; 2597a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2607a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2617a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2627a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek# UpdateInFilePath - Update the path in the report file. 2637a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2647a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2657a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremeneksub UpdateInFilePath { 2667a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $fname = shift; 2677a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $regex = shift; 2687a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek my $newtext = shift; 26963c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2707a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek open (RIN, $fname) or die "cannot open $fname"; 27163c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 27263c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2737a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek while (<RIN>) { 2747a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek s/$regex/$newtext/; 2757a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek print ROUT $_; 2767a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek } 27763c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek 2787a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (ROUT); 2797a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek close (RIN); 28020161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("mv", "$fname.tmp", $fname); 2817a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek} 2827a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 2837a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek##----------------------------------------------------------------------------## 2844f2b10b24bab0049020d268382eda144e2aa064cTom Care# AddStatLine - Decode and insert a statistics line into the database. 2854f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 2864f2b10b24bab0049020d268382eda144e2aa064cTom Care 2874f2b10b24bab0049020d268382eda144e2aa064cTom Caresub AddStatLine { 2884f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Line = shift; 2894f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 2904f2b10b24bab0049020d268382eda144e2aa064cTom Care 2914f2b10b24bab0049020d268382eda144e2aa064cTom Care print $Line . "\n"; 2924f2b10b24bab0049020d268382eda144e2aa064cTom Care 2934f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Regex = qr/(.*?)\ :\ (.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable 2946bdda82234ff106d561dc8c0ce5ca48b97726bbfTed Kremenek \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: 2954f2b10b24bab0049020d268382eda144e2aa064cTom Care \ (yes|no)/x; 2964f2b10b24bab0049020d268382eda144e2aa064cTom Care 2974f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($Line !~ $Regex) { 2984f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 2994f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3004f2b10b24bab0049020d268382eda144e2aa064cTom Care 3014f2b10b24bab0049020d268382eda144e2aa064cTom Care # Create a hash of the interesting fields 3024f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Row = { 3034f2b10b24bab0049020d268382eda144e2aa064cTom Care Filename => $1, 3044f2b10b24bab0049020d268382eda144e2aa064cTom Care Function => $2, 3054f2b10b24bab0049020d268382eda144e2aa064cTom Care Total => $3, 3064f2b10b24bab0049020d268382eda144e2aa064cTom Care Unreachable => $4, 3074f2b10b24bab0049020d268382eda144e2aa064cTom Care Aborted => $5, 3084f2b10b24bab0049020d268382eda144e2aa064cTom Care Empty => $6 3094f2b10b24bab0049020d268382eda144e2aa064cTom Care }; 3104f2b10b24bab0049020d268382eda144e2aa064cTom Care 3114f2b10b24bab0049020d268382eda144e2aa064cTom Care # Add them to the stats array 3124f2b10b24bab0049020d268382eda144e2aa064cTom Care push @$Stats, $Row; 3134f2b10b24bab0049020d268382eda144e2aa064cTom Care} 3144f2b10b24bab0049020d268382eda144e2aa064cTom Care 3154f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 3165744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek# ScanFile - Scan a report file for various identifying attributes. 3175744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 3185744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 31957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# Sometimes a source file is scanned more than once, and thus produces 32057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek# multiple error reports. We use a cache to solve this problem. 32157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 32257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenekmy %AlreadyScanned; 32357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 3245744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremeneksub ScanFile { 3255744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Index = shift; 3275744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $Dir = shift; 3285744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek my $FName = shift; 3294f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 3305744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 33157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Compute a digest for the report file. Determine if we have already 33257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # scanned a file that looks just like it. 33357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 33457cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek my $digest = ComputeDigest("$Dir/$FName"); 33557cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 336fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $AlreadyScanned{$digest}) { 33757cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek # Redundant file. Remove it. 33820161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-f", "$Dir/$FName"); 33957cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek return; 34057cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek } 34157cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 34257cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek $AlreadyScanned{$digest} = 1; 34357cf446d344bb2649e8742cedf1cf4342ed78aa9Ted Kremenek 344809709f46f2516b4054681f0b76284055a84a50fTed Kremenek # At this point the report file is not world readable. Make it happen. 34520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("chmod", "644", "$Dir/$FName"); 346684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek 347684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenek # Scan the report file for tags. 34823cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 3495744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3504f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugType = ""; 3514f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugFile = ""; 3524f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugCategory = ""; 3534f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugDescription = ""; 3544f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugPathLength = 1; 3554f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BugLine = 0; 356ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 3575744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek while (<IN>) { 358d658e67b438c60fbe3bd1773a3172fd0f082c483Ted Kremenek last if (/<!-- BUGMETAEND -->/); 359ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 360a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek if (/<!-- BUGTYPE (.*) -->$/) { 361a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek $BugType = $1; 3625744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 36322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGFILE (.*) -->$/) { 364990c2f45e566d8ff097fa90176ba90036892b3cdTed Kremenek $BugFile = abs_path($1); 3657a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek UpdatePrefix($BugFile); 36622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 36722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 36822d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugPathLength = $1; 36922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 37022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek elsif (/<!-- BUGLINE (.*) -->$/) { 37122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek $BugLine = $1; 372ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 373ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek elsif (/<!-- BUGCATEGORY (.*) -->$/) { 374ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = $1; 37522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek } 3764f2b10b24bab0049020d268382eda144e2aa064cTom Care elsif (/<!-- BUGDESC (.*) -->$/) { 3774f2b10b24bab0049020d268382eda144e2aa064cTom Care $BugDescription = $1; 3784f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3795744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 3805744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 3815744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(IN); 382ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 383ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $BugCategory) { 384ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $BugCategory = "Other"; 385ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 3864f2b10b24bab0049020d268382eda144e2aa064cTom Care 3874f2b10b24bab0049020d268382eda144e2aa064cTom Care # Don't add internal statistics to the bug reports 3884f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($BugCategory =~ /statistics/i) { 3894f2b10b24bab0049020d268382eda144e2aa064cTom Care AddStatLine($BugDescription, $Stats); 3904f2b10b24bab0049020d268382eda144e2aa064cTom Care return; 3914f2b10b24bab0049020d268382eda144e2aa064cTom Care } 3924f2b10b24bab0049020d268382eda144e2aa064cTom Care 393a26ddabc0eb8cf8ea4de1878f84d3b920fc2349fTed Kremenek push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, 39481983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek $BugPathLength ]; 39522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek} 39622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 39722d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 3983ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek# CopyFiles - Copy resource files to target directory. 39922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek##----------------------------------------------------------------------------## 40022d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 4013ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremeneksub CopyFiles { 40222d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek my $Dir = shift; 404e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 405e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $JS = Cwd::realpath("$RealBin/sorttable.js"); 40622d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 40723cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Cannot find 'sorttable.js'.\n") 408e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $JS); 40922d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 410e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $JS, "$Dir"); 41122d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek 41223cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 41322d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek if (! -r "$Dir/sorttable.js"); 4143ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 415e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek my $CSS = Cwd::realpath("$RealBin/scanview.css"); 416e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 4173ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Cannot find 'scanview.css'.\n") 418e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4193ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 420e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek system ("cp", $CSS, "$Dir"); 4213ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek 4223ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 423e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if (! -r $CSS); 4245744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek} 4255744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 4265744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek##----------------------------------------------------------------------------## 4274f2b10b24bab0049020d268382eda144e2aa064cTom Care# CalcStats - Calculates visitation statistics and returns the string. 4284f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 4294f2b10b24bab0049020d268382eda144e2aa064cTom Care 4304f2b10b24bab0049020d268382eda144e2aa064cTom Caresub CalcStats { 4314f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Stats = shift; 4324f2b10b24bab0049020d268382eda144e2aa064cTom Care 4334f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalBlocks = 0; 4344f2b10b24bab0049020d268382eda144e2aa064cTom Care my $UnreachedBlocks = 0; 4354f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFunctions = scalar(@$Stats); 4364f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BlockAborted = 0; 4374f2b10b24bab0049020d268382eda144e2aa064cTom Care my $WorkListAborted = 0; 4384f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Aborted = 0; 4394f2b10b24bab0049020d268382eda144e2aa064cTom Care 4404f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculate the unique files 4414f2b10b24bab0049020d268382eda144e2aa064cTom Care my $FilesHash = {}; 4424f2b10b24bab0049020d268382eda144e2aa064cTom Care 4434f2b10b24bab0049020d268382eda144e2aa064cTom Care foreach my $Row (@$Stats) { 4444f2b10b24bab0049020d268382eda144e2aa064cTom Care $FilesHash->{$Row->{Filename}} = 1; 4454f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalBlocks += $Row->{Total}; 4464f2b10b24bab0049020d268382eda144e2aa064cTom Care $UnreachedBlocks += $Row->{Unreachable}; 4474f2b10b24bab0049020d268382eda144e2aa064cTom Care $BlockAborted++ if $Row->{Aborted} eq 'yes'; 4484f2b10b24bab0049020d268382eda144e2aa064cTom Care $WorkListAborted++ if $Row->{Empty} eq 'no'; 4494f2b10b24bab0049020d268382eda144e2aa064cTom Care $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; 4504f2b10b24bab0049020d268382eda144e2aa064cTom Care } 4514f2b10b24bab0049020d268382eda144e2aa064cTom Care 4524f2b10b24bab0049020d268382eda144e2aa064cTom Care my $TotalFiles = scalar(keys(%$FilesHash)); 4534f2b10b24bab0049020d268382eda144e2aa064cTom Care 4544f2b10b24bab0049020d268382eda144e2aa064cTom Care # Calculations 4554f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); 4564f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions 4574f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4584f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / 4594f2b10b24bab0049020d268382eda144e2aa064cTom Care $TotalFunctions * 100); 4604f2b10b24bab0049020d268382eda144e2aa064cTom Care my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks 4614f2b10b24bab0049020d268382eda144e2aa064cTom Care * 100); 4624f2b10b24bab0049020d268382eda144e2aa064cTom Care 4634f2b10b24bab0049020d268382eda144e2aa064cTom Care my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" 4644f2b10b24bab0049020d268382eda144e2aa064cTom Care . " in $TotalFiles files\n" 4654f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$Aborted functions aborted early ($PercentAborted%)\n" 4664f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" 4674f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" 4684f2b10b24bab0049020d268382eda144e2aa064cTom Care . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; 4694f2b10b24bab0049020d268382eda144e2aa064cTom Care 4704f2b10b24bab0049020d268382eda144e2aa064cTom Care return $StatsString; 4714f2b10b24bab0049020d268382eda144e2aa064cTom Care} 4724f2b10b24bab0049020d268382eda144e2aa064cTom Care 4734f2b10b24bab0049020d268382eda144e2aa064cTom Care##----------------------------------------------------------------------------## 4749cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Postprocess - Postprocess the results of an analysis scan. 4759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 4769cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 477a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub Postprocess { 4789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4794f2b10b24bab0049020d268382eda144e2aa064cTom Care my $Dir = shift; 4804f2b10b24bab0049020d268382eda144e2aa064cTom Care my $BaseDir = shift; 4814f2b10b24bab0049020d268382eda144e2aa064cTom Care my $AnalyzerStats = shift; 4829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 483fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek die "No directory specified." if (!defined $Dir); 4849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4859cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (! -d $Dir) { 48623cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No bugs found.\n"); 487363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4899cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 4909cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek opendir(DIR, $Dir); 491938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @files = grep { /^report-.*\.html$/ } readdir(DIR); 4929cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek closedir(DIR); 4939cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 494938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar(@files) == 0 and ! -e "$Dir/failures") { 49523cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("Removing directory '$Dir' because it contains no reports.\n"); 49620161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system ("rm", "-fR", $Dir); 497363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return 0; 4989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 4995744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 500991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Scan each report file and build an index. 5014f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Index; 5024f2b10b24bab0049020d268382eda144e2aa064cTom Care my @Stats; 5034f2b10b24bab0049020d268382eda144e2aa064cTom Care foreach my $file (@files) { ScanFile(\@Index, $Dir, $file, \@Stats); } 5045744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 505938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Scan the failures directory and use the information in the .info files 506d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek # to update the common prefix directory. 507938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @failures; 508938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my @attributes_ignored; 509938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (-d "$Dir/failures") { 510938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 511938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 512d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek closedir(DIR); 513938eef139ad43345248235da31f78a759dd18f13Ted Kremenek opendir(DIR, "$Dir/failures"); 514938eef139ad43345248235da31f78a759dd18f13Ted Kremenek @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 515938eef139ad43345248235da31f78a759dd18f13Ted Kremenek closedir(DIR); 516938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (@failures) { 517938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 518d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $Path = <IN>; 519d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek if (defined $Path) { UpdatePrefix($Path); } 520d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek close IN; 521d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 522d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek } 523d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek 52463c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek # Generate an index.html file. 52563c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek my $FName = "$Dir/index.html"; 52663c2017737530a7009f709f2fe822f20f63930b1Ted Kremenek open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 5275744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 5286e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the header. 5296e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 5305744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint OUT <<ENDTEXT; 5315744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<html> 5325744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek<head> 5337cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<title>${HtmlTitle}</title> 534f143545ce5ce125e7c1aa6fca9df372bfb604e9cTed Kremenek<link type="text/css" rel="stylesheet" href="scanview.css"/> 53522d6a639ce04ababc6900ea8b50ed7167db0f39cTed Kremenek<script src="sorttable.js"></script> 5366e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<script language='javascript' type="text/javascript"> 5376e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction SetDisplay(RowClass, DisplayVal) 5386e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek{ 5396e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek var Rows = document.getElementsByTagName("tr"); 5406e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek for ( var i = 0 ; i < Rows.length; ++i ) { 5416e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (Rows[i].className == RowClass) { 5426e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek Rows[i].style.display = DisplayVal; 5436e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5446e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5456e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 546ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 5472350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenekfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 5482350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek var Inputs = document.getElementsByTagName("input"); 5492350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek for ( var i = 0 ; i < Inputs.length; ++i ) { 5502350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if (Inputs[i].type == "checkbox") { 5512350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek if(Inputs[i] != SummaryCheckButton) { 5522350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].checked = SummaryCheckButton.checked; 5532350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek Inputs[i].onclick(); 5542350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5552350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5562350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek } 5572350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek} 5582350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek 559999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekfunction returnObjById( id ) { 560999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (document.getElementById) 561999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.getElementById(id); 562999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.all) 563999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.all[id]; 564999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek else if (document.layers) 565999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek var returnVar = document.layers[id]; 566999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek return returnVar; 567999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek} 568999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 569999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenekvar NumUnchecked = 0; 570999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek 5716e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekfunction ToggleDisplay(CheckButton, ClassName) { 5726e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek if (CheckButton.checked) { 5736e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, ""); 574999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek if (--NumUnchecked == 0) { 575999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = true; 576999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek } 5776e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5786e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek else { 5796e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek SetDisplay(ClassName, "none"); 580999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek NumUnchecked++; 581999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed Kremenek returnObjById("AllBugsCheck").checked = false; 5826e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 5836e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek} 5846e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</script> 5851d1abb1dec3d0b7609809d876a16a64a021e96e7Ted Kremenek<!-- SUMMARYENDHEAD --> 5866e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</head> 5876e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek<body> 5887cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h1>${HtmlTitle}</h1> 5897cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5907cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<table> 5917cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 5927cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 5937cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 594b4882d50923881d1a01af4d5604b5baaa141cdf9Douglas Gregor<tr><th>Clang Version:</th><td>${ClangVersion}</td></tr> 5957cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<tr><th>Date:</th><td>${Date}</td></tr> 5967cba11262458df05951432b54997eb40a35dbf9eTed KremenekENDTEXT 5977cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 5987cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 5997cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (defined($BuildName) && defined($BuildDate)); 6007cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 6017cba11262458df05951432b54997eb40a35dbf9eTed Kremenekprint OUT <<ENDTEXT; 6027cba11262458df05951432b54997eb40a35dbf9eTed Kremenek</table> 6036e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6046e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 605991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (scalar(@files)) { 606991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print out the summary table. 607991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my %Totals; 608ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 609991c54b9b7409656e5593364e065878b5210d556Ted Kremenek for my $row ( @Index ) { 610ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_type = ($row->[2]); 611ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $bug_category = ($row->[1]); 612ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $key = "$bug_category:$bug_type"; 613ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 614ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 615ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { $Totals{$key}->[0]++; } 6166e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 617991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 6187cba11262458df05951432b54997eb40a35dbf9eTed Kremenek print OUT "<h2>Bug Summary</h2>"; 619991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 620991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $BuildName) { 621991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 6226e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek } 623f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 6242350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek my $TotalBugs = scalar(@Index); 6256e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 626ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table> 627ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 628999e120c1f5bb4064fa9961d82c2b02b6c41cb0dTed 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> 6296e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted KremenekENDTEXT 6306e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 631ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $last_category; 632ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 633ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $key ( 634ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek sort { 635ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = $Totals{$a}; 636ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $y = $Totals{$b}; 637ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $res = $x->[1] cmp $y->[1]; 638ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res = $x->[2] cmp $y->[2] if ($res == 0); 639ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $res 640ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } keys %Totals ) 641ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek { 642ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $val = $Totals{$key}; 643ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $category = $val->[1]; 644ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if (!defined $last_category or $last_category ne $category) { 645ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $last_category = $category; 646ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 647ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 648ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = lc $key; 649ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 650ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr><td class=\"SUMM_DESC\">"; 651ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[2]; 6522350a46bec7c581b2e3808e205aa3f3f5fae71ccTed Kremenek print OUT "</td><td class=\"Q\">"; 653ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $val->[0]; 654ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 655991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6566e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6576e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek # Print out the table of errors. 6586e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 6596e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenekprint OUT <<ENDTEXT; 6606e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek</table> 6617cba11262458df05951432b54997eb40a35dbf9eTed Kremenek<h2>Reports</h2> 662ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 663ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<table class="sortable" style="table-layout:automatic"> 664ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<thead><tr> 665ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td>Bug Group</td> 666ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 667bba1cf550015b088f94c2d3a60a769806f84cd15Ted Kremenek <td>File</td> 668ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <td class="Q">Line</td> 66981983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek <td class="Q">Path Length</td> 6702645c77072d45fabb2bdc0a3621908035c7113dcTed Kremenek <td class="sorttable_nosort"></td> 671ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek <!-- REPORTBUGCOL --> 672ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek</tr></thead> 673ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek<tbody> 6745744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekENDTEXT 6759cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 676991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $prefix = GetPrefix(); 677991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $regex; 678991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFileRegex; 679991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $InFilePrefix = "File:</td><td>"; 6807a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 681991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $prefix) { 682991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $regex = qr/^\Q$prefix\E/is; 683991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 684991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 6857a4648df321be70bb009a8dc56e0162c3f13c18cTed Kremenek 686ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 687ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = "$row->[1]:$row->[2]"; 688ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x = lc $x; 689ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek $x =~ s/[ ,'":\/()]+/_/g; 6906e6eff7aaac376a08cdb3c6ae9d177491f800ca8Ted Kremenek 691991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ReportFile = $row->[0]; 692ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 693ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<tr class=\"bt_$x\">"; 694ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 695991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT $row->[1]; 696ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 697ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"DESC\">"; 698ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $row->[2]; 699ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 700ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 701ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Update the file prefix. 702ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $fname = $row->[3]; 703ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 704991c54b9b7409656e5593364e065878b5210d556Ted Kremenek if (defined $regex) { 705991c54b9b7409656e5593364e065878b5210d556Ted Kremenek $fname =~ s/$regex//; 706991c54b9b7409656e5593364e065878b5210d556Ted Kremenek UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 707991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 708ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 70991639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek print OUT "<td>"; 710ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my @fname = split /\//,$fname; 711ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname > 0) { 712ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek while ($#fname >= 0) { 713ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek my $x = shift @fname; 714ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $x; 715ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek if ($#fname >= 0) { 716ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<span class=\"W\"> </span>/"; 717ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 718ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 719ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 720ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek else { 721ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT $fname; 72291639ef5aa2bd94c14ae872cf747c58174ffe9b8Ted Kremenek } 723ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</td>"; 724ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 725ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek # Print out the quantities. 72681983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for my $j ( 4 .. 5 ) { 727ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td class=\"Q\">$row->[$j]</td>"; 728ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek } 729ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek 730991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the rest of the columns. 73181983111dfa43e5f6b21b221c959586a6a766e76Ted Kremenek for (my $j = 6; $j <= $#{$row}; ++$j) { 732ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "<td>$row->[$j]</td>" 733991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 7347f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 735991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Emit the "View" link. 73668005ddb49b88c2f6cdd88185d72d8b411d2dbc9Ted Kremenek print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 7373cea9ee6b77ac797ebb910bdf45d1d7f8f68e37bTed Kremenek 738e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar # Emit REPORTBUG markers. 739ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 740e43038ec3d0ef187fcdddf101ef653bbbdb1069aDaniel Dunbar 741991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # End the row. 742991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</tr>\n"; 743991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 744991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 745ebb7413bbe518fa6230eddebf6e51857b47b5cd3Ted Kremenek print OUT "</tbody>\n</table>\n\n"; 746991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 747991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 748938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar (@failures) || scalar(@attributes_ignored)) { 749938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<h2>Analyzer Failures</h2>\n"; 750938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 751938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @attributes_ignored) { 752938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 753938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 754938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 755938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @attributes_ignored) { 756938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 757938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $attribute = $1; 758938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the attribute file to get the first file that failed. 759938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (!open (ATTR, "$Dir/failures/$file")); 760938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile = <ATTR>; 761938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $ppfile; 762938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close ATTR; 763938eef139ad43345248235da31f78a759dd18f13Ted Kremenek next if (! -e "$Dir/failures/$ppfile"); 764938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Open the info file and get the name of the source file. 765938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$ppfile.info.txt") or 766938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 767938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $srcfile = <INFO>; 768938eef139ad43345248235da31f78a759dd18f13Ted Kremenek chomp $srcfile; 769938eef139ad43345248235da31f78a759dd18f13Ted Kremenek close (INFO); 770938eef139ad43345248235da31f78a759dd18f13Ted Kremenek # Print the information in the table. 771938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $prefix = GetPrefix(); 772938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 773938eef139ad43345248235da31f78a759dd18f13Ted 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"; 774938eef139ad43345248235da31f78a759dd18f13Ted Kremenek my $ppfile_clang = $ppfile; 775938eef139ad43345248235da31f78a759dd18f13Ted Kremenek $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 776938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 777938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 778938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 779938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 780938eef139ad43345248235da31f78a759dd18f13Ted Kremenek 781938eef139ad43345248235da31f78a759dd18f13Ted Kremenek if (scalar @failures) { 782938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 783938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<table>\n"; 784938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 785938eef139ad43345248235da31f78a759dd18f13Ted Kremenek foreach my $file (sort @failures) { 78682a1253077cd0832e4d347062b911cd305ab62d1Ted Kremenek $file =~ /(.+).info.txt$/; 787991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Get the preprocessed file. 788991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $ppfile = $1; 789991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Open the info file and get the name of the source file. 790938eef139ad43345248235da31f78a759dd18f13Ted Kremenek open (INFO, "$Dir/failures/$file") or 791938eef139ad43345248235da31f78a759dd18f13Ted Kremenek die "Cannot open $Dir/failures/$file\n"; 792991c54b9b7409656e5593364e065878b5210d556Ted Kremenek my $srcfile = <INFO>; 7935d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $srcfile; 7945d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek my $problem = <INFO>; 7955d31f83bbe990aeb070ce6c8d919d229d4eb5052Ted Kremenek chomp $problem; 796991c54b9b7409656e5593364e065878b5210d556Ted Kremenek close (INFO); 797991c54b9b7409656e5593364e065878b5210d556Ted Kremenek # Print the information in the table. 798d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed Kremenek my $prefix = GetPrefix(); 7999f9b1fded49acff77e61b3ed1afc8bbaaefe6f34Ted Kremenek if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 800938eef139ad43345248235da31f78a759dd18f13Ted 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"; 801ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar my $ppfile_clang = $ppfile; 802ce723ce2346fccb102d4dc93b80356824544d1afDaniel Dunbar $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 803938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 804991c54b9b7409656e5593364e065878b5210d556Ted Kremenek } 805938eef139ad43345248235da31f78a759dd18f13Ted Kremenek print OUT "</table>\n"; 806938eef139ad43345248235da31f78a759dd18f13Ted Kremenek } 807e2c8663ad2b110712401145b866072bb94108058Nico Weber print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang-analyzer.llvm.org/filing_bugs.html\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n"; 8085744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek } 8095744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek 810991c54b9b7409656e5593364e065878b5210d556Ted Kremenek print OUT "</body></html>\n"; 8115744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenek close(OUT); 8123ce1207f90340f9f773ace4d475b99b75ff65088Ted Kremenek CopyFiles($Dir); 81320161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 81420161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek # Make sure $Dir and $BaseDir are world readable/executable. 81520161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek system("chmod", "755", $Dir); 816fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 81720161e9ed795fa7ff2f7855324aa836a927fb0f5Ted Kremenek 8184f2b10b24bab0049020d268382eda144e2aa064cTom Care # Print statistics 8194f2b10b24bab0049020d268382eda144e2aa064cTom Care print CalcStats(\@Stats) if $AnalyzerStats; 8204f2b10b24bab0049020d268382eda144e2aa064cTom Care 82123cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek my $Num = scalar(@Index); 822150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek Diag("$Num bugs found.\n"); 823150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek if ($Num > 0 && -r "$Dir/index.html") { 8245950b3f93a6e8a6ae8bd59a0ef5797e9f88f0bc3Ted Kremenek Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 825150c2120ab4a44b4ac62b401ffece9049ff9b2c0Ted Kremenek } 826363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 827938eef139ad43345248235da31f78a759dd18f13Ted Kremenek DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 828991c54b9b7409656e5593364e065878b5210d556Ted Kremenek 829363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek return $Num; 8309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 8319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 8329cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 833dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek# RunBuildCommand - Run the build command. 834dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 835dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8366b6289848e215ff12d4d54fe0602d3371db52788Ted Kremeneksub AddIfNotPresent { 8376b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Args = shift; 8386b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $Arg = shift; 8396b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek my $found = 0; 8406b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8416b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek foreach my $k (@$Args) { 8426b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($k eq $Arg) { 8436b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek $found = 1; 8446b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek last; 8456b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8466b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8476b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 8486b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($found == 0) { 8496b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek push @$Args, $Arg; 8506b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 8516b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek} 8526b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 853dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremeneksub RunBuildCommand { 854dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 855dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Args = shift; 8567442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek my $IgnoreErrors = shift; 857dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek my $Cmd = $Args->[0]; 8586195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek my $CCAnalyzer = shift; 859524c308506e77e173092e87a0724a27817311428Ted Kremenek my $CXXAnalyzer = shift; 860dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 8613301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek # Get only the part of the command after the last '/'. 8623301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek if ($Cmd =~ /\/([^\/]+)$/) { 8633301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek $Cmd = $1; 8643301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek } 8653301cb103d5f32056d62f13bde036988f7cf1330Ted Kremenek 86692548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 86792548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?cc[^\/]*$)/ or 86892548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 86905acf8b689257d8b7349ffdfe309b4d7f7d6ae13Ted Kremenek $Cmd =~ /(.*\/?clang$)/ or 87092548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 87192548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 87292548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 87351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CC"} = $1; 87492548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek } 87592548fed40519a09a1c016ceb6ab078384ab5ebcTed Kremenek 876dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek shift @$Args; 8776195c373b86963b029a2d1d2501f899789d74ba8Ted Kremenek unshift @$Args, $CCAnalyzer; 878dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek } 87951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 88051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or 88151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or 88205acf8b689257d8b7349ffdfe309b4d7f7d6ae13Ted Kremenek $Cmd =~ /(.*\/?clang\+\+$)/ or 88351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { 88451365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { 88551365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = $1; 88651365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek } 88751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek shift @$Args; 888524c308506e77e173092e87a0724a27817311428Ted Kremenek unshift @$Args, $CXXAnalyzer; 88951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek } 8907442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($IgnoreErrors) { 8917442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek if ($Cmd eq "make" or $Cmd eq "gmake") { 8926fba85dc6509069ff7735283464bd02da2da6eebTed Kremenek AddIfNotPresent($Args, "CC=$CCAnalyzer"); 893524c308506e77e173092e87a0724a27817311428Ted Kremenek AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); 8946b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-k"); 8958912b5427a22d9032cad959c5c22cd9d28d4a66cTed Kremenek AddIfNotPresent($Args,"-i"); 8967442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 8977442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek elsif ($Cmd eq "xcodebuild") { 8986b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 8997442ca6b274f1a935c31e34221fbd0a68077ddc5Ted Kremenek } 9006b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 9016b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek 9026b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek if ($Cmd eq "xcodebuild") { 90387752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek # Check if using iPhone SDK 3.0 (simulator). If so the compiler being 90487752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek # used should be gcc-4.2. 90587752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek if (!defined $ENV{"CCC_CC"}) { 90687752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek for (my $i = 0 ; $i < scalar(@$Args); ++$i) { 90787752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { 90887752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek if (@$Args[$i+1] =~ /^iphonesimulator3/) { 90987752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek $ENV{"CCC_CC"} = "gcc-4.2"; 91051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = "g++-4.2"; 91187752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek } 91287752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek } 91387752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek } 91487752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek } 91587752b2442260fcf569e7a1447a04cd8955494c5Ted Kremenek 916cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek # Disable PCH files until clang supports them. 917cfd4c7bef7a76c568ec033e91ba3f521e10bcbb3Ted Kremenek AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 918915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek 919915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 920915e972098f1e67c7559613ccde7205cee582e61Ted Kremenek # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 921524c308506e77e173092e87a0724a27817311428Ted Kremenek # (via c++-analyzer) when linking such files. 922524c308506e77e173092e87a0724a27817311428Ted Kremenek $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; 9236b6289848e215ff12d4d54fe0602d3371db52788Ted Kremenek } 924dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 9255a4ddaf39a26f9c7e30d3aeca17c702213a29d9fTed Kremenek return (system(@$Args) >> 8); 926dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek} 927dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek 928dab111099e5e21b4f8eb929c7af9a7a0241eca98Ted Kremenek##----------------------------------------------------------------------------## 9299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# DisplayHelp - Utility function to display all help options. 9309cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 9319cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 932a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishopsub DisplayHelp { 9339cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 9345744dc294e2d658a904e6bb258c0875fbac0d4a1Ted Kremenekprint <<ENDTEXT; 935a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam BishopUSAGE: $Prog [options] <build command> [build options] 9362b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 937f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted KremenekENDTEXT 938f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 939fc1d340169265375704404a8eec1d8acf1c2038dTed Kremenek if (defined $BuildName) { 940f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 941f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek } 942f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenek 943f4cdf41fc7a9026b24d369ba932396e7c51209b7Ted Kremenekprint <<ENDTEXT; 9442b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekOPTIONS: 9452b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 946e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek -analyze-headers - Also analyze functions in #included files. 9478382cf57b722f130f1a6b45380639871c07271c1Ted Kremenek 948363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -o - Target directory for HTML report files. Subdirectories 949a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop will be created as needed to represent separate "runs" of 9502b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek the analyzer. If this option is not specified, a directory 951ffda0b44eb02ddf2f168df8e14ae98de790f2b05Ted Kremenek is created in /tmp (TMPDIR on Mac OS X) to store the reports. 952db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 953363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -h - Display this message. 954363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --help 9551262fc4d66584224234691d30d779f8ff004585cTed Kremenek 956363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -k - Add a "keep on going" option to the specified build command. 957363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --keep-going This option currently supports make and xcodebuild. 958f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek This is a convenience option; one can specify this 959f02e8dbf7e3bddac4efec77b0ea3f07b26eaa955Ted Kremenek behavior directly using build options. 9602b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 9617cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title [title] - Specify the title used on generated HTML pages. 9627cba11262458df05951432b54997eb40a35dbf9eTed Kremenek --html-title=[title] If not specified, a default title will be used. 9637cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 964db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek -plist - By default the output of scan-build is a set of HTML files. 965db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek This option outputs the results as a set of .plist files. 9662c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks 9672c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks -plist-html - By default the output of scan-build is a set of HTML files. 9682c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks This option outputs the results as a set of HTML 9692c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks and .plist files. 9702c3038edc2a691b2462ef4bc7fae8f4c9a494154Anna Zaks 971363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --status-bugs - By default, the exit status of $Prog is the same as the 972363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek executed build command. Specifying this option causes the 973363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek exit status of $Prog to be 1 if it found potential bugs 974363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek and 0 otherwise. 9752b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 976a772b86a6edaf9f110bf7d3e6c8201723371bc9aAnna Zaks --use-cc [compiler path] - $Prog attempts to guess the default compiler for 977386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-cc=[compiler path] your C and Objective-C code. Use this option 978386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 979386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 980a772b86a6edaf9f110bf7d3e6c8201723371bc9aAnna Zaks --use-c++ [compiler path] - $Prog attempts to guess the default compiler for 981386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option 982386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek to specify an alternate compiler. 983f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 984363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -v - Verbose output from $Prog and the analyzer. 985386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek A second and third '-v' increases verbosity. 986363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 987363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek -V - View analysis results in a web browser when the build 988363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek --view completes. 9897f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 990be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed KremenekADVANCED OPTIONS: 991be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 9929f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek -constraints [model] - Specify the contraint engine used by the analyzer. 9939f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek By default the 'range' model is used. Specifying 9949f4ecb34d502f6aad7d635dd3aec24a373ef5c9bTed Kremenek 'basic' uses a simpler, less powerful constraint model 995d4c7684f19703d75b989364da80727d635f99b53Ted Kremenek used by checker-0.160 and earlier. 996be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 997be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek -store [model] - Specify the store model used by the analyzer. By default, 998b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek the 'region' store model is used. 'region' specifies a field- 999b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek sensitive store model. Users can also specify 'basic', which 1000b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek is far less precise but can more quickly analyze code. 1001b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek 'basic' was the default store model for checker-0.221 and 1002b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek earlier. 1003b8bb3e797c5687715c6d9d960ee573e4d0e62230Ted Kremenek 1004e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek -no-failure-reports - Do not create a 'failures' subdirectory that includes 1005e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek analyzer crash reports and preprocessed source files. 1006b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 10074f2b10b24bab0049020d268382eda144e2aa064cTom Care -stats - Generates visitation statistics for the project being analyzed. 10084f2b10b24bab0049020d268382eda144e2aa064cTom Care 10094f2b10b24bab0049020d268382eda144e2aa064cTom Care -maxloop N - specifiy the number of times a block can be visited before giving 101009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek up. Default is 4. Increase for more comprehensive coverage at a 10114f2b10b24bab0049020d268382eda144e2aa064cTom Care cost of speed. 101209fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 101309fbf297da918760ce33302a3f709a77f43af265Ted KremenekCONTROLLING CHECKERS: 101409fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 101509fbf297da918760ce33302a3f709a77f43af265Ted Kremenek A default group of checkers are always run unless explicitly disabled. 101609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek Checkers may be enabled/disabled using the following options: 101709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek 101809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -enable-checker [checker name] 101909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek -disable-checker [checker name] 1020d52e4252264f9d1f62da0b5b89d099cd7dd7fa2fTed KremenekENDTEXT 1021b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1022ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for list of checkers that are enabled. 1023ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy %EnabledCheckers; 1024ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekforeach my $lang ("c", "objective-c", "objective-c++", "c++") { 1025ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek pipe(FROM_CHILD, TO_PARENT); 1026ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $pid = fork(); 1027ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($pid == 0) { 1028ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close FROM_CHILD; 1029ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDOUT,">&", \*TO_PARENT); 1030ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDERR,">&", \*TO_PARENT); 1031ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek exec $Clang, ('--analyze', '-x', $lang, '-', '-###'); 1032ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1033ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(TO_PARENT); 1034ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 1035ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek foreach my $val (split /\s+/) { 1036ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $val =~ s/\"//g; 1037ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($val =~ /-analyzer-checker\=([^\s]+)/) { 1038ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $EnabledCheckers{$1} = 1; 1039ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1040ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1041ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1042ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek waitpid($pid,0); 1043ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close(FROM_CHILD); 1044ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1045ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1046ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Query clang for complete list of checkers. 1047ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekpipe(FROM_CHILD, TO_PARENT); 1048ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy $pid = fork(); 1049ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekif ($pid == 0) { 1050ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek close FROM_CHILD; 1051ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDOUT,">&", \*TO_PARENT); 1052ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek open(STDERR,">&", \*TO_PARENT); 1053ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek exec $Clang, ('-cc1', '-analyzer-checker-help'); 1054ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1055ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekclose(TO_PARENT); 1056ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy $foundCheckers = 0; 1057ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekwhile(<FROM_CHILD>) { 1058ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if (/CHECKERS:/) { 1059ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $foundCheckers = 1; 1060ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek last; 1061ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1062ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1063ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekif (!$foundCheckers) { 1064ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " *** Could not query Clang for the list of available checkers."; 1065ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1066ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekelse { 1067ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print("\nAVAILABLE CHECKERS:\n\n"); 1068ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $skip = 0; 1069ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek while(<FROM_CHILD>) { 10704cd6ea9989989e9f3a87b22c794ce76c6899d0a1Ted Kremenek if (/experimental/) { 1071ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $skip = 1; 1072ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek next; 1073ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1074ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($skip) { 1075ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek next if (!/^\s\s[^\s]/); 1076ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $skip = 0; 1077ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1078ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek s/^\s\s//; 1079ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if (/^([^\s]+)/) { 1080ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek # Is the checker enabled? 1081ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $checker = $1; 1082ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $enabled = 0; 1083ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek my $aggregate = ""; 1084ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek foreach my $domain (split /\./, $checker) { 1085ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $aggregate .= $domain; 1086ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($EnabledCheckers{$aggregate}) { 1087ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $enabled =1; 1088ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek last; 1089ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1090ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1091ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1092ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek if ($enabled) { 1093ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " + "; 1094ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1095ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek else { 1096ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " "; 1097ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1098ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1099ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek else { 1100ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print " "; 1101ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1102ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek print $_; 1103ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek } 1104ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1105ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekwaitpid($pid,0); 1106ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekclose(FROM_CHILD); 11077fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1108b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekprint <<ENDTEXT 1109b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 1110ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek NOTE: "+" indicates that an analysis is enabled by default. 1111b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenek 11122b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekBUILD OPTIONS 11132b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1114363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek You can specify any build option acceptable to the build command. 111539eefde0ae1851c8b35896ee468deb3d802d03d1Ted Kremenek 11165744dc294e2d658a904e6bb258c0875fbac0d4a1Ted KremenekEXAMPLE 11172b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1118363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $Prog -o /tmp/myhtmldir make -j4 11192b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 1120363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The above example causes analysis reports to be deposited into 1121363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option. 1122363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek A different subdirectory is created each time $Prog analyzes a project. 1123363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek The analyzer should support most parallel builds, but not distributed builds. 11242b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek 11252b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed KremenekENDTEXT 11269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 11279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 11297cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# HtmlEscape - HTML entity encode characters that are special in HTML 11307cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 11317cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 11327cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub HtmlEscape { 11337cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 11347cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 11357cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $tmp = $arg; 113687f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/&/&/g; 113787f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/</</g; 113887f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek $tmp =~ s/>/>/g; 11397cba11262458df05951432b54997eb40a35dbf9eTed Kremenek return $tmp; 11407cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 11417cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 11427cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 11437cba11262458df05951432b54997eb40a35dbf9eTed Kremenek# ShellEscape - backslash escape characters that are special to the shell 11447cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 11457cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 11467cba11262458df05951432b54997eb40a35dbf9eTed Kremeneksub ShellEscape { 11477cba11262458df05951432b54997eb40a35dbf9eTed Kremenek # copy argument to new variable so we don't clobber the original 11487cba11262458df05951432b54997eb40a35dbf9eTed Kremenek my $arg = shift || ''; 114987f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 115087f8de72a3c5d61736a14dca271504aaa5020d6fTed Kremenek return $arg; 11517cba11262458df05951432b54997eb40a35dbf9eTed Kremenek} 11527cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 11537cba11262458df05951432b54997eb40a35dbf9eTed Kremenek##----------------------------------------------------------------------------## 11549cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Process command-line arguments. 11559cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek##----------------------------------------------------------------------------## 11569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1157e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekmy $AnalyzeHeaders = 0; 11589cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $HtmlDir; # Parent directory to store HTML files. 11599cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekmy $IgnoreErrors = 0; # Ignore build errors. 11607f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenekmy $ViewResults = 0; # View results when the build terminates. 1161363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenekmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 1162b7770c0b4970606b53cca14ae3ca0588a0bfcb30Ted Kremenekmy @AnalysesToRun; 116307c3767be59472e19183c7b51fae76481465cb51Zhongxing Xumy $StoreModel; 1164be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekmy $ConstraintsModel; 11658d8bc9157fccab6a4089c41cdad9e12045edd736Ted Kremenekmy $OutputFormat = "html"; 11664f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $AnalyzerStats = 0; 11674f2b10b24bab0049020d268382eda144e2aa064cTom Caremy $MaxLoop = 0; 11689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif (!@ARGV) { 11709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1171a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 11729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 11739cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1174ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1175ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekmy $displayHelp = 0; 1176ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 11779cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekwhile (@ARGV) { 11789cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11799cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek # Scan for options we recognize. 11809cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11819cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek my $arg = $ARGV[0]; 11829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11832f2418eacfdc68e09a75f4343ed93ba292e8d895Sam Bishop if ($arg eq "-h" or $arg eq "--help") { 1184ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $displayHelp = 1; 1185ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek shift @ARGV; 1186ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek next; 11879cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 11889cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1189e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek if ($arg eq '-analyze-headers') { 1190e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek shift @ARGV; 1191e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek $AnalyzeHeaders = 1; 1192e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek next; 1193e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek } 1194e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek 11959cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-o") { 11969cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 11979cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 11989cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if (!@ARGV) { 119923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("'-o' option requires a target directory name.\n"); 12009cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12019cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1202db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # Construct an absolute path. Uses the current working directory 1203db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek # as a base if the original path was not absolute. 1204db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek $HtmlDir = abs_path(shift @ARGV); 1205db51a55c4922b055a90a370ce9906455887a8564Ted Kremenek 12069cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 12079cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12087cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12097cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--html-title(=(.+))?$/) { 12107cba11262458df05951432b54997eb40a35dbf9eTed Kremenek shift @ARGV; 12117cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 1212278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq '') { 12137cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if (!@ARGV) { 12147cba11262458df05951432b54997eb40a35dbf9eTed Kremenek DieDiag("'--html-title' option requires a string.\n"); 12157cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 12167cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12177cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = shift @ARGV; 12187cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } else { 12197cba11262458df05951432b54997eb40a35dbf9eTed Kremenek $HtmlTitle = $2; 12207cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 12217cba11262458df05951432b54997eb40a35dbf9eTed Kremenek 12227cba11262458df05951432b54997eb40a35dbf9eTed Kremenek next; 12237cba11262458df05951432b54997eb40a35dbf9eTed Kremenek } 12249cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12252b74ab6fdf0e3ed455bf6e0d30e24845f0c2846eTed Kremenek if ($arg eq "-k" or $arg eq "--keep-going") { 12269cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 12279cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $IgnoreErrors = 1; 12289cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 12299cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12307fe679f300bd063d7edf7071d14c7f3823ef8cceTed Kremenek 1231f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if ($arg =~ /^--use-cc(=(.+))?$/) { 1232f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek shift @ARGV; 1233f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek my $cc; 1234f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1235278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1236f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek if (!@ARGV) { 1237f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek DieDiag("'--use-cc' option requires a compiler executable name.\n"); 1238f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1239f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = shift @ARGV; 1240f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1241f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek else { 1242f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $cc = $2; 1243f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1244f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 1245f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek $ENV{"CCC_CC"} = $cc; 1246f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek next; 1247f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek } 1248f17ef3caf19ebff18a4ee0e7984dfc6036f34b2eTed Kremenek 12497cba11262458df05951432b54997eb40a35dbf9eTed Kremenek if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 1250386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek shift @ARGV; 125151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek my $cxx; 1252386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 1253278a55103a66e3a83530f15d0df3d4b80ed4cfeeTed Kremenek if (!defined $2 || $2 eq "") { 1254386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek if (!@ARGV) { 1255386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek DieDiag("'--use-c++' option requires a compiler executable name.\n"); 1256386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 125751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = shift @ARGV; 1258386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1259386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek else { 126051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $cxx = $2; 1261386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 126251365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek 126351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $ENV{"CCC_CXX"} = $cxx; 1264386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek next; 1265386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek } 1266386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 12679cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek if ($arg eq "-v") { 12689cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek shift @ARGV; 12699cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $Verbose++; 12709cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek next; 12719cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek } 12729cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 12737f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek if ($arg eq "-V" or $arg eq "--view") { 12747f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek shift @ARGV; 12757f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek $ViewResults = 1; 12767f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek next; 12777f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek } 12787f8a32572e1ee7cf96c1a65bf0eddb0f2f9b3769Ted Kremenek 1279363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek if ($arg eq "--status-bugs") { 1280363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek shift @ARGV; 1281363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek $ExitStatusFoundBugs = 1; 1282363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek next; 1283363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek } 128407c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu 128507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu if ($arg eq "-store") { 128607c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu shift @ARGV; 1287be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $StoreModel = shift @ARGV; 1288be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek next; 1289be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek } 1290be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek 1291be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek if ($arg eq "-constraints") { 1292be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek shift @ARGV; 1293be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ConstraintsModel = shift @ARGV; 129407c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu next; 129507c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu } 1296363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 1297db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek if ($arg eq "-plist") { 1298db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek shift @ARGV; 1299db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $OutputFormat = "plist"; 1300db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek next; 1301db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 13027753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($arg eq "-plist-html") { 13037753b352366778d01c5cda4117356f181d3dd468Ted Kremenek shift @ARGV; 13047753b352366778d01c5cda4117356f181d3dd468Ted Kremenek $OutputFormat = "plist-html"; 13057753b352366778d01c5cda4117356f181d3dd468Ted Kremenek next; 13067753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1307e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek 1308e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek if ($arg eq "-no-failure-reports") { 1309e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek $ENV{"CCC_REPORT_FAILURES"} = 0; 1310e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek next; 1311e600bedcfea91622a0003fdb5f66c500b2f9f17dTed Kremenek } 13124f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-stats") { 13134f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 13144f2b10b24bab0049020d268382eda144e2aa064cTom Care $AnalyzerStats = 1; 13154f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 13164f2b10b24bab0049020d268382eda144e2aa064cTom Care } 13174f2b10b24bab0049020d268382eda144e2aa064cTom Care if ($arg eq "-maxloop") { 13184f2b10b24bab0049020d268382eda144e2aa064cTom Care shift @ARGV; 13194f2b10b24bab0049020d268382eda144e2aa064cTom Care $MaxLoop = shift @ARGV; 13204f2b10b24bab0049020d268382eda144e2aa064cTom Care next; 13214f2b10b24bab0049020d268382eda144e2aa064cTom Care } 132209fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-enable-checker") { 132309fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 132409fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-checker", shift @ARGV; 132509fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 132609fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 132709fbf297da918760ce33302a3f709a77f43af265Ted Kremenek if ($arg eq "-disable-checker") { 132809fbf297da918760ce33302a3f709a77f43af265Ted Kremenek shift @ARGV; 132909fbf297da918760ce33302a3f709a77f43af265Ted Kremenek push @AnalysesToRun, "-analyzer-disable-checker", shift @ARGV; 133009fbf297da918760ce33302a3f709a77f43af265Ted Kremenek next; 133109fbf297da918760ce33302a3f709a77f43af265Ted Kremenek } 13327753b352366778d01c5cda4117356f181d3dd468Ted Kremenek 133323cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 13340062ad4f47d152def1f720878aaf5904b22aefbfTed Kremenek 13359cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek last; 13369cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 13379cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1338ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekif (!@ARGV and $displayHelp == 0) { 133923cfca3760c482f8543daab62051f5eaa1f98fb4Ted Kremenek Diag("No build command specified.\n\n"); 1340ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek $displayHelp = 1; 1341ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek} 1342ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek 1343ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenekif ($displayHelp) { 13449cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek DisplayHelp(); 1345a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop exit 1; 13469cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 13479cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1348ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine where results go. 13497cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 13507cba11262458df05951432b54997eb40a35dbf9eTed Kremenek$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 13517cba11262458df05951432b54997eb40a35dbf9eTed Kremenek unless (defined($HtmlTitle)); 1352386c69316668b9ea8c2591af56f994be16e3ff62Ted Kremenek 13539cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Determine the output directory for the HTML reports. 1354684bb097fbb51fe4e8852925d93d6fd2adec31c7Ted Kremenekmy $BaseDir = $HtmlDir; 1355a0e226621b424e9fcaf6bf145c6ab439fbb7b8e6Sam Bishop$HtmlDir = GetHTMLRunDir($HtmlDir); 13569cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 1357ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Determine the location of ccc-analyzer. 135851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $AbsRealBin = Cwd::realpath($RealBin); 135951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; 136051365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekmy $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; 136151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek 1362ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenekif (!defined $Cmd || ! -x $Cmd) { 136351365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $Cmd = "$AbsRealBin/ccc-analyzer"; 13646b89636db873142f562cf576df9bc195c5b8674bTed Kremenek DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd); 1365ce87b929703cac0b3f236b0b0d1c7b78d8af38f2Ted Kremenek} 136651365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenekif (!defined $CmdCXX || ! -x $CmdCXX) { 136751365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek $CmdCXX = "$AbsRealBin/c++-analyzer"; 136851365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX); 136951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek} 1370f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek 1371fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenekif (!defined $ClangSB || ! -x $ClangSB) { 1372fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek Diag("'clang' executable not found in '$RealBin/bin'.\n"); 13736492200c313937adf8c9dd206790933a228e3ef3Ted Kremenek Diag("Using 'clang' from path: $Clang\n"); 1374fd9df0eddd7d2b190f740f33a3d08f611c0be3f0Ted Kremenek} 13750b6c15349121a030ce914e5192bb3621c79a0656Ted Kremenek 1376ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted Kremenek# Set the appropriate environment variables. 1377ba90e8a12e6e8889035ed57fb49b40b9cd4ef990Ted KremenekSetHtmlEnv(\@ARGV, $HtmlDir); 13784f4b17da43d3be87a248e1e10bf0b7d8b5891efdTed Kremenek$ENV{'CC'} = $Cmd; 137951365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek$ENV{'CXX'} = $CmdCXX; 1380f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek$ENV{'CLANG'} = $Clang; 138151365b5f74977c13c4902991c076dff8fddc96b7Ted Kremenek$ENV{'CLANG_CXX'} = $ClangCXX; 13829cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenekif ($Verbose >= 2) { 13839cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 13849cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek} 1385a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenekif ($Verbose >= 3) { 1386a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek $ENV{'CCC_ANALYZER_LOG'} = 1; 1387a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek} 1388e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenekif ($AnalyzeHeaders) { 1389e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek push @AnalysesToRun,"-analyzer-opt-analyze-headers"; 1390e15fa2736413224dfdaf457e0fd7204d7c056b3dTed Kremenek} 13914f2b10b24bab0049020d268382eda144e2aa064cTom Careif ($AnalyzerStats) { 1392251c27b6299a841d97901a014d02e4a62f1b6e8eTed Kremenek push @AnalysesToRun, '-analyzer-checker', 'debug.Stats'; 13934f2b10b24bab0049020d268382eda144e2aa064cTom Care} 13944f2b10b24bab0049020d268382eda144e2aa064cTom Careif ($MaxLoop > 0) { 13954f2b10b24bab0049020d268382eda144e2aa064cTom Care push @AnalysesToRun, '-analyzer-max-loop ' . $MaxLoop; 13964f2b10b24bab0049020d268382eda144e2aa064cTom Care} 13974f2b10b24bab0049020d268382eda144e2aa064cTom Care 13989012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun; 13999012599f4ccfe066c093cf0885fd3994bdc256d1Ted Kremenek 14003cab2b1c3798f2a6aa3526875801a02aebf6fc1dZhongxing Xuif (defined $StoreModel) { 140107c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; 140207c3767be59472e19183c7b51fae76481465cb51Zhongxing Xu} 1403be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenekif (defined $ConstraintsModel) { 1404be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; 1405be1fe1eb12a1cb91c8e3a9fcc2db4dfe989def6cTed Kremenek} 1406db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenekif (defined $OutputFormat) { 1407db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; 1408db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek} 1409db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 14109cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek# Run the build. 1411524c308506e77e173092e87a0724a27817311428Ted Kremenekmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX); 14129cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5Ted Kremenek 14137753b352366778d01c5cda4117356f181d3dd468Ted Kremenekif (defined $OutputFormat) { 14141182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar if ($OutputFormat =~ /plist/) { 14151182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis run complete.\n"; 14161182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; 14171182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar } 14181182502c78ad61693995f5b3ff516fdf983b5cd7Daniel Dunbar elsif ($OutputFormat =~ /html/) { 14197753b352366778d01c5cda4117356f181d3dd468Ted Kremenek # Postprocess the HTML directory. 14204f2b10b24bab0049020d268382eda144e2aa064cTom Care my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats); 14217753b352366778d01c5cda4117356f181d3dd468Ted Kremenek 14227753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ViewResults and -r "$HtmlDir/index.html") { 14237753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Analysis run complete.\n"; 14247753b352366778d01c5cda4117356f181d3dd468Ted Kremenek Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 14257753b352366778d01c5cda4117356f181d3dd468Ted Kremenek my $ScanView = Cwd::realpath("$RealBin/scan-view"); 14267753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if (! -x $ScanView) { $ScanView = "scan-view"; } 14277753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exec $ScanView, "$HtmlDir"; 14287753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1429db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek 14307753b352366778d01c5cda4117356f181d3dd468Ted Kremenek if ($ExitStatusFoundBugs) { 14317753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 1 if ($NumBugs > 0); 14327753b352366778d01c5cda4117356f181d3dd468Ted Kremenek exit 0; 14337753b352366778d01c5cda4117356f181d3dd468Ted Kremenek } 1434db4f5f26182c522e659af655e2582cc5ea35a971Ted Kremenek } 1435363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek} 1436363dc3f40ffc4cc71fb3a04087cf627aeb6918d4Ted Kremenek 14375656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenekexit $ExitStatus; 14385656a985574c00aa9b77fec51d41023e27e7a81fTed Kremenek 1439