]> git.cworth.org Git - apitrace/blob - common/formatter.hpp
Use skiplist-based FastCallSet within trace::CallSet
[apitrace] / common / formatter.hpp
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 /*
27  * Helpers for coloring output.
28  */
29
30 #ifndef _FORMATTER_HPP_
31 #define _FORMATTER_HPP_
32
33
34 #include <iostream>
35
36 #ifdef _WIN32
37 #include <windows.h>
38
39 #ifndef COMMON_LVB_LEADING_BYTE
40 #define COMMON_LVB_LEADING_BYTE    0x0100
41 #endif
42
43 #ifndef COMMON_LVB_TRAILING_BYTE
44 #define COMMON_LVB_TRAILING_BYTE   0x0200
45 #endif
46
47 #ifndef COMMON_LVB_GRID_HORIZONTAL
48 #define COMMON_LVB_GRID_HORIZONTAL 0x0400
49 #endif
50
51 #ifndef COMMON_LVB_GRID_LVERTICAL
52 #define COMMON_LVB_GRID_LVERTICAL  0x0800
53 #endif
54
55 #ifndef COMMON_LVB_GRID_RVERTICAL
56 #define COMMON_LVB_GRID_RVERTICAL  0x1000
57 #endif
58
59 #ifndef COMMON_LVB_REVERSE_VIDEO
60 #define COMMON_LVB_REVERSE_VIDEO   0x4000
61 #endif
62
63 #ifndef COMMON_LVB_UNDERSCORE
64 #define COMMON_LVB_UNDERSCORE      0x8000
65 #endif
66
67 #endif /* _WIN32 */
68
69
70 namespace formatter {
71
72 /*
73  * See also http://bytes.com/topic/c/answers/63822-design-question-little-c-header-colorizing-text-linux-comments-ideas
74  */
75
76 class Attribute {
77 public:
78     virtual ~Attribute() {}
79
80     virtual void apply(std::ostream &) const {}
81 };
82
83
84 enum Color {
85     RED,
86     GREEN,
87     BLUE,
88 };
89
90
91 class Formatter {
92 public:
93     virtual ~Formatter() {}
94
95     virtual Attribute *normal(void) const { return new Attribute; }
96     virtual Attribute *bold(void) const { return new Attribute; }
97     virtual Attribute *italic(void) const { return new Attribute; }
98     virtual Attribute *strike(void) const { return new Attribute; }
99     virtual Attribute *color(Color) const { return new Attribute; }
100 };
101
102
103 class AnsiAttribute : public Attribute {
104 protected:
105     const char *escape;
106 public:
107     AnsiAttribute(const char *_escape) : escape(_escape) {}
108     void apply(std::ostream& os) const {
109         os << "\33[" << escape;
110     }
111 };
112
113
114 /**
115  * Formatter for plain-text files which outputs ANSI escape codes. See
116  * http://en.wikipedia.org/wiki/ANSI_escape_code for more information
117  * concerning ANSI escape codes.
118  */
119 class AnsiFormatter : public Formatter {
120 protected:
121 public:
122     virtual Attribute *normal(void) const { return new AnsiAttribute("0m"); }
123     virtual Attribute *bold(void) const { return new AnsiAttribute("1m"); }
124     /* Italic is not widely supported, or worse, implemented with a reverse */
125 #if 0
126     virtual Attribute *italic(void) const { return new AnsiAttribute("3m"); }
127 #endif
128     virtual Attribute *strike(void) const { return new AnsiAttribute("9m"); }
129     virtual Attribute *color(Color c) const { 
130         static const char *color_escapes[] = {
131             "31m", /* red */
132             "32m", /* green */
133             "34m", /* blue */
134         };
135         return new AnsiAttribute(color_escapes[c]); 
136     }
137 };
138
139
140 inline std::ostream& operator<<(std::ostream& os, const Attribute *attr) {
141     attr->apply(os);
142     return os;
143 }
144
145
146 #ifdef _WIN32
147
148
149 class WindowsAttribute : public Attribute {
150 protected:
151     WORD wAttributes;
152 public:
153     WindowsAttribute(WORD _wAttributes) : wAttributes(_wAttributes) {}
154     void apply(std::ostream& os) const {
155         DWORD nStdHandleOutput;
156         if (os == std::cout) {
157             nStdHandleOutput = STD_OUTPUT_HANDLE;
158         } else if (os == std::cerr) {
159             nStdHandleOutput = STD_ERROR_HANDLE;
160         } else {
161             return;
162         }
163         HANDLE hConsoleOutput = GetStdHandle(nStdHandleOutput);
164         if (hConsoleOutput == INVALID_HANDLE_VALUE) {
165             return;
166         }
167
168         SetConsoleTextAttribute(hConsoleOutput, wAttributes);
169     }
170 };
171
172
173 /**
174  * Formatter for the Windows Console.
175  */
176 class WindowsFormatter : public Formatter {
177 protected:
178 public:
179     virtual Attribute *normal(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
180     virtual Attribute *bold(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); }
181     virtual Attribute *italic(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
182     virtual Attribute *strike(void) const { return new WindowsAttribute(COMMON_LVB_REVERSE_VIDEO | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
183     virtual Attribute *color(Color c) const { 
184         static const WORD color_escapes[] = {
185             FOREGROUND_RED | FOREGROUND_INTENSITY,
186             FOREGROUND_GREEN | FOREGROUND_INTENSITY,
187             FOREGROUND_BLUE | FOREGROUND_INTENSITY, 
188         };
189         return new WindowsAttribute(color_escapes[c]); 
190     }
191 };
192
193
194 #endif /* _WIN32 */
195
196
197 inline Formatter *defaultFormatter(bool color = true) {
198     if (color) {
199 #ifdef _WIN32
200         // http://wiki.winehq.org/DeveloperFaq#detect-wine
201         static HMODULE hNtDll = NULL;
202         static bool bWine = false;
203         if (!hNtDll) {
204             hNtDll = LoadLibraryA("ntdll");
205             if (hNtDll) {
206                 bWine = GetProcAddress(hNtDll, "wine_get_version") != NULL;
207             }
208         }
209         if (bWine) {
210             return new AnsiFormatter;
211         }
212         return new WindowsFormatter;
213 #else
214         return new AnsiFormatter;
215 #endif
216     } else {
217         return new Formatter;
218     }
219 }
220
221
222 } /* namespace formatter */
223
224
225 #endif /* _FORMATTER_HPP_ */