From 9cc8c2cc79d8c91627c0dcc5cb679aad4e37c7f5 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 1 Apr 2008 20:47:38 +0000 Subject: [PATCH] Initial checking of 'scan-build' script, a script used to wrap builds and interpose calls to gcc with calls to the analyzer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49049 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/scan-build | 246 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100755 utils/scan-build diff --git a/utils/scan-build b/utils/scan-build new file mode 100755 index 0000000000..4d86040976 --- /dev/null +++ b/utils/scan-build @@ -0,0 +1,246 @@ +#!/usr/bin/env perl +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# A script designed to wrap a build so that all calls to gcc are intercepted +# and piped to the static analyzer. +# +##===----------------------------------------------------------------------===## + +use strict; +use warnings; +use File::Temp qw/ :mktemp /; + +my $Verbose = 0; # Verbose output from this script. +my $Prog = "scan-build"; + +##----------------------------------------------------------------------------## +# GetHTMLRunDir - Construct an HTML directory name for the current run. +##----------------------------------------------------------------------------## + +sub GetHTMLRunDir() { + + die "Not enough arguments." if (@_ == 0); + + my $Dir = shift @_; + + # Get current date and time. + + my @CurrentTime = localtime(); + + my $year = $CurrentTime[5] + 1900; + my $day = $CurrentTime[3]; + my $month = $CurrentTime[4] + 1; + + my $DateString = "$year-$month-$day"; + + # Determine the run number. + + my $RunNumber; + + if (-d $Dir) { + + if (! -r $Dir) { + print STDERR "error: '$Dir' exists but is not readable.\n"; + exit 0; + } + + # Iterate over all files in the specified directory. + + my $max = 0; + + opendir(DIR, $Dir); + my @FILES= readdir(DIR); + closedir(DIR); + + foreach my $f (@FILES) { + + my @x = split/-/, $f; + + next if (scalar(@x) != 4); + next if ($x[0] != $year); + next if ($x[1] != $month); + next if ($x[2] != $day); + + if ($x[3] > $max) { + $max = $x[3]; + } + } + + $RunNumber = $max + 1; + } + else { + + if (-x $Dir) { + print STDERR "error: '$Dir' exists but is not a directory.\n"; + exit 0; + } + + # $Dir does not exist. It will be automatically created by the + # clang driver. Set the run number to 1. + + $RunNumber = 1; + } + + die "RunNumber must be defined!" if (!defined($RunNumber)); + + # Append the run number. + + return "$Dir/$DateString-$RunNumber"; +} + +sub SetHtmlEnv() { + + die "Wrong number of arguments." if (scalar(@_) != 2); + + my $Args = shift; + my $Dir = shift; + + die "No build command." if (scalar(@$Args) == 0); + + my $Cmd = $$Args[0]; + + if ($Cmd =~ /configure/) { + return; + } + + if ($Verbose) { + print "$Prog: Emitting reports for this run to '$Dir'.\n"; + } + + $ENV{'CCC_ANALYZER_HTML'} = $Dir; +} + +##----------------------------------------------------------------------------## +# Postprocess - Postprocess the results of an analysis scan. +##----------------------------------------------------------------------------## + +sub Postprocess() { + + my $Dir = shift; + + die "No directory specified." if (!defined($Dir)); + + if (! -d $Dir) { + return; + } + + opendir(DIR, $Dir); + my @files = grep(/^report-.*\.html$/,readdir(DIR)); + closedir(DIR); + + if (scalar(@files) == 0) { + print "$Prog: Remove directory '$Dir' because it contains no reports.\n"; + `rm -fR $Dir`; + return; + } + + +} + +##----------------------------------------------------------------------------## +# DisplayHelp - Utility function to display all help options. +##----------------------------------------------------------------------------## + +sub DisplayHelp() { + + + +} + +##----------------------------------------------------------------------------## +# Process command-line arguments. +##----------------------------------------------------------------------------## + +my $HtmlDir; # Parent directory to store HTML files. +my $IgnoreErrors = 0; # Ignore build errors. + +if (!@ARGV) { + DisplayHelp(); + exit 1 +} + +while (@ARGV) { + + # Scan for options we recognize. + + my $arg = $ARGV[0]; + + if ($arg eq "-?") { + DisplayHelp(); + exit 1; + } + + if ($arg eq "-o") { + shift @ARGV; + + if (!@ARGV) { + print STDERR "'-o' option requires a target directory name."; + exit 0; + } + + $HtmlDir = shift @ARGV; + next; + } + + if ($arg eq "-k") { + shift @ARGV; + $IgnoreErrors = 1; + next; + } + + if ($arg eq "-v") { + shift @ARGV; + $Verbose++; + next; + } + + last; +} + +if (!@ARGV) { + print STDERR "$Prog: No build command specified.\n\n"; + DisplayHelp(); + exit 0; +} + +# Determine the output directory for the HTML reports. + +if (!defined($HtmlDir)) { + + $HtmlDir = mkdtemp("/tmp/scan-build-XXXXXX"); + + if (!defined($HtmlDir)) { + print STDERR "error: Cannot create HTML directory in /tmp.\n"; + exit 0; + } + + if (!$Verbose) { + print "$Prog: Using '$HtmlDir' as base HTML report directory.\n"; + } +} + +$HtmlDir = &GetHTMLRunDir($HtmlDir); + +# Set the appropriate environment variables. + +&SetHtmlEnv(\@ARGV, $HtmlDir); + +$ENV{'CC'} = "ccc-analyzer"; + +if ($Verbose >= 2) { + $ENV{'CCC_ANALYZER_VERBOSE'} = 1; +} + +# Run the build. + +system(@ARGV); + +# Postprocess the HTML directory. + +&Postprocess($HtmlDir); -- 2.40.0