16bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker#!/usr/bin/env perl 26bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 36bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# The LLVM Compiler Infrastructure 46bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 56bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# This file is distributed under the University of Illinois Open Source 66bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# License. See LICENSE.TXT for details. 76bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 86bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##===----------------------------------------------------------------------===## 96bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# A script designed to wrap a build so that all calls to gcc are intercepted 116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# and piped to the static analyzer. 126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# 136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##===----------------------------------------------------------------------===## 146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse strict; 166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse warnings; 176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse FindBin qw($RealBin); 186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Digest::MD5; 196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse File::Basename; 206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse File::Find; 216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse File::Copy qw(copy); 226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse File::Path qw( rmtree mkpath ); 236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Term::ANSIColor; 246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Term::ANSIColor qw(:constants); 256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Cwd qw/ getcwd abs_path /; 266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Sys::Hostname; 276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickeruse Hash::Util qw(lock_keys); 286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $Prog = "scan-build"; 306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $BuildName; 316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $BuildDate; 326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $TERM = $ENV{'TERM'}; 346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT 356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker and defined $ENV{'SCAN_BUILD_COLOR'}); 366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Portability: getpwuid is not implemented for Win32 (see Perl language 386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# reference, perlport), use getlogin instead. 396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown'); 406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $HostName = HtmlEscape(hostname() || 'unknown'); 416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CurrentDir = HtmlEscape(getcwd()); 426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CmdArgs; 446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $Date = localtime(); 466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Command-line/config arguments. 486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy %Options = ( 496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Verbose => 0, # Verbose output from this script. 506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AnalyzeHeaders => 0, 516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker OutputDir => undef, # Parent directory to store HTML files. 526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker HtmlTitle => basename($CurrentDir)." - scan-build results", 536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker IgnoreErrors => 0, # Ignore build errors. 546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ViewResults => 0, # View results when the build terminates. 556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ExitStatusFoundBugs => 0, # Exit status reflects whether bugs were found 566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker KeepEmpty => 0, # Don't remove output directory even with 0 results. 576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker EnableCheckers => {}, 586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DisableCheckers => {}, 596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker UseCC => undef, # C compiler to use for compilation. 606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker UseCXX => undef, # C++ compiler to use for compilation. 616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AnalyzerTarget => undef, 626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker StoreModel => undef, 636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ConstraintsModel => undef, 646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker InternalStats => undef, 656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker OutputFormat => "html", 666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ConfigOptions => [], # Options to pass through to the analyzer's -analyzer-config flag. 676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ReportFailures => undef, 686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AnalyzerStats => 0, 696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker MaxLoop => 0, 706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker PluginsToLoad => [], 716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AnalyzerDiscoveryMethod => undef, 726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker OverrideCompiler => 0, # The flag corresponding to the --override-compiler command line option. 736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ForceAnalyzeDebugCode => 0 746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker); 756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerlock_keys(%Options); 766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Diagnostics 796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub Diag { 826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($UseColor) { 836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print BOLD, MAGENTA "$Prog: @_"; 846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print RESET; 856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print "$Prog: @_"; 886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub ErrorDiag { 926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($UseColor) { 936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR BOLD, RED "$Prog: "; 946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR RESET, RED @_; 956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR RESET; 966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } else { 976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR "$Prog: @_"; 986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 1006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub DiagCrashes { 1026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift; 1036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag ("The analyzer encountered problems on some source files.\n"); 1046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); 1056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag ("Please consider submitting a bug report using these files:\n"); 1066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") 1076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 1086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub DieDiag { 1106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($UseColor) { 1116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR BOLD, RED "$Prog: "; 1126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR RESET, RED @_; 1136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR RESET; 1146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 1166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print STDERR "$Prog: ", @_; 1176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exit 1; 1196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 1206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Print default checker names 1236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (grep /^--help-checkers$/, @ARGV) { 1266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @options = qx($0 -h); 1276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach (@options) { 1286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next unless /^ \+/; 1296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker s/^\s*//; 1306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my ($sign, $name, @text) = split ' ', $_; 1316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print $name, $/ if $sign eq '+'; 1326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exit 0; 1346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 1356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Declaration of Clang options. Populated later. 1386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $Clang; 1416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ClangSB; 1426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ClangCXX; 1436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ClangVersion; 1446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. 1476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 1486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub GetHTMLRunDir { 1506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "Not enough arguments." if (@_ == 0); 1516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift @_; 1526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TmpMode = 0; 1536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Dir) { 1546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp"; 1556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $TmpMode = 1; 1566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Chop off any trailing '/' characters. 1596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while ($Dir =~ /\/$/) { chop $Dir; } 1606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Get current date and time. 1626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @CurrentTime = localtime(); 1636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $year = $CurrentTime[5] + 1900; 1646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $day = $CurrentTime[3]; 1656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $month = $CurrentTime[4] + 1; 1666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $hour = $CurrentTime[2]; 1676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $min = $CurrentTime[1]; 1686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $sec = $CurrentTime[0]; 1696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec); 1716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $DateString = sprintf("%d-%02d-%02d-%s-$$", 1726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $year, $month, $day, $TimeString); 1736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Determine the run number. 1756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $RunNumber; 1766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (-d $Dir) { 1786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -r $Dir) { 1796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("directory '$Dir' exists but is not readable.\n"); 1806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Iterate over all files in the specified directory. 1826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $max = 0; 1836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker opendir(DIR, $Dir); 1846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @FILES = grep { -d "$Dir/$_" } readdir(DIR); 1856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker closedir(DIR); 1866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $f (@FILES) { 1886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Strip the prefix '$Prog-' if we are dumping files to /tmp. 1896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($TmpMode) { 1906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if (!($f =~ /^$Prog-(.+)/)); 1916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $f = $1; 1926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 1936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 1946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @x = split/-/, $f; 1956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if (scalar(@x) != 4); 1966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if ($x[0] != $year); 1976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if ($x[1] != $month); 1986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if ($x[2] != $day); 1996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if ($x[3] != $TimeString); 2006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if ($x[4] != $$); 2016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($x[5] > $max) { 2036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $max = $x[5]; 2046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $RunNumber = $max + 1; 2086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 2106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (-x $Dir) { 2126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'$Dir' exists but is not a directory.\n"); 2136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($TmpMode) { 2166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); 2176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # $Dir does not exist. It will be automatically created by the 2206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # clang driver. Set the run number to 1. 2216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $RunNumber = 1; 2236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "RunNumber must be defined!" if (!defined $RunNumber); 2266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Append the run number. 2286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $NewDir; 2296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($TmpMode) { 2306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; 2316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 2336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $NewDir = "$Dir/$DateString-$RunNumber"; 2346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Make sure that the directory does not exist in order to avoid hijack. 2376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (-e $NewDir) { 2386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("The directory '$NewDir' already exists.\n"); 2396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker mkpath($NewDir); 2426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $NewDir; 2436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 2446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub SetHtmlEnv { 2466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "Wrong number of arguments." if (scalar(@_) != 2); 2486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Args = shift; 2506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift; 2516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "No build command." if (scalar(@$Args) == 0); 2536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Cmd = $$Args[0]; 2556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { 2576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return; 2586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{Verbose}) { 2616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("Emitting reports for this run to '$Dir'.\n"); 2626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 2636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{'CCC_ANALYZER_HTML'} = $Dir; 2656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 2666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 2686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# ComputeDigest - Compute a digest of the specified file. 2696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 2706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub ComputeDigest { 2726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $FName = shift; 2736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); 2746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Use Digest::MD5. We don't have to be cryptographically secure. We're 2766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # just looking for duplicate files that come from a non-malicious source. 2776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # We use Digest::MD5 because it is a standard Perl module that should 2786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # come bundled on most systems. 2796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); 2806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker binmode FILE; 2816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; 2826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close(FILE); 2836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Return the digest. 2856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $Result; 2866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 2876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 2896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# UpdatePrefix - Compute the common prefix of files. 2906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 2916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $Prefix; 2936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub UpdatePrefix { 2956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = shift; 2966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $y = basename($x); 2976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $x =~ s/\Q$y\E$//; 2986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 2996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Prefix) { 3006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Prefix = $x; 3016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return; 3026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 3036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chop $Prefix while (!($x =~ /^\Q$Prefix/)); 3056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 3066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub GetPrefix { 3086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $Prefix; 3096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 3106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# UpdateInFilePath - Update the path in the report file. 3136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub UpdateInFilePath { 3166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $fname = shift; 3176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $regex = shift; 3186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $newtext = shift; 3196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open (RIN, $fname) or die "cannot open $fname"; 3216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; 3226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while (<RIN>) { 3246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker s/$regex/$newtext/; 3256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print ROUT $_; 3266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 3276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close (ROUT); 3296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close (RIN); 3306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker rename("$fname.tmp", $fname) 3316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 3326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# AddStatLine - Decode and insert a statistics line into the database. 3356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub AddStatLine { 3386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Line = shift; 3396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Stats = shift; 3406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $File = shift; 3416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print $Line . "\n"; 3436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Regex = qr/(.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable 3456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: 3466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker \ (yes|no)/x; 3476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Line !~ $Regex) { 3496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return; 3506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 3516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Create a hash of the interesting fields 3536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Row = { 3546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Filename => $File, 3556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Function => $1, 3566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Total => $2, 3576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Unreachable => $3, 3586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Aborted => $4, 3596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Empty => $5 3606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker }; 3616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Add them to the stats array 3636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @$Stats, $Row; 3646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 3656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# ScanFile - Scan a report file for various identifying attributes. 3686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 3696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Sometimes a source file is scanned more than once, and thus produces 3716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# multiple error reports. We use a cache to solve this problem. 3726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy %AlreadyScanned; 3746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub ScanFile { 3766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Index = shift; 3786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift; 3796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $FName = shift; 3806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Stats = shift; 3816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Compute a digest for the report file. Determine if we have already 3836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # scanned a file that looks just like it. 3846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $digest = ComputeDigest("$Dir/$FName"); 3866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $AlreadyScanned{$digest}) { 3886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Redundant file. Remove it. 3896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker unlink("$Dir/$FName"); 3906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return; 3916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 3926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $AlreadyScanned{$digest} = 1; 3946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # At this point the report file is not world readable. Make it happen. 3966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chmod(0644, "$Dir/$FName"); 3976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 3986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Scan the report file for tags. 3996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); 4006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugType = ""; 4026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugFile = ""; 4036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugFunction = ""; 4046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugCategory = ""; 4056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugDescription = ""; 4066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugPathLength = 1; 4076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BugLine = 0; 4086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while (<IN>) { 4106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last if (/<!-- BUGMETAEND -->/); 4116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (/<!-- BUGTYPE (.*) -->$/) { 4136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugType = $1; 4146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- BUGFILE (.*) -->$/) { 4166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugFile = abs_path($1); 4176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $BugFile) { 4186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # The file no longer exists: use the original path. 4196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugFile = $1; 4206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker UpdatePrefix($BugFile); 4226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { 4246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugPathLength = $1; 4256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- BUGLINE (.*) -->$/) { 4276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugLine = $1; 4286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- BUGCATEGORY (.*) -->$/) { 4306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugCategory = $1; 4316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- BUGDESC (.*) -->$/) { 4336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugDescription = $1; 4346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif (/<!-- FUNCTIONNAME (.*) -->$/) { 4366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugFunction = $1; 4376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close(IN); 4436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $BugCategory) { 4456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugCategory = "Other"; 4466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Don't add internal statistics to the bug reports 4496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($BugCategory =~ /statistics/i) { 4506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddStatLine($BugDescription, $Stats, $BugFile); 4516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return; 4526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 4536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugFunction, $BugLine, 4556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BugPathLength ]; 4566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 4576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 4596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# CopyFiles - Copy resource files to target directory. 4606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 4616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub CopyFiles { 4636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift; 4656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $JS = Cwd::realpath("$RealBin/../share/scan-build/sorttable.js"); 4676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("Cannot find 'sorttable.js'.\n") 4696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -r $JS); 4706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker copy($JS, "$Dir"); 4726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") 4746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -r "$Dir/sorttable.js"); 4756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CSS = Cwd::realpath("$RealBin/../share/scan-build/scanview.css"); 4776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("Cannot find 'scanview.css'.\n") 4796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -r $CSS); 4806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker copy($CSS, "$Dir"); 4826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") 4846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -r $CSS); 4856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 4866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 4886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# CalcStats - Calculates visitation statistics and returns the string. 4896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 4906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub CalcStats { 4926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Stats = shift; 4936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 4946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TotalBlocks = 0; 4956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $UnreachedBlocks = 0; 4966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TotalFunctions = scalar(@$Stats); 4976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BlockAborted = 0; 4986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $WorkListAborted = 0; 4996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Aborted = 0; 5006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Calculate the unique files 5026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $FilesHash = {}; 5036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $Row (@$Stats) { 5056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $FilesHash->{$Row->{Filename}} = 1; 5066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $TotalBlocks += $Row->{Total}; 5076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $UnreachedBlocks += $Row->{Unreachable}; 5086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $BlockAborted++ if $Row->{Aborted} eq 'yes'; 5096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $WorkListAborted++ if $Row->{Empty} eq 'no'; 5106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; 5116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TotalFiles = scalar(keys(%$FilesHash)); 5146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Calculations 5166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); 5176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions 5186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker * 100); 5196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / 5206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $TotalFunctions * 100); 5216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks 5226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker * 100); 5236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" 5256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker . " in $TotalFiles files\n" 5266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker . "$Aborted functions aborted early ($PercentAborted%)\n" 5276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" 5286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" 5296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; 5306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $StatsString; 5326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 5336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 5356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Postprocess - Postprocess the results of an analysis scan. 5366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 5376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy @filesFound; 5396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $baseDir; 5406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub FileWanted { 5416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $baseDirRegEx = quotemeta $baseDir; 5426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $file = $File::Find::name; 5436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # The name of the file is generated by clang binary (HTMLDiagnostics.cpp) 5456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($file =~ /report-.*\.html$/) { 5466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $relative_file = $file; 5476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $relative_file =~ s/$baseDirRegEx//g; 5486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @filesFound, $relative_file; 5496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 5516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub Postprocess { 5536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Dir = shift; 5556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $BaseDir = shift; 5566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $AnalyzerStats = shift; 5576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $KeepEmpty = shift; 5586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "No directory specified." if (!defined $Dir); 5606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -d $Dir) { 5626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("No bugs found.\n"); 5636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return 0; 5646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $baseDir = $Dir . "/"; 5676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker find({ wanted => \&FileWanted, follow => 0}, $Dir); 5686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") { 5706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! $KeepEmpty) { 5716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("Removing directory '$Dir' because it contains no reports.\n"); 5726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker rmtree($Dir) or die "Cannot rmtree '$Dir' : $!"; 5736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("No bugs found.\n"); 5756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return 0; 5766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 5776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Scan each report file and build an index. 5796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @Index; 5806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @Stats; 5816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); } 5826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 5836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Scan the failures directory and use the information in the .info files 5846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # to update the common prefix directory. 5856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @failures; 5866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @attributes_ignored; 5876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (-d "$Dir/failures") { 5886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker opendir(DIR, "$Dir/failures"); 5896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); 5906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker closedir(DIR); 5916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker opendir(DIR, "$Dir/failures"); 5926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); 5936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker closedir(DIR); 5946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $file (@failures) { 5956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); 5966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Path = <IN>; 5976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $Path) { UpdatePrefix($Path); } 5986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close IN; 5996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Generate an index.html file. 6036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $FName = "$Dir/index.html"; 6046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); 6056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print out the header. 6076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint OUT <<ENDTEXT; 6096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<html> 6106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<head> 6116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<title>${Options{HtmlTitle}}</title> 6126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<link type="text/css" rel="stylesheet" href="scanview.css"/> 6136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<script src="sorttable.js"></script> 6146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<script language='javascript' type="text/javascript"> 6156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction SetDisplay(RowClass, DisplayVal) 6166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker{ 6176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker var Rows = document.getElementsByTagName("tr"); 6186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for ( var i = 0 ; i < Rows.length; ++i ) { 6196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (Rows[i].className == RowClass) { 6206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Rows[i].style.display = DisplayVal; 6216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 6246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction CopyCheckedStateToCheckButtons(SummaryCheckButton) { 6266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker var Inputs = document.getElementsByTagName("input"); 6276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for ( var i = 0 ; i < Inputs.length; ++i ) { 6286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (Inputs[i].type == "checkbox") { 6296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if(Inputs[i] != SummaryCheckButton) { 6306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Inputs[i].checked = SummaryCheckButton.checked; 6316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Inputs[i].onclick(); 6326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 6366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction returnObjById( id ) { 6386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (document.getElementById) 6396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker var returnVar = document.getElementById(id); 6406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else if (document.all) 6416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker var returnVar = document.all[id]; 6426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else if (document.layers) 6436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker var returnVar = document.layers[id]; 6446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return returnVar; 6456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 6466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickervar NumUnchecked = 0; 6486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerfunction ToggleDisplay(CheckButton, ClassName) { 6506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (CheckButton.checked) { 6516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SetDisplay(ClassName, ""); 6526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (--NumUnchecked == 0) { 6536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker returnObjById("AllBugsCheck").checked = true; 6546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 6576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SetDisplay(ClassName, "none"); 6586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker NumUnchecked++; 6596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker returnObjById("AllBugsCheck").checked = false; 6606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 6626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</script> 6636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<!-- SUMMARYENDHEAD --> 6646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</head> 6656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<body> 6666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<h1>${Options{HtmlTitle}}</h1> 6676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table> 6696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> 6706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> 6716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> 6726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><th>Clang Version:</th><td>${ClangVersion}</td></tr> 6736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tr><th>Date:</th><td>${Date}</td></tr> 6746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 6756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" 6776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined($BuildName) && defined($BuildDate)); 6786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint OUT <<ENDTEXT; 6806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 6816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 6826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (scalar(@filesFound)) { 6846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print out the summary table. 6856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my %Totals; 6866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for my $row ( @Index ) { 6886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $bug_type = ($row->[2]); 6896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $bug_category = ($row->[1]); 6906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $key = "$bug_category:$bug_type"; 6916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } 6936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { $Totals{$key}->[0]++; } 6946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 6956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<h2>Bug Summary</h2>"; 6976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 6986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $BuildName) { 6996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" 7006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $TotalBugs = scalar(@Index); 7036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint OUT <<ENDTEXT; 7046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table> 7056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> 7066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<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> 7076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 7086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $last_category; 7106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for my $key ( 7126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker sort { 7136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = $Totals{$a}; 7146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $y = $Totals{$b}; 7156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $res = $x->[1] cmp $y->[1]; 7166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $res = $x->[2] cmp $y->[2] if ($res == 0); 7176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $res 7186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } keys %Totals ) 7196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker { 7206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $val = $Totals{$key}; 7216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $category = $val->[1]; 7226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $last_category or $last_category ne $category) { 7236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $last_category = $category; 7246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; 7256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = lc $key; 7276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $x =~ s/[ ,'":\/()]+/_/g; 7286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<tr><td class=\"SUMM_DESC\">"; 7296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $val->[2]; 7306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td><td class=\"Q\">"; 7316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $val->[0]; 7326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; 7336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print out the table of errors. 7366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint OUT <<ENDTEXT; 7386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</table> 7396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<h2>Reports</h2> 7406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<table class="sortable" style="table-layout:automatic"> 7426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<thead><tr> 7436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td>Bug Group</td> 7446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> 7456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td>File</td> 7466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td>Function/Method</td> 7476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="Q">Line</td> 7486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="Q">Path Length</td> 7496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <td class="sorttable_nosort"></td> 7506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker <!-- REPORTBUGCOL --> 7516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker</tr></thead> 7526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker<tbody> 7536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 7546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $prefix = GetPrefix(); 7566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $regex; 7576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $InFileRegex; 7586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $InFilePrefix = "File:</td><td>"; 7596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $prefix) { 7616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $regex = qr/^\Q$prefix\E/is; 7626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; 7636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { 7666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = "$row->[1]:$row->[2]"; 7676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $x = lc $x; 7686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $x =~ s/[ ,'":\/()]+/_/g; 7696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ReportFile = $row->[0]; 7716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<tr class=\"bt_$x\">"; 7736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td class=\"DESC\">"; 7746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $row->[1]; 7756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td>"; 7766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td class=\"DESC\">"; 7776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $row->[2]; 7786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td>"; 7796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Update the file prefix. 7816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $fname = $row->[3]; 7826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $regex) { 7846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $fname =~ s/$regex//; 7856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) 7866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 7886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td>"; 7896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @fname = split /\//,$fname; 7906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($#fname > 0) { 7916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while ($#fname >= 0) { 7926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = shift @fname; 7936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $x; 7946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($#fname >= 0) { 7956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "/"; 7966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 7996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 8006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $fname; 8016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td>"; 8036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td class=\"DESC\">"; 8056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT $row->[4]; 8066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</td>"; 8076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print out the quantities. 8096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for my $j ( 5 .. 6 ) { 8106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td class=\"Q\">$row->[$j]</td>"; 8116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print the rest of the columns. 8146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for (my $j = 7; $j <= $#{$row}; ++$j) { 8156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td>$row->[$j]</td>" 8166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Emit the "View" link. 8196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; 8206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Emit REPORTBUG markers. 8226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; 8236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # End the row. 8256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</tr>\n"; 8266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</tbody>\n</table>\n\n"; 8296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (scalar (@failures) || scalar(@attributes_ignored)) { 8326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<h2>Analyzer Failures</h2>\n"; 8336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (scalar @attributes_ignored) { 8356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "The analyzer's parser ignored the following attributes:<p>\n"; 8366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<table>\n"; 8376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 8386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $file (sort @attributes_ignored) { 8396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); 8406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $attribute = $1; 8416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Open the attribute file to get the first file that failed. 8426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if (!open (ATTR, "$Dir/failures/$file")); 8436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ppfile = <ATTR>; 8446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $ppfile; 8456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close ATTR; 8466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if (! -e "$Dir/failures/$ppfile"); 8476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Open the info file and get the name of the source file. 8486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open (INFO, "$Dir/failures/$ppfile.info.txt") or 8496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "Cannot open $Dir/failures/$ppfile.info.txt\n"; 8506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $srcfile = <INFO>; 8516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $srcfile; 8526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close (INFO); 8536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print the information in the table. 8546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $prefix = GetPrefix(); 8556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 8566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 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"; 8576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ppfile_clang = $ppfile; 8586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 8596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 8606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</table>\n"; 8626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (scalar @failures) { 8656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<p>The analyzer had problems processing the following files:</p>\n"; 8666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<table>\n"; 8676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; 8686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $file (sort @failures) { 8696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $file =~ /(.+).info.txt$/; 8706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Get the preprocessed file. 8716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ppfile = $1; 8726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Open the info file and get the name of the source file. 8736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open (INFO, "$Dir/failures/$file") or 8746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "Cannot open $Dir/failures/$file\n"; 8756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $srcfile = <INFO>; 8766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $srcfile; 8776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $problem = <INFO>; 8786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $problem; 8796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close (INFO); 8806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print the information in the table. 8816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $prefix = GetPrefix(); 8826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } 8836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 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"; 8846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ppfile_clang = $ppfile; 8856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ppfile_clang =~ s/[.](.+)$/.clang.$1/; 8866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; 8876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</table>\n"; 8896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 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"; 8916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 8926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print OUT "</body></html>\n"; 8946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close(OUT); 8956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker CopyFiles($Dir); 8966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 8976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Make sure $Dir and $BaseDir are world readable/executable. 8986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chmod(0755, $Dir); 8996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $BaseDir) { chmod(0755, $BaseDir); } 9006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Print statistics 9026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print CalcStats(\@Stats) if $AnalyzerStats; 9036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Num = scalar(@Index); 9056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Num == 1) { 9066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("$Num bug found.\n"); 9076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } else { 9086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("$Num bugs found.\n"); 9096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Num > 0 && -r "$Dir/index.html") { 9116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag("Run 'scan-view $Dir' to examine bug reports.\n"); 9126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); 9156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $Num; 9176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 9186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 9206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# RunBuildCommand - Run the build command. 9216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 9226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub AddIfNotPresent { 9246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Args = shift; 9256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Arg = shift; 9266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $found = 0; 9276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $k (@$Args) { 9296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($k eq $Arg) { 9306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $found = 1; 9316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last; 9326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($found == 0) { 9366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @$Args, $Arg; 9376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 9396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub SetEnv { 9416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $EnvVars = shift @_; 9426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $var ('CC', 'CXX', 'CLANG', 'CLANG_CXX', 9436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS', 9446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_CONFIG') { 9456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "$var is undefined\n" if (!defined $var); 9466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{$var} = $EnvVars->{$var}; 9476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $var ('CCC_ANALYZER_STORE_MODEL', 9496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_CONSTRAINTS_MODEL', 9506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_INTERNAL_STATS', 9516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_OUTPUT_FORMAT', 9526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_CC', 9536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_CXX', 9546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_REPORT_FAILURES', 9556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CLANG_ANALYZER_TARGET', 9566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE') { 9576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $x = $EnvVars->{$var}; 9586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $x) { $ENV{$var} = $x } 9596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Verbose = $EnvVars->{'VERBOSE'}; 9616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Verbose >= 2) { 9626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{'CCC_ANALYZER_VERBOSE'} = 1; 9636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Verbose >= 3) { 9656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{'CCC_ANALYZER_LOG'} = 1; 9666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 9686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub RunXcodebuild { 9706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Args = shift; 9716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $IgnoreErrors = shift; 9726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CCAnalyzer = shift; 9736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CXXAnalyzer = shift; 9746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $EnvVars = shift; 9756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($IgnoreErrors) { 9776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); 9786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Detect the version of Xcode. If Xcode 4.6 or higher, use new 9816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # in situ support for analyzer interposition without needed to override 9826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # the compiler. 9836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(DETECT_XCODE, "-|", $Args->[0], "-version") or 9846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker die "error: cannot detect version of xcodebuild\n"; 9856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $oldBehavior = 1; 9876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 9886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while(<DETECT_XCODE>) { 9896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (/^Xcode (.+)$/) { 9906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ver = $1; 9916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($ver =~ /^([0-9]+[.][0-9]+)[^0-9]?/) { 9926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($1 >= 4.6) { 9936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $oldBehavior = 0; 9946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last; 9956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 9996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close(DETECT_XCODE); 10006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # If --override-compiler is explicitely requested, resort to the old 10026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # behavior regardless of Xcode version. 10036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{OverrideCompiler}) { 10046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $oldBehavior = 1; 10056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($oldBehavior == 0) { 10086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $OutputDir = $EnvVars->{"OUTPUT_DIR"}; 10096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CLANG = $EnvVars->{"CLANG"}; 10106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $OtherFlags = $EnvVars->{"CCC_ANALYZER_ANALYSIS"}; 10116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @$Args, 10126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker "RUN_CLANG_STATIC_ANALYZER=YES", 10136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker "CLANG_ANALYZER_OUTPUT=plist-html", 10146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker "CLANG_ANALYZER_EXEC=$CLANG", 10156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker "CLANG_ANALYZER_OUTPUT_DIR=$OutputDir", 10166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker "CLANG_ANALYZER_OTHER_FLAGS=$OtherFlags"; 10176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (system(@$Args) >> 8); 10196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Default to old behavior where we insert a bogus compiler. 10226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SetEnv($EnvVars); 10236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Check if using iPhone SDK 3.0 (simulator). If so the compiler being 10256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # used should be gcc-4.2. 10266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $ENV{"CCC_CC"}) { 10276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker for (my $i = 0 ; $i < scalar(@$Args); ++$i) { 10286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { 10296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (@$Args[$i+1] =~ /^iphonesimulator3/) { 10306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{"CCC_CC"} = "gcc-4.2"; 10316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{"CCC_CXX"} = "g++-4.2"; 10326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Disable PCH files until clang supports them. 10386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); 10396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # When 'CC' is set, xcodebuild uses it to do all linking, even if we are 10416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' 10426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # (via c++-analyzer) when linking such files. 10436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; 10446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (system(@$Args) >> 8); 10466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 10476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub RunBuildCommand { 10496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Args = shift; 10506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $IgnoreErrors = shift; 10516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Cmd = $Args->[0]; 10526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CCAnalyzer = shift; 10536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $CXXAnalyzer = shift; 10546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $EnvVars = shift; 10556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Cmd =~ /\bxcodebuild$/) { 10576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return RunXcodebuild($Args, $IgnoreErrors, $CCAnalyzer, $CXXAnalyzer, $EnvVars); 10586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Setup the environment. 10616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker SetEnv($EnvVars); 10626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 10646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?cc[^\/]*$)/ or 10656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or 10666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?clang$)/ or 10676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { 10686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { 10706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{"CCC_CC"} = $1; 10716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 10746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker unshift @$Args, $CCAnalyzer; 10756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 10776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or 10786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or 10796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?clang\+\+$)/ or 10806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { 10816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { 10826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ENV{"CCC_CXX"} = $1; 10836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 10856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker unshift @$Args, $CXXAnalyzer; 10866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker elsif ($Cmd eq "make" or $Cmd eq "gmake" or $Cmd eq "mingw32-make") { 10886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args, "CC=$CCAnalyzer"); 10896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); 10906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($IgnoreErrors) { 10916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args,"-k"); 10926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker AddIfNotPresent($Args,"-i"); 10936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 10956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return (system(@$Args) >> 8); 10976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 10986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 10996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 11006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# DisplayHelp - Utility function to display all help options. 11016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 11026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub DisplayHelp { 11046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ArgClangNotFoundErrMsg = shift; 11066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint <<ENDTEXT; 11076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerUSAGE: $Prog [options] <build command> [build options] 11086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 11106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $BuildName) { 11126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; 11136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 11146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint <<ENDTEXT; 11166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerOPTIONS: 11176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -analyze-headers 11196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Also analyze functions in #included files. By default, such functions 11216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker are skipped unless they are called by functions within the main source file. 11226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --force-analyze-debug-code 11246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Tells analyzer to enable assertions in code even if they were disabled 11266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker during compilation to enable more precise results. 11276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -o <output location> 11296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Specifies the output directory for analyzer reports. Subdirectories will be 11316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker created as needed to represent separate "runs" of the analyzer. If this 11326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X) 11336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker to store the reports. 11346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -h 11366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --help 11376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Display this message. 11396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -k 11416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --keep-going 11426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Add a "keep on going" option to the specified build command. This option 11446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker currently supports make and xcodebuild. This is a convenience option; one 11456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker can specify this behavior directly using build options. 11466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --html-title [title] 11486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --html-title=[title] 11496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Specify the title used on generated HTML pages. If not specified, a default 11516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker title will be used. 11526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -plist 11546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker By default the output of scan-build is a set of HTML files. This option 11566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker outputs the results as a set of .plist files. 11576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -plist-html 11596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker By default the output of scan-build is a set of HTML files. This option 11616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker outputs the results as a set of HTML and .plist files. 11626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --status-bugs 11646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker By default, the exit status of scan-build is the same as the executed build 11666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker command. Specifying this option causes the exit status of scan-build to be 1 11676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if it found potential bugs and 0 otherwise. 11686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-cc [compiler path] 11706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-cc=[compiler path] 11716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker scan-build analyzes a project by interposing a "fake compiler", which 11736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker executes a real compiler for compilation and the static analyzer for analysis. 11746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Because of the current implementation of interposition, scan-build does not 11756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker know what compiler your project normally uses. Instead, it simply overrides 11766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker the CC environment variable, and guesses your default compiler. 11776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker In the future, this interposition mechanism to be improved, but if you need 11796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker scan-build to use a specific compiler for *compilation* then you can use 11806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker this option to specify a path to that compiler. 11816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker If the given compiler is a cross compiler, you may also need to provide 11836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --analyzer-target option to properly analyze the source code because static 11846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker analyzer runs as if the code is compiled for the host machine by default. 11856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-c++ [compiler path] 11876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-c++=[compiler path] 11886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker This is the same as "--use-cc" but for C++ code. 11906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --analyzer-target [target triple name for analysis] 11926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --analyzer-target=[target triple name for analysis] 11936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker This provides target triple information to clang static analyzer. 11956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker It only changes the target for analysis but doesn't change the target of a 11966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker real compiler given by --use-cc and --use-c++ options. 11976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 11986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -v 11996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Enable verbose output from scan-build. A second and third '-v' increases 12016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker verbosity. 12026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -V 12046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --view 12056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker View analysis results in a web browser when the build completes. 12076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerADVANCED OPTIONS: 12096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -no-failure-reports 12116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Do not create a 'failures' subdirectory that includes analyzer crash reports 12136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker and preprocessed source files. 12146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -stats 12166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Generates visitation statistics for the project being analyzed. 12186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -maxloop <loop count> 12206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Specifiy the number of times a block can be visited before giving up. 12226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Default is 4. Increase for more comprehensive coverage at a cost of speed. 12236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -internal-stats 12256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Generate internal analyzer statistics. 12276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-analyzer [Xcode|path to clang] 12296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --use-analyzer=[Xcode|path to clang] 12306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker scan-build uses the 'clang' executable relative to itself for static 12326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker analysis. One can override this behavior with this option by using the 12336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'clang' packaged with Xcode (on OS X) or from the PATH. 12346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --keep-empty 12366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Don't remove the build results directory even if no issues were reported. 12386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker --override-compiler 12406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Always resort to the ccc-analyzer even when better interposition methods 12416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker are available. 12426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -analyzer-config <options> 12446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Provide options to pass through to the analyzer's -analyzer-config flag. 12466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Several options are separated with comma: 'key1=val1,key2=val2' 12476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Available options: 12496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker * stable-report-filename=true or false (default) 12506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Switch the page naming to: 12516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker report-<filename>-<function/method name>-<id>.html 12526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker instead of report-XXXXXX.html 12536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerCONTROLLING CHECKERS: 12556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker A default group of checkers are always run unless explicitly disabled. 12576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Checkers may be enabled/disabled using the following options: 12586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -enable-checker [checker name] 12606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -disable-checker [checker name] 12616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerLOADING CHECKERS: 12636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Loading external checkers using the clang plugin interface: 12656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker -load-plugin [plugin library] 12676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 12686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $Clang && -x $Clang) { 12706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Query clang for list of checkers that are enabled. 12716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # create a list to load the plugins via the 'Xclang' command line 12736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # argument 12746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @PluginLoadCommandline_xclang; 12756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $param ( @{$Options{PluginsToLoad}} ) { 12766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline_xclang, "-Xclang" ); 12776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline_xclang, "-load" ); 12786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline_xclang, "-Xclang" ); 12796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline_xclang, $param ); 12806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 12816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my %EnabledCheckers; 12836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $lang ("c", "objective-c", "objective-c++", "c++") { 12846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ExecLine = join(' ', qq/"$Clang"/, @PluginLoadCommandline_xclang, "--analyze", "-x", $lang, "-", "-###", "2>&1", "|"); 12856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(PS, $ExecLine); 12866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while (<PS>) { 12876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $val (split /\s+/) { 12886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $val =~ s/\"//g; 12896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($val =~ /-analyzer-checker\=([^\s]+)/) { 12906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $EnabledCheckers{$1} = 1; 12916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 12926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 12936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 12946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 12956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 12966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Query clang for complete list of checkers. 12976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my @PluginLoadCommandline; 12986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $param ( @{$Options{PluginsToLoad}} ) { 12996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline, "-load" ); 13006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push ( @PluginLoadCommandline, $param ); 13016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ExecLine = join(' ', qq/"$Clang"/, "-cc1", @PluginLoadCommandline, "-analyzer-checker-help", "2>&1", "|"); 13046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker open(PS, $ExecLine); 13056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $foundCheckers = 0; 13066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while (<PS>) { 13076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (/CHECKERS:/) { 13086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $foundCheckers = 1; 13096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last; 13106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!$foundCheckers) { 13136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " *** Could not query Clang for the list of available checkers."; 13146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 13166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print("\nAVAILABLE CHECKERS:\n\n"); 13176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $skip = 0; 13186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while(<PS>) { 13196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (/experimental/) { 13206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $skip = 1; 13216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 13226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($skip) { 13246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next if (!/^\s\s[^\s]/); 13256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $skip = 0; 13266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker s/^\s\s//; 13286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (/^([^\s]+)/) { 13296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Is the checker enabled? 13306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $checker = $1; 13316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $enabled = 0; 13326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $aggregate = ""; 13336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker foreach my $domain (split /\./, $checker) { 13346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $aggregate .= $domain; 13356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($EnabledCheckers{$aggregate}) { 13366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $enabled =1; 13376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last; 13386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # append a dot, if an additional domain is added in the next iteration 13406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $aggregate .= "."; 13416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($enabled) { 13446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " + "; 13456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 13476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " "; 13486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 13516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " "; 13526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print $_; 13546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print "\nNOTE: \"+\" indicates that an analysis is enabled by default.\n"; 13566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker close PS; 13586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 13606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " *** Could not query Clang for the list of available checkers.\n"; 13616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (defined $ArgClangNotFoundErrMsg) { 13626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker print " *** Reason: $ArgClangNotFoundErrMsg\n"; 13636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 13656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerprint <<ENDTEXT 13676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerBUILD OPTIONS 13696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker You can specify any build option acceptable to the build command. 13716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerEXAMPLE 13736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker scan-build -o /tmp/myhtmldir make -j4 13756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerThe above example causes analysis reports to be deposited into a subdirectory 13776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerof "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different 13786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersubdirectory is created each time scan-build analyzes a project. The analyzer 13796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickershould support most parallel builds, but not distributed builds. 13806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerENDTEXT 13826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 13836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 13856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# HtmlEscape - HTML entity encode characters that are special in HTML 13866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 13876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub HtmlEscape { 13896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # copy argument to new variable so we don't clobber the original 13906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $arg = shift || ''; 13916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $tmp = $arg; 13926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $tmp =~ s/&/&/g; 13936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $tmp =~ s/</</g; 13946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $tmp =~ s/>/>/g; 13956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $tmp; 13966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 13976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 13986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 13996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# ShellEscape - backslash escape characters that are special to the shell 14006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 14016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub ShellEscape { 14036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # copy argument to new variable so we don't clobber the original 14046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $arg = shift || ''; 14056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } 14066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $arg; 14076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 14086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 14106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# FindClang - searches for 'clang' executable. 14116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 14126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub FindClang { 14146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Options{AnalyzerDiscoveryMethod}) { 14156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Clang = Cwd::realpath("$RealBin/bin/clang") if (-f "$RealBin/bin/clang"); 14166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Clang || ! -x $Clang) { 14176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Clang = Cwd::realpath("$RealBin/clang") if (-f "$RealBin/clang"); 14186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Clang || ! -x $Clang) { 14206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return "error: Cannot find an executable 'clang' relative to" . 14216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker " scan-build. Consider using --use-analyzer to pick a version of" . 14226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker " 'clang' to use for static analysis.\n"; 14236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 14266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{AnalyzerDiscoveryMethod} =~ /^[Xx]code$/) { 14276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $xcrun = `which xcrun`; 14286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $xcrun; 14296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($xcrun eq "") { 14306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return "Cannot find 'xcrun' to find 'clang' for analysis.\n"; 14316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Clang = `$xcrun -toolchain XcodeDefault -find clang`; 14336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker chomp $Clang; 14346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Clang eq "") { 14356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return "No 'clang' executable found by 'xcrun'\n"; 14366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 14396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Clang = $Options{AnalyzerDiscoveryMethod}; 14406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $Clang or not -x $Clang) { 14416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return "Cannot find an executable clang at '$Options{AnalyzerDiscoveryMethod}'\n"; 14426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return undef; 14466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 14476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 14496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Process command-line arguments. 14506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker##----------------------------------------------------------------------------## 14516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $RequestDisplayHelp = 0; 14536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ForceDisplayHelp = 0; 14546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickersub ProcessArgs { 14566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Args = shift; 14576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $NumArgs = 0; 14586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker while (@$Args) { 14606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $NumArgs++; 14626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Scan for options we recognize. 14646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $arg = $Args->[0]; 14666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-h" or $arg eq "--help") { 14686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $RequestDisplayHelp = 1; 14696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 14706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 14716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq '-analyze-headers') { 14746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 14756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzeHeaders} = 1; 14766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 14776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-o") { 14806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 14816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!@$Args) { 14836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'-o' option requires a target directory name.\n"); 14846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Construct an absolute path. Uses the current working directory 14876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # as a base if the original path was not absolute. 14886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $OutDir = shift @$Args; 14896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker mkpath($OutDir) unless (-e $OutDir); # abs_path wants existing dir 14906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{OutputDir} = abs_path($OutDir); 14916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 14936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 14946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /^--html-title(=(.+))?$/) { 14966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 14976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 14986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $2 || $2 eq '') { 14996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!@$Args) { 15006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'--html-title' option requires a string.\n"); 15016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{HtmlTitle} = shift @$Args; 15046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } else { 15056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{HtmlTitle} = $2; 15066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-k" or $arg eq "--keep-going") { 15126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{IgnoreErrors} = 1; 15146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /^--use-cc(=(.+))?$/) { 15186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $cc; 15206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $2 || $2 eq "") { 15226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!@$Args) { 15236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'--use-cc' option requires a compiler executable name.\n"); 15246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $cc = shift @$Args; 15266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 15286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $cc = $2; 15296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{UseCC} = $cc; 15326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /^--use-c\+\+(=(.+))?$/) { 15366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $cxx; 15386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $2 || $2 eq "") { 15406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!@$Args) { 15416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'--use-c++' option requires a compiler executable name.\n"); 15426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $cxx = shift @$Args; 15446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 15466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $cxx = $2; 15476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{UseCXX} = $cxx; 15506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /^--analyzer-target(=(.+))?$/) { 15546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @ARGV; 15556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $AnalyzerTarget; 15566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!defined $2 || $2 eq "") { 15586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (!@ARGV) { 15596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'--analyzer-target' option requires a target triple name.\n"); 15606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $AnalyzerTarget = shift @ARGV; 15626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 15646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $AnalyzerTarget = $2; 15656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzerTarget} = $AnalyzerTarget; 15686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-v") { 15726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{Verbose}++; 15746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-V" or $arg eq "--view") { 15786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{ViewResults} = 1; 15806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "--status-bugs") { 15846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{ExitStatusFoundBugs} = 1; 15866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-store") { 15906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{StoreModel} = shift @$Args; 15926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 15946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 15956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-constraints") { 15966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 15976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{ConstraintsModel} = shift @$Args; 15986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 15996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-internal-stats") { 16026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{InternalStats} = 1; 16046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-plist") { 16086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{OutputFormat} = "plist"; 16106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-plist-html") { 16146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{OutputFormat} = "plist-html"; 16166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-analyzer-config") { 16206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @{$Options{ConfigOptions}}, shift @$Args; 16226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-no-failure-reports") { 16266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{ReportFailures} = 0; 16286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-stats") { 16326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzerStats} = 1; 16346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-maxloop") { 16386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{MaxLoop} = shift @$Args; 16406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-enable-checker") { 16446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Checker = shift @$Args; 16466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Store $NumArgs to preserve the order the checkers were enabled. 16476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{EnableCheckers}{$Checker} = $NumArgs; 16486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker delete $Options{DisableCheckers}{$Checker}; 16496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-disable-checker") { 16536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $Checker = shift @$Args; 16556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Store $NumArgs to preserve the order the checkers were disabled. 16566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{DisableCheckers}{$Checker} = $NumArgs; 16576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker delete $Options{EnableCheckers}{$Checker}; 16586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "-load-plugin") { 16626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @{$Options{PluginsToLoad}}, shift @$Args; 16646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "--use-analyzer") { 16686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzerDiscoveryMethod} = shift @$Args; 16706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg =~ /^--use-analyzer=(.+)$/) { 16746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzerDiscoveryMethod} = $1; 16766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "--keep-empty") { 16806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{KeepEmpty} = 1; 16826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "--override-compiler") { 16866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{OverrideCompiler} = 1; 16886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($arg eq "--force-analyze-debug-code") { 16926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker shift @$Args; 16936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{ForceAnalyzeDebugCode} = 1; 16946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker next; 16956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 16966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); 16986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 16996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $NumArgs--; 17006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker last; 17016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 17026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker return $NumArgs; 17036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (!@ARGV) { 17066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ForceDisplayHelp = 1 17076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerProcessArgs(\@ARGV); 17106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# All arguments are now shifted from @ARGV. The rest is a build command, if any. 17116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (!@ARGV and !$RequestDisplayHelp) { 17136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker ErrorDiag("No build command specified.\n\n"); 17146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ForceDisplayHelp = 1; 17156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ClangNotFoundErrMsg = FindClang(); 17186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif ($ForceDisplayHelp || $RequestDisplayHelp) { 17206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DisplayHelp($ClangNotFoundErrMsg); 17216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exit $ForceDisplayHelp; 17226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerDieDiag($ClangNotFoundErrMsg) if (defined $ClangNotFoundErrMsg); 17256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker$ClangCXX = $Clang; 17276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif ($Clang !~ /\+\+(\.exe)?$/) { 17286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # If $Clang holds the name of the clang++ executable then we leave 17296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # $ClangCXX and $Clang equal, otherwise construct the name of the clang++ 17306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # executable from the clang executable name. 17316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Determine operating system under which this copy of Perl was built. 17336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $IsWinBuild = ($^O =~/msys|cygwin|MSWin32/); 17346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if($IsWinBuild) { 17356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ClangCXX =~ s/.exe$/++.exe/; 17366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 17376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker else { 17386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ClangCXX =~ s/\-\d+\.\d+$//; 17396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $ClangCXX .= "++"; 17406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 17416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Make sure to use "" to handle paths with spaces. 17446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker$ClangVersion = HtmlEscape(`"$Clang" --version`); 17456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Determine where results go. 17476bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); 17486bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17496bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Determine the output directory for the HTML reports. 17506bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $BaseDir = $Options{OutputDir}; 17516bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker$Options{OutputDir} = GetHTMLRunDir($Options{OutputDir}); 17526bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17536bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Determine the location of ccc-analyzer. 17546bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $AbsRealBin = Cwd::realpath($RealBin); 17556bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $Cmd = "$AbsRealBin/../libexec/ccc-analyzer"; 17566bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CmdCXX = "$AbsRealBin/../libexec/c++-analyzer"; 17576bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17586bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Portability: use less strict but portable check -e (file exists) instead of 17596bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# non-portable -x (file is executable). On some windows ports -x just checks 17606bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# file extension to determine if a file is executable (see Perl language 17616bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# reference, perlport) 17626bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (!defined $Cmd || ! -e $Cmd) { 17636bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Cmd = "$AbsRealBin/ccc-analyzer"; 17646bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'ccc-analyzer' does not exist at '$Cmd'\n") if(! -e $Cmd); 17656bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17666bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (!defined $CmdCXX || ! -e $CmdCXX) { 17676bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $CmdCXX = "$AbsRealBin/c++-analyzer"; 17686bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker DieDiag("'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -e $CmdCXX); 17696bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17706bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17716bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerDiag("Using '$Clang' for static analysis\n"); 17726bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17736bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerSetHtmlEnv(\@ARGV, $Options{OutputDir}); 17746bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17756bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy @AnalysesToRun; 17766bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerforeach (sort { $Options{EnableCheckers}{$a} <=> $Options{EnableCheckers}{$b} } 17776bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys %{$Options{EnableCheckers}}) { 17786bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Push checkers in order they were enabled. 17796bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @AnalysesToRun, "-analyzer-checker", $_; 17806bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17816bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerforeach (sort { $Options{DisableCheckers}{$a} <=> $Options{DisableCheckers}{$b} } 17826bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker keys %{$Options{DisableCheckers}}) { 17836bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Push checkers in order they were disabled. 17846bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker push @AnalysesToRun, "-analyzer-disable-checker", $_; 17856bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 17866bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif ($Options{AnalyzeHeaders}) { push @AnalysesToRun, "-analyzer-opt-analyze-headers"; } 17876bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif ($Options{AnalyzerStats}) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; } 17886bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif ($Options{MaxLoop} > 0) { push @AnalysesToRun, "-analyzer-max-loop $Options{MaxLoop}"; } 17896bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 17906bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Delay setting up other environment variables in case we can do true 17916bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# interposition. 17926bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CCC_ANALYZER_ANALYSIS = join ' ', @AnalysesToRun; 17936bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CCC_ANALYZER_PLUGINS = join ' ', map { "-load ".$_ } @{$Options{PluginsToLoad}}; 17946bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $CCC_ANALYZER_CONFIG = join ' ', map { "-analyzer-config ".$_ } @{$Options{ConfigOptions}}; 17956bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy %EnvVars = ( 17966bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CC' => $Cmd, 17976bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CXX' => $CmdCXX, 17986bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CLANG' => $Clang, 17996bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CLANG_CXX' => $ClangCXX, 18006bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'VERBOSE' => $Options{Verbose}, 18016bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS, 18026bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS, 18036bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_CONFIG' => $CCC_ANALYZER_CONFIG, 18046bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'OUTPUT_DIR' => $Options{OutputDir}, 18056bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_CC' => $Options{UseCC}, 18066bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_CXX' => $Options{UseCXX}, 18076bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_REPORT_FAILURES' => $Options{ReportFailures}, 18086bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_STORE_MODEL' => $Options{StoreModel}, 18096bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_CONSTRAINTS_MODEL' => $Options{ConstraintsModel}, 18106bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_INTERNAL_STATS' => $Options{InternalStats}, 18116bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_OUTPUT_FORMAT' => $Options{OutputFormat}, 18126bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CLANG_ANALYZER_TARGET' => $Options{AnalyzerTarget}, 18136bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 'CCC_ANALYZER_FORCE_ANALYZE_DEBUG_CODE' => $Options{ForceAnalyzeDebugCode} 18146bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker); 18156bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 18166bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker# Run the build. 18176bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickermy $ExitStatus = RunBuildCommand(\@ARGV, $Options{IgnoreErrors}, $Cmd, $CmdCXX, 18186bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker \%EnvVars); 18196bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 18206bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerif (defined $Options{OutputFormat}) { 18216bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{OutputFormat} =~ /plist/) { 18226bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag "Analysis run complete.\n"; 18236bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag "Analysis results (plist files) deposited in '$Options{OutputDir}'\n"; 18246bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 18256bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{OutputFormat} =~ /html/) { 18266bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker # Postprocess the HTML directory. 18276bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $NumBugs = Postprocess($Options{OutputDir}, $BaseDir, 18286bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker $Options{AnalyzerStats}, $Options{KeepEmpty}); 18296bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 18306bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{ViewResults} and -r "$Options{OutputDir}/index.html") { 18316bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag "Analysis run complete.\n"; 18326bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker Diag "Viewing analysis results in '$Options{OutputDir}' using scan-view.\n"; 18336bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker my $ScanView = Cwd::realpath("$RealBin/scan-view"); 18346bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -x $ScanView) { $ScanView = "scan-view"; } 18356bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if (! -x $ScanView) { $ScanView = Cwd::realpath("$RealBin/../../scan-view/bin/scan-view"); } 18366bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exec $ScanView, "$Options{OutputDir}"; 18376bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 18386bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 18396bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker if ($Options{ExitStatusFoundBugs}) { 18406bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exit 1 if ($NumBugs > 0); 18416bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker exit 0; 18426bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 18436bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker } 18446bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker} 18456bdbd720989797e8a53237ef3ef213c4114f869gitbuildkicker 18466bdbd720989797e8a53237ef3ef213c4114f869gitbuildkickerexit $ExitStatus; 1847