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

Anna Zaks ganna at apple.com
Mon Sep 12 14:07:18 PDT 2011


Author: zaks
Date: Mon Sep 12 16:07:18 2011
New Revision: 139540

URL: http://llvm.org/viewvc/llvm-project?rev=139540&view=rev
Log:
Rename CmpRuns into CmpRuns.py so that it could be used as a module.

Added:
    cfe/trunk/utils/analyzer/CmpRuns.py
      - copied unchanged from r139539, cfe/trunk/utils/analyzer/CmpRuns
Removed:
    cfe/trunk/utils/analyzer/CmpRuns

Removed: cfe/trunk/utils/analyzer/CmpRuns
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/CmpRuns?rev=139539&view=auto
==============================================================================
--- cfe/trunk/utils/analyzer/CmpRuns (original)
+++ cfe/trunk/utils/analyzer/CmpRuns (removed)
@@ -1,230 +0,0 @@
-#!/usr/bin/env python
-
-"""
-CmpRuns - A simple tool for comparing two static analyzer runs to determine
-which reports have been added, removed, or changed.
-
-This is designed to support automated testing using the static analyzer, from
-two perspectives: 
-  1. To monitor changes in the static analyzer's reports on real code bases, for
-     regression testing.
-
-  2. For use by end users who want to integrate regular static analyzer testing
-     into a buildbot like environment.
-"""
-
-import os
-import plistlib
-
-#
-
-class multidict:
-    def __init__(self, elts=()):
-        self.data = {}
-        for key,value in elts:
-            self[key] = value
-    
-    def __getitem__(self, item):
-        return self.data[item]
-    def __setitem__(self, key, value):
-        if key in self.data:
-            self.data[key].append(value)
-        else:
-            self.data[key] = [value]
-    def items(self):
-        return self.data.items()
-    def values(self):
-        return self.data.values()
-    def keys(self):
-        return self.data.keys()
-    def __len__(self):
-        return len(self.data)
-    def get(self, key, default=None):
-        return self.data.get(key, default)
-    
-#
-
-class AnalysisReport:
-    def __init__(self, run, files):
-        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']
-
-        # FIXME: Get a report number based on this key, to 'distinguish'
-        # reports, or something.
-        
-        return '%s:%d:%d' % (filename, line, column)
-
-    def getReportData(self):
-        if self.htmlReport is None:
-            return "This diagnostic does not have any report data."
-
-        return open(os.path.join(self.report.run.path,
-                                 self.htmlReport), "rb").read() 
-
-class AnalysisRun:
-    def __init__(self, path, opts):
-        self.path = path
-        self.reports = []
-        self.diagnostics = []
-        self.opts = opts
-
-    def getSourceName(self, path):
-        if path.startswith(self.opts.root):
-            return path[len(self.opts.root):]
-        return path
-
-def loadResults(path, opts):
-    run = AnalysisRun(path, opts)
-
-    for f in os.listdir(path):
-        if (not f.startswith('report') or
-            not f.endswith('plist')):
-            continue
-
-        p = os.path.join(path, f)
-        data = plistlib.readPlist(p)
-
-        # Ignore empty reports.
-        if not data['files']:
-            continue
-
-        # Extract the HTML reports, if they exists.
-        if 'HTMLDiagnostics_files' in data['diagnostics'][0]:
-            htmlFiles = []
-            for d in data['diagnostics']:
-                # FIXME: Why is this named files, when does it have multiple
-                # files?
-                assert len(d['HTMLDiagnostics_files']) == 1
-                htmlFiles.append(d.pop('HTMLDiagnostics_files')[0])
-        else:
-            htmlFiles = [None] * len(data['diagnostics'])
-            
-        report = AnalysisReport(run, data.pop('files'))
-        diagnostics = [AnalysisDiagnostic(d, report, h) 
-                       for d,h in zip(data.pop('diagnostics'),
-                                      htmlFiles)]
-
-        assert not data
-
-        run.reports.append(report)
-        run.diagnostics.extend(diagnostics)
-
-    return run
-
-def compareResults(A, B):
-    """
-    compareResults - Generate a relation from diagnostics in run A to
-    diagnostics in run B.
-
-    The result is the relation as a list of triples (a, b, confidence) where
-    each element {a,b} is None or an element from the respective run, and
-    confidence is a measure of the match quality (where 0 indicates equality,
-    and None is used if either element is None).
-    """
-
-    res = []
-
-    # Quickly eliminate equal elements.
-    neqA = []
-    neqB = []
-    eltsA = list(A.diagnostics)
-    eltsB = list(B.diagnostics)
-    eltsA.sort(key = lambda d: d.data)
-    eltsB.sort(key = lambda d: d.data)
-    while eltsA and eltsB:
-        a = eltsA.pop()
-        b = eltsB.pop()
-        if a.data == b.data:
-            res.append((a, b, 0))
-        elif a.data > b.data:
-            neqA.append(a)
-            eltsB.append(b)
-        else:
-            neqB.append(b)
-            eltsA.append(a)
-    neqA.extend(eltsA)
-    neqB.extend(eltsB)
-
-    # FIXME: Add fuzzy matching. One simple and possible effective idea would be
-    # to bin the diagnostics, print them in a normalized form (based solely on
-    # the structure of the diagnostic), compute the diff, then use that as the
-    # basis for matching. This has the nice property that we don't depend in any
-    # way on the diagnostic format.
-
-    for a in neqA:
-        res.append((a, None, None))
-    for b in neqB:
-        res.append((None, b, None))
-
-    return res
-
-def main():
-    from optparse import OptionParser
-    parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
-    parser.add_option("", "--root", dest="root",
-                      help="Prefix to ignore on source files",
-                      action="store", type=str, default="")
-    parser.add_option("", "--verbose-log", dest="verboseLog",
-                      help="Write additional information to LOG [default=None]",
-                      action="store", type=str, default=None,
-                      metavar="LOG")
-    (opts, args) = parser.parse_args()
-
-    if len(args) != 2:
-        parser.error("invalid number of arguments")
-
-    dirA,dirB = args
-
-    # Load the run results.
-    resultsA = loadResults(dirA, opts)
-    resultsB = loadResults(dirB, opts)
-    
-    # Open the verbose log, if given.
-    if opts.verboseLog:
-        auxLog = open(opts.verboseLog, "wb")
-    else:
-        auxLog = None
-
-    diff = compareResults(resultsA, resultsB)
-    for res in diff:
-        a,b,confidence = res
-        if a is None:
-            print "ADDED: %r" % b.getReadableName()
-            if auxLog:
-                print >>auxLog, ("('ADDED', %r, %r)" % (b.getReadableName(),
-                                                        b.getReportData()))
-        elif b is None:
-            print "REMOVED: %r" % a.getReadableName()
-            if auxLog:
-                print >>auxLog, ("('REMOVED', %r, %r)" % (a.getReadableName(),
-                                                          a.getReportData()))
-        elif confidence:
-            print "CHANGED: %r to %r" % (a.getReadableName(),
-                                         b.getReadableName())
-            if auxLog:
-                print >>auxLog, ("('CHANGED', %r, %r, %r, %r)" 
-                                 % (a.getReadableName(),
-                                    b.getReadableName(),
-                                    a.getReportData(),
-                                    b.getReportData()))
-        else:
-            pass
-
-    print "TOTAL REPORTS: %r" % len(resultsB.diagnostics)
-    if auxLog:
-        print >>auxLog, "('TOTAL', %r)" % len(resultsB.diagnostics)
-
-if __name__ == '__main__':
-    main()





More information about the cfe-commits mailing list