]> git.cworth.org Git - apitrace/blob - common/formatter.hpp
43b816eb1ef1fb453817bd850ac5f6aad6e56191
[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
37 namespace formatter {
38
39 /*
40  * See also http://bytes.com/topic/c/answers/63822-design-question-little-c-header-colorizing-text-linux-comments-ideas
41  */
42
43 class Attribute {
44 public:
45     virtual ~Attribute() {}
46
47     virtual void apply(std::ostream &) const {}
48 };
49
50
51 enum Color {
52     RED,
53     GREEN,
54     BLUE,
55 };
56
57
58 class Formatter {
59 public:
60     virtual ~Formatter() {}
61
62     virtual Attribute *normal(void) const { return new Attribute; }
63     virtual Attribute *bold(void) const { return new Attribute; }
64     virtual Attribute *italic(void) const { return new Attribute; }
65     virtual Attribute *strike(void) const { return new Attribute; }
66     virtual Attribute *color(Color) const { return new Attribute; }
67 };
68
69
70 class AnsiAttribute : public Attribute {
71 protected:
72     const char *escape;
73 public:
74     AnsiAttribute(const char *_escape) : escape(_escape) {}
75     void apply(std::ostream& os) const {
76         os << "\33[" << escape;
77     }
78 };
79
80
81 /**
82  * Formatter for plain-text files which outputs ANSI escape codes. See
83  * http://en.wikipedia.org/wiki/ANSI_escape_code for more information
84  * concerning ANSI escape codes.
85  */
86 class AnsiFormatter : public Formatter {
87 protected:
88 public:
89     virtual Attribute *normal(void) const { return new AnsiAttribute("0m"); }
90     virtual Attribute *bold(void) const { return new AnsiAttribute("1m"); }
91     /* Italic is not widely supported, or worse, implemented with a reverse */
92 #if 0
93     virtual Attribute *italic(void) const { return new AnsiAttribute("3m"); }
94 #endif
95     virtual Attribute *strike(void) const { return new AnsiAttribute("9m"); }
96     virtual Attribute *color(Color c) const { 
97         static const char *color_escapes[] = {
98             "31m", /* red */
99             "32m", /* green */
100             "34m", /* blue */
101         };
102         return new AnsiAttribute(color_escapes[c]); 
103     }
104 };
105
106
107 inline std::ostream& operator<<(std::ostream& os, const Attribute *attr) {
108     attr->apply(os);
109     return os;
110 }
111
112
113 #ifdef _WIN32
114
115
116 #include <windows.h>
117
118
119 #ifndef COMMON_LVB_LEADING_BYTE
120 #define COMMON_LVB_LEADING_BYTE    0x0100
121 #endif
122
123 #ifndef COMMON_LVB_TRAILING_BYTE
124 #define COMMON_LVB_TRAILING_BYTE   0x0200
125 #endif
126
127 #ifndef COMMON_LVB_GRID_HORIZONTAL
128 #define COMMON_LVB_GRID_HORIZONTAL 0x0400
129 #endif
130
131 #ifndef COMMON_LVB_GRID_LVERTICAL
132 #define COMMON_LVB_GRID_LVERTICAL  0x0800
133 #endif
134
135 #ifndef COMMON_LVB_GRID_RVERTICAL
136 #define COMMON_LVB_GRID_RVERTICAL  0x1000
137 #endif
138
139 #ifndef COMMON_LVB_REVERSE_VIDEO
140 #define COMMON_LVB_REVERSE_VIDEO   0x4000
141 #endif
142
143 #ifndef COMMON_LVB_UNDERSCORE
144 #define COMMON_LVB_UNDERSCORE      0x8000
145 #endif
146
147
148 class WindowsAttribute : public Attribute {
149 protected:
150     WORD wAttributes;
151 public:
152     WindowsAttribute(WORD _wAttributes) : wAttributes(_wAttributes) {}
153     void apply(std::ostream& os) const {
154         DWORD nStdHandleOutput;
155         if (os == std::cout) {
156             nStdHandleOutput = STD_OUTPUT_HANDLE;
157         } else if (os == std::cerr) {
158             nStdHandleOutput = STD_ERROR_HANDLE;
159         } else {
160             return;
161         }
162         HANDLE hConsoleOutput = GetStdHandle(nStdHandleOutput);
163         if (hConsoleOutput == INVALID_HANDLE_VALUE) {
164             return;
165         }
166
167         SetConsoleTextAttribute(hConsoleOutput, wAttributes);
168     }
169 };
170
171
172 /**
173  * Formatter for the Windows Console.
174  */
175 class WindowsFormatter : public Formatter {
176 protected:
177 public:
178     virtual Attribute *normal(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
179     virtual Attribute *bold(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); }
180     virtual Attribute *italic(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
181     virtual Attribute *strike(void) const { return new WindowsAttribute(COMMON_LVB_REVERSE_VIDEO | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
182     virtual Attribute *color(Color c) const { 
183         static const WORD color_escapes[] = {
184             FOREGROUND_RED | FOREGROUND_INTENSITY,
185             FOREGROUND_GREEN | FOREGROUND_INTENSITY,
186             FOREGROUND_BLUE | FOREGROUND_INTENSITY, 
187         };
188         return new WindowsAttribute(color_escapes[c]); 
189     }
190 };
191
192 #endif
193
194
195 inline Formatter *defaultFormatter(bool color = true) {
196     if (color) {
197 #ifdef _WIN32
198         // http://wiki.winehq.org/DeveloperFaq#detect-wine
199         static HMODULE hNtDll = NULL;
200         static bool bWine = false;
201         if (!hNtDll) {
202             hNtDll = LoadLibraryA("ntdll");
203             if (hNtDll) {
204                 bWine = GetProcAddress(hNtDll, "wine_get_version") != NULL;
205             }
206         }
207         if (bWine) {
208             return new AnsiFormatter;
209         }
210         return new WindowsFormatter;
211 #else
212         return new AnsiFormatter;
213 #endif
214     } else {
215         return new Formatter;
216     }
217 }
218
219
220 } /* namespace formatter */
221
222
223 #endif /* _FORMATTER_HPP_ */