1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
25 **************************************************************************/
27 // File: vogl_colorized_console.cpp
28 #include "vogl_core.h"
29 #include "vogl_colorized_console.h"
30 #ifdef VOGL_USE_WIN32_API
31 #include "vogl_winhdr.h"
36 static vogl_exception_callback_t g_pPrev_exception_callback;
38 void colorized_console::atexit_func()
43 void colorized_console::exception_callback()
47 if (g_pPrev_exception_callback)
48 (*g_pPrev_exception_callback)();
51 void colorized_console::init()
54 console::add_console_output_func(console_output_func, NULL);
59 void colorized_console::set_exception_callback()
61 g_pPrev_exception_callback = vogl_set_exception_callback(exception_callback);
64 void colorized_console::deinit()
66 console::remove_console_output_func(console_output_func);
70 void colorized_console::tick()
74 #ifdef VOGL_USE_WIN32_API
75 void colorized_console::set_default_color()
77 DWORD attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
78 SetConsoleTextAttribute(cons, (WORD)attr);
81 bool colorized_console::console_output_func(eConsoleMessageType type, const char *pMsg, void *pData)
85 if (console::get_output_disabled())
88 HANDLE cons = GetStdHandle(STD_OUTPUT_HANDLE);
90 DWORD attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
93 case cDebugConsoleMessage:
94 attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
96 case cMessageConsoleMessage:
97 attr = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
99 case cWarningConsoleMessage:
100 attr = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
102 case cErrorConsoleMessage:
103 attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
109 if (INVALID_HANDLE_VALUE != cons)
110 SetConsoleTextAttribute(cons, (WORD)attr);
114 if (INVALID_HANDLE_VALUE != cons)
115 SetConsoleTextAttribute(cons, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
119 #elif VOGL_USE_LINUX_API
120 #define ANSI_RESET "\033[0m"
121 #define ANSI_BLACK "\033[30m" /* Black */
122 #define ANSI_RED "\033[31m" /* Red */
123 #define ANSI_GREEN "\033[32m" /* Green */
124 #define ANSI_YELLOW "\033[33m" /* Yellow */
125 #define ANSI_BLUE "\033[34m" /* Blue */
126 #define ANSI_MAGENTA "\033[35m" /* Magenta */
127 #define ANSI_CYAN "\033[36m" /* Cyan */
128 #define ANSI_WHITE "\033[37m" /* White */
129 #define ANSI_BOLDBLACK "\033[1m\033[30m" /* Bold Black */
130 #define ANSI_BOLDRED "\033[1m\033[31m" /* Bold Red */
131 #define ANSI_BOLDGREEN "\033[1m\033[32m" /* Bold Green */
132 #define ANSI_BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
133 #define ANSI_BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
134 #define ANSI_BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
135 #define ANSI_BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
136 #define ANSI_BOLDWHITE "\033[1m\033[37m" /* Bold White */
138 void colorized_console::set_default_color()
140 if (isatty(fileno(stdout)))
142 fputs(ANSI_RESET, stdout);
145 if (isatty(fileno(stderr)))
147 fputs(ANSI_RESET, stderr);
151 bool colorized_console::console_output_func(eConsoleMessageType type, const char *pMsg, void *pData)
155 static bool g_colors_inited = false;
156 static dynamic_string g_colors[cCMTTotal];
158 if (console::get_output_disabled())
161 if (!g_colors_inited)
163 g_colors_inited = true;
165 g_colors[cDebugConsoleMessage] = ANSI_BOLDBLUE; // debugging messages
166 g_colors[cProgressConsoleMessage] = ""; // progress messages
167 g_colors[cInfoConsoleMessage] = ""; // ordinary messages
168 g_colors[cConsoleConsoleMessage] = ""; // user console output
169 g_colors[cMessageConsoleMessage] = ANSI_BOLDCYAN; // high importance messages
170 g_colors[cWarningConsoleMessage] = ANSI_BOLDYELLOW; // warnings
171 g_colors[cErrorConsoleMessage] = ANSI_BOLDRED; // errors
172 g_colors[cHeader1ConsoleMessage] = "\033[44m\033[1m"; // header (dark blue background)
174 // Use just like LS_COLORS. Example: VOGL_COLORS='warning=1;34:message=31'
175 // Tokens are debug, progress, info, default, message, warning, error.
176 const char *vogl_colors = getenv("VOGL_COLORS");
179 dynamic_string_array tokens;
180 dynamic_string colors = (vogl_colors[0] == '\'') ? (vogl_colors + 1) : vogl_colors;
182 colors.tokenize(":", tokens, true);
183 for (uint i = 0; i < tokens.size(); i++)
185 dynamic_string &str = tokens[i];
186 dynamic_string_array color_tokens;
188 str.tokenize("=;", color_tokens, true);
189 if (color_tokens.size() >= 2)
191 eConsoleMessageType color_type = console::get_message_type_from_str(color_tokens[0].c_str());
194 for (uint j = 1; j < color_tokens.size(); j++)
197 g_colors[color_type].format("\033[%sm", color_tokens[j].c_str());
199 g_colors[color_type].format_append("\033[%sm", color_tokens[j].c_str());
207 const char *pANSIColor = g_colors[type].c_str();
208 FILE *pFile = (type == cErrorConsoleMessage) ? stderr : stdout;
209 bool is_redirected = !isatty(fileno(pFile)) && pANSIColor[0];
212 fputs(pANSIColor, pFile);
217 fputs(ANSI_RESET, pFile);
223 void colorized_console::set_default_color()
227 bool colorized_console::console_output_func(eConsoleMessageType type, const char *pMsg, void *pData)
230 if (console::get_output_disabled())
233 FILE *pFile = (type == cErrorConsoleMessage) ? stderr : stdout;