]> git.cworth.org Git - apitrace/blob - scripts/highlight.py
Use skiplist-based FastCallSet within trace::CallSet
[apitrace] / scripts / highlight.py
1 ##########################################################################
2 #
3 # Copyright 2011-2012 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 platform
29 import subprocess
30 import sys
31
32
33 class PlainHighlighter:
34     '''Plain formatter'''
35
36     black = None
37     red = None
38     green = None
39     yellow = None
40     blue = None
41     magenta = None
42     cyan = None
43     white = None
44
45     def __init__(self, stream = sys.stdout):
46         self.stream = stream
47
48     def write(self, text):
49         self.stream.write(text)
50
51     def flush(self):
52         self.stream.flush()
53
54     def normal(self):
55         pass
56
57     def color(self, color):
58         pass
59
60     def bold(self, enable = True):
61         pass
62
63     def strike(self):
64         pass
65
66     def italic(self):
67         pass
68
69
70 class AnsiHighlighter(PlainHighlighter):
71     '''Highlighter for plain-text files which outputs ANSI escape codes. See
72     http://en.wikipedia.org/wiki/ANSI_escape_code for more information
73     concerning ANSI escape codes.
74     '''
75
76     _csi = '\33['
77
78     _normal = '0m'
79     _italic = '3m'
80
81     black = 0
82     red = 1
83     green = 2
84     yellow = 3
85     blue = 4
86     magenta = 5
87     cyan = 6
88     white = 7
89
90     def __init__(self, stream = sys.stdout):
91         PlainHighlighter.__init__(self, stream)
92
93     def _escape(self, code):
94         self.stream.write(self._csi + code)
95
96     def normal(self):
97         self._escape(self._normal)
98
99     def color(self, color):
100         self._escape(str(30 + color) + 'm')
101
102     def bold(self, enable = True):
103         if enable:
104             self._escape('1m')
105         else:
106             self._escape('21m')
107
108     def strike(self):
109         self._escape('9m')
110
111     def italic(self):
112         self._escape(self._italic)
113
114
115 class WindowsConsoleHighlighter(PlainHighlighter):
116     '''Highlighter for the Windows Console. See 
117     http://code.activestate.com/recipes/496901/ for more information.
118     '''
119
120     INVALID_HANDLE_VALUE = -1
121     STD_INPUT_HANDLE  = -10
122     STD_OUTPUT_HANDLE = -11
123     STD_ERROR_HANDLE  = -12
124
125     FOREGROUND_BLUE      = 0x01
126     FOREGROUND_GREEN     = 0x02
127     FOREGROUND_RED       = 0x04
128     FOREGROUND_INTENSITY = 0x08
129     BACKGROUND_BLUE      = 0x10
130     BACKGROUND_GREEN     = 0x20
131     BACKGROUND_RED       = 0x40
132     BACKGROUND_INTENSITY = 0x80
133
134     COMMON_LVB_LEADING_BYTE = 0x0100
135     COMMON_LVB_TRAILING_BYTE = 0x0200
136     COMMON_LVB_GRID_HORIZONTAL = 0x0400
137     COMMON_LVB_GRID_LVERTICAL = 0x0800
138     COMMON_LVB_GRID_RVERTICAL = 0x1000
139     COMMON_LVB_REVERSE_VIDEO = 0x4000
140     COMMON_LVB_UNDERSCORE = 0x8000
141
142     _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
143     _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
144
145     black   = 0
146     red     =                                      FOREGROUND_RED
147     green   =                   FOREGROUND_GREEN                 
148     blue    = FOREGROUND_BLUE                                    
149     white   = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
150
151     def __init__(self, stream = sys.stdout):
152         PlainHighlighter.__init__(self, stream)
153
154         if stream is sys.stdin:
155             nStdHandle = self.STD_INPUT_HANDLE
156         elif stream is sys.stdout:
157             nStdHandle = self.STD_OUTPUT_HANDLE
158         elif stream is sys.stderr:
159             nStdHandle = self.STD_ERROR_HANDLE
160         else:
161             nStdHandle = None
162
163         if nStdHandle is not None:
164             import ctypes
165             self._handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle)
166         else:
167             self._handle = self.INVALID_HANDLE_VALUE
168
169         self._attribute = self.white
170
171     def _setAttribute(self, attr):
172         if self._handle != self.INVALID_HANDLE_VALUE:
173             import ctypes
174             ctypes.windll.kernel32.SetConsoleTextAttribute(self._handle, attr)
175         self._attribute = attr
176
177     def normal(self):
178         self._setAttribute(self._normal)
179
180     def color(self, color):
181         intensity = self._attribute & self.FOREGROUND_INTENSITY
182         self._setAttribute(color | intensity)
183
184     def bold(self, enable = True):
185         if enable:
186             attribute = self._attribute | self.FOREGROUND_INTENSITY
187         else:
188             attribute = self._attribute & ~self.FOREGROUND_INTENSITY
189         self._setAttribute(attribute)
190
191     def italic(self):
192         pass
193
194
195 if platform.system() == 'Windows':
196     ColorHighlighter = WindowsConsoleHighlighter
197 else:
198     ColorHighlighter = AnsiHighlighter
199
200
201 def AutoHighlighter(stream = sys.stdout):
202     if stream.isatty():
203         return ColorHighlighter(stream)
204     else:
205         return PlainHighlighter(stream)
206
207
208 class _LessHighlighter(AnsiHighlighter):
209
210     def __init__(self, less):
211         AnsiHighlighter.__init__(self, less.stdin)
212         self.less = less
213
214     def __del__(self):
215         self.less.stdin.close()
216         self.less.wait()
217
218
219 def LessHighlighter():
220     if sys.stdout.isatty():
221         try:
222             less = subprocess.Popen(
223                 args = ['less', '-FRXn'],
224                 stdin = subprocess.PIPE
225             )
226         except OSError:
227             return ColorHighlighter()
228         else:
229             return _LessHighlighter(less)
230     return PlainHighlighter(sys.stdout)
231