]> git.cworth.org Git - apitrace/commitdiff
Highlight retracediff output.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 6 Sep 2011 09:22:56 +0000 (10:22 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Tue, 6 Sep 2011 09:22:56 +0000 (10:22 +0100)
scripts/highlight.py [new file with mode: 0644]
scripts/retracediff.py

diff --git a/scripts/highlight.py b/scripts/highlight.py
new file mode 100644 (file)
index 0000000..986bd1d
--- /dev/null
@@ -0,0 +1,194 @@
+##########################################################################
+#
+# Copyright 2011 Jose Fonseca
+# Copyright 2008-2009 VMware, Inc.
+# All Rights Reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+##########################################################################/
+
+
+import sys
+import platform
+
+
+class PlainHighlighter:
+    '''Plain formatter'''
+
+    black = None
+    red = None
+    green = None
+    yellow = None
+    blue = None
+    magenta = None
+    cyan = None
+    white = None
+
+    def __init__(self, stream):
+        self.stream = stream
+
+    def write(self, text):
+        self.stream.write(text)
+
+    def flush(self):
+        self.stream.flush()
+
+    def normal(self):
+        pass
+
+    def color(self, color):
+        pass
+
+    def bold(self):
+        pass
+
+    def italic(self):
+        pass
+
+
+class AnsiHighlighter(PlainHighlighter):
+    '''Highlighter for plain-text files which outputs ANSI escape codes. See
+    http://en.wikipedia.org/wiki/ANSI_escape_code for more information
+    concerning ANSI escape codes.
+    '''
+
+    _csi = '\33['
+
+    _normal = '0m'
+    _bold = '1m'
+    _italic = '3m'
+
+    black = 0
+    red = 1
+    green = 2
+    yellow = 3
+    blue = 4
+    magenta = 5
+    cyan = 6
+    white = 7
+
+    def __init__(self, stream):
+        PlainHighlighter.__init__(self, stream)
+        self.isatty = stream.isatty()
+
+    def _escape(self, code):
+        if self.isatty:
+            self.stream.write(self._csi + code)
+
+    def normal(self):
+        self._escape(self._normal)
+
+    def color(self, color):
+        self._escape(str(30 + color) + 'm')
+
+    def bold(self):
+        self._escape(self._bold)
+
+    def italic(self):
+        self._escape(self._italic)
+
+
+class WindowsConsoleHighlighter(PlainHighlighter):
+    '''Highlighter for the Windows Console. See 
+    http://code.activestate.com/recipes/496901/ for more information.
+    '''
+
+    INVALID_HANDLE_VALUE = -1
+    STD_INPUT_HANDLE  = -10
+    STD_OUTPUT_HANDLE = -11
+    STD_ERROR_HANDLE  = -12
+
+    FOREGROUND_BLUE      = 0x01
+    FOREGROUND_GREEN     = 0x02
+    FOREGROUND_RED       = 0x04
+    FOREGROUND_INTENSITY = 0x08
+    BACKGROUND_BLUE      = 0x10
+    BACKGROUND_GREEN     = 0x20
+    BACKGROUND_RED       = 0x40
+    BACKGROUND_INTENSITY = 0x80
+
+    COMMON_LVB_LEADING_BYTE = 0x0100
+    COMMON_LVB_TRAILING_BYTE = 0x0200
+    COMMON_LVB_GRID_HORIZONTAL = 0x0400
+    COMMON_LVB_GRID_LVERTICAL = 0x0800
+    COMMON_LVB_GRID_RVERTICAL = 0x1000
+    COMMON_LVB_REVERSE_VIDEO = 0x4000
+    COMMON_LVB_UNDERSCORE = 0x8000
+
+    _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
+    _bold   = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
+    _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
+
+    black   = 0
+    red     =                                      FOREGROUND_RED
+    green   =                   FOREGROUND_GREEN                 
+    blue    = FOREGROUND_BLUE                                    
+    white   = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
+
+    def __init__(self, stream):
+        PlainHighlighter.__init__(self, stream)
+
+        if stream is sys.stdin:
+            nStdHandle = self.STD_INPUT_HANDLE
+        elif stream is sys.stdout:
+            nStdHandle = self.STD_OUTPUT_HANDLE
+        elif stream is sys.stderr:
+            nStdHandle = self.STD_ERROR_HANDLE
+        else:
+            nStdHandle = None
+
+        if nStdHandle is not None:
+            import ctypes
+            self._handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle)
+        else:
+            self._handle = INVALID_HANDLE_VALUE
+
+        self._attribute = self.white
+
+    def _setAttribute(self, attr):
+        if self._handle != INVALID_HANDLE_VALUE:
+            import ctypes
+            ctypes.windll.kernel32.SetConsoleTextAttribute(self._handle, attr)
+        self._attribute = attr
+
+    def normal(self):
+        self._setAttribute(self._normal)
+
+    def color(self, color):
+        intensity = self._attribute & FOREGROUND_INTENSITY
+        self._setAttribute(color | intensity)
+
+    def bold(self):
+        self._setAttribute(self._attribute | FOREGROUND_INTENSITY)
+
+    def italic(self):
+        pass
+
+
+def Highlighter(stream = sys.stdout):
+    if platform.system() == 'Windows':
+        return WindowsConsoleHighlighter(stream)
+    else:
+        return AnsiHighlighter(stream)
+
+
+__all__ = [
+    'Highlighter',
+]
index 42c36bbac3c1b3e5d110285bed065668a6f333de..0b6a3b09f5713402b8ae8d249891ed31c7d76b5c 100755 (executable)
@@ -37,6 +37,7 @@ import sys
 from PIL import Image
 
 from snapdiff import Comparer
+from highlight import Highlighter
 import jsondiff
 
 
@@ -72,13 +73,14 @@ class Setup:
         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)
@@ -162,7 +164,9 @@ def main():
     ref_setup = Setup(args, ref_env)
     src_setup = Setup(args, src_env)
 
-    sys.stdout.write('call\tprecision\n')
+    highligher = Highlighter(sys.stdout)
+
+    highligher.write('call\tprecision\n')
 
     last_bad = -1
     last_good = 0
@@ -189,9 +193,16 @@ def main():
                 comparer = Comparer(ref_image, src_image)
                 precision = comparer.precision()
 
-                sys.stdout.write('%u\t%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)
@@ -206,7 +217,7 @@ def main():
                 else:
                     last_good = call_no
 
-                sys.stdout.flush()
+                highligher.flush()
         finally:
             src_proc.terminate()
     finally: