[cfe-commits] r62156 - /cfe/trunk/utils/CmpDriver

Daniel Dunbar daniel at zuster.org
Mon Jan 12 23:38:29 PST 2009


Author: ddunbar
Date: Tue Jan 13 01:38:29 2009
New Revision: 62156

URL: http://llvm.org/viewvc/llvm-project?rev=62156&view=rev
Log:
Add simple tool for comparing drivers (hardcoded to gcc and xcc) which
support -###.

Added:
    cfe/trunk/utils/CmpDriver   (with props)

Added: cfe/trunk/utils/CmpDriver
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/CmpDriver?rev=62156&view=auto

==============================================================================
--- cfe/trunk/utils/CmpDriver (added)
+++ cfe/trunk/utils/CmpDriver Tue Jan 13 01:38:29 2009
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+
+import subprocess
+
+def splitArgs(s):
+    it = iter(s)
+    current = ''
+    inQuote = False
+    for c in it:
+        if c == '"':
+            if inQuote:
+                inQuote = False
+                yield current + '"'
+            else:
+                inQuote = True
+                current = '"'
+        elif inQuote:
+            if c == '\\':
+                current += c
+                current += it.next()
+            else:
+                current += c
+        elif not c.isspace():
+            yield c
+
+def insertMinimumPadding(a, b, dist):
+    """insertMinimumPadding(a,b) -> (a',b')
+
+    Return two lists of equal length, where some number of Nones have
+    been inserted into the shorter list such that sum(map(dist, a',
+    b')) is minimized.
+
+    Assumes dist(X, Y) -> int and non-negative.
+    """
+    
+    # Yay for simplicity over complexity.
+
+    def extend(aElt, bElt, solution):
+        d0,(a0,b0) = solution
+        return d0 + dist(aElt,bElt), (([aElt]+a0),([bElt]+b0))
+
+    def f(a, b):
+        if len(a) == len(b):
+            return (sum(map(dist, a, b)), (a, b))
+        
+        if not a or not b:
+            if not a:
+                a += [None] * len(b)
+            else:
+                b += [None] * len(a)
+            return (sum(map(dist, a, b)), (a, b))
+
+        if int(dist(a[0], b[0])) == 0:
+            # Non-negative condition implies maximum is satisfied
+            # taking this.
+            return extend(a[0], b[0], f(a[1:], b[1:]))
+
+        if len(a) < len(b):
+            return min(f([None] + a, b),
+                       extend(a[0], b[0], f(a[1:], b[1:])))
+        else:
+            return min(f(a, [None] + b),
+                       extend(a[0], b[0], f(a[1:], b[1:])))
+            
+    return f(a, b)[1]
+
+class ZipperDiff(object):
+    """ZipperDiff - Simple (slow) diff only accomodating inserts."""
+    
+    def __init__(self, a, b):
+        self.a = a
+        self.b = b
+
+    def dist(self, a, b):
+        return a != b
+
+    def getDiffs(self):
+        a,b =  insertMinimumPadding(self.a, self.b, self.dist)
+        for aElt,bElt in zip(a,b):
+            if self.dist(aElt, bElt):
+                yield aElt,bElt
+
+class DriverZipperDiff(ZipperDiff):
+    def isTempFile(self, filename):
+        if filename[0] != '"' or filename[-1] != '"':
+            return False
+        return (filename.startswith('/tmp/', 1) or
+                filename.startswith('/var/', 1))
+
+    def dist(self, a, b):
+        if a and b and self.isTempFile(a) and self.isTempFile(b):
+            return 0
+        return super(DriverZipperDiff, self).dist(a,b)        
+
+class CompileInfo:
+    def __init__(self, out, err, res):
+        self.commands = []
+        
+        # Standard out isn't used for much.
+        self.stdout = out
+        self.stderr = ''
+
+        # FIXME: Compare error messages as well.
+        for ln in err.split('\n'):
+            if (ln == 'Using built-in specs.' or
+                ln.startswith('Target: ') or
+                ln.startswith('Configured with: ') or
+                ln.startswith('Thread model: ') or
+                ln.startswith('gcc version')):
+                pass
+            elif ln.strip().startswith('"'):
+                self.commands.append(list(splitArgs(ln)))
+            else:
+                self.stderr += ln + '\n'
+        
+        self.stderr = self.stderr.strip()
+        self.exitCode = res
+
+def captureDriverInfo(cmd, args):
+    p = subprocess.Popen([cmd,'-###'] + args,
+                         stdin=None,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.PIPE)
+    out,err = p.communicate()
+    res = p.wait()
+    return CompileInfo(out,err,res)
+
+def main():
+    import sys
+
+    args = sys.argv[1:]
+    driverA = 'gcc'
+    driverB = 'xcc'
+
+    infoA = captureDriverInfo(driverA, args)
+    infoB = captureDriverInfo(driverB, args)
+
+    # Compare stdout.
+    if infoA.stdout != infoB.stdout:
+        print '-- STDOUT DIFFERS -'
+        print 'A: ',infoA.stdout
+        print 'B: ',infoB.stdout
+
+    # Compare stderr.
+    if infoA.stderr != infoB.stderr:
+        print '-- STDERR DIFFERS -'
+        print 'A: ',infoA.stderr
+        print 'B: ',infoB.stderr
+
+    # Compare commands.
+    for i,(a,b) in enumerate(zip(infoA.commands, infoB.commands)):
+        diff = DriverZipperDiff(a,b)
+        diffs = list(diff.getDiffs())
+        if diffs:
+            print '-- COMMAND %d DIFFERS -' % i
+            print 'A COMMAND:',' '.join(a)
+            print 'B COMMAND:',' '.join(b)
+            print
+            for i,(aElt,bElt) in enumerate(diffs):
+                if aElt is None:
+                    print 'A missing: %s' % bElt
+                elif bElt is None:
+                    print 'B missing: %s' % aElt
+                else:
+                    print 'mismatch: A: %s' % aElt
+                    print '          B: %s' % bElt
+
+    # Compare result codes.
+    if infoA.exitCode != infoB.exitCode:
+        print '-- EXIT CODES DIFFER -'
+        print 'A: ',infoA.exitCode
+        print 'B: ',infoB.exitCode
+
+if __name__ == '__main__':
+   main()

Propchange: cfe/trunk/utils/CmpDriver

------------------------------------------------------------------------------
    svn:executable = *





More information about the cfe-commits mailing list