diff options
author | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-08-15 20:02:54 +0000 |
commit | 554bcb69c2d785a011a30e7db87a36a87fe7db10 (patch) | |
tree | 9abb1a658a297776086f4e0dfa6ca533de02104e /utils/analyzer/CmpRuns.py | |
parent | bb67ca86b31f67faee50bd10c3b036d65751745a (diff) | |
download | FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.zip FreeBSD-src-554bcb69c2d785a011a30e7db87a36a87fe7db10.tar.gz |
Vendor import of clang trunk r161861:
http://llvm.org/svn/llvm-project/cfe/trunk@161861
Diffstat (limited to 'utils/analyzer/CmpRuns.py')
-rwxr-xr-x | utils/analyzer/CmpRuns.py | 135 |
1 files changed, 85 insertions, 50 deletions
diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py index e68c45df..f2961cf 100755 --- a/utils/analyzer/CmpRuns.py +++ b/utils/analyzer/CmpRuns.py @@ -11,12 +11,67 @@ two perspectives: 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. + # + # root - the name of the root directory, which will be disregarded when + # determining the source file name + # + resultsA = loadResults(dirA, opts, root, deleteEmpty) + resultsB = loadResults(dirB, opts, root, 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 + ":" + self.getFileName() + + 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=()): @@ -45,8 +100,9 @@ class multidict: # class CmpOptions: - def __init__(self, verboseLog=None, root=""): - self.root = root + def __init__(self, verboseLog=None, rootA="", rootB=""): + self.rootA = rootA + self.rootB = rootB self.verboseLog = verboseLog class AnalysisReport: @@ -54,49 +110,22 @@ class AnalysisReport: 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): + def __init__(self, path, root, opts): self.path = path + self.root = root self.reports = [] self.diagnostics = [] self.opts = opts def getSourceName(self, path): - if path.startswith(self.opts.root): - return path[len(self.opts.root):] + if path.startswith(self.root): + return path[len(self.root):] return path -def loadResults(path, opts, deleteEmpty=True): - run = AnalysisRun(path, opts) - +def loadResults(path, opts, root = "", deleteEmpty=True): + run = AnalysisRun(path, root, opts) + for f in os.listdir(path): if (not f.startswith('report') or not f.endswith('plist')): @@ -134,6 +163,9 @@ def loadResults(path, opts, deleteEmpty=True): return run +def cmpAnalysisDiagnostic(d) : + return d.getIssueIdentifier() + def compareResults(A, B): """ compareResults - Generate a relation from diagnostics in run A to @@ -152,14 +184,14 @@ def compareResults(A, B): neqB = [] eltsA = list(A.diagnostics) eltsB = list(B.diagnostics) - eltsA.sort(key = lambda d: d.data) - eltsB.sort(key = lambda d: d.data) + eltsA.sort(key = cmpAnalysisDiagnostic) + eltsB.sort(key = cmpAnalysisDiagnostic) while eltsA and eltsB: a = eltsA.pop() b = eltsB.pop() - if a.data['location'] == b.data['location']: + 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: @@ -181,10 +213,10 @@ def compareResults(A, B): 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) + resultsA = loadResults(dirA, opts, opts.rootA, deleteEmpty) + resultsB = loadResults(dirB, opts, opts.rootB, deleteEmpty) # Open the verbose log, if given. if opts.verboseLog: @@ -201,13 +233,13 @@ def cmpScanBuildResults(dirA, dirB, opts, deleteEmpty=True): 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()) @@ -216,8 +248,8 @@ def cmpScanBuildResults(dirA, dirB, opts, deleteEmpty=True): print >>auxLog, ("('CHANGED', %r, %r, %r, %r)" % (a.getReadableName(), b.getReadableName(), - a.getReportData(), - b.getReportData())) + a.getReport(), + b.getReport())) else: pass @@ -233,8 +265,11 @@ def cmpScanBuildResults(dirA, dirB, opts, deleteEmpty=True): 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", + parser.add_option("", "--rootA", dest="rootA", + help="Prefix to ignore on source files for directory A", + action="store", type=str, default="") + parser.add_option("", "--rootB", dest="rootB", + help="Prefix to ignore on source files for directory B", action="store", type=str, default="") parser.add_option("", "--verbose-log", dest="verboseLog", help="Write additional information to LOG [default=None]", @@ -247,7 +282,7 @@ def main(): dirA,dirB = args - cmpScanBuildResults(dirA, dirB, opts) + dumpScanBuildResultsDiff(dirA, dirB, opts) if __name__ == '__main__': main() |