[cfe-commits] r160314 - in /cfe/trunk/utils/analyzer: CmpRuns.py SATestBuild.py

Anna Zaks ganna at apple.com
Mon Jul 16 13:21:42 PDT 2012


Author: zaks
Date: Mon Jul 16 15:21:42 2012
New Revision: 160314

URL: http://llvm.org/viewvc/llvm-project?rev=160314&view=rev
Log:
[analyzer] Make CmpRuns external-user friendly.

CmpRuns can be used for static analyzer bug report comparison. However,
we want to make sure external users do not rely on the way bugs are
represented (plist files). Make sure that we have a user
friendly/documented API for CmpRuns script.

Modified:
    cfe/trunk/utils/analyzer/CmpRuns.py
    cfe/trunk/utils/analyzer/SATestBuild.py

Modified: cfe/trunk/utils/analyzer/CmpRuns.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/CmpRuns.py?rev=160314&r1=160313&r2=160314&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/CmpRuns.py (original)
+++ cfe/trunk/utils/analyzer/CmpRuns.py Mon Jul 16 15:21:42 2012
@@ -11,12 +11,63 @@
 
   2. For use by end users who want to integrate regular static analyzer testing
      into a buildbot like environment.
+
+Usage:
+
+    # Load the results of both runs, to obtain lists of the corresponding
+    # AnalysisDiagnostic objects.
+    resultsA = loadResults(dirA, opts, deleteEmpty)
+    resultsB = loadResults(dirB, opts, deleteEmpty)
+    
+    # Generate a relation from diagnostics in run A to diagnostics in run B 
+    # to obtain a list of triples (a, b, confidence). 
+    diff = compareResults(resultsA, resultsB)
+           
 """
 
 import os
 import plistlib
 
 #
+class AnalysisDiagnostic:
+    def __init__(self, data, report, htmlReport):
+        self._data = data
+        self._loc = self._data['location']
+        self._report = report
+        self._htmlReport = htmlReport
+
+    def getFileName(self):
+        return self._report.run.getSourceName(self._report.files[self._loc['file']])
+
+    def getLine(self):
+        return self._loc['line']
+        
+    def getColumn(self):
+        return self._loc['col']
+
+    def getCategory(self):
+        return self._data['category']
+
+    def getDescription(self):
+        return self._data['description']
+
+    def getIssueIdentifier(self) :
+        id = ''
+        if 'issue_context' in self._data :
+          id += self._data['issue_context']
+        if 'issue_hash' in self._data :
+          id += str(self._data['issue_hash'])
+        return id
+
+    def getReport(self):
+        if self._htmlReport is None:
+            return " "
+        return os.path.join(self._report.run.path, self._htmlReport)
+
+    def getReadableName(self):
+        return '%s:%d:%d, %s: %s' % (self.getFileName(), self.getLine(), 
+                                     self.getColumn(), self.getCategory(), 
+                                     self.getDescription())
 
 class multidict:
     def __init__(self, elts=()):
@@ -54,34 +105,6 @@
         self.run = run
         self.files = files
 
-class AnalysisDiagnostic:
-    def __init__(self, data, report, htmlReport):
-        self.data = data
-        self.report = report
-        self.htmlReport = htmlReport
-
-    def getReadableName(self):
-        loc = self.data['location']
-        filename = self.report.run.getSourceName(self.report.files[loc['file']])
-        line = loc['line']
-        column = loc['col']
-        category = self.data['category']
-        description = self.data['description']
-
-        # FIXME: Get a report number based on this key, to 'distinguish'
-        # reports, or something.
-        
-        return '%s:%d:%d, %s: %s' % (filename, line, column, category, 
-                                   description)
-
-    def getReportData(self):
-        if self.htmlReport is None:
-            return " "
-        return os.path.join(self.report.run.path, self.htmlReport)
-        # We could also dump the report with:
-        # return open(os.path.join(self.report.run.path,
-        #                         self.htmlReport), "rb").read() 
-
 class AnalysisRun:
     def __init__(self, path, opts):
         self.path = path
@@ -134,13 +157,8 @@
 
     return run
 
-def getIssueIdentifier(d) :
-    id = ''
-    if 'issue_context' in d.data :
-      id += d.data['issue_context']
-    if 'issue_hash' in d.data :
-      id += str(d.data['issue_hash'])
-    return id
+def cmpAnalysisDiagnostic(d) :
+    return d.getIssueIdentifier()
 
 def compareResults(A, B):
     """
@@ -160,14 +178,14 @@
     neqB = []
     eltsA = list(A.diagnostics)
     eltsB = list(B.diagnostics)
-    eltsA.sort(key = getIssueIdentifier)
-    eltsB.sort(key = getIssueIdentifier)
+    eltsA.sort(key = cmpAnalysisDiagnostic)
+    eltsB.sort(key = cmpAnalysisDiagnostic)
     while eltsA and eltsB:
         a = eltsA.pop()
         b = eltsB.pop()
-        if (getIssueIdentifier(a) == getIssueIdentifier(b)) :
+        if (a.getIssueIdentifier() == b.getIssueIdentifier()) :
             res.append((a, b, 0))
-        elif a.data > b.data:
+        elif a._data > b._data:
             neqA.append(a)
             eltsB.append(b)
         else:
@@ -189,7 +207,7 @@
 
     return res
 
-def cmpScanBuildResults(dirA, dirB, opts, deleteEmpty=True):
+def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
     # Load the run results.
     resultsA = loadResults(dirA, opts, deleteEmpty)
     resultsB = loadResults(dirB, opts, deleteEmpty)
@@ -209,13 +227,13 @@
             foundDiffs += 1
             if auxLog:
                 print >>auxLog, ("('ADDED', %r, %r)" % (b.getReadableName(),
-                                                        b.getReportData()))
+                                                        b.getReport()))
         elif b is None:
             print "REMOVED: %r" % a.getReadableName()
             foundDiffs += 1
             if auxLog:
                 print >>auxLog, ("('REMOVED', %r, %r)" % (a.getReadableName(),
-                                                          a.getReportData()))
+                                                          a.getReport()))
         elif confidence:
             print "CHANGED: %r to %r" % (a.getReadableName(),
                                          b.getReadableName())
@@ -224,8 +242,8 @@
                 print >>auxLog, ("('CHANGED', %r, %r, %r, %r)" 
                                  % (a.getReadableName(),
                                     b.getReadableName(),
-                                    a.getReportData(),
-                                    b.getReportData()))
+                                    a.getReport(),
+                                    b.getReport()))
         else:
             pass
 

Modified: cfe/trunk/utils/analyzer/SATestBuild.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/SATestBuild.py?rev=160314&r1=160313&r2=160314&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/SATestBuild.py (original)
+++ cfe/trunk/utils/analyzer/SATestBuild.py Mon Jul 16 15:21:42 2012
@@ -357,7 +357,7 @@
         OLD_STDOUT = sys.stdout
         sys.stdout = Discarder()
         # Scan the results, delete empty plist files.
-        NumDiffs = CmpRuns.cmpScanBuildResults(RefDir, NewDir, Opts, False)
+        NumDiffs = CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
         sys.stdout = OLD_STDOUT
         if (NumDiffs > 0) :
             print "Warning: %r differences in diagnostics. See %s" % \





More information about the cfe-commits mailing list