]> git.cworth.org Git - apitrace/blobdiff - scripts/retracediff.py
Strip (non-standard) JSON comments.
[apitrace] / scripts / retracediff.py
index 1b2d2eb81d8dcd5e8269fffba7a89a24c8991920..bed216c314921e386ec03bc849c7a1a3d2c59359 100755 (executable)
 
 import optparse
 import os.path
-import re
-import shutil
 import subprocess
 import platform
 import sys
-import tempfile
 
 from PIL import Image
 
 from snapdiff import Comparer
+from highlight import Highlighter
 import jsondiff
 
 
@@ -56,26 +54,42 @@ class Setup:
         self.args = args
         self.env = env
 
-    def retrace(self):
+    def _retrace(self, args):
         cmd = [
             options.retrace,
+        ] + args + self.args
+        try:
+            return subprocess.Popen(cmd, env=self.env, stdout=subprocess.PIPE, stderr=NULL)
+        except OSError, ex:
+            sys.stderr.write('error: failed to execute %s: %s\n' % (cmd[0], ex.strerror))
+            sys.exit(1)
+
+    def retrace(self):
+        return self._retrace([
             '-s', '-',
             '-S', options.snapshot_frequency,
-        ] + self.args
-        p = subprocess.Popen(cmd, env=self.env, stdout=subprocess.PIPE, stderr=NULL)
-        return p
+        ])
 
     def dump_state(self, call_no):
         '''Get the state dump at the specified call no.'''
 
-        cmd = [
-            options.retrace,
+        p = self._retrace([
             '-D', str(call_no),
-        ] + self.args
-        p = subprocess.Popen(cmd, env=self.env, stdout=subprocess.PIPE, stderr=NULL)
+        ])
         state = jsondiff.load(p.stdout)
         p.wait()
-        return state
+        return state.get('parameters', {})
+
+    def diff_state(self, ref_call_no, src_call_no):
+        '''Compare the state between two calls.'''
+
+        ref_state = self.dump_state(ref_call_no)
+        src_state = self.dump_state(src_call_no)
+
+        sys.stdout.flush()
+        differ = jsondiff.Differ(sys.stdout)
+        differ.visit(ref_state, src_state)
+        sys.stdout.write('\n')
 
 
 def read_pnm(stream):
@@ -98,17 +112,6 @@ def read_pnm(stream):
     return image, comment
 
 
-def diff_state(setup, ref_call_no, src_call_no):
-    '''Compare the state between two calls.'''
-
-    ref_state = setup.dump_state(ref_call_no)
-    src_state = setup.dump_state(src_call_no)
-    sys.stdout.flush()
-    differ = jsondiff.Differ(sys.stdout)
-    differ.visit(ref_state, src_state)
-    sys.stdout.write('\n')
-
-
 def parse_env(optparser, entries):
     '''Translate a list of NAME=VALUE entries into an environment dictionary.'''
 
@@ -166,10 +169,12 @@ def main():
     ref_setup = Setup(args, ref_env)
     src_setup = Setup(args, src_env)
 
-    image_re = re.compile('^Wrote (.*\.png)$')
+    highligher = Highlighter(sys.stdout)
+
+    highligher.write('call\tprecision\n')
 
-    last_good = -1
     last_bad = -1
+    last_good = 0
     ref_proc = ref_setup.retrace()
     try:
         src_proc = src_setup.retrace()
@@ -193,9 +198,16 @@ def main():
                 comparer = Comparer(ref_image, src_image)
                 precision = comparer.precision()
 
-                sys.stdout.write('%u %f\n' % (call_no, precision))
+                mismatch = precision < options.threshold
+
+                if mismatch:
+                    highligher.color(highligher.red)
+                    highligher.bold()
+                highligher.write('%u\t%f\n' % (call_no, precision))
+                if mismatch:
+                    highligher.normal()
 
-                if precision < options.threshold:
+                if mismatch:
                     if options.diff_prefix:
                         prefix = os.path.join(options.diff_prefix, '%010u' % call_no)
                         prefix_dir = os.path.dirname(prefix)
@@ -205,12 +217,12 @@ def main():
                         src_image.save(prefix + '.src.png')
                         comparer.write_diff(prefix + '.diff.png')
                     if last_bad < last_good:
-                        diff_state(src_setup, last_good, call_no)
+                        src_setup.diff_state(last_good, call_no)
                     last_bad = call_no
                 else:
                     last_good = call_no
 
-                sys.stdout.flush()
+                highligher.flush()
         finally:
             src_proc.terminate()
     finally: