[cfe-commits] r143786 - in /cfe/trunk/utils/analyzer: SATestAdd.py SATestBuild.py

Anna Zaks ganna at apple.com
Fri Nov 4 22:20:48 PDT 2011


Author: zaks
Date: Sat Nov  5 00:20:48 2011
New Revision: 143786

URL: http://llvm.org/viewvc/llvm-project?rev=143786&view=rev
Log:
[analyzer] Add support for testing with individual preprocessed files.

Modified:
    cfe/trunk/utils/analyzer/SATestAdd.py   (contents, props changed)
    cfe/trunk/utils/analyzer/SATestBuild.py   (contents, props changed)

Modified: cfe/trunk/utils/analyzer/SATestAdd.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/SATestAdd.py?rev=143786&r1=143785&r2=143786&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/SATestAdd.py (original)
+++ cfe/trunk/utils/analyzer/SATestAdd.py Sat Nov  5 00:20:48 2011
@@ -26,7 +26,7 @@
 # Params:
 #   Dir is the directory where the sources are.
 #   ID is a short string used to identify a project.
-def addNewProject(ID) :
+def addNewProject(ID, IsScanBuild) :
     CurDir = os.path.abspath(os.curdir)
     Dir = SATestBuild.getProjectDir(ID)
     if not os.path.exists(Dir):
@@ -34,7 +34,7 @@
         sys.exit(-1)
         
     # Build the project.
-    SATestBuild.testProject(ID, True, Dir)
+    SATestBuild.testProject(ID, True, IsScanBuild, Dir)
 
     # Add the project ID to the project map.
     ProjectMapPath = os.path.join(CurDir, SATestBuild.ProjectMapFile)
@@ -53,7 +53,7 @@
                 sys.exit(-1)
 
         PMapWriter = csv.writer(PMapFile)
-        PMapWriter.writerow( (ID, Dir) );
+        PMapWriter.writerow( (ID, int(IsScanBuild)) );
     finally:
         PMapFile.close()
         
@@ -65,7 +65,13 @@
 if __name__ == '__main__':
     if len(sys.argv) < 2:
         print >> sys.stderr, 'Usage: ', sys.argv[0],\
-                             '[project ID]'
+                             'project_ID <mode>' \
+                             'mode - 0 for single file project; 1 for scan_build'
         sys.exit(-1)
+    
+    IsScanBuild = 1    
+    if (len(sys.argv) >= 3):
+        IsScanBuild = int(sys.argv[2])  
+    assert((IsScanBuild == 0) | (IsScanBuild == 1))
         
-    addNewProject(sys.argv[1])
+    addNewProject(sys.argv[1], IsScanBuild)

Propchange: cfe/trunk/utils/analyzer/SATestAdd.py
------------------------------------------------------------------------------
    svn:executable = *

Modified: cfe/trunk/utils/analyzer/SATestBuild.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/SATestBuild.py?rev=143786&r1=143785&r2=143786&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/SATestBuild.py (original)
+++ cfe/trunk/utils/analyzer/SATestBuild.py Sat Nov  5 00:20:48 2011
@@ -45,7 +45,7 @@
 import shutil
 import time
 import plistlib
-from subprocess import check_call
+from subprocess import check_call, CalledProcessError
 
 # Project map stores info about all the "registered" projects.
 ProjectMapFile = "projectMap.csv"
@@ -57,6 +57,7 @@
 BuildScript = "run_static_analyzer.cmd"
 
 # The log file name.
+LogFolderName = "Logs"
 BuildLogName = "run_static_analyzer.log"
 # Summary file - contains the summary of the failures. Ex: This info can be be  
 # displayed when buildbot detects a build failure.
@@ -71,6 +72,8 @@
 
 Verbose = 1
 
+IsReferenceBuild = False
+
 def getProjectMapPath():
     ProjectMapPath = os.path.join(os.path.abspath(os.curdir), 
                                   ProjectMapFile)
@@ -83,6 +86,12 @@
 def getProjectDir(ID):
     return os.path.join(os.path.abspath(os.curdir), ID)        
 
+def getSBOutputDirName() :
+    if IsReferenceBuild == True :
+        return SBOutputDirReferencePrefix + SBOutputDirName
+    else :
+        return SBOutputDirName
+
 # Run pre-processing script if any.
 def runCleanupScript(Dir, PBuildLogFile):
     ScriptPath = os.path.join(Dir, CleanupScript)
@@ -124,36 +133,105 @@
     except:
         print "Error: scan-build failed. See ",PBuildLogFile.name,\
               " for details."
-        sys.exit(-1)
+        raise
 
-def buildProject(Dir, SBOutputDir, ClenupAfterBuild):
+def hasNoExtension(FileName):
+    (Root, Ext) = os.path.splitext(FileName)
+    if ((Ext == "")) :
+        return True
+    return False
+
+def isValidSingleInputFile(FileName):
+    (Root, Ext) = os.path.splitext(FileName)
+    if ((Ext == ".i") | (Ext == ".ii") | 
+        (Ext == ".c") | (Ext == ".cpp") | 
+        (Ext == ".m") | (Ext == "")) :
+        return True
+    return False
+
+# Run analysis on a set of preprocessed files.
+def runAnalyzePreprocessed(Dir, SBOutputDir):
+    if os.path.exists(os.path.join(Dir, BuildScript)):
+        print "Error: The preprocessed files project should not contain %s" % \
+               BuildScript
+        raise Exception()       
+
+    CmdPrefix = "clang -cc1 -analyze -analyzer-output=plist -w "
+    CmdPrefix += "-analyzer-checker=core "   
+    
+    PlistPath = os.path.join(Dir, SBOutputDir, "date")
+    FailPath = os.path.join(PlistPath, "failures");
+    os.makedirs(FailPath);
+ 
+    for FullFileName in glob.glob(Dir + "/*"):
+        FileName = os.path.basename(FullFileName)
+        Failed = False
+        
+        # Only run the analyzes on supported files.
+        if (hasNoExtension(FileName)):
+            continue
+        if (isValidSingleInputFile(FileName) == False):
+            print "Error: Invalid single input file %s." % (FullFileName,)
+            raise Exception()
+        
+        # Build and call the analyzer command.
+        OutputOption = "-o " + os.path.join(PlistPath, FileName) + ".plist "
+        Command = CmdPrefix + OutputOption + os.path.join(Dir, FileName)
+        LogFile = open(os.path.join(FailPath, FileName + ".stderr.txt"), "w+b")
+        try:
+            if Verbose == 1:        
+                print "  Executing: %s" % (Command,)
+            check_call(Command, cwd = Dir, stderr=LogFile,
+                                           stdout=LogFile, 
+                                           shell=True)
+        except CalledProcessError, e:
+            print "Error: Analyzes of %s failed. See %s for details." \
+                  "Error code %d." % \
+                   (FullFileName, LogFile.name, e.returncode)
+            Failed = True       
+        finally:
+            LogFile.close()            
+        
+        # If command did not fail, erase the log file.
+        if Failed == False:
+            os.remove(LogFile.name);
+
+def buildProject(Dir, SBOutputDir, IsScanBuild):
     TBegin = time.time() 
 
-    BuildLogPath = os.path.join(Dir, BuildLogName)
+    BuildLogPath = os.path.join(SBOutputDir, LogFolderName, BuildLogName)
     print "Log file: %s" % (BuildLogPath,) 
-
+    print "Output directory: %s" %(SBOutputDir, )
+    
     # Clean up the log file.
     if (os.path.exists(BuildLogPath)) :
         RmCommand = "rm " + BuildLogPath
         if Verbose == 1:
             print "  Executing: %s" % (RmCommand,)
         check_call(RmCommand, shell=True)
+    
+    # Clean up scan build results.
+    if (os.path.exists(SBOutputDir)) :
+        RmCommand = "rm -r " + SBOutputDir
+        if Verbose == 1: 
+            print "  Executing: %s" % (RmCommand,)
+            check_call(RmCommand, shell=True)
+    assert(not os.path.exists(SBOutputDir))
+    os.makedirs(os.path.join(SBOutputDir, LogFolderName))
         
     # Open the log file.
     PBuildLogFile = open(BuildLogPath, "wb+")
-    try:
-        # Clean up scan build results.
-        if (os.path.exists(SBOutputDir)) :
-            RmCommand = "rm -r " + SBOutputDir
-            if Verbose == 1: 
-                print "  Executing: %s" % (RmCommand,)
-                check_call(RmCommand, stderr=PBuildLogFile, 
-                                      stdout=PBuildLogFile, shell=True)
     
+    # Build and analyze the project.
+    try:
         runCleanupScript(Dir, PBuildLogFile)
-        runScanBuild(Dir, SBOutputDir, PBuildLogFile)
         
-        if ClenupAfterBuild :
+        if IsScanBuild:
+            runScanBuild(Dir, SBOutputDir, PBuildLogFile)
+        else:
+            runAnalyzePreprocessed(Dir, SBOutputDir)
+        
+        if IsReferenceBuild :
             runCleanupScript(Dir, PBuildLogFile)
            
     finally:
@@ -189,9 +267,9 @@
         return;
     
     # Create summary file to display when the build fails.
-    SummaryPath = os.path.join(SBOutputDir, FailuresSummaryFileName);
+    SummaryPath = os.path.join(SBOutputDir, LogFolderName, FailuresSummaryFileName)
     if (Verbose > 0):
-        print "  Creating the failures summary file %s." % (SummaryPath,)
+        print "  Creating the failures summary file %s" % (SummaryPath,)
     
     SummaryLog = open(SummaryPath, "w+")
     try:
@@ -216,7 +294,7 @@
     finally:
         SummaryLog.close()
     
-    print "Error: Scan-build failed. See ", \
+    print "Error: analysis failed. See ", \
           os.path.join(SBOutputDir, FailuresSummaryFileName)
     sys.exit(-1)       
 
@@ -235,6 +313,11 @@
     # We have to go one level down the directory tree.
     RefList = glob.glob(RefDir + "/*") 
     NewList = glob.glob(NewDir + "/*")
+    
+    # Log folders are also located in the results dir, so ignore them. 
+    RefList.remove(os.path.join(RefDir, LogFolderName))
+    NewList.remove(os.path.join(NewDir, LogFolderName))
+    
     if len(RefList) == 0 or len(NewList) == 0:
         return False
     assert(len(RefList) == len(NewList))
@@ -271,8 +354,13 @@
                     
     print "Diagnostic comparison complete (time: %.2f)." % (time.time()-TBegin) 
     return HaveDiffs
+    
+def testProject(ID, InIsReferenceBuild, IsScanBuild , Dir=None):
+    global IsReferenceBuild
+    IsReferenceBuild = InIsReferenceBuild
+
+    print " \n\n--- Building project %s" % (ID,)
 
-def testProject(ID, IsReferenceBuild, Dir=None):
     TBegin = time.time() 
 
     if Dir is None :
@@ -281,13 +369,9 @@
         print "  Build directory: %s." % (Dir,)
     
     # Set the build results directory.
-    if IsReferenceBuild == True :
-        SBOutputDir = os.path.join(Dir, SBOutputDirReferencePrefix + \
-                                        SBOutputDirName)
-    else :    
-        SBOutputDir = os.path.join(Dir, SBOutputDirName)
-    
-    buildProject(Dir, SBOutputDir, IsReferenceBuild)    
+    SBOutputDir = os.path.join(Dir, getSBOutputDirName())
+        
+    buildProject(Dir, SBOutputDir, IsScanBuild)    
 
     checkBuild(SBOutputDir)
     
@@ -297,13 +381,22 @@
     print "Completed tests for project %s (time: %.2f)." % \
           (ID, (time.time()-TBegin))
     
-def testAll(IsReferenceBuild=False):
+def testAll(InIsReferenceBuild = False):
+    
     PMapFile = open(getProjectMapPath(), "rb")
     try:
         PMapReader = csv.reader(PMapFile)
         for I in PMapReader:
-            print " --- Building project %s" % (I[0],)
-            testProject(I[0], IsReferenceBuild)            
+            if (len(I) != 2) :
+                print "Error: Rows in the ProjectMapFile should have 3 entries."
+                raise Exception()
+            if (not ((I[1] == "1") | (I[1] == "0"))):
+                print "Error: Second entry in the ProjectMapFile should be 0 or 1."
+                raise Exception()              
+            testProject(I[0], InIsReferenceBuild, int(I[1]))
+    except:
+        print "Error occurred. Premature termination."
+        raise                            
     finally:
         PMapFile.close()    
             

Propchange: cfe/trunk/utils/analyzer/SATestBuild.py
------------------------------------------------------------------------------
    svn:executable = *





More information about the cfe-commits mailing list