]> git.cworth.org Git - apitrace/blob - scripts/highlight.py
Better highlighting of tracediff2.
[apitrace] / scripts / highlight.py
1 ##########################################################################
2 #
3 # Copyright 2011 Jose Fonseca
4 # Copyright 2008-2009 VMware, Inc.
5 # All Rights Reserved.
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 # THE SOFTWARE.
24 #
25 ##########################################################################/
26
27
28 import sys
29 import platform
30
31
32 class PlainHighlighter:
33     '''Plain formatter'''
34
35     black = None
36     red = None
37     green = None
38     yellow = None
39     blue = None
40     magenta = None
41     cyan = None
42     white = None
43
44     def __init__(self, stream):
45         self.stream = stream
46
47     def write(self, text):
48         self.stream.write(text)
49
50     def flush(self):
51         self.stream.flush()
52
53     def normal(self):
54         pass
55
56     def color(self, color):
57         pass
58
59     def bold(self):
60         pass
61
62     def italic(self):
63         pass
64
65
66 class AnsiHighlighter(PlainHighlighter):
67     '''Highlighter for plain-text files which outputs ANSI escape codes. See
68     http://en.wikipedia.org/wiki/ANSI_escape_code for more information
69     concerning ANSI escape codes.
70     '''
71
72     _csi = '\33['
73
74     _normal = '0m'
75     _bold = '1m'
76     _italic = '3m'
77
78     black = 0
79     red = 1
80     green = 2
81     yellow = 3
82     blue = 4
83     magenta = 5
84     cyan = 6
85     white = 7
86
87     def __init__(self, stream):
88         PlainHighlighter.__init__(self, stream)
89
90     def _escape(self, code):
91         self.stream.write(self._csi + code)
92
93     def normal(self):
94         self._escape(self._normal)
95
96     def color(self, color):
97         self._escape(str(30 + color) + 'm')
98
99     def bold(self):
100         self._escape(self._bold)
101
102     def italic(self):
103         self._escape(self._italic)
104
105
106 class WindowsConsoleHighlighter(PlainHighlighter):
107     '''Highlighter for the Windows Console. See 
108     http://code.activestate.com/recipes/496901/ for more information.
109     '''
110
111     INVALID_HANDLE_VALUE = -1
112     STD_INPUT_HANDLE  = -10
113     STD_OUTPUT_HANDLE = -11
114     STD_ERROR_HANDLE  = -12
115
116     FOREGROUND_BLUE      = 0x01
117     FOREGROUND_GREEN     = 0x02
118     FOREGROUND_RED       = 0x04
119     FOREGROUND_INTENSITY = 0x08
120     BACKGROUND_BLUE      = 0x10
121     BACKGROUND_GREEN     = 0x20
122     BACKGROUND_RED       = 0x40
123     BACKGROUND_INTENSITY = 0x80
124
125     COMMON_LVB_LEADING_BYTE = 0x0100
126     COMMON_LVB_TRAILING_BYTE = 0x0200
127     COMMON_LVB_GRID_HORIZONTAL = 0x0400
128     COMMON_LVB_GRID_LVERTICAL = 0x0800
129     COMMON_LVB_GRID_RVERTICAL = 0x1000
130     COMMON_LVB_REVERSE_VIDEO = 0x4000
131     COMMON_LVB_UNDERSCORE = 0x8000
132
133     _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
134     _bold   = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
135     _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
136
137     black   = 0
138     red     =                                      FOREGROUND_RED
139     green   =                   FOREGROUND_GREEN                 
140     blue    = FOREGROUND_BLUE                                    
141     white   = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
142
143     def __init__(self, stream):
144         PlainHighlighter.__init__(self, stream)
145
146         if stream is sys.stdin:
147             nStdHandle = self.STD_INPUT_HANDLE
148         elif stream is sys.stdout:
149             nStdHandle = self.STD_OUTPUT_HANDLE
150         elif stream is sys.stderr:
151             nStdHandle = self.STD_ERROR_HANDLE
152         else:
153             nStdHandle = None
154
155         if nStdHandle is not None:
156             import ctypes
157             self._handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle)
158         else:
159             self._handle = self.INVALID_HANDLE_VALUE
160
161         self._attribute = self.white
162
163     def _setAttribute(self, attr):
164         if self._handle != self.INVALID_HANDLE_VALUE:
165             import ctypes
166             ctypes.windll.kernel32.SetConsoleTextAttribute(self._handle, attr)
167         self._attribute = attr
168
169     def normal(self):
170         self._setAttribute(self._normal)
171
172     def color(self, color):
173         intensity = self._attribute & self.FOREGROUND_INTENSITY
174         self._setAttribute(color | intensity)
175
176     def bold(self):
177         self._setAttribute(self._attribute | self.FOREGROUND_INTENSITY)
178
179     def italic(self):
180         pass
181
182
183 def Highlighter(stream = sys.stdout, force = False):
184     if force or stream.isatty():
185         if platform.system() == 'Windows':
186             return WindowsConsoleHighlighter(stream)
187         else:
188             return AnsiHighlighter(stream)
189     else:
190         return PlainHighlighter(stream)
191
192
193 __all__ = [
194     'Highlighter',
195 ]