1e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh#!/usr/bin/env perl 2e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# 3e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# The LLVM Compiler Infrastructure 4e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# 5e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# This file is distributed under the University of Illinois Open Source 6e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# License. See LICENSE.TXT for details. 7e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# 8e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##===----------------------------------------------------------------------===## 9e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# 10e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# A script designed to wrap a build so that all calls to gcc are intercepted 11e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# and piped to the static analyzer. 12e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# 13e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##===----------------------------------------------------------------------===## 14e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 15e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse strict; 16e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse warnings; 17e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse FindBin qw($RealBin); 18e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse Digest::MD5; 19e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse File::Basename; 20e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse File::Find; 21e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse Term::ANSIColor; 22e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse Term::ANSIColor qw(:constants); 23e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse Cwd qw/ getcwd abs_path /; 24e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehuse Sys::Hostname; 25e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 26e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Verbose = 0; # Verbose output from this script. 27e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Prog = "scan-build"; 28e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $BuildName; 29e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $BuildDate; 30e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Top; 31e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 32e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $TERM = $ENV{'TERM'}; 33e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT 34e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh and defined $ENV{'SCAN_BUILD_COLOR'}); 35e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 36e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Portability: getpwuid is not implemented for Win32 (see Perl language 37e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# reference, perlport), use getlogin instead. 38e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown'); 39e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $HostName = HtmlEscape(hostname() || 'unknown'); 40e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CurrentDir = HtmlEscape(getcwd()); 41e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CurrentDirSuffix = basename($CurrentDir); 42e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 43e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy @PluginsToLoad; 44e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CmdArgs; 45e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 46e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $HtmlTitle; 47e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 48e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Date = localtime(); 49e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 50e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 51e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Diagnostics 52e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 53e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 54e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub Diag { 55e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($UseColor) { 56e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print BOLD, MAGENTA "$Prog: @_"; 57e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print RESET; 58e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 59e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 60e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print "$Prog: @_"; 61e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 62e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 63e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 64e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub ErrorDiag { 65e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($UseColor) { 66e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR BOLD, RED "$Prog: "; 67e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR RESET, RED @_; 68e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR RESET; 69e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } else { 70e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR "$Prog: @_"; 71e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 72e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 73e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 74e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub DiagCrashes { 75e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift; 76e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag ("The analyzer encountered problems on some source files.\n"); 77e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 78e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag ("Please consider submitting a bug report using these files:\n"); 79e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") 80e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 81e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 82e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub DieDiag { 83e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($UseColor) { 84e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR BOLD, RED "$Prog: "; 85e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR RESET, RED @_; 86e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR RESET; 87e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 88e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 89e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print STDERR "$Prog: ", @_; 90e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 91e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exit 1; 92e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 93e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 94e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 95e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Print default checker names 96e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 97e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 98e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (grep /^--help-checkers$/, @ARGV) { 99e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @options = qx($0 -h); 100e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach (@options) { 101e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next unless /^ \+/; 102e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh s/^\s*//; 103e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my ($sign, $name, @text) = split ' ', $_; 104e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print $name, $/ if $sign eq '+'; 105e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 106e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exit 0; 107e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 108e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 109e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 110e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Declaration of Clang options. Populated later. 111e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 112e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 113e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Clang; 114e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ClangSB; 115e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ClangCXX; 116e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ClangVersion; 117e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 118e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 119e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 120e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 121e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 122e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub GetHTMLRunDir { 123e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "Not enough arguments." if (@_ == 0); 124e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift @_; 125e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $TmpMode = 0; 126e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Dir) { 127e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp"; 128e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $TmpMode = 1; 129e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 130e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 131e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Chop off any trailing '/' characters. 132e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while ($Dir =~ /\/$/) { chop $Dir; } 133e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 134e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Get current date and time. 135e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @CurrentTime = localtime(); 136e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $year = $CurrentTime[5] + 1900; 137e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $day = $CurrentTime[3]; 138e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $month = $CurrentTime[4] + 1; 139e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); 140e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 141e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Determine the run number. 142e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $RunNumber; 143e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 144e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (-d $Dir) { 145e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -r $Dir) { 146e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("directory '$Dir' exists but is not readable.\n"); 147e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 148e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Iterate over all files in the specified directory. 149e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $max = 0; 150e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh opendir(DIR, $Dir); 151e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 152e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh closedir(DIR); 153e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 154e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $f (@FILES) { 155e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Strip the prefix '$Prog-' if we are dumping files to /tmp. 156e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($TmpMode) { 157e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if (!($f =~ /^$Prog-(.+)/)); 158e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $f = $1; 159e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 160e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 161e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @x = split/-/, $f; 162e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if (scalar(@x) != 4); 163e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if ($x[0] != $year); 164e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if ($x[1] != $month); 165e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if ($x[2] != $day); 166e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 167e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($x[3] > $max) { 168e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $max = $x[3]; 169e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 170e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 171e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 172e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $RunNumber = $max + 1; 173e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 174e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 175e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 176e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (-x $Dir) { 177e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'$Dir' exists but is not a directory.\n"); 178e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 179e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 180e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($TmpMode) { 181e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 182e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 183e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 184e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # $Dir does not exist. It will be automatically created by the 185e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # clang driver. Set the run number to 1. 186e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 187e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $RunNumber = 1; 188e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 189e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 190e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "RunNumber must be defined!" if (!defined $RunNumber); 191e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 192e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Append the run number. 193e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $NewDir; 194e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($TmpMode) { 195e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 196e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 197e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 198e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $NewDir = "$Dir/$DateString-$RunNumber"; 199e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 200e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system 'mkdir','-p',$NewDir; 201e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $NewDir; 202e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 203e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 204e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub SetHtmlEnv { 205e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 206e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "Wrong number of arguments." if (scalar(@_) != 2); 207e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 208e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Args = shift; 209e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift; 210e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 211e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "No build command." if (scalar(@$Args) == 0); 212e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 213e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Cmd = $$Args[0]; 214e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 215e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { 216e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return; 217e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 218e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 219e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Verbose) { 220e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("Emitting reports for this run to '$Dir'.\n"); 221e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 222e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 223e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{'CCC_ANALYZER_HTML'} = $Dir; 224e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 225e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 226e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 227e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ComputeDigest - Compute a digest of the specified file. 228e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 229e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 230e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub ComputeDigest { 231e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $FName = shift; 232e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 233e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 234e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Use Digest::MD5. We don't have to be cryptographically secure. We're 235e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # just looking for duplicate files that come from a non-malicious source. 236e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # We use Digest::MD5 because it is a standard Perl module that should 237e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # come bundled on most systems. 238e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 239e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh binmode FILE; 240e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 241e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(FILE); 242e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 243e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Return the digest. 244e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $Result; 245e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 246e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 247e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 248e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# UpdatePrefix - Compute the common prefix of files. 249e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 250e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 251e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Prefix; 252e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 253e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub UpdatePrefix { 254e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = shift; 255e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $y = basename($x); 256e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $x =~ s/\Q$y\E$//; 257e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 258e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Prefix) { 259e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Prefix = $x; 260e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return; 261e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 262e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 263e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chop $Prefix while (!($x =~ /^\Q$Prefix/)); 264e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 265e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 266e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub GetPrefix { 267e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $Prefix; 268e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 269e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 270e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 271e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# UpdateInFilePath - Update the path in the report file. 272e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 273e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 274e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub UpdateInFilePath { 275e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $fname = shift; 276e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $regex = shift; 277e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $newtext = shift; 278e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 279e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open (RIN, $fname) or die "cannot open $fname"; 280e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 281e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 282e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while (<RIN>) { 283e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh s/$regex/$newtext/; 284e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print ROUT $_; 285e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 286e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 287e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close (ROUT); 288e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close (RIN); 289e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system("mv", "$fname.tmp", $fname); 290e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 291e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 292e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 293e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# AddStatLine - Decode and insert a statistics line into the database. 294e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 295e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 296e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub AddStatLine { 297e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Line = shift; 298e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Stats = shift; 299e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $File = shift; 300e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 301e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print $Line . "\n"; 302e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 303e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Regex = qr/(.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable 304e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: 305e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh \ (yes|no)/x; 306e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 307e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Line !~ $Regex) { 308e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return; 309e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 310e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 311e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Create a hash of the interesting fields 312e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Row = { 313e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Filename => $File, 314e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Function => $1, 315e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Total => $2, 316e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Unreachable => $3, 317e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Aborted => $4, 318e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Empty => $5 319e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh }; 320e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 321e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Add them to the stats array 322e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @$Stats, $Row; 323e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 324e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 325e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 326e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ScanFile - Scan a report file for various identifying attributes. 327e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 328e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 329e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Sometimes a source file is scanned more than once, and thus produces 330e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# multiple error reports. We use a cache to solve this problem. 331e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 332e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy %AlreadyScanned; 333e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 334e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub ScanFile { 335e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 336e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Index = shift; 337e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift; 338e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $FName = shift; 339e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Stats = shift; 340e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 341e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Compute a digest for the report file. Determine if we have already 342e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # scanned a file that looks just like it. 343e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 344e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $digest = ComputeDigest("$Dir/$FName"); 345e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 346e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $AlreadyScanned{$digest}) { 347e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Redundant file. Remove it. 348e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system ("rm", "-f", "$Dir/$FName"); 349e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return; 350e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 351e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 352e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $AlreadyScanned{$digest} = 1; 353e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 354e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # At this point the report file is not world readable. Make it happen. 355e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system ("chmod", "644", "$Dir/$FName"); 356e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 357e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Scan the report file for tags. 358e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 359e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 360e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugType = ""; 361e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugFile = ""; 362e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugCategory = ""; 363e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugDescription = ""; 364e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugPathLength = 1; 365e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BugLine = 0; 366e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 367e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while (<IN>) { 368e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last if (/<!-- BUGMETAEND -->/); 369e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 370e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (/<!-- BUGTYPE (.*) -->$/) { 371e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugType = $1; 372e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 373e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif (/<!-- BUGFILE (.*) -->$/) { 374e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugFile = abs_path($1); 375e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh UpdatePrefix($BugFile); 376e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 377e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 378e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugPathLength = $1; 379e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 380e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif (/<!-- BUGLINE (.*) -->$/) { 381e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugLine = $1; 382e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 383e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif (/<!-- BUGCATEGORY (.*) -->$/) { 384e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugCategory = $1; 385e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 386e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif (/<!-- BUGDESC (.*) -->$/) { 387e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugDescription = $1; 388e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 389e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 390e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 391e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(IN); 392e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 393e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $BugCategory) { 394e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugCategory = "Other"; 395e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 396e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 397e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Don't add internal statistics to the bug reports 398e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($BugCategory =~ /statistics/i) { 399e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddStatLine($BugDescription, $Stats, $BugFile); 400e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return; 401e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 402e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 403e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, 404e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BugPathLength ]; 405e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 406e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 407e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 408e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# CopyFiles - Copy resource files to target directory. 409e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 410e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 411e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub CopyFiles { 412e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 413e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift; 414e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 415e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $JS = Cwd::realpath("$RealBin/sorttable.js"); 416e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 417e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Cannot find 'sorttable.js'.\n") 418e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -r $JS); 419e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 420e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system ("cp", $JS, "$Dir"); 421e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 422e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 423e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -r "$Dir/sorttable.js"); 424e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 425e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CSS = Cwd::realpath("$RealBin/scanview.css"); 426e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 427e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Cannot find 'scanview.css'.\n") 428e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -r $CSS); 429e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 430e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system ("cp", $CSS, "$Dir"); 431e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 432e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 433e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -r $CSS); 434e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 435e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 436e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 437e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# CalcStats - Calculates visitation statistics and returns the string. 438e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 439e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 440e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub CalcStats { 441e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Stats = shift; 442e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 443e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $TotalBlocks = 0; 444e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $UnreachedBlocks = 0; 445e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $TotalFunctions = scalar(@$Stats); 446e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BlockAborted = 0; 447e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $WorkListAborted = 0; 448e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Aborted = 0; 449e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 450e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Calculate the unique files 451e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $FilesHash = {}; 452e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 453e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $Row (@$Stats) { 454e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $FilesHash->{$Row->{Filename}} = 1; 455e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $TotalBlocks += $Row->{Total}; 456e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $UnreachedBlocks += $Row->{Unreachable}; 457e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $BlockAborted++ if $Row->{Aborted} eq 'yes'; 458e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $WorkListAborted++ if $Row->{Empty} eq 'no'; 459e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; 460e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 461e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 462e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $TotalFiles = scalar(keys(%$FilesHash)); 463e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 464e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Calculations 465e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); 466e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions 467e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 100); 468e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / 469e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $TotalFunctions * 100); 470e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks 471e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh * 100); 472e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 473e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" 474e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh . " in $TotalFiles files\n" 475e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh . "$Aborted functions aborted early ($PercentAborted%)\n" 476e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" 477e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" 478e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; 479e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 480e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $StatsString; 481e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 482e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 483e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 484e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Postprocess - Postprocess the results of an analysis scan. 485e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 486e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 487e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy @filesFound; 488e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $baseDir; 489e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub FileWanted { 490e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $baseDirRegEx = quotemeta $baseDir; 491e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $file = $File::Find::name; 492e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($file =~ /report-.*\.html$/) { 493e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $relative_file = $file; 494e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $relative_file =~ s/$baseDirRegEx//g; 495e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @filesFound, $relative_file; 496e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 497e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 498e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 499e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub Postprocess { 500e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 501e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Dir = shift; 502e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $BaseDir = shift; 503e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $AnalyzerStats = shift; 504e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $KeepEmpty = shift; 505e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 506e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "No directory specified." if (!defined $Dir); 507e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 508e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -d $Dir) { 509e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("No bugs found.\n"); 510e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return 0; 511e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 512e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 513e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $baseDir = $Dir . "/"; 514e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh find({ wanted => \&FileWanted, follow => 0}, $Dir); 515e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 516e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") { 517e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! $KeepEmpty) { 518e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("Removing directory '$Dir' because it contains no reports.\n"); 519e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system ("rm", "-fR", $Dir); 520e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 521e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("No bugs found.\n"); 522e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return 0; 523e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 524e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 525e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Scan each report file and build an index. 526e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @Index; 527e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @Stats; 528e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); } 529e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 530e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Scan the failures directory and use the information in the .info files 531e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # to update the common prefix directory. 532e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @failures; 533e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @attributes_ignored; 534e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (-d "$Dir/failures") { 535e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh opendir(DIR, "$Dir/failures"); 536e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 537e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh closedir(DIR); 538e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh opendir(DIR, "$Dir/failures"); 539e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 540e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh closedir(DIR); 541e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $file (@failures) { 542e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 543e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Path = <IN>; 544e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $Path) { UpdatePrefix($Path); } 545e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close IN; 546e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 547e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 548e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 549e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Generate an index.html file. 550e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $FName = "$Dir/index.html"; 551e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 552e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 553e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print out the header. 554e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 555e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint OUT <<ENDTEXT; 556e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<html> 557e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<head> 558e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<title>${HtmlTitle}</title> 559e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<link type="text/css" rel="stylesheet" href="scanview.css"/> 560e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<script src="sorttable.js"></script> 561e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<script language='javascript' type="text/javascript"> 562e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehfunction SetDisplay(RowClass, DisplayVal) 563e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh{ 564e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh var Rows = document.getElementsByTagName("tr"); 565e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for ( var i = 0 ; i < Rows.length; ++i ) { 566e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (Rows[i].className == RowClass) { 567e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Rows[i].style.display = DisplayVal; 568e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 569e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 570e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 571e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 572e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 573e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh var Inputs = document.getElementsByTagName("input"); 574e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for ( var i = 0 ; i < Inputs.length; ++i ) { 575e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (Inputs[i].type == "checkbox") { 576e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if(Inputs[i] != SummaryCheckButton) { 577e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Inputs[i].checked = SummaryCheckButton.checked; 578e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Inputs[i].onclick(); 579e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 580e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 581e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 582e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 583e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 584e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehfunction returnObjById( id ) { 585e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (document.getElementById) 586e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh var returnVar = document.getElementById(id); 587e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else if (document.all) 588e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh var returnVar = document.all[id]; 589e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else if (document.layers) 590e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh var returnVar = document.layers[id]; 591e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return returnVar; 592e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 593e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 594e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehvar NumUnchecked = 0; 595e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 596e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehfunction ToggleDisplay(CheckButton, ClassName) { 597e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (CheckButton.checked) { 598e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh SetDisplay(ClassName, ""); 599e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (--NumUnchecked == 0) { 600e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh returnObjById("AllBugsCheck").checked = true; 601e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 602e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 603e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 604e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh SetDisplay(ClassName, "none"); 605e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh NumUnchecked++; 606e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh returnObjById("AllBugsCheck").checked = false; 607e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 608e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 609e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh</script> 610e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<!-- SUMMARYENDHEAD --> 611e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh</head> 612e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<body> 613e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<h1>${HtmlTitle}</h1> 614e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 615e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<table> 616e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 617e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 618e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 619e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tr><th>Clang Version:</th><td>${ClangVersion}</td></tr> 620e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tr><th>Date:</th><td>${Date}</td></tr> 621e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 622e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 623e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 624e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined($BuildName) && defined($BuildDate)); 625e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 626e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint OUT <<ENDTEXT; 627e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh</table> 628e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 629e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 630e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (scalar(@filesFound)) { 631e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print out the summary table. 632e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my %Totals; 633e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 634e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for my $row ( @Index ) { 635e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $bug_type = ($row->[2]); 636e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $bug_category = ($row->[1]); 637e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $key = "$bug_category:$bug_type"; 638e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 639e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 640e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { $Totals{$key}->[0]++; } 641e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 642e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 643e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<h2>Bug Summary</h2>"; 644e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 645e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $BuildName) { 646e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 647e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 648e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 649e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $TotalBugs = scalar(@Index); 650e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint OUT <<ENDTEXT; 651e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<table> 652e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 653e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<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> 654e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 655e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 656e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $last_category; 657e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 658e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for my $key ( 659e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh sort { 660e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = $Totals{$a}; 661e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $y = $Totals{$b}; 662e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $res = $x->[1] cmp $y->[1]; 663e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $res = $x->[2] cmp $y->[2] if ($res == 0); 664e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $res 665e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } keys %Totals ) 666e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh { 667e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $val = $Totals{$key}; 668e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $category = $val->[1]; 669e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $last_category or $last_category ne $category) { 670e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $last_category = $category; 671e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 672e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 673e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = lc $key; 674e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $x =~ s/[ ,'":\/()]+/_/g; 675e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<tr><td class=\"SUMM_DESC\">"; 676e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $val->[2]; 677e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</td><td class=\"Q\">"; 678e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $val->[0]; 679e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 680e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 681e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 682e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print out the table of errors. 683e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 684e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint OUT <<ENDTEXT; 685e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh</table> 686e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<h2>Reports</h2> 687e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 688e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<table class="sortable" style="table-layout:automatic"> 689e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<thead><tr> 690e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td>Bug Group</td> 691e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 692e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td>File</td> 693e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td class="Q">Line</td> 694e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td class="Q">Path Length</td> 695e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <td class="sorttable_nosort"></td> 696e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh <!-- REPORTBUGCOL --> 697e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh</tr></thead> 698e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh<tbody> 699e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 700e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 701e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $prefix = GetPrefix(); 702e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $regex; 703e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $InFileRegex; 704e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $InFilePrefix = "File:</td><td>"; 705e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 706e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $prefix) { 707e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $regex = qr/^\Q$prefix\E/is; 708e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 709e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 710e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 711e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 712e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = "$row->[1]:$row->[2]"; 713e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $x = lc $x; 714e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $x =~ s/[ ,'":\/()]+/_/g; 715e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 716e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ReportFile = $row->[0]; 717e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 718e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<tr class=\"bt_$x\">"; 719e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td class=\"DESC\">"; 720e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $row->[1]; 721e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</td>"; 722e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td class=\"DESC\">"; 723e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $row->[2]; 724e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</td>"; 725e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 726e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Update the file prefix. 727e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $fname = $row->[3]; 728e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 729e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $regex) { 730e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $fname =~ s/$regex//; 731e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 732e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 733e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 734e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td>"; 735e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my @fname = split /\//,$fname; 736e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($#fname > 0) { 737e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while ($#fname >= 0) { 738e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = shift @fname; 739e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $x; 740e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($#fname >= 0) { 741e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<span class=\"W\"> </span>/"; 742e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 743e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 744e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 745e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 746e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT $fname; 747e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 748e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</td>"; 749e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 750e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print out the quantities. 751e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for my $j ( 4 .. 5 ) { 752e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td class=\"Q\">$row->[$j]</td>"; 753e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 754e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 755e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print the rest of the columns. 756e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for (my $j = 6; $j <= $#{$row}; ++$j) { 757e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td>$row->[$j]</td>" 758e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 759e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 760e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Emit the "View" link. 761e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 762e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 763e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Emit REPORTBUG markers. 764e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 765e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 766e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # End the row. 767e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</tr>\n"; 768e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 769e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 770e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</tbody>\n</table>\n\n"; 771e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 772e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 773e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (scalar (@failures) || scalar(@attributes_ignored)) { 774e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<h2>Analyzer Failures</h2>\n"; 775e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 776e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (scalar @attributes_ignored) { 777e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 778e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<table>\n"; 779e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 780e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $file (sort @attributes_ignored) { 781e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 782e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $attribute = $1; 783e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Open the attribute file to get the first file that failed. 784e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if (!open (ATTR, "$Dir/failures/$file")); 785e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ppfile = <ATTR>; 786e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $ppfile; 787e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close ATTR; 788e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if (! -e "$Dir/failures/$ppfile"); 789e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Open the info file and get the name of the source file. 790e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open (INFO, "$Dir/failures/$ppfile.info.txt") or 791e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 792e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $srcfile = <INFO>; 793e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $srcfile; 794e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close (INFO); 795e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print the information in the table. 796e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $prefix = GetPrefix(); 797e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 798e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 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"; 799e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ppfile_clang = $ppfile; 800e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 801e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 802e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 803e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</table>\n"; 804e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 805e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 806e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (scalar @failures) { 807e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 808e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<table>\n"; 809e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 810e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $file (sort @failures) { 811e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $file =~ /(.+).info.txt$/; 812e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Get the preprocessed file. 813e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ppfile = $1; 814e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Open the info file and get the name of the source file. 815e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open (INFO, "$Dir/failures/$file") or 816e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "Cannot open $Dir/failures/$file\n"; 817e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $srcfile = <INFO>; 818e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $srcfile; 819e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $problem = <INFO>; 820e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $problem; 821e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close (INFO); 822e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print the information in the table. 823e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $prefix = GetPrefix(); 824e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 825e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 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"; 826e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ppfile_clang = $ppfile; 827e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 828e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 829e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 830e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</table>\n"; 831e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 832e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 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"; 833e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 834e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 835e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print OUT "</body></html>\n"; 836e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(OUT); 837e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh CopyFiles($Dir); 838e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 839e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Make sure $Dir and $BaseDir are world readable/executable. 840e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh system("chmod", "755", $Dir); 841e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $BaseDir) { system("chmod", "755", $BaseDir); } 842e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 843e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Print statistics 844e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print CalcStats(\@Stats) if $AnalyzerStats; 845e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 846e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Num = scalar(@Index); 847e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("$Num bugs found.\n"); 848e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Num > 0 && -r "$Dir/index.html") { 849e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag("Run '$Top/prebuilts/misc/linux-x86/analyzer/tools/scan-view/scan-view $Dir' to examine bug reports.\n"); 850e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 851e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 852e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 853e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 854e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $Num; 855e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 856e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 857e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 858e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# RunBuildCommand - Run the build command. 859e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 860e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 861e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub AddIfNotPresent { 862e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Args = shift; 863e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Arg = shift; 864e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $found = 0; 865e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 866e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $k (@$Args) { 867e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($k eq $Arg) { 868e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $found = 1; 869e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last; 870e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 871e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 872e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 873e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($found == 0) { 874e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @$Args, $Arg; 875e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 876e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 877e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 878e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub SetEnv { 879e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Options = shift @_; 880e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX', 881e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS') { 882e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "$opt is undefined\n" if (!defined $opt); 883e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{$opt} = $Options->{$opt}; 884e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 885e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $opt ('CCC_ANALYZER_STORE_MODEL', 886e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_PLUGINS', 887e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_INTERNAL_STATS', 888e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_OUTPUT_FORMAT') { 889e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $x = $Options->{$opt}; 890e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $x) { $ENV{$opt} = $x } 891e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 892e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Verbose = $Options->{'VERBOSE'}; 893e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Verbose >= 2) { 894e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 895e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 896e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Verbose >= 3) { 897e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{'CCC_ANALYZER_LOG'} = 1; 898e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 899e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 900e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 901e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# The flag corresponding to the --override-compiler command line option. 902e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $OverrideCompiler = 0; 903e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 904e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub RunXcodebuild { 905e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Args = shift; 906e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $IgnoreErrors = shift; 907e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CCAnalyzer = shift; 908e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CXXAnalyzer = shift; 909e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Options = shift; 910e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 911e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($IgnoreErrors) { 912e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 913e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 914e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 915e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Detect the version of Xcode. If Xcode 4.6 or higher, use new 916e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # in situ support for analyzer interposition without needed to override 917e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # the compiler. 918e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(DETECT_XCODE, "-|", $Args->[0], "-version") or 919e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh die "error: cannot detect version of xcodebuild\n"; 920e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 921e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $oldBehavior = 1; 922e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 923e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while(<DETECT_XCODE>) { 924e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (/^Xcode (.+)$/) { 925e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ver = $1; 926e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($ver =~ /^([0-9]+[.][0-9]+)[^0-9]?/) { 927e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($1 >= 4.6) { 928e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $oldBehavior = 0; 929e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last; 930e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 931e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 932e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 933e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 934e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(DETECT_XCODE); 935e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 936e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # If --override-compiler is explicitely requested, resort to the old 937e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # behavior regardless of Xcode version. 938e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($OverrideCompiler) { 939e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $oldBehavior = 1; 940e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 941e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 942e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($oldBehavior == 0) { 943e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $OutputDir = $Options->{"OUTPUT_DIR"}; 944e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CLANG = $Options->{"CLANG"}; 945e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $OtherFlags = $Options->{"CCC_ANALYZER_ANALYSIS"}; 946e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @$Args, 947e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh "RUN_CLANG_STATIC_ANALYZER=YES", 948e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh "CLANG_ANALYZER_OUTPUT=plist-html", 949e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh "CLANG_ANALYZER_EXEC=$CLANG", 950e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh "CLANG_ANALYZER_OUTPUT_DIR=$OutputDir", 951e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh "CLANG_ANALYZER_OTHER_FLAGS=$OtherFlags"; 952e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 953e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return (system(@$Args) >> 8); 954e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 955e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 956e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Default to old behavior where we insert a bogus compiler. 957e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh SetEnv($Options); 958e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 959e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Check if using iPhone SDK 3.0 (simulator). If so the compiler being 960e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # used should be gcc-4.2. 961e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $ENV{"CCC_CC"}) { 962e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh for (my $i = 0 ; $i < scalar(@$Args); ++$i) { 963e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { 964e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (@$Args[$i+1] =~ /^iphonesimulator3/) { 965e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CC"} = "gcc-4.2"; 966e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CXX"} = "g++-4.2"; 967e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 968e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 969e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 970e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 971e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 972e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Disable PCH files until clang supports them. 973e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 974e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 975e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 976e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 977e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # (via c++-analyzer) when linking such files. 978e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; 979e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 980e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return (system(@$Args) >> 8); 981e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 982e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 983e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub RunBuildCommand { 984e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Args = shift; 985e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $IgnoreErrors = shift; 986e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Cmd = $Args->[0]; 987e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CCAnalyzer = shift; 988e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $CXXAnalyzer = shift; 989e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $Options = shift; 990e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 991e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Cmd =~ /\bxcodebuild$/) { 992e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return RunXcodebuild($Args, $IgnoreErrors, $CCAnalyzer, $CXXAnalyzer, $Options); 993e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 994e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 995e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Setup the environment. 996e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh SetEnv($Options); 997e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 998e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 999e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?cc[^\/]*$)/ or 1000e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 1001e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?clang$)/ or 1002e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 1003e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1004e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 1005e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CC"} = $1; 1006e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1007e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1008e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @$Args; 1009e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh unshift @$Args, $CCAnalyzer; 1010e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1011e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 1012e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or 1013e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or 1014e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?clang\+\+$)/ or 1015e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { 1016e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { 1017e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CXX"} = $1; 1018e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1019e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @$Args; 1020e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh unshift @$Args, $CXXAnalyzer; 1021e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1022e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh elsif ($Cmd eq "make" or $Cmd eq "gmake") { 1023e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args, "CC=$CCAnalyzer"); 1024e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); 1025e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($IgnoreErrors) { 1026e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args,"-k"); 1027e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh AddIfNotPresent($Args,"-i"); 1028e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1029e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1030e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1031e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return (system(@$Args) >> 8); 1032e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1033e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1034e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1035e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# DisplayHelp - Utility function to display all help options. 1036e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1037e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1038e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub DisplayHelp { 1039e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1040e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint <<ENDTEXT; 1041e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehUSAGE: $Prog [options] <build command> [build options] 1042e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1043e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 1044e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1045e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (defined $BuildName) { 1046e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 1047e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1048e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1049e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint <<ENDTEXT; 1050e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehOPTIONS: 1051e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1052e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -analyze-headers 1053e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1054e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Also analyze functions in #included files. By default, such functions 1055e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh are skipped unless they are called by functions within the main source file. 1056e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1057e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -o <output location> 1058e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1059e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Specifies the output directory for analyzer reports. Subdirectories will be 1060e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh created as needed to represent separate "runs" of the analyzer. If this 1061e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X) 1062e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh to store the reports. 1063e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1064e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -h 1065e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --help 1066e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1067e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Display this message. 1068e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1069e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -k 1070e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --keep-going 1071e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1072e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Add a "keep on going" option to the specified build command. This option 1073e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh currently supports make and xcodebuild. This is a convenience option; one 1074e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh can specify this behavior directly using build options. 1075e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1076e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --html-title [title] 1077e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --html-title=[title] 1078e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1079e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Specify the title used on generated HTML pages. If not specified, a default 1080e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh title will be used. 1081e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1082e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -plist 1083e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1084e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh By default the output of scan-build is a set of HTML files. This option 1085e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh outputs the results as a set of .plist files. 1086e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1087e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -plist-html 1088e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1089e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh By default the output of scan-build is a set of HTML files. This option 1090e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh outputs the results as a set of HTML and .plist files. 1091e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1092e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --status-bugs 1093e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1094e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh By default, the exit status of scan-build is the same as the executed build 1095e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh command. Specifying this option causes the exit status of scan-build to be 1 1096e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if it found potential bugs and 0 otherwise. 1097e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1098e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-cc [compiler path] 1099e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-cc=[compiler path] 1100e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1101e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh scan-build analyzes a project by interposing a "fake compiler", which 1102e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh executes a real compiler for compilation and the static analyzer for analysis. 1103e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Because of the current implementation of interposition, scan-build does not 1104e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh know what compiler your project normally uses. Instead, it simply overrides 1105e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh the CC environment variable, and guesses your default compiler. 1106e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1107e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh In the future, this interposition mechanism to be improved, but if you need 1108e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh scan-build to use a specific compiler for *compilation* then you can use 1109e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh this option to specify a path to that compiler. 1110e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1111e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-c++ [compiler path] 1112e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-c++=[compiler path] 1113e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1114e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh This is the same as "-use-cc" but for C++ code. 1115e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1116e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -v 1117e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1118e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Enable verbose output from scan-build. A second and third '-v' increases 1119e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh verbosity. 1120e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1121e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -V 1122e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --view 1123e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1124e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh View analysis results in a web browser when the build completes. 1125e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1126e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehADVANCED OPTIONS: 1127e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1128e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -no-failure-reports 1129e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1130e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Do not create a 'failures' subdirectory that includes analyzer crash reports 1131e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh and preprocessed source files. 1132e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1133e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -stats 1134e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1135e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Generates visitation statistics for the project being analyzed. 1136e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1137e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -maxloop <loop count> 1138e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1139e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Specifiy the number of times a block can be visited before giving up. 1140e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Default is 4. Increase for more comprehensive coverage at a cost of speed. 1141e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1142e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -internal-stats 1143e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1144e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Generate internal analyzer statistics. 1145e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1146e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-analyzer [Xcode|path to clang] 1147e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --use-analyzer=[Xcode|path to clang] 1148e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1149e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh scan-build uses the 'clang' executable relative to itself for static 1150e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh analysis. One can override this behavior with this option by using the 1151e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'clang' packaged with Xcode (on OS X) or from the PATH. 1152e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1153e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --keep-empty 1154e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1155e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Don't remove the build results directory even if no issues were reported. 1156e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1157e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh --override-compiler 1158e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Always resort to the ccc-analyzer even when better interposition methods 1159e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh are available. 1160e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1161e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehCONTROLLING CHECKERS: 1162e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1163e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh A default group of checkers are always run unless explicitly disabled. 1164e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Checkers may be enabled/disabled using the following options: 1165e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1166e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -enable-checker [checker name] 1167e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -disable-checker [checker name] 1168e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1169e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehLOADING CHECKERS: 1170e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1171e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Loading external checkers using the clang plugin interface: 1172e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1173e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh -load-plugin [plugin library] 1174e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 1175e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1176e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Query clang for list of checkers that are enabled. 1177e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1178e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# create a list to load the plugins via the 'Xclang' command line 1179e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# argument 1180e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy @PluginLoadCommandline_xclang; 1181e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehforeach my $param ( @PluginsToLoad ) { 1182e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push ( @PluginLoadCommandline_xclang, "-Xclang" ); 1183e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push ( @PluginLoadCommandline_xclang, $param ); 1184e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1185e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy %EnabledCheckers; 1186e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehforeach my $lang ("c", "objective-c", "objective-c++", "c++") { 1187e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh pipe(FROM_CHILD, TO_PARENT); 1188e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $pid = fork(); 1189e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($pid == 0) { 1190e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close FROM_CHILD; 1191e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(STDOUT,">&", \*TO_PARENT); 1192e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(STDERR,">&", \*TO_PARENT); 1193e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###'); 1194e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1195e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(TO_PARENT); 1196e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while(<FROM_CHILD>) { 1197e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $val (split /\s+/) { 1198e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $val =~ s/\"//g; 1199e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($val =~ /-analyzer-checker\=([^\s]+)/) { 1200e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $EnabledCheckers{$1} = 1; 1201e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1202e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1203e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1204e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh waitpid($pid,0); 1205e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(FROM_CHILD); 1206e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1207e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1208e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Query clang for complete list of checkers. 1209e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $Clang && -x $Clang) { 1210e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh pipe(FROM_CHILD, TO_PARENT); 1211e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $pid = fork(); 1212e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($pid == 0) { 1213e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close FROM_CHILD; 1214e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(STDOUT,">&", \*TO_PARENT); 1215e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh open(STDERR,">&", \*TO_PARENT); 1216e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exec $Clang, ('-cc1', @PluginsToLoad , '-analyzer-checker-help'); 1217e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1218e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(TO_PARENT); 1219e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $foundCheckers = 0; 1220e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while(<FROM_CHILD>) { 1221e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (/CHECKERS:/) { 1222e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $foundCheckers = 1; 1223e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last; 1224e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1225e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1226e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!$foundCheckers) { 1227e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print " *** Could not query Clang for the list of available checkers."; 1228e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1229e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1230e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print("\nAVAILABLE CHECKERS:\n\n"); 1231e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $skip = 0; 1232e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh while(<FROM_CHILD>) { 1233e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (/experimental/) { 1234e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $skip = 1; 1235e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1236e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1237e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($skip) { 1238e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next if (!/^\s\s[^\s]/); 1239e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $skip = 0; 1240e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1241e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh s/^\s\s//; 1242e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (/^([^\s]+)/) { 1243e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Is the checker enabled? 1244e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $checker = $1; 1245e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $enabled = 0; 1246e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $aggregate = ""; 1247e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh foreach my $domain (split /\./, $checker) { 1248e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $aggregate .= $domain; 1249e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($EnabledCheckers{$aggregate}) { 1250e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $enabled =1; 1251e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last; 1252e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1253e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # append a dot, if an additional domain is added in the next iteration 1254e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $aggregate .= "."; 1255e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1256e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1257e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($enabled) { 1258e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print " + "; 1259e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1260e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1261e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print " "; 1262e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1263e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1264e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1265e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print " "; 1266e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1267e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print $_; 1268e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1269e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n" 1270e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1271e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh waitpid($pid,0); 1272e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh close(FROM_CHILD); 1273e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1274e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1275e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehprint <<ENDTEXT 1276e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1277e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehBUILD OPTIONS 1278e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1279e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh You can specify any build option acceptable to the build command. 1280e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1281e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehEXAMPLE 1282e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1283e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh scan-build -o /tmp/myhtmldir make -j4 1284e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1285e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehThe above example causes analysis reports to be deposited into a subdirectory 1286e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehof "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different 1287e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsubdirectory is created each time scan-build analyzes a project. The analyzer 1288e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehshould support most parallel builds, but not distributed builds. 1289e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1290e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehENDTEXT 1291e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1292e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1293e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1294e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# HtmlEscape - HTML entity encode characters that are special in HTML 1295e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1296e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1297e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub HtmlEscape { 1298e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # copy argument to new variable so we don't clobber the original 1299e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $arg = shift || ''; 1300e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $tmp = $arg; 1301e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $tmp =~ s/&/&/g; 1302e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $tmp =~ s/</</g; 1303e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $tmp =~ s/>/>/g; 1304e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $tmp; 1305e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1306e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1307e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1308e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# ShellEscape - backslash escape characters that are special to the shell 1309e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1310e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1311e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehsub ShellEscape { 1312e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # copy argument to new variable so we don't clobber the original 1313e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $arg = shift || ''; 1314e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 1315e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh return $arg; 1316e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1317e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1318e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1319e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Process command-line arguments. 1320e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh##----------------------------------------------------------------------------## 1321e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1322e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $AnalyzeHeaders = 0; 1323e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $HtmlDir; # Parent directory to store HTML files. 1324e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $IgnoreErrors = 0; # Ignore build errors. 1325e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ViewResults = 0; # View results when the build terminates. 1326e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found 1327e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $KeepEmpty = 0; # Don't remove output directory even with 0 results. 1328e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy @AnalysesToRun; 1329e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $StoreModel; 1330e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ConstraintsModel; 1331e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $InternalStats; 1332e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $OutputFormat = "html"; 1333e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $AnalyzerStats = 0; 1334e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $MaxLoop = 0; 1335e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $RequestDisplayHelp = 0; 1336e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ForceDisplayHelp = 0; 1337e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $AnalyzerDiscoveryMethod; 1338e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1339e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (!@ARGV) { 1340e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ForceDisplayHelp = 1 1341e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1342e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1343e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehwhile (@ARGV) { 1344e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1345e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Scan for options we recognize. 1346e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1347e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $arg = $ARGV[0]; 1348e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1349e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-h" or $arg eq "--help") { 1350e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $RequestDisplayHelp = 1; 1351e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1352e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1353e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1354e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1355e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq '-analyze-headers') { 1356e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1357e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $AnalyzeHeaders = 1; 1358e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1359e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1360e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1361e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-o") { 1362e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1363e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1364e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!@ARGV) { 1365e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'-o' option requires a target directory name.\n"); 1366e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1367e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1368e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Construct an absolute path. Uses the current working directory 1369e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # as a base if the original path was not absolute. 1370e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $HtmlDir = abs_path(shift @ARGV); 1371e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1372e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1373e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1374e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1375e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /^--html-title(=(.+))?$/) { 1376e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1377e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1378e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $2 || $2 eq '') { 1379e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!@ARGV) { 1380e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'--html-title' option requires a string.\n"); 1381e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1382e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1383e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $HtmlTitle = shift @ARGV; 1384e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } else { 1385e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $HtmlTitle = $2; 1386e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1387e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1388e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1389e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1390e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1391e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-k" or $arg eq "--keep-going") { 1392e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1393e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $IgnoreErrors = 1; 1394e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1395e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1396e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1397e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /^--use-cc(=(.+))?$/) { 1398e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1399e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $cc; 1400e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1401e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $2 || $2 eq "") { 1402e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!@ARGV) { 1403e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'--use-cc' option requires a compiler executable name.\n"); 1404e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1405e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $cc = shift @ARGV; 1406e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1407e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1408e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $cc = $2; 1409e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1410e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1411e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CC"} = $cc; 1412e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1413e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1414e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1415e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 1416e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1417e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $cxx; 1418e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1419e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $2 || $2 eq "") { 1420e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!@ARGV) { 1421e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'--use-c++' option requires a compiler executable name.\n"); 1422e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1423e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $cxx = shift @ARGV; 1424e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1425e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1426e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $cxx = $2; 1427e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1428e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1429e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_CXX"} = $cxx; 1430e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1431e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1432e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1433e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-v") { 1434e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1435e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Verbose++; 1436e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1437e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1438e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1439e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-V" or $arg eq "--view") { 1440e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1441e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ViewResults = 1; 1442e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1443e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1444e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1445e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "--status-bugs") { 1446e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1447e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ExitStatusFoundBugs = 1; 1448e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1449e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1450e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1451e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-store") { 1452e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1453e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $StoreModel = shift @ARGV; 1454e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1455e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1456e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1457e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-constraints") { 1458e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1459e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ConstraintsModel = shift @ARGV; 1460e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1461e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1462e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1463e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-internal-stats") { 1464e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1465e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $InternalStats = 1; 1466e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1467e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1468e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1469e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-plist") { 1470e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1471e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $OutputFormat = "plist"; 1472e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1473e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1474e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-plist-html") { 1475e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1476e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $OutputFormat = "plist-html"; 1477e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1478e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1479e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1480e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-no-failure-reports") { 1481e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ENV{"CCC_REPORT_FAILURES"} = 0; 1482e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1483e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1484e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-stats") { 1485e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1486e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $AnalyzerStats = 1; 1487e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1488e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1489e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-maxloop") { 1490e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1491e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $MaxLoop = shift @ARGV; 1492e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1493e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1494e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-enable-checker") { 1495e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1496e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @AnalysesToRun, "-analyzer-checker", shift @ARGV; 1497e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1498e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1499e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-disable-checker") { 1500e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1501e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @AnalysesToRun, "-analyzer-disable-checker", shift @ARGV; 1502e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1503e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1504e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "-load-plugin") { 1505e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1506e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh push @PluginsToLoad, "-load", shift @ARGV; 1507e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1508e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1509e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "--use-analyzer") { 1510e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1511e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $AnalyzerDiscoveryMethod = shift @ARGV; 1512e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1513e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1514e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /^--use-analyzer=(.+)$/) { 1515e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1516e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $AnalyzerDiscoveryMethod = $1; 1517e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1518e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1519e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "--keep-empty") { 1520e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1521e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $KeepEmpty = 1; 1522e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1523e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1524e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1525e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg eq "--override-compiler") { 1526e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1527e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $OverrideCompiler = 1; 1528e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1529e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1530e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1531e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($arg =~ /^--top(=(.+))?$/) { 1532e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh shift @ARGV; 1533e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1534e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $2 || $2 eq "") { 1535e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!@ARGV) { 1536e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'--top' option requires a directory.\n"); 1537e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1538e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Top = shift @ARGV; 1539e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1540e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1541e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Top = $2; 1542e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1543e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh next; 1544e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1545e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1546e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 1547e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1548e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh last; 1549e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1550e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1551e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (!@ARGV and !$RequestDisplayHelp) { 1552e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh ErrorDiag("No build command specified.\n\n"); 1553e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ForceDisplayHelp = 1; 1554e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1555e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1556e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Find 'clang' 1557e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (!defined $AnalyzerDiscoveryMethod) { 1558e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Clang = Cwd::realpath("$RealBin/bin/clang"); 1559e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Clang || ! -x $Clang) { 1560e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Clang = Cwd::realpath("$RealBin/clang"); 1561e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1562e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Clang || ! -x $Clang) { 1563e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!$RequestDisplayHelp && !$ForceDisplayHelp) { 1564e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("error: Cannot find an executable 'clang' relative to scan-build." . 1565e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh " Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n"); 1566e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1567e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1568e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1569e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehelse { 1570e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) { 1571e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $xcrun = `which xcrun`; 1572e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $xcrun; 1573e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($xcrun eq "") { 1574e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n"); 1575e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1576e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Clang = `$xcrun -toolchain XcodeDefault -find clang`; 1577e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh chomp $Clang; 1578e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($Clang eq "") { 1579e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("No 'clang' executable found by 'xcrun'\n"); 1580e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1581e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1582e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh else { 1583e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Clang = Cwd::realpath($AnalyzerDiscoveryMethod); 1584e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (!defined $Clang or not -x $Clang) { 1585e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("Cannot find an executable clang at '$AnalyzerDiscoveryMethod'\n"); 1586e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1587e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1588e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1589e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1590e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif ($ForceDisplayHelp || $RequestDisplayHelp) { 1591e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DisplayHelp(); 1592e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exit $ForceDisplayHelp; 1593e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1594e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1595e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh$ClangCXX = $Clang; 1596e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Determine operating system under which this copy of Perl was built. 1597e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $IsWinBuild = ($^O =~/msys|cygwin|MSWin32/); 1598e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif($IsWinBuild) { 1599e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ClangCXX =~ s/.exe$/++.exe/; 1600e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1601e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehelse { 1602e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ClangCXX =~ s/\-\d+\.\d+$//; 1603e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $ClangCXX .= "++"; 1604e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1605e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1606e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Make sure to use "" to handle paths with spaces. 1607e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh$ClangVersion = HtmlEscape(`"$Clang" --version`); 1608e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1609e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Determine where results go. 1610e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 1611e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh$HtmlTitle = "${CurrentDirSuffix} - scan-build results" 1612e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh unless (defined($HtmlTitle)); 1613e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1614e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Determine the output directory for the HTML reports. 1615e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $BaseDir = $HtmlDir; 1616e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh$HtmlDir = GetHTMLRunDir($HtmlDir); 1617e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1618e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Determine the location of ccc-analyzer. 1619e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $AbsRealBin = Cwd::realpath($RealBin); 1620e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; 1621e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; 1622e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1623e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Portability: use less strict but portable check -e (file exists) instead of 1624e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# non-portable -x (file is executable). On some windows ports -x just checks 1625e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# file extension to determine if a file is executable (see Perl language 1626e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# reference, perlport) 1627e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (!defined $Cmd || ! -e $Cmd) { 1628e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Cmd = "$AbsRealBin/ccc-analyzer"; 1629e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'ccc-analyzer' does not exist at '$Cmd'\n") if(! -e $Cmd); 1630e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1631e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (!defined $CmdCXX || ! -e $CmdCXX) { 1632e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $CmdCXX = "$AbsRealBin/c++-analyzer"; 1633e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh DieDiag("'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -e $CmdCXX); 1634e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1635e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1636e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehDiag("Using '$Clang' for static analysis\n"); 1637e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1638e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew HsiehSetHtmlEnv(\@ARGV, $HtmlDir); 1639e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; } 1640e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif ($AnalyzerStats) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; } 1641e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif ($MaxLoop > 0) { push @AnalysesToRun, "-analyzer-max-loop $MaxLoop"; } 1642e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1643e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Delay setting up other environment variables in case we can do true 1644e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# interposition. 1645e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun; 1646e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad; 1647e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy %Options = ( 1648e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CC' => $Cmd, 1649e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CXX' => $CmdCXX, 1650e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CLANG' => $Clang, 1651e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CLANG_CXX' => $ClangCXX, 1652e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'VERBOSE' => $Verbose, 1653e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS, 1654e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS, 1655e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 'OUTPUT_DIR' => $HtmlDir 1656e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh); 1657e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1658e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $StoreModel) { 1659e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Options{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; 1660e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1661e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $ConstraintsModel) { 1662e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Options{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; 1663e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1664e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $InternalStats) { 1665e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Options{'CCC_ANALYZER_INTERNAL_STATS'} = 1; 1666e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1667e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $OutputFormat) { 1668e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh $Options{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; 1669e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1670e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1671e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh# Run the build. 1672e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehmy $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX, 1673e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh \%Options); 1674e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1675e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehif (defined $OutputFormat) { 1676e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($OutputFormat =~ /plist/) { 1677e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag "Analysis run complete.\n"; 1678e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; 1679e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1680e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($OutputFormat =~ /html/) { 1681e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh # Postprocess the HTML directory. 1682e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats, $KeepEmpty); 1683e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1684e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($ViewResults and -r "$HtmlDir/index.html") { 1685e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag "Analysis run complete.\n"; 1686e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; 1687e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh my $ScanView = Cwd::realpath("$RealBin/scan-view"); 1688e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if (! -x $ScanView) { $ScanView = "scan-view"; } 1689e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exec $ScanView, "$HtmlDir"; 1690e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1691e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1692e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh if ($ExitStatusFoundBugs) { 1693e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exit 1 if ($NumBugs > 0); 1694e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh exit 0; 1695e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1696e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh } 1697e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh} 1698e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1699e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsiehexit $ExitStatus; 1700e5ae5b5826d42d2e26812699c4ced96a43c02eb7Andrew Hsieh 1701