[cfe-commits] r90215 - in /cfe/trunk: tools/scan-build/ tools/scan-build/ccc-analyzer tools/scan-build/scan-build tools/scan-build/scanview.css tools/scan-build/sorttable.js utils/ccc-analyzer utils/scan-build utils/scanview.css utils/sorttable.js www/analyzer/installation.html
Ted Kremenek
kremenek at apple.com
Mon Nov 30 23:42:53 PST 2009
Great! Thanks!
On Nov 30, 2009, at 10:52 PM, Kovarththanan Rajaratnam wrote:
> Author: krj
> Date: Tue Dec 1 00:52:01 2009
> New Revision: 90215
>
> URL: http://llvm.org/viewvc/llvm-project?rev=90215&view=rev
> Log:
> Tuck away scan-build related files into tools/scan-build
>
> Added:
> cfe/trunk/tools/scan-build/
> cfe/trunk/tools/scan-build/ccc-analyzer (props changed)
> - copied unchanged from r90212, cfe/trunk/utils/ccc-analyzer
> cfe/trunk/tools/scan-build/scan-build (props changed)
> - copied unchanged from r90212, cfe/trunk/utils/scan-build
> cfe/trunk/tools/scan-build/scanview.css (props changed)
> - copied unchanged from r90212, cfe/trunk/utils/scanview.css
> cfe/trunk/tools/scan-build/sorttable.js (props changed)
> - copied unchanged from r90212, cfe/trunk/utils/sorttable.js
> Removed:
> cfe/trunk/utils/ccc-analyzer
> cfe/trunk/utils/scan-build
> cfe/trunk/utils/scanview.css
> cfe/trunk/utils/sorttable.js
> Modified:
> cfe/trunk/www/analyzer/installation.html
>
> Propchange: cfe/trunk/tools/scan-build/ccc-analyzer
>
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Propchange: cfe/trunk/tools/scan-build/ccc-analyzer
>
> ------------------------------------------------------------------------------
> svn:mergeinfo =
>
> Propchange: cfe/trunk/tools/scan-build/scan-build
>
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Propchange: cfe/trunk/tools/scan-build/scan-build
>
> ------------------------------------------------------------------------------
> svn:mergeinfo =
>
> Propchange: cfe/trunk/tools/scan-build/scanview.css
>
> ------------------------------------------------------------------------------
> svn:mergeinfo =
>
> Propchange: cfe/trunk/tools/scan-build/sorttable.js
>
> ------------------------------------------------------------------------------
> svn:mergeinfo =
>
> Removed: cfe/trunk/utils/ccc-analyzer
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ccc-analyzer?rev=90214&view=auto
>
> ==============================================================================
> --- cfe/trunk/utils/ccc-analyzer (original)
> +++ cfe/trunk/utils/ccc-analyzer (removed)
> @@ -1,632 +0,0 @@
> -#!/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 interpose between the build system and gcc. It invokes
> -# both gcc and the static analyzer.
> -#
> -##===----------------------------------------------------------------------===##
> -
> -use strict;
> -use warnings;
> -use Cwd qw/ getcwd abs_path /;
> -use File::Temp qw/ tempfile /;
> -use File::Path qw / mkpath /;
> -use File::Basename;
> -use Text::ParseWords;
> -
> -my $CC = $ENV{'CCC_CC'};
> -if (!defined $CC) { $CC = "gcc"; }
> -
> -my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
> -if (!defined $ReportFailures) { $ReportFailures = 1; }
> -
> -my $CleanupFile;
> -my $ResultFile;
> -
> -# Remove any stale files at exit.
> -END {
> - if (defined $CleanupFile && -z $CleanupFile) {
> - `rm -f $CleanupFile`;
> - }
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Process Clang Crashes.
> -##----------------------------------------------------------------------------##
> -
> -sub GetPPExt {
> - my $Lang = shift;
> - if ($Lang =~ /objective-c/) { return ".mi"; }
> - return ".i";
> -}
> -
> -# Set this to 1 if we want to include 'parser rejects' files.
> -my $IncludeParserRejects = 0;
> -my $ParserRejects = "Parser Rejects";
> -
> -my $AttributeIgnored = "Attribute Ignored";
> -
> -sub ProcessClangFailure {
> - my ($ClangCC, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
> - my $Dir = "$HtmlDir/failures";
> - mkpath $Dir;
> -
> - my $prefix = "clang_crash";
> - if ($ErrorType eq $ParserRejects) {
> - $prefix = "clang_parser_rejects";
> - }
> - elsif ($ErrorType eq $AttributeIgnored) {
> - $prefix = "clang_attribute_ignored";
> - }
> -
> - # Generate the preprocessed file with Clang.
> - my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
> - SUFFIX => GetPPExt($Lang),
> - DIR => $Dir);
> - system $ClangCC, @$Args, "-E", "-o", $PPFile;
> - close ($PPH);
> -
> - # Create the info file.
> - open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
> - print OUT abs_path($file), "\n";
> - print OUT "$ErrorType\n";
> - print OUT "@$Args\n";
> - close OUT;
> - `uname -a >> $PPFile.info.txt 2>&1`;
> - `$CC -v >> $PPFile.info.txt 2>&1`;
> - system 'mv',$ofile,"$PPFile.stderr.txt";
> - return (basename $PPFile);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Running the analyzer.
> -##----------------------------------------------------------------------------##
> -
> -# Determine what clang executable to use.
> -my $Clang = $ENV{'CLANG'};
> -if (!defined $Clang) { $Clang = 'clang'; }
> -
> -sub GetCCArgs {
> - my $Args = shift;
> -
> - pipe (FROM_CHILD, TO_PARENT);
> - my $pid = fork();
> - if ($pid == 0) {
> - close FROM_CHILD;
> - open(STDOUT,">&", \*TO_PARENT);
> - open(STDERR,">&", \*TO_PARENT);
> - exec $Clang, "-###", "-fsyntax-only", @$Args;
> - }
> - close(TO_PARENT);
> - my $line;
> - while (<FROM_CHILD>) {
> - next if (!/clang-cc/);
> - $line = $_;
> - }
> -
> - waitpid($pid,0);
> - close(FROM_CHILD);
> -
> - die "could not find clang-cc line\n" if (!defined $line);
> - # Strip the newline and initial whitspace
> - chomp $line;
> - $line =~ s/^\s+//;
> -
> - my @items = quotewords('\s+', 1, $line);
> - for (my $i = 0 ; $ i < scalar(@items); ++$i) {
> - $items[$i] =~ s/^\"//;
> - $items[$i] =~ s/\"$//;
> - }
> - my $cmd = shift @items;
> - die "cannot find 'clang-cc' in 'clang' command\n" if (!($cmd =~ /clang-cc/));
> - return \@items;
> -}
> -
> -sub Analyze {
> - my ($ClangCC, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
> - $file, $Analyses) = @_;
> -
> - $Args = GetCCArgs($Args);
> -
> - # Skip anything related to C++.
> - return if ($Lang =~ /c[+][+]/);
> -
> - my $RunAnalyzer = 0;
> - my $Cmd;
> - my @CmdArgs;
> - my @CmdArgsSansAnalyses;
> -
> - if ($Lang =~ /header/) {
> - exit 0 if (!defined ($Output));
> - $Cmd = 'cp';
> - push @CmdArgs,$file;
> - # Remove the PCH extension.
> - $Output =~ s/[.]gch$//;
> - push @CmdArgs,$Output;
> - @CmdArgsSansAnalyses = @CmdArgs;
> - }
> - else {
> - $Cmd = $ClangCC;
> - push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
> - push @CmdArgs,@$Args;
> - @CmdArgsSansAnalyses = @CmdArgs;
> - push @CmdArgs,'-analyze';
> - push @CmdArgs,"-analyzer-display-progress";
> - push @CmdArgs,"-analyzer-eagerly-assume";
> - push @CmdArgs,(split /\s/,$Analyses);
> -
> - if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) {
> - push @CmdArgs,"-analyzer-experimental-internal-checks";
> - push @CmdArgs,"-analyzer-experimental-checks";
> - }
> -
> - $RunAnalyzer = 1;
> - }
> -
> - # Add the analysis arguments passed down from scan-build.
> - foreach my $Arg (@$AnalyzeArgs) {
> - push @CmdArgs, $Arg;
> - }
> -
> - my @PrintArgs;
> - my $dir;
> -
> - if ($RunAnalyzer) {
> - if (defined $ResultFile) {
> - push @CmdArgs,'-o';
> - push @CmdArgs, $ResultFile;
> - }
> - elsif (defined $HtmlDir) {
> - push @CmdArgs,'-o';
> - push @CmdArgs, $HtmlDir;
> - }
> - }
> -
> - if ($Verbose) {
> - $dir = getcwd();
> - print STDERR "\n[LOCATION]: $dir\n";
> - push @PrintArgs,"'$Cmd'";
> - foreach my $arg (@CmdArgs) { push @PrintArgs,"\'$arg\'"; }
> - }
> -
> - if ($Verbose == 1) {
> - # We MUST print to stderr. Some clients use the stdout output of
> - # gcc for various purposes.
> - print STDERR join(' ', at PrintArgs);
> - print STDERR "\n";
> - }
> - elsif ($Verbose == 2) {
> - print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n";
> - }
> -
> - if (defined $ENV{'CCC_UBI'}) {
> - push @CmdArgs,"--analyzer-viz-egraph-ubigraph";
> - }
> -
> - # Capture the STDERR of clang and send it to a temporary file.
> - # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
> - # We save the output file in the 'crashes' directory if clang encounters
> - # any problems with the file.
> - pipe (FROM_CHILD, TO_PARENT);
> - my $pid = fork();
> - if ($pid == 0) {
> - close FROM_CHILD;
> - open(STDOUT,">&", \*TO_PARENT);
> - open(STDERR,">&", \*TO_PARENT);
> - exec $Cmd, @CmdArgs;
> - }
> -
> - close TO_PARENT;
> - my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
> -
> - while (<FROM_CHILD>) {
> - print $ofh $_;
> - print STDERR $_;
> - }
> -
> - waitpid($pid,0);
> - close(FROM_CHILD);
> - my $Result = $?;
> -
> - # Did the command die because of a signal?
> - if ($ReportFailures) {
> - if ($Result & 127 and $Cmd eq $ClangCC and defined $HtmlDir) {
> - ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses,
> - $HtmlDir, "Crash", $ofile);
> - }
> - elsif ($Result) {
> - if ($IncludeParserRejects && !($file =~/conftest/)) {
> - ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses,
> - $HtmlDir, $ParserRejects, $ofile);
> - }
> - }
> - else {
> - # Check if there were any unhandled attributes.
> - if (open(CHILD, $ofile)) {
> - my %attributes_not_handled;
> -
> - # Don't flag warnings about the following attributes that we
> - # know are currently not supported by Clang.
> - $attributes_not_handled{"cdecl"} = 1;
> -
> - my $ppfile;
> - while (<CHILD>) {
> - next if (! /warning: '([^\']+)' attribute ignored/);
> -
> - # Have we already spotted this unhandled attribute?
> - next if (defined $attributes_not_handled{$1});
> - $attributes_not_handled{$1} = 1;
> -
> - # Get the name of the attribute file.
> - my $dir = "$HtmlDir/failures";
> - my $afile = "$dir/attribute_ignored_$1.txt";
> -
> - # Only create another preprocessed file if the attribute file
> - # doesn't exist yet.
> - next if (-e $afile);
> -
> - # Add this file to the list of files that contained this attribute.
> - # Generate a preprocessed file if we haven't already.
> - if (!(defined $ppfile)) {
> - $ppfile = ProcessClangFailure($ClangCC, $Lang, $file,
> - \@CmdArgsSansAnalyses,
> - $HtmlDir, $AttributeIgnored, $ofile);
> - }
> -
> - mkpath $dir;
> - open(AFILE, ">$afile");
> - print AFILE "$ppfile\n";
> - close(AFILE);
> - }
> - close CHILD;
> - }
> - }
> - }
> -
> - unlink($ofile);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Lookup tables.
> -##----------------------------------------------------------------------------##
> -
> -my %CompileOptionMap = (
> - '-nostdinc' => 0,
> - '-fblocks' => 0,
> - '-fobjc-gc-only' => 0,
> - '-fobjc-gc' => 0,
> - '-ffreestanding' => 0,
> - '-include' => 1,
> - '-idirafter' => 1,
> - '-iprefix' => 1,
> - '-iquote' => 1,
> - '-isystem' => 1,
> - '-iwithprefix' => 1,
> - '-iwithprefixbefore' => 1
> -);
> -
> -my %LinkerOptionMap = (
> - '-framework' => 1
> -);
> -
> -my %CompilerLinkerOptionMap = (
> - '-isysroot' => 1,
> - '-arch' => 1,
> - '-v' => 0,
> - '-fpascal-strings' => 0,
> - '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
> - '-miphoneos-version-min' => 0 # This is really a 1 argument, but always has '='
> -);
> -
> -my %IgnoredOptionMap = (
> - '-MT' => 1, # Ignore these preprocessor options.
> - '-MF' => 1,
> -
> - '-fsyntax-only' => 0,
> - '-save-temps' => 0,
> - '-install_name' => 1,
> - '-exported_symbols_list' => 1,
> - '-current_version' => 1,
> - '-compatibility_version' => 1,
> - '-init' => 1,
> - '-e' => 1,
> - '-seg1addr' => 1,
> - '-bundle_loader' => 1,
> - '-multiply_defined' => 1,
> - '-sectorder' => 3,
> - '--param' => 1,
> - '-u' => 1
> -);
> -
> -my %LangMap = (
> - 'c' => 'c',
> - 'cpp' => 'c++',
> - 'cc' => 'c++',
> - 'i' => 'c-cpp-output',
> - 'm' => 'objective-c',
> - 'mi' => 'objective-c-cpp-output'
> -);
> -
> -my %UniqueOptions = (
> - '-isysroot' => 0
> -);
> -
> -my %LangsAccepted = (
> - "objective-c" => 1,
> - "c" => 1
> -);
> -
> -##----------------------------------------------------------------------------##
> -# Main Logic.
> -##----------------------------------------------------------------------------##
> -
> -my $Action = 'link';
> -my @CompileOpts;
> -my @LinkOpts;
> -my @Files;
> -my $Lang;
> -my $Output;
> -my %Uniqued;
> -
> -# Forward arguments to gcc.
> -my $Status = system($CC, at ARGV);
> -if ($Status) { exit($Status >> 8); }
> -
> -# Get the analysis options.
> -my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'};
> -if (!defined($Analyses)) { $Analyses = '-checker-cfref'; }
> -
> -# Get the store model.
> -my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'};
> -if (!defined $StoreModel) { $StoreModel = "region"; }
> -
> -# Get the constraints engine.
> -my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'};
> -if (!defined $ConstraintsModel) { $ConstraintsModel = "range"; }
> -
> -# Get the output format.
> -my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
> -if (!defined $OutputFormat) { $OutputFormat = "html"; }
> -
> -# Determine the level of verbosity.
> -my $Verbose = 0;
> -if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }
> -if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; }
> -
> -# Determine what clang-cc executable to use.
> -my $ClangCC = $ENV{'CLANG_CC'};
> -if (!defined $ClangCC) { $ClangCC = 'clang-cc'; }
> -
> -# Get the HTML output directory.
> -my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
> -
> -my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
> -my %ArchsSeen;
> -my $HadArch = 0;
> -
> -# Process the arguments.
> -foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
> - my $Arg = $ARGV[$i];
> - my ($ArgKey) = split /=/,$Arg,2;
> -
> - # Modes ccc-analyzer supports
> - if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; }
> - elsif ($Arg eq '-c') { $Action = 'compile'; }
> - elsif ($Arg =~ /^-print-prog-name/) { exit 0; }
> -
> - # Specially handle duplicate cases of -arch
> - if ($Arg eq "-arch") {
> - my $arch = $ARGV[$i+1];
> - # We don't want to process 'ppc' because of Clang's lack of support
> - # for Altivec (also some #defines won't likely be defined correctly, etc.)
> - if (!(defined $DisabledArchs{$arch})) { $ArchsSeen{$arch} = 1; }
> - $HadArch = 1;
> - ++$i;
> - next;
> - }
> -
> - # Options with possible arguments that should pass through to compiler.
> - if (defined $CompileOptionMap{$ArgKey}) {
> - my $Cnt = $CompileOptionMap{$ArgKey};
> - push @CompileOpts,$Arg;
> - while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
> - next;
> - }
> -
> - # Options with possible arguments that should pass through to linker.
> - if (defined $LinkerOptionMap{$ArgKey}) {
> - my $Cnt = $LinkerOptionMap{$ArgKey};
> - push @LinkOpts,$Arg;
> - while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; }
> - next;
> - }
> -
> - # Options with possible arguments that should pass through to both compiler
> - # and the linker.
> - if (defined $CompilerLinkerOptionMap{$ArgKey}) {
> - my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
> -
> - # Check if this is an option that should have a unique value, and if so
> - # determine if the value was checked before.
> - if ($UniqueOptions{$Arg}) {
> - if (defined $Uniqued{$Arg}) {
> - $i += $Cnt;
> - next;
> - }
> - $Uniqued{$Arg} = 1;
> - }
> -
> - push @CompileOpts,$Arg;
> - push @LinkOpts,$Arg;
> -
> - while ($Cnt > 0) {
> - ++$i; --$Cnt;
> - push @CompileOpts, $ARGV[$i];
> - push @LinkOpts, $ARGV[$i];
> - }
> - next;
> - }
> -
> - # Ignored options.
> - if (defined $IgnoredOptionMap{$ArgKey}) {
> - my $Cnt = $IgnoredOptionMap{$ArgKey};
> - while ($Cnt > 0) {
> - ++$i; --$Cnt;
> - }
> - next;
> - }
> -
> - # Compile mode flags.
> - if ($Arg =~ /^-[D,I,U](.*)$/) {
> - my $Tmp = $Arg;
> - if ($1 eq '') {
> - # FIXME: Check if we are going off the end.
> - ++$i;
> - $Tmp = $Arg . $ARGV[$i];
> - }
> - push @CompileOpts,$Tmp;
> - next;
> - }
> -
> - # Language.
> - if ($Arg eq '-x') {
> - $Lang = $ARGV[$i+1];
> - ++$i; next;
> - }
> -
> - # Output file.
> - if ($Arg eq '-o') {
> - ++$i;
> - $Output = $ARGV[$i];
> - next;
> - }
> -
> - # Get the link mode.
> - if ($Arg =~ /^-[l,L,O]/) {
> - if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
> - elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; }
> - else { push @LinkOpts,$Arg; }
> - next;
> - }
> -
> - if ($Arg =~ /^-std=/) {
> - push @CompileOpts,$Arg;
> - next;
> - }
> -
> -# if ($Arg =~ /^-f/) {
> -# # FIXME: Not sure if the remaining -fxxxx options have no arguments.
> -# push @CompileOpts,$Arg;
> -# push @LinkOpts,$Arg; # FIXME: Not sure if these are link opts.
> -# }
> -
> - # Get the compiler/link mode.
> - if ($Arg =~ /^-F(.+)$/) {
> - my $Tmp = $Arg;
> - if ($1 eq '') {
> - # FIXME: Check if we are going off the end.
> - ++$i;
> - $Tmp = $Arg . $ARGV[$i];
> - }
> - push @CompileOpts,$Tmp;
> - push @LinkOpts,$Tmp;
> - next;
> - }
> -
> - # Input files.
> - if ($Arg eq '-filelist') {
> - # FIXME: Make sure we aren't walking off the end.
> - open(IN, $ARGV[$i+1]);
> - while (<IN>) { s/\015?\012//; push @Files,$_; }
> - close(IN);
> - ++$i;
> - next;
> - }
> -
> - # Handle -Wno-. We don't care about extra warnings, but
> - # we should suppress ones that we don't want to see.
> - if ($Arg =~ /^-Wno-/) {
> - push @CompileOpts, $Arg;
> - next;
> - }
> -
> - if (!($Arg =~ /^-/)) {
> - push @Files, $Arg;
> - next;
> - }
> -}
> -
> -if ($Action eq 'compile' or $Action eq 'link') {
> - my @Archs = keys %ArchsSeen;
> - # Skip the file if we don't support the architectures specified.
> - exit 0 if ($HadArch && scalar(@Archs) == 0);
> -
> - foreach my $file (@Files) {
> - # Determine the language for the file.
> - my $FileLang = $Lang;
> -
> - if (!defined($FileLang)) {
> - # Infer the language from the extension.
> - if ($file =~ /[.]([^.]+)$/) {
> - $FileLang = $LangMap{$1};
> - }
> - }
> -
> - next if (!defined $FileLang);
> - next if (!defined $LangsAccepted{$FileLang});
> -
> - my @CmdArgs;
> - my @AnalyzeArgs;
> -
> - if ($FileLang ne 'unknown') {
> - push @CmdArgs,'-x';
> - push @CmdArgs,$FileLang;
> - }
> -
> - if (defined $StoreModel) {
> - push @AnalyzeArgs, "-analyzer-store=$StoreModel";
> - }
> -
> - if (defined $ConstraintsModel) {
> - push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
> - }
> -
> - if (defined $OutputFormat) {
> - push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;
> - if ($OutputFormat =~ /plist/) {
> - # Change "Output" to be a file.
> - my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
> - DIR => $HtmlDir);
> - $ResultFile = $f;
> - $CleanupFile = $f;
> - }
> - }
> -
> - push @CmdArgs, at CompileOpts;
> - push @CmdArgs,$file;
> -
> - if (scalar @Archs) {
> - foreach my $arch (@Archs) {
> - my @NewArgs;
> - push @NewArgs, '-arch';
> - push @NewArgs, $arch;
> - push @NewArgs, @CmdArgs;
> - Analyze($ClangCC, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
> - $Verbose, $HtmlDir, $file, $Analyses);
> - }
> - }
> - else {
> - Analyze($ClangCC, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
> - $Verbose, $HtmlDir, $file, $Analyses);
> - }
> - }
> -}
> -
> -exit($Status >> 8);
> -
>
> Removed: cfe/trunk/utils/scan-build
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/scan-build?rev=90214&view=auto
>
> ==============================================================================
> --- cfe/trunk/utils/scan-build (original)
> +++ cfe/trunk/utils/scan-build (removed)
> @@ -1,1297 +0,0 @@
> -#!/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 FindBin qw($RealBin);
> -use Digest::MD5;
> -use File::Basename;
> -use Term::ANSIColor;
> -use Term::ANSIColor qw(:constants);
> -use Cwd qw/ getcwd abs_path /;
> -use Sys::Hostname;
> -
> -my $Verbose = 0; # Verbose output from this script.
> -my $Prog = "scan-build";
> -my $BuildName;
> -my $BuildDate;
> -my $CXX; # Leave undefined initially.
> -
> -my $TERM = $ENV{'TERM'};
> -my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
> - and defined $ENV{'SCAN_BUILD_COLOR'});
> -
> -my $UserName = HtmlEscape(getpwuid($<) || 'unknown');
> -my $HostName = HtmlEscape(hostname() || 'unknown');
> -my $CurrentDir = HtmlEscape(getcwd());
> -my $CurrentDirSuffix = basename($CurrentDir);
> -
> -my $CmdArgs;
> -
> -my $HtmlTitle;
> -
> -my $Date = localtime();
> -
> -##----------------------------------------------------------------------------##
> -# Diagnostics
> -##----------------------------------------------------------------------------##
> -
> -sub Diag {
> - if ($UseColor) {
> - print BOLD, MAGENTA "$Prog: @_";
> - print RESET;
> - }
> - else {
> - print "$Prog: @_";
> - }
> -}
> -
> -sub DiagCrashes {
> - my $Dir = shift;
> - Diag ("The analyzer encountered problems on some source files.\n");
> - Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n");
> - Diag ("Please consider submitting a bug report using these files:\n");
> - Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
> -}
> -
> -sub DieDiag {
> - if ($UseColor) {
> - print BOLD, RED "$Prog: ";
> - print RESET, RED @_;
> - print RESET;
> - }
> - else {
> - print "$Prog: ", @_;
> - }
> - exit(0);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Some initial preprocessing of Clang options.
> -##----------------------------------------------------------------------------##
> -
> -# First, look for 'clang-cc' in libexec.
> -my $ClangCCSB = Cwd::realpath("$RealBin/libexec/clang-cc");
> -# Second, look for 'clang-cc' in the same directory as scan-build.
> -if (!defined $ClangCCSB || ! -x $ClangCCSB) {
> - $ClangCCSB = Cwd::realpath("$RealBin/clang-cc");
> -}
> -# Third, look for 'clang-cc' in ../libexec
> -if (!defined $ClangCCSB || ! -x $ClangCCSB) {
> - $ClangCCSB = Cwd::realpath("$RealBin/../libexec/clang-cc");
> -}
> -# Finally, default to looking for 'clang-cc' in the path.
> -if (!defined $ClangCCSB || ! -x $ClangCCSB) {
> - $ClangCCSB = "clang-cc";
> -}
> -my $ClangCC = $ClangCCSB;
> -
> -# Now find 'clang'
> -my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
> -if (!defined $ClangSB || ! -x $ClangSB) {
> - $ClangSB = Cwd::realpath("$RealBin/clang");
> -}
> -# Third, look for 'clang' in ../bin
> -if (!defined $ClangSB || ! -x $ClangSB) {
> - $ClangSB = Cwd::realpath("$RealBin/../bin/clang");
> -}
> -# Finally, default to looking for 'clang-cc' in the path.
> -if (!defined $ClangSB || ! -x $ClangSB) {
> - $ClangSB = "clang";
> -}
> -my $Clang = $ClangSB;
> -
> -
> -my %AvailableAnalyses;
> -
> -# Query clang for analysis options.
> -open(PIPE, "-|", $ClangCC, "--help") or
> - DieDiag("Cannot execute '$ClangCC'\n");
> -
> -my $FoundAnalysis = 0;
> -
> -while(<PIPE>) {
> - if ($FoundAnalysis == 0) {
> - if (/Checks and Analyses/) {
> - $FoundAnalysis = 1;
> - }
> - next;
> - }
> -
> - if (/^\s\s\s\s([^\s]+)\s(.+)$/) {
> - next if ($1 =~ /-dump/ or $1 =~ /-view/
> - or $1 =~ /-warn-uninit/);
> -
> - $AvailableAnalyses{$1} = $2;
> - next;
> - }
> - last;
> -}
> -
> -close (PIPE);
> -
> -my %AnalysesDefaultEnabled = (
> - '-warn-dead-stores' => 1,
> - '-checker-cfref' => 1,
> - '-warn-objc-methodsigs' => 1,
> - # Do not enable the missing -dealloc check by default.
> - # '-warn-objc-missing-dealloc' => 1,
> - '-warn-objc-unused-ivars' => 1,
> - '-warn-security-syntactic' => 1
> -);
> -
> -##----------------------------------------------------------------------------##
> -# GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
> -##----------------------------------------------------------------------------##
> -
> -sub GetHTMLRunDir {
> -
> - die "Not enough arguments." if (@_ == 0);
> - my $Dir = shift @_;
> -
> - my $TmpMode = 0;
> - if (!defined $Dir) {
> - if (`uname` =~ /Darwin/) {
> - $Dir = $ENV{'TMPDIR'};
> - if (!defined $Dir) { $Dir = "/tmp"; }
> - }
> - else {
> - $Dir = "/tmp";
> - }
> -
> - $TmpMode = 1;
> - }
> -
> - # Chop off any trailing '/' characters.
> - while ($Dir =~ /\/$/) { chop $Dir; }
> -
> - # Get current date and time.
> -
> - my @CurrentTime = localtime();
> -
> - my $year = $CurrentTime[5] + 1900;
> - my $day = $CurrentTime[3];
> - my $month = $CurrentTime[4] + 1;
> -
> - my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day);
> -
> - # Determine the run number.
> -
> - my $RunNumber;
> -
> - if (-d $Dir) {
> -
> - if (! -r $Dir) {
> - DieDiag("directory '$Dir' exists but is not readable.\n");
> - }
> -
> - # Iterate over all files in the specified directory.
> -
> - my $max = 0;
> -
> - opendir(DIR, $Dir);
> - my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
> - closedir(DIR);
> -
> - foreach my $f (@FILES) {
> -
> - # Strip the prefix '$Prog-' if we are dumping files to /tmp.
> - if ($TmpMode) {
> - next if (!($f =~ /^$Prog-(.+)/));
> - $f = $1;
> - }
> -
> -
> - 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) {
> - DieDiag("'$Dir' exists but is not a directory.\n");
> - }
> -
> - if ($TmpMode) {
> - DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n");
> - }
> -
> - # $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.
> - my $NewDir;
> - if ($TmpMode) {
> - $NewDir = "$Dir/$Prog-$DateString-$RunNumber";
> - }
> - else {
> - $NewDir = "$Dir/$DateString-$RunNumber";
> - }
> - system 'mkdir','-p',$NewDir;
> - return $NewDir;
> -}
> -
> -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) {
> - Diag("Emitting reports for this run to '$Dir'.\n");
> - }
> -
> - $ENV{'CCC_ANALYZER_HTML'} = $Dir;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# ComputeDigest - Compute a digest of the specified file.
> -##----------------------------------------------------------------------------##
> -
> -sub ComputeDigest {
> - my $FName = shift;
> - DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);
> -
> - # Use Digest::MD5. We don't have to be cryptographically secure. We're
> - # just looking for duplicate files that come from a non-malicious source.
> - # We use Digest::MD5 because it is a standard Perl module that should
> - # come bundled on most systems.
> - open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n");
> - binmode FILE;
> - my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest;
> - close(FILE);
> -
> - # Return the digest.
> - return $Result;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# UpdatePrefix - Compute the common prefix of files.
> -##----------------------------------------------------------------------------##
> -
> -my $Prefix;
> -
> -sub UpdatePrefix {
> - my $x = shift;
> - my $y = basename($x);
> - $x =~ s/\Q$y\E$//;
> -
> - if (!defined $Prefix) {
> - $Prefix = $x;
> - return;
> - }
> -
> - chop $Prefix while (!($x =~ /^\Q$Prefix/));
> -}
> -
> -sub GetPrefix {
> - return $Prefix;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# UpdateInFilePath - Update the path in the report file.
> -##----------------------------------------------------------------------------##
> -
> -sub UpdateInFilePath {
> - my $fname = shift;
> - my $regex = shift;
> - my $newtext = shift;
> -
> - open (RIN, $fname) or die "cannot open $fname";
> - open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp";
> -
> - while (<RIN>) {
> - s/$regex/$newtext/;
> - print ROUT $_;
> - }
> -
> - close (ROUT);
> - close (RIN);
> - system("mv", "$fname.tmp", $fname);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# ScanFile - Scan a report file for various identifying attributes.
> -##----------------------------------------------------------------------------##
> -
> -# Sometimes a source file is scanned more than once, and thus produces
> -# multiple error reports. We use a cache to solve this problem.
> -
> -my %AlreadyScanned;
> -
> -sub ScanFile {
> -
> - my $Index = shift;
> - my $Dir = shift;
> - my $FName = shift;
> -
> - # Compute a digest for the report file. Determine if we have already
> - # scanned a file that looks just like it.
> -
> - my $digest = ComputeDigest("$Dir/$FName");
> -
> - if (defined $AlreadyScanned{$digest}) {
> - # Redundant file. Remove it.
> - system ("rm", "-f", "$Dir/$FName");
> - return;
> - }
> -
> - $AlreadyScanned{$digest} = 1;
> -
> - # At this point the report file is not world readable. Make it happen.
> - system ("chmod", "644", "$Dir/$FName");
> -
> - # Scan the report file for tags.
> - open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
> -
> - my $BugType = "";
> - my $BugFile = "";
> - my $BugCategory;
> - my $BugPathLength = 1;
> - my $BugLine = 0;
> -
> - while (<IN>) {
> - last if (/<!-- BUGMETAEND -->/);
> -
> - if (/<!-- BUGTYPE (.*) -->$/) {
> - $BugType = $1;
> - }
> - elsif (/<!-- BUGFILE (.*) -->$/) {
> - $BugFile = abs_path($1);
> - UpdatePrefix($BugFile);
> - }
> - elsif (/<!-- BUGPATHLENGTH (.*) -->$/) {
> - $BugPathLength = $1;
> - }
> - elsif (/<!-- BUGLINE (.*) -->$/) {
> - $BugLine = $1;
> - }
> - elsif (/<!-- BUGCATEGORY (.*) -->$/) {
> - $BugCategory = $1;
> - }
> - }
> -
> - close(IN);
> -
> - if (!defined $BugCategory) {
> - $BugCategory = "Other";
> - }
> -
> - push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
> - $BugPathLength ];
> -}
> -
> -##----------------------------------------------------------------------------##
> -# CopyFiles - Copy resource files to target directory.
> -##----------------------------------------------------------------------------##
> -
> -sub CopyFiles {
> -
> - my $Dir = shift;
> -
> - my $JS = Cwd::realpath("$RealBin/sorttable.js");
> -
> - DieDiag("Cannot find 'sorttable.js'.\n")
> - if (! -r $JS);
> -
> - system ("cp", $JS, "$Dir");
> -
> - DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n")
> - if (! -r "$Dir/sorttable.js");
> -
> - my $CSS = Cwd::realpath("$RealBin/scanview.css");
> -
> - DieDiag("Cannot find 'scanview.css'.\n")
> - if (! -r $CSS);
> -
> - system ("cp", $CSS, "$Dir");
> -
> - DieDiag("Could not copy 'scanview.css' to '$Dir'.\n")
> - if (! -r $CSS);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Postprocess - Postprocess the results of an analysis scan.
> -##----------------------------------------------------------------------------##
> -
> -sub Postprocess {
> -
> - my $Dir = shift;
> - my $BaseDir = shift;
> -
> - die "No directory specified." if (!defined $Dir);
> -
> - if (! -d $Dir) {
> - Diag("No bugs found.\n");
> - return 0;
> - }
> -
> - opendir(DIR, $Dir);
> - my @files = grep { /^report-.*\.html$/ } readdir(DIR);
> - closedir(DIR);
> -
> - if (scalar(@files) == 0 and ! -e "$Dir/failures") {
> - Diag("Removing directory '$Dir' because it contains no reports.\n");
> - system ("rm", "-fR", $Dir);
> - return 0;
> - }
> -
> - # Scan each report file and build an index.
> - my @Index;
> - foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
> -
> - # Scan the failures directory and use the information in the .info files
> - # to update the common prefix directory.
> - my @failures;
> - my @attributes_ignored;
> - if (-d "$Dir/failures") {
> - opendir(DIR, "$Dir/failures");
> - @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR);
> - closedir(DIR);
> - opendir(DIR, "$Dir/failures");
> - @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR);
> - closedir(DIR);
> - foreach my $file (@failures) {
> - open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n");
> - my $Path = <IN>;
> - if (defined $Path) { UpdatePrefix($Path); }
> - close IN;
> - }
> - }
> -
> - # Generate an index.html file.
> - my $FName = "$Dir/index.html";
> - open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n");
> -
> - # Print out the header.
> -
> -print OUT <<ENDTEXT;
> -<html>
> -<head>
> -<title>${HtmlTitle}</title>
> -<link type="text/css" rel="stylesheet" href="scanview.css"/>
> -<script src="sorttable.js"></script>
> -<script language='javascript' type="text/javascript">
> -function SetDisplay(RowClass, DisplayVal)
> -{
> - var Rows = document.getElementsByTagName("tr");
> - for ( var i = 0 ; i < Rows.length; ++i ) {
> - if (Rows[i].className == RowClass) {
> - Rows[i].style.display = DisplayVal;
> - }
> - }
> -}
> -
> -function CopyCheckedStateToCheckButtons(SummaryCheckButton) {
> - var Inputs = document.getElementsByTagName("input");
> - for ( var i = 0 ; i < Inputs.length; ++i ) {
> - if (Inputs[i].type == "checkbox") {
> - if(Inputs[i] != SummaryCheckButton) {
> - Inputs[i].checked = SummaryCheckButton.checked;
> - Inputs[i].onclick();
> - }
> - }
> - }
> -}
> -
> -function returnObjById( id ) {
> - if (document.getElementById)
> - var returnVar = document.getElementById(id);
> - else if (document.all)
> - var returnVar = document.all[id];
> - else if (document.layers)
> - var returnVar = document.layers[id];
> - return returnVar;
> -}
> -
> -var NumUnchecked = 0;
> -
> -function ToggleDisplay(CheckButton, ClassName) {
> - if (CheckButton.checked) {
> - SetDisplay(ClassName, "");
> - if (--NumUnchecked == 0) {
> - returnObjById("AllBugsCheck").checked = true;
> - }
> - }
> - else {
> - SetDisplay(ClassName, "none");
> - NumUnchecked++;
> - returnObjById("AllBugsCheck").checked = false;
> - }
> -}
> -</script>
> -<!-- SUMMARYENDHEAD -->
> -</head>
> -<body>
> -<h1>${HtmlTitle}</h1>
> -
> -<table>
> -<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr>
> -<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr>
> -<tr><th>Command Line:</th><td>${CmdArgs}</td></tr>
> -<tr><th>Date:</th><td>${Date}</td></tr>
> -ENDTEXT
> -
> -print OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n"
> - if (defined($BuildName) && defined($BuildDate));
> -
> -print OUT <<ENDTEXT;
> -</table>
> -ENDTEXT
> -
> - if (scalar(@files)) {
> - # Print out the summary table.
> - my %Totals;
> -
> - for my $row ( @Index ) {
> - my $bug_type = ($row->[2]);
> - my $bug_category = ($row->[1]);
> - my $key = "$bug_category:$bug_type";
> -
> - if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; }
> - else { $Totals{$key}->[0]++; }
> - }
> -
> - print OUT "<h2>Bug Summary</h2>";
> -
> - if (defined $BuildName) {
> - print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
> - }
> -
> - my $TotalBugs = scalar(@Index);
> -print OUT <<ENDTEXT;
> -<table>
> -<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead>
> -<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>
> -ENDTEXT
> -
> - my $last_category;
> -
> - for my $key (
> - sort {
> - my $x = $Totals{$a};
> - my $y = $Totals{$b};
> - my $res = $x->[1] cmp $y->[1];
> - $res = $x->[2] cmp $y->[2] if ($res == 0);
> - $res
> - } keys %Totals )
> - {
> - my $val = $Totals{$key};
> - my $category = $val->[1];
> - if (!defined $last_category or $last_category ne $category) {
> - $last_category = $category;
> - print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n";
> - }
> - my $x = lc $key;
> - $x =~ s/[ ,'":\/()]+/_/g;
> - print OUT "<tr><td class=\"SUMM_DESC\">";
> - print OUT $val->[2];
> - print OUT "</td><td class=\"Q\">";
> - print OUT $val->[0];
> - print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n";
> - }
> -
> - # Print out the table of errors.
> -
> -print OUT <<ENDTEXT;
> -</table>
> -<h2>Reports</h2>
> -
> -<table class="sortable" style="table-layout:automatic">
> -<thead><tr>
> - <td>Bug Group</td>
> - <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td>
> - <td>File</td>
> - <td class="Q">Line</td>
> - <td class="Q">Path Length</td>
> - <td class="sorttable_nosort"></td>
> - <!-- REPORTBUGCOL -->
> -</tr></thead>
> -<tbody>
> -ENDTEXT
> -
> - my $prefix = GetPrefix();
> - my $regex;
> - my $InFileRegex;
> - my $InFilePrefix = "File:</td><td>";
> -
> - if (defined $prefix) {
> - $regex = qr/^\Q$prefix\E/is;
> - $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is;
> - }
> -
> - for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) {
> - my $x = "$row->[1]:$row->[2]";
> - $x = lc $x;
> - $x =~ s/[ ,'":\/()]+/_/g;
> -
> - my $ReportFile = $row->[0];
> -
> - print OUT "<tr class=\"bt_$x\">";
> - print OUT "<td class=\"DESC\">";
> - print OUT $row->[1];
> - print OUT "</td>";
> - print OUT "<td class=\"DESC\">";
> - print OUT $row->[2];
> - print OUT "</td>";
> -
> - # Update the file prefix.
> - my $fname = $row->[3];
> -
> - if (defined $regex) {
> - $fname =~ s/$regex//;
> - UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
> - }
> -
> - print OUT "<td>";
> - my @fname = split /\//,$fname;
> - if ($#fname > 0) {
> - while ($#fname >= 0) {
> - my $x = shift @fname;
> - print OUT $x;
> - if ($#fname >= 0) {
> - print OUT "<span class=\"W\"> </span>/";
> - }
> - }
> - }
> - else {
> - print OUT $fname;
> - }
> - print OUT "</td>";
> -
> - # Print out the quantities.
> - for my $j ( 4 .. 5 ) {
> - print OUT "<td class=\"Q\">$row->[$j]</td>";
> - }
> -
> - # Print the rest of the columns.
> - for (my $j = 6; $j <= $#{$row}; ++$j) {
> - print OUT "<td>$row->[$j]</td>"
> - }
> -
> - # Emit the "View" link.
> - print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>";
> -
> - # Emit REPORTBUG markers.
> - print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n";
> -
> - # End the row.
> - print OUT "</tr>\n";
> - }
> -
> - print OUT "</tbody>\n</table>\n\n";
> - }
> -
> - if (scalar (@failures) || scalar(@attributes_ignored)) {
> - print OUT "<h2>Analyzer Failures</h2>\n";
> -
> - if (scalar @attributes_ignored) {
> - print OUT "The analyzer's parser ignored the following attributes:<p>\n";
> - print OUT "<table>\n";
> - print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
> - foreach my $file (sort @attributes_ignored) {
> - die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/));
> - my $attribute = $1;
> - # Open the attribute file to get the first file that failed.
> - next if (!open (ATTR, "$Dir/failures/$file"));
> - my $ppfile = <ATTR>;
> - chomp $ppfile;
> - close ATTR;
> - next if (! -e "$Dir/failures/$ppfile");
> - # Open the info file and get the name of the source file.
> - open (INFO, "$Dir/failures/$ppfile.info.txt") or
> - die "Cannot open $Dir/failures/$ppfile.info.txt\n";
> - my $srcfile = <INFO>;
> - chomp $srcfile;
> - close (INFO);
> - # Print the information in the table.
> - my $prefix = GetPrefix();
> - if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
> - 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";
> - my $ppfile_clang = $ppfile;
> - $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
> - print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
> - }
> - print OUT "</table>\n";
> - }
> -
> - if (scalar @failures) {
> - print OUT "<p>The analyzer had problems processing the following files:</p>\n";
> - print OUT "<table>\n";
> - print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
> - foreach my $file (sort @failures) {
> - $file =~ /(.+).info.txt$/;
> - # Get the preprocessed file.
> - my $ppfile = $1;
> - # Open the info file and get the name of the source file.
> - open (INFO, "$Dir/failures/$file") or
> - die "Cannot open $Dir/failures/$file\n";
> - my $srcfile = <INFO>;
> - chomp $srcfile;
> - my $problem = <INFO>;
> - chomp $problem;
> - close (INFO);
> - # Print the information in the table.
> - my $prefix = GetPrefix();
> - if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
> - 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";
> - my $ppfile_clang = $ppfile;
> - $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
> - print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
> - }
> - print OUT "</table>\n";
> - }
> - print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
> - }
> -
> - print OUT "</body></html>\n";
> - close(OUT);
> - CopyFiles($Dir);
> -
> - # Make sure $Dir and $BaseDir are world readable/executable.
> - system("chmod", "755", $Dir);
> - if (defined $BaseDir) { system("chmod", "755", $BaseDir); }
> -
> - my $Num = scalar(@Index);
> - Diag("$Num bugs found.\n");
> - if ($Num > 0 && -r "$Dir/index.html") {
> - Diag("Run 'scan-view $Dir' to examine bug reports.\n");
> - }
> -
> - DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored);
> -
> - return $Num;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# RunBuildCommand - Run the build command.
> -##----------------------------------------------------------------------------##
> -
> -sub AddIfNotPresent {
> - my $Args = shift;
> - my $Arg = shift;
> - my $found = 0;
> -
> - foreach my $k (@$Args) {
> - if ($k eq $Arg) {
> - $found = 1;
> - last;
> - }
> - }
> -
> - if ($found == 0) {
> - push @$Args, $Arg;
> - }
> -}
> -
> -sub RunBuildCommand {
> -
> - my $Args = shift;
> - my $IgnoreErrors = shift;
> - my $Cmd = $Args->[0];
> - my $CCAnalyzer = shift;
> -
> - # Get only the part of the command after the last '/'.
> - if ($Cmd =~ /\/([^\/]+)$/) {
> - $Cmd = $1;
> - }
> -
> - if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or
> - $Cmd =~ /(.*\/?cc[^\/]*$)/ or
> - $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or
> - $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
> -
> - if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
> - $ENV{"CCC_CC"} = $1;
> - }
> -
> - shift @$Args;
> - unshift @$Args, $CCAnalyzer;
> - }
> - elsif ($IgnoreErrors) {
> - if ($Cmd eq "make" or $Cmd eq "gmake") {
> - AddIfNotPresent($Args,"-k");
> - AddIfNotPresent($Args,"-i");
> - }
> - elsif ($Cmd eq "xcodebuild") {
> - AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
> - }
> - }
> -
> - if ($Cmd eq "xcodebuild") {
> - # Check if using iPhone SDK 3.0 (simulator). If so the compiler being
> - # used should be gcc-4.2.
> - if (!defined $ENV{"CCC_CC"}) {
> - for (my $i = 0 ; $i < scalar(@$Args); ++$i) {
> - if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
> - if (@$Args[$i+1] =~ /^iphonesimulator3/) {
> - $ENV{"CCC_CC"} = "gcc-4.2";
> - }
> - }
> - }
> - }
> -
> - # Disable distributed builds for xcodebuild.
> - AddIfNotPresent($Args,"-nodistribute");
> -
> - # Disable PCH files until clang supports them.
> - AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
> -
> - # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
> - # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
> - # when linking such files.
> - die if (!defined $CXX);
> - my $LDPLUSPLUS = `which $CXX`;
> - $LDPLUSPLUS =~ s/\015?\012//; # strip newlines
> - $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS;
> - }
> -
> - return (system(@$Args) >> 8);
> -}
> -
> -##----------------------------------------------------------------------------##
> -# DisplayHelp - Utility function to display all help options.
> -##----------------------------------------------------------------------------##
> -
> -sub DisplayHelp {
> -
> -print <<ENDTEXT;
> -USAGE: $Prog [options] <build command> [build options]
> -
> -ENDTEXT
> -
> - if (defined $BuildName) {
> - print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n";
> - }
> -
> -print <<ENDTEXT;
> -OPTIONS:
> -
> - -analyze-headers - Also analyze functions in #included files.
> -
> - --experimental-checks - Enable experimental checks that are currently in heavy testing
> -
> - -o - Target directory for HTML report files. Subdirectories
> - will be created as needed to represent separate "runs" of
> - the analyzer. If this option is not specified, a directory
> - is created in /tmp (TMPDIR on Mac OS X) to store the reports.
> -
> - -h - Display this message.
> - --help
> -
> - -k - Add a "keep on going" option to the specified build command.
> - --keep-going This option currently supports make and xcodebuild.
> - This is a convenience option; one can specify this
> - behavior directly using build options.
> -
> - --html-title [title] - Specify the title used on generated HTML pages.
> - --html-title=[title] If not specified, a default title will be used.
> -
> - -plist - By default the output of scan-build is a set of HTML files.
> - This option outputs the results as a set of .plist files.
> -
> - --status-bugs - By default, the exit status of $Prog is the same as the
> - executed build command. Specifying this option causes the
> - exit status of $Prog to be 1 if it found potential bugs
> - and 0 otherwise.
> -
> - --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link
> - --use-cc=[compiler path] your C and Objective-C code. Use this option
> - to specify an alternate compiler.
> -
> - --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link
> - --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option
> - to specify an alternate compiler.
> -
> - -v - Verbose output from $Prog and the analyzer.
> - A second and third '-v' increases verbosity.
> -
> - -V - View analysis results in a web browser when the build
> - --view completes.
> -
> -ADVANCED OPTIONS:
> -
> - -constraints [model] - Specify the contraint engine used by the analyzer.
> - By default the 'range' model is used. Specifying
> - 'basic' uses a simpler, less powerful constraint model
> - used by checker-0.160 and earlier.
> -
> - -store [model] - Specify the store model used by the analyzer. By default,
> - the 'region' store model is used. 'region' specifies a field-
> - sensitive store model. Users can also specify 'basic', which
> - is far less precise but can more quickly analyze code.
> - 'basic' was the default store model for checker-0.221 and
> - earlier.
> -
> - -no-failure-reports - Do not create a 'failures' subdirectory that includes
> - analyzer crash reports and preprocessed source files.
> -
> -AVAILABLE ANALYSES (multiple analyses may be specified):
> -
> -ENDTEXT
> -
> - foreach my $Analysis (sort keys %AvailableAnalyses) {
> - if (defined $AnalysesDefaultEnabled{$Analysis}) {
> - print " (+)";
> - }
> - else {
> - print " ";
> - }
> -
> - print " $Analysis $AvailableAnalyses{$Analysis}\n";
> - }
> -
> -print <<ENDTEXT
> -
> - NOTE: "(+)" indicates that an analysis is enabled by default unless one
> - or more analysis options are specified
> -
> -BUILD OPTIONS
> -
> - You can specify any build option acceptable to the build command.
> -
> -EXAMPLE
> -
> - $Prog -o /tmp/myhtmldir make -j4
> -
> - The above example causes analysis reports to be deposited into
> - a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option.
> - A different subdirectory is created each time $Prog analyzes a project.
> - The analyzer should support most parallel builds, but not distributed builds.
> -
> -ENDTEXT
> -}
> -
> -##----------------------------------------------------------------------------##
> -# HtmlEscape - HTML entity encode characters that are special in HTML
> -##----------------------------------------------------------------------------##
> -
> -sub HtmlEscape {
> - # copy argument to new variable so we don't clobber the original
> - my $arg = shift || '';
> - my $tmp = $arg;
> - $tmp =~ s/&/&/g;
> - $tmp =~ s/</</g;
> - $tmp =~ s/>/>/g;
> - return $tmp;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# ShellEscape - backslash escape characters that are special to the shell
> -##----------------------------------------------------------------------------##
> -
> -sub ShellEscape {
> - # copy argument to new variable so we don't clobber the original
> - my $arg = shift || '';
> - if ($arg =~ /["\s]/) { return "'" . $arg . "'"; }
> - return $arg;
> -}
> -
> -##----------------------------------------------------------------------------##
> -# Process command-line arguments.
> -##----------------------------------------------------------------------------##
> -
> -my $AnalyzeHeaders = 0;
> -my $HtmlDir; # Parent directory to store HTML files.
> -my $IgnoreErrors = 0; # Ignore build errors.
> -my $ViewResults = 0; # View results when the build terminates.
> -my $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found
> -my @AnalysesToRun;
> -my $StoreModel;
> -my $ConstraintsModel;
> -my $OutputFormat = "html";
> -
> -if (!@ARGV) {
> - DisplayHelp();
> - exit 1;
> -}
> -
> -while (@ARGV) {
> -
> - # Scan for options we recognize.
> -
> - my $arg = $ARGV[0];
> -
> - if ($arg eq "-h" or $arg eq "--help") {
> - DisplayHelp();
> - exit 0;
> - }
> -
> - if ($arg eq '-analyze-headers') {
> - shift @ARGV;
> - $AnalyzeHeaders = 1;
> - next;
> - }
> -
> - if (defined $AvailableAnalyses{$arg}) {
> - shift @ARGV;
> - push @AnalysesToRun, $arg;
> - next;
> - }
> -
> - if ($arg eq "-o") {
> - shift @ARGV;
> -
> - if (!@ARGV) {
> - DieDiag("'-o' option requires a target directory name.\n");
> - }
> -
> - # Construct an absolute path. Uses the current working directory
> - # as a base if the original path was not absolute.
> - $HtmlDir = abs_path(shift @ARGV);
> -
> - next;
> - }
> -
> - if ($arg =~ /^--html-title(=(.+))?$/) {
> - shift @ARGV;
> -
> - if (!defined $2 || $2 eq '') {
> - if (!@ARGV) {
> - DieDiag("'--html-title' option requires a string.\n");
> - }
> -
> - $HtmlTitle = shift @ARGV;
> - } else {
> - $HtmlTitle = $2;
> - }
> -
> - next;
> - }
> -
> - if ($arg eq "-k" or $arg eq "--keep-going") {
> - shift @ARGV;
> - $IgnoreErrors = 1;
> - next;
> - }
> -
> - if ($arg eq "--experimental-checks") {
> - shift @ARGV;
> - $ENV{"CCC_EXPERIMENTAL_CHECKS"} = 1;
> - next;
> - }
> -
> - if ($arg =~ /^--use-cc(=(.+))?$/) {
> - shift @ARGV;
> - my $cc;
> -
> - if (!defined $2 || $2 eq "") {
> - if (!@ARGV) {
> - DieDiag("'--use-cc' option requires a compiler executable name.\n");
> - }
> - $cc = shift @ARGV;
> - }
> - else {
> - $cc = $2;
> - }
> -
> - $ENV{"CCC_CC"} = $cc;
> - next;
> - }
> -
> - if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
> - shift @ARGV;
> -
> - if (!defined $2 || $2 eq "") {
> - if (!@ARGV) {
> - DieDiag("'--use-c++' option requires a compiler executable name.\n");
> - }
> - $CXX = shift @ARGV;
> - }
> - else {
> - $CXX = $2;
> - }
> - next;
> - }
> -
> - if ($arg eq "-v") {
> - shift @ARGV;
> - $Verbose++;
> - next;
> - }
> -
> - if ($arg eq "-V" or $arg eq "--view") {
> - shift @ARGV;
> - $ViewResults = 1;
> - next;
> - }
> -
> - if ($arg eq "--status-bugs") {
> - shift @ARGV;
> - $ExitStatusFoundBugs = 1;
> - next;
> - }
> -
> - if ($arg eq "-store") {
> - shift @ARGV;
> - $StoreModel = shift @ARGV;
> - next;
> - }
> -
> - if ($arg eq "-constraints") {
> - shift @ARGV;
> - $ConstraintsModel = shift @ARGV;
> - next;
> - }
> -
> - if ($arg eq "-plist") {
> - shift @ARGV;
> - $OutputFormat = "plist";
> - next;
> - }
> - if ($arg eq "-plist-html") {
> - shift @ARGV;
> - $OutputFormat = "plist-html";
> - next;
> - }
> -
> - if ($arg eq "-no-failure-reports") {
> - $ENV{"CCC_REPORT_FAILURES"} = 0;
> - next;
> - }
> -
> - DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
> -
> - last;
> -}
> -
> -if (!@ARGV) {
> - Diag("No build command specified.\n\n");
> - DisplayHelp();
> - exit 1;
> -}
> -
> -$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
> -$HtmlTitle = "${CurrentDirSuffix} - scan-build results"
> - unless (defined($HtmlTitle));
> -
> -# Determine the output directory for the HTML reports.
> -my $BaseDir = $HtmlDir;
> -$HtmlDir = GetHTMLRunDir($HtmlDir);
> -
> -# Set the appropriate environment variables.
> -SetHtmlEnv(\@ARGV, $HtmlDir);
> -
> -my $Cmd = Cwd::realpath("$RealBin/libexec/ccc-analyzer");
> -if (!defined $Cmd || ! -x $Cmd) {
> - $Cmd = Cwd::realpath("$RealBin/ccc-analyzer");
> - DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
> -}
> -
> -if (!defined $ClangCCSB || ! -x $ClangCCSB) {
> - Diag("'clang-cc' executable not found in '$RealBin/libexec'.\n");
> - Diag("Using 'clang-cc' from path.\n");
> -}
> -if (!defined $ClangSB || ! -x $ClangSB) {
> - Diag("'clang' executable not found in '$RealBin/bin'.\n");
> - Diag("Using 'clang' from path.\n");
> -}
> -
> -if (defined $CXX) {
> - $ENV{'CXX'} = $CXX;
> -}
> -else {
> - $CXX = 'g++'; # This variable is used by other parts of scan-build
> - # that need to know a default C++ compiler to fall back to.
> -}
> -
> -$ENV{'CC'} = $Cmd;
> -$ENV{'CLANG_CC'} = $ClangCC;
> -$ENV{'CLANG'} = $Clang;
> -
> -if ($Verbose >= 2) {
> - $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
> -}
> -
> -if ($Verbose >= 3) {
> - $ENV{'CCC_ANALYZER_LOG'} = 1;
> -}
> -
> -if (scalar(@AnalysesToRun) == 0) {
> - foreach my $key (keys %AnalysesDefaultEnabled) {
> - push @AnalysesToRun,$key;
> - }
> -}
> -
> -if ($AnalyzeHeaders) {
> - push @AnalysesToRun,"-analyzer-opt-analyze-headers";
> -}
> -
> -$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ', at AnalysesToRun;
> -
> -if (defined $StoreModel) {
> - $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel;
> -}
> -
> -if (defined $ConstraintsModel) {
> - $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel;
> -}
> -
> -if (defined $OutputFormat) {
> - $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat;
> -}
> -
> -
> -# Run the build.
> -my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd);
> -
> -if (defined $OutputFormat) {
> - if ($OutputFormat =~ /plist/) {
> - Diag "Analysis run complete.\n";
> - Diag "Analysis results (plist files) deposited in '$HtmlDir'\n";
> - }
> - elsif ($OutputFormat =~ /html/) {
> - # Postprocess the HTML directory.
> - my $NumBugs = Postprocess($HtmlDir, $BaseDir);
> -
> - if ($ViewResults and -r "$HtmlDir/index.html") {
> - Diag "Analysis run complete.\n";
> - Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n";
> - my $ScanView = Cwd::realpath("$RealBin/scan-view");
> - if (! -x $ScanView) { $ScanView = "scan-view"; }
> - exec $ScanView, "$HtmlDir";
> - }
> -
> - if ($ExitStatusFoundBugs) {
> - exit 1 if ($NumBugs > 0);
> - exit 0;
> - }
> - }
> -}
> -
> -exit $ExitStatus;
> -
>
> Removed: cfe/trunk/utils/scanview.css
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/scanview.css?rev=90214&view=auto
>
> ==============================================================================
> --- cfe/trunk/utils/scanview.css (original)
> +++ cfe/trunk/utils/scanview.css (removed)
> @@ -1,62 +0,0 @@
> -body { color:#000000; background-color:#ffffff }
> -body { font-family: Helvetica, sans-serif; font-size:9pt }
> -h1 { font-size: 14pt; }
> -h2 { font-size: 12pt; }
> -table { font-size:9pt }
> -table { border-spacing: 0px; border: 1px solid black }
> -th, table thead {
> - background-color:#eee; color:#666666;
> - font-weight: bold; cursor: default;
> - text-align:center;
> - font-weight: bold; font-family: Verdana;
> - white-space:nowrap;
> -}
> -.W { font-size:0px }
> -th, td { padding:5px; padding-left:8px; text-align:left }
> -td.SUMM_DESC { padding-left:12px }
> -td.DESC { white-space:pre }
> -td.Q { text-align:right }
> -td { text-align:left }
> -tbody.scrollContent { overflow:auto }
> -
> -table.form_group {
> - background-color: #ccc;
> - border: 1px solid #333;
> - padding: 2px;
> -}
> -
> -table.form_inner_group {
> - background-color: #ccc;
> - border: 1px solid #333;
> - padding: 0px;
> -}
> -
> -table.form {
> - background-color: #999;
> - border: 1px solid #333;
> - padding: 2px;
> -}
> -
> -td.form_label {
> - text-align: right;
> - vertical-align: top;
> -}
> -/* For one line entires */
> -td.form_clabel {
> - text-align: right;
> - vertical-align: center;
> -}
> -td.form_value {
> - text-align: left;
> - vertical-align: top;
> -}
> -td.form_submit {
> - text-align: right;
> - vertical-align: top;
> -}
> -
> -h1.SubmitFail {
> - color: #f00;
> -}
> -h1.SubmitOk {
> -}
>
> Removed: cfe/trunk/utils/sorttable.js
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/sorttable.js?rev=90214&view=auto
>
> ==============================================================================
> --- cfe/trunk/utils/sorttable.js (original)
> +++ cfe/trunk/utils/sorttable.js (removed)
> @@ -1,493 +0,0 @@
> -/*
> - SortTable
> - version 2
> - 7th April 2007
> - Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
> -
> - Instructions:
> - Download this file
> - Add <script src="sorttable.js"></script> to your HTML
> - Add class="sortable" to any table you'd like to make sortable
> - Click on the headers to sort
> -
> - Thanks to many, many people for contributions and suggestions.
> - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
> - This basically means: do what you want with it.
> -*/
> -
> -
> -var stIsIE = /*@cc_on!@*/false;
> -
> -sorttable = {
> - init: function() {
> - // quit if this function has already been called
> - if (arguments.callee.done) return;
> - // flag this function so we don't do the same thing twice
> - arguments.callee.done = true;
> - // kill the timer
> - if (_timer) clearInterval(_timer);
> -
> - if (!document.createElement || !document.getElementsByTagName) return;
> -
> - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
> -
> - forEach(document.getElementsByTagName('table'), function(table) {
> - if (table.className.search(/\bsortable\b/) != -1) {
> - sorttable.makeSortable(table);
> - }
> - });
> -
> - },
> -
> - makeSortable: function(table) {
> - if (table.getElementsByTagName('thead').length == 0) {
> - // table doesn't have a tHead. Since it should have, create one and
> - // put the first table row in it.
> - the = document.createElement('thead');
> - the.appendChild(table.rows[0]);
> - table.insertBefore(the,table.firstChild);
> - }
> - // Safari doesn't support table.tHead, sigh
> - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
> -
> - if (table.tHead.rows.length != 1) return; // can't cope with two header rows
> -
> - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
> - // "total" rows, for example). This is B&R, since what you're supposed
> - // to do is put them in a tfoot. So, if there are sortbottom rows,
> - // for backwards compatibility, move them to tfoot (creating it if needed).
> - sortbottomrows = [];
> - for (var i=0; i<table.rows.length; i++) {
> - if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
> - sortbottomrows[sortbottomrows.length] = table.rows[i];
> - }
> - }
> - if (sortbottomrows) {
> - if (table.tFoot == null) {
> - // table doesn't have a tfoot. Create one.
> - tfo = document.createElement('tfoot');
> - table.appendChild(tfo);
> - }
> - for (var i=0; i<sortbottomrows.length; i++) {
> - tfo.appendChild(sortbottomrows[i]);
> - }
> - delete sortbottomrows;
> - }
> -
> - // work through each column and calculate its type
> - headrow = table.tHead.rows[0].cells;
> - for (var i=0; i<headrow.length; i++) {
> - // manually override the type with a sorttable_type attribute
> - if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
> - mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
> - if (mtch) { override = mtch[1]; }
> - if (mtch && typeof sorttable["sort_"+override] == 'function') {
> - headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
> - } else {
> - headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
> - }
> - // make it clickable to sort
> - headrow[i].sorttable_columnindex = i;
> - headrow[i].sorttable_tbody = table.tBodies[0];
> - dean_addEvent(headrow[i],"click", function(e) {
> -
> - if (this.className.search(/\bsorttable_sorted\b/) != -1) {
> - // if we're already sorted by this column, just
> - // reverse the table, which is quicker
> - sorttable.reverse(this.sorttable_tbody);
> - this.className = this.className.replace('sorttable_sorted',
> - 'sorttable_sorted_reverse');
> - this.removeChild(document.getElementById('sorttable_sortfwdind'));
> - sortrevind = document.createElement('span');
> - sortrevind.id = "sorttable_sortrevind";
> - sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴';
> - this.appendChild(sortrevind);
> - return;
> - }
> - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
> - // if we're already sorted by this column in reverse, just
> - // re-reverse the table, which is quicker
> - sorttable.reverse(this.sorttable_tbody);
> - this.className = this.className.replace('sorttable_sorted_reverse',
> - 'sorttable_sorted');
> - this.removeChild(document.getElementById('sorttable_sortrevind'));
> - sortfwdind = document.createElement('span');
> - sortfwdind.id = "sorttable_sortfwdind";
> - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';
> - this.appendChild(sortfwdind);
> - return;
> - }
> -
> - // remove sorttable_sorted classes
> - theadrow = this.parentNode;
> - forEach(theadrow.childNodes, function(cell) {
> - if (cell.nodeType == 1) { // an element
> - cell.className = cell.className.replace('sorttable_sorted_reverse','');
> - cell.className = cell.className.replace('sorttable_sorted','');
> - }
> - });
> - sortfwdind = document.getElementById('sorttable_sortfwdind');
> - if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
> - sortrevind = document.getElementById('sorttable_sortrevind');
> - if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
> -
> - this.className += ' sorttable_sorted';
> - sortfwdind = document.createElement('span');
> - sortfwdind.id = "sorttable_sortfwdind";
> - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';
> - this.appendChild(sortfwdind);
> -
> - // build an array to sort. This is a Schwartzian transform thing,
> - // i.e., we "decorate" each row with the actual sort key,
> - // sort based on the sort keys, and then put the rows back in order
> - // which is a lot faster because you only do getInnerText once per row
> - row_array = [];
> - col = this.sorttable_columnindex;
> - rows = this.sorttable_tbody.rows;
> - for (var j=0; j<rows.length; j++) {
> - row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
> - }
> - /* If you want a stable sort, uncomment the following line */
> - sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
> - /* and comment out this one */
> - //row_array.sort(this.sorttable_sortfunction);
> -
> - tb = this.sorttable_tbody;
> - for (var j=0; j<row_array.length; j++) {
> - tb.appendChild(row_array[j][1]);
> - }
> -
> - delete row_array;
> - });
> - }
> - }
> - },
> -
> - guessType: function(table, column) {
> - // guess the type of a column based on its first non-blank row
> - sortfn = sorttable.sort_alpha;
> - for (var i=0; i<table.tBodies[0].rows.length; i++) {
> - text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
> - if (text != '') {
> - if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
> - return sorttable.sort_numeric;
> - }
> - // check for a date: dd/mm/yyyy or dd/mm/yy
> - // can have / or . or - as separator
> - // can be mm/dd as well
> - possdate = text.match(sorttable.DATE_RE)
> - if (possdate) {
> - // looks like a date
> - first = parseInt(possdate[1]);
> - second = parseInt(possdate[2]);
> - if (first > 12) {
> - // definitely dd/mm
> - return sorttable.sort_ddmm;
> - } else if (second > 12) {
> - return sorttable.sort_mmdd;
> - } else {
> - // looks like a date, but we can't tell which, so assume
> - // that it's dd/mm (English imperialism!) and keep looking
> - sortfn = sorttable.sort_ddmm;
> - }
> - }
> - }
> - }
> - return sortfn;
> - },
> -
> - getInnerText: function(node) {
> - // gets the text we want to use for sorting for a cell.
> - // strips leading and trailing whitespace.
> - // this is *not* a generic getInnerText function; it's special to sorttable.
> - // for example, you can override the cell text with a customkey attribute.
> - // it also gets .value for <input> fields.
> -
> - hasInputs = (typeof node.getElementsByTagName == 'function') &&
> - node.getElementsByTagName('input').length;
> -
> - if (node.getAttribute("sorttable_customkey") != null) {
> - return node.getAttribute("sorttable_customkey");
> - }
> - else if (typeof node.textContent != 'undefined' && !hasInputs) {
> - return node.textContent.replace(/^\s+|\s+$/g, '');
> - }
> - else if (typeof node.innerText != 'undefined' && !hasInputs) {
> - return node.innerText.replace(/^\s+|\s+$/g, '');
> - }
> - else if (typeof node.text != 'undefined' && !hasInputs) {
> - return node.text.replace(/^\s+|\s+$/g, '');
> - }
> - else {
> - switch (node.nodeType) {
> - case 3:
> - if (node.nodeName.toLowerCase() == 'input') {
> - return node.value.replace(/^\s+|\s+$/g, '');
> - }
> - case 4:
> - return node.nodeValue.replace(/^\s+|\s+$/g, '');
> - break;
> - case 1:
> - case 11:
> - var innerText = '';
> - for (var i = 0; i < node.childNodes.length; i++) {
> - innerText += sorttable.getInnerText(node.childNodes[i]);
> - }
> - return innerText.replace(/^\s+|\s+$/g, '');
> - break;
> - default:
> - return '';
> - }
> - }
> - },
> -
> - reverse: function(tbody) {
> - // reverse the rows in a tbody
> - newrows = [];
> - for (var i=0; i<tbody.rows.length; i++) {
> - newrows[newrows.length] = tbody.rows[i];
> - }
> - for (var i=newrows.length-1; i>=0; i--) {
> - tbody.appendChild(newrows[i]);
> - }
> - delete newrows;
> - },
> -
> - /* sort functions
> - each sort function takes two parameters, a and b
> - you are comparing a[0] and b[0] */
> - sort_numeric: function(a,b) {
> - aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
> - if (isNaN(aa)) aa = 0;
> - bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
> - if (isNaN(bb)) bb = 0;
> - return aa-bb;
> - },
> - sort_alpha: function(a,b) {
> - if (a[0]==b[0]) return 0;
> - if (a[0]<b[0]) return -1;
> - return 1;
> - },
> - sort_ddmm: function(a,b) {
> - mtch = a[0].match(sorttable.DATE_RE);
> - y = mtch[3]; m = mtch[2]; d = mtch[1];
> - if (m.length == 1) m = '0'+m;
> - if (d.length == 1) d = '0'+d;
> - dt1 = y+m+d;
> - mtch = b[0].match(sorttable.DATE_RE);
> - y = mtch[3]; m = mtch[2]; d = mtch[1];
> - if (m.length == 1) m = '0'+m;
> - if (d.length == 1) d = '0'+d;
> - dt2 = y+m+d;
> - if (dt1==dt2) return 0;
> - if (dt1<dt2) return -1;
> - return 1;
> - },
> - sort_mmdd: function(a,b) {
> - mtch = a[0].match(sorttable.DATE_RE);
> - y = mtch[3]; d = mtch[2]; m = mtch[1];
> - if (m.length == 1) m = '0'+m;
> - if (d.length == 1) d = '0'+d;
> - dt1 = y+m+d;
> - mtch = b[0].match(sorttable.DATE_RE);
> - y = mtch[3]; d = mtch[2]; m = mtch[1];
> - if (m.length == 1) m = '0'+m;
> - if (d.length == 1) d = '0'+d;
> - dt2 = y+m+d;
> - if (dt1==dt2) return 0;
> - if (dt1<dt2) return -1;
> - return 1;
> - },
> -
> - shaker_sort: function(list, comp_func) {
> - // A stable sort function to allow multi-level sorting of data
> - // see: http://en.wikipedia.org/wiki/Cocktail_sort
> - // thanks to Joseph Nahmias
> - var b = 0;
> - var t = list.length - 1;
> - var swap = true;
> -
> - while(swap) {
> - swap = false;
> - for(var i = b; i < t; ++i) {
> - if ( comp_func(list[i], list[i+1]) > 0 ) {
> - var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
> - swap = true;
> - }
> - } // for
> - t--;
> -
> - if (!swap) break;
> -
> - for(var i = t; i > b; --i) {
> - if ( comp_func(list[i], list[i-1]) < 0 ) {
> - var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
> - swap = true;
> - }
> - } // for
> - b++;
> -
> - } // while(swap)
> - }
> -}
> -
> -/* ******************************************************************
> - Supporting functions: bundled here to avoid depending on a library
> - ****************************************************************** */
> -
> -// Dean Edwards/Matthias Miller/John Resig
> -
> -/* for Mozilla/Opera9 */
> -if (document.addEventListener) {
> - document.addEventListener("DOMContentLoaded", sorttable.init, false);
> -}
> -
> -/* for Internet Explorer */
> -/*@cc_on @*/
> -/*@if (@_win32)
> - document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
> - var script = document.getElementById("__ie_onload");
> - script.onreadystatechange = function() {
> - if (this.readyState == "complete") {
> - sorttable.init(); // call the onload handler
> - }
> - };
> -/*@end @*/
> -
> -/* for Safari */
> -if (/WebKit/i.test(navigator.userAgent)) { // sniff
> - var _timer = setInterval(function() {
> - if (/loaded|complete/.test(document.readyState)) {
> - sorttable.init(); // call the onload handler
> - }
> - }, 10);
> -}
> -
> -/* for other browsers */
> -window.onload = sorttable.init;
> -
> -// written by Dean Edwards, 2005
> -// with input from Tino Zijdel, Matthias Miller, Diego Perini
> -
> -// http://dean.edwards.name/weblog/2005/10/add-event/
> -
> -function dean_addEvent(element, type, handler) {
> - if (element.addEventListener) {
> - element.addEventListener(type, handler, false);
> - } else {
> - // assign each event handler a unique ID
> - if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
> - // create a hash table of event types for the element
> - if (!element.events) element.events = {};
> - // create a hash table of event handlers for each element/event pair
> - var handlers = element.events[type];
> - if (!handlers) {
> - handlers = element.events[type] = {};
> - // store the existing event handler (if there is one)
> - if (element["on" + type]) {
> - handlers[0] = element["on" + type];
> - }
> - }
> - // store the event handler in the hash table
> - handlers[handler.$$guid] = handler;
> - // assign a global event handler to do all the work
> - element["on" + type] = handleEvent;
> - }
> -};
> -// a counter used to create unique IDs
> -dean_addEvent.guid = 1;
> -
> -function removeEvent(element, type, handler) {
> - if (element.removeEventListener) {
> - element.removeEventListener(type, handler, false);
> - } else {
> - // delete the event handler from the hash table
> - if (element.events && element.events[type]) {
> - delete element.events[type][handler.$$guid];
> - }
> - }
> -};
> -
> -function handleEvent(event) {
> - var returnValue = true;
> - // grab the event object (IE uses a global event object)
> - event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
> - // get a reference to the hash table of event handlers
> - var handlers = this.events[event.type];
> - // execute each event handler
> - for (var i in handlers) {
> - this.$$handleEvent = handlers[i];
> - if (this.$$handleEvent(event) === false) {
> - returnValue = false;
> - }
> - }
> - return returnValue;
> -};
> -
> -function fixEvent(event) {
> - // add W3C standard event methods
> - event.preventDefault = fixEvent.preventDefault;
> - event.stopPropagation = fixEvent.stopPropagation;
> - return event;
> -};
> -fixEvent.preventDefault = function() {
> - this.returnValue = false;
> -};
> -fixEvent.stopPropagation = function() {
> - this.cancelBubble = true;
> -}
> -
> -// Dean's forEach: http://dean.edwards.name/base/forEach.js
> -/*
> - forEach, version 1.0
> - Copyright 2006, Dean Edwards
> - License: http://www.opensource.org/licenses/mit-license.php
> -*/
> -
> -// array-like enumeration
> -if (!Array.forEach) { // mozilla already supports this
> - Array.forEach = function(array, block, context) {
> - for (var i = 0; i < array.length; i++) {
> - block.call(context, array[i], i, array);
> - }
> - };
> -}
> -
> -// generic enumeration
> -Function.prototype.forEach = function(object, block, context) {
> - for (var key in object) {
> - if (typeof this.prototype[key] == "undefined") {
> - block.call(context, object[key], key, object);
> - }
> - }
> -};
> -
> -// character enumeration
> -String.forEach = function(string, block, context) {
> - Array.forEach(string.split(""), function(chr, index) {
> - block.call(context, chr, index, string);
> - });
> -};
> -
> -// globally resolve forEach enumeration
> -var forEach = function(object, block, context) {
> - if (object) {
> - var resolve = Object; // default
> - if (object instanceof Function) {
> - // functions have a "length" property
> - resolve = Function;
> - } else if (object.forEach instanceof Function) {
> - // the object implements a custom forEach method so use that
> - object.forEach(block, context);
> - return;
> - } else if (typeof object == "string") {
> - // the object is a string
> - resolve = String;
> - } else if (typeof object.length == "number") {
> - // the object is array-like
> - resolve = Array;
> - }
> - resolve.forEach(object, block, context);
> - }
> -};
> -
>
> Modified: cfe/trunk/www/analyzer/installation.html
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/installation.html?rev=90215&r1=90214&r2=90215&view=diff
>
> ==============================================================================
> --- cfe/trunk/www/analyzer/installation.html (original)
> +++ cfe/trunk/www/analyzer/installation.html Tue Dec 1 00:52:01 2009
> @@ -100,7 +100,7 @@
> programs.
>
> <p>Currently these are not installed using <tt>make install</tt>, and
> -are located in <tt>$(SRCDIR)/tools/clang/util</tt> and
> +are located in <tt>$(SRCDIR)/tools/clang/tools/scan-build</tt> and
> <tt>$(SRCDIR)/tools/clang/tools/scan-view</tt> respectively (where
> <tt>$(SRCDIR)</tt> is the root LLVM source directory). These locations
> are subject to change.</p></li>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list