1 // (C) Copyright Gennadiy Rozental 2001. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 // See http://www.boost.org/libs/test for the library home page. 7 // 8 // File : $RCSfile$ 9 // 10 // Version : $Revision$ 11 // 12 // Description : contains definition for setcolor iostream manipulator 13 // *************************************************************************** 14 15 #ifndef BOOST_TEST_UTILS_SETCOLOR_HPP 16 #define BOOST_TEST_UTILS_SETCOLOR_HPP 17 18 // Boost.Test 19 #include <boost/test/detail/config.hpp> 20 21 // STL 22 #include <iostream> 23 #include <cstdio> 24 25 #include <boost/test/detail/suppress_warnings.hpp> 26 27 #ifdef _WIN32 28 #include <windows.h> 29 30 #if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE) 31 // mingw badly mimicking windows.h 32 #define COMMON_LVB_UNDERSCORE 0x8000 33 #endif 34 #endif 35 36 //____________________________________________________________________________// 37 38 namespace boost { 39 namespace unit_test { 40 namespace utils { 41 42 // ************************************************************************** // 43 // ************** term_attr ************** // 44 // ************************************************************************** // 45 46 struct term_attr { enum _ { 47 NORMAL = 0, 48 BRIGHT = 1, 49 DIM = 2, 50 UNDERLINE = 4, 51 BLINK = 5, 52 REVERSE = 7, 53 CROSSOUT = 9 54 }; }; 55 56 // ************************************************************************** // 57 // ************** term_color ************** // 58 // ************************************************************************** // 59 60 struct term_color { enum _ { 61 BLACK = 0, 62 RED = 1, 63 GREEN = 2, 64 YELLOW = 3, 65 BLUE = 4, 66 MAGENTA = 5, 67 CYAN = 6, 68 WHITE = 7, 69 ORIGINAL = 9 70 }; }; 71 72 // ************************************************************************** // 73 // ************** setcolor ************** // 74 // ************************************************************************** // 75 76 #ifndef _WIN32 77 class setcolor { 78 public: 79 // Constructor setcolor(bool is_color_output=false,term_attr::_ attr=term_attr::NORMAL,term_color::_ fg=term_color::ORIGINAL,term_color::_ bg=term_color::ORIGINAL)80 explicit setcolor( bool is_color_output = false, 81 term_attr::_ attr = term_attr::NORMAL, 82 term_color::_ fg = term_color::ORIGINAL, 83 term_color::_ bg = term_color::ORIGINAL ) 84 : m_is_color_output(is_color_output) 85 { 86 m_command_size = std::sprintf( m_control_command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40 ); 87 } 88 89 friend std::ostream& operator <<(std::ostream & os,setcolor const & sc)90 operator<<( std::ostream& os, setcolor const& sc ) 91 { 92 if (sc.m_is_color_output && (&os == &std::cout || &os == &std::cerr)) { 93 return os.write( sc.m_control_command, sc.m_command_size ); 94 } 95 return os; 96 } 97 98 private: 99 // Data members 100 bool m_is_color_output; 101 char m_control_command[13]; 102 int m_command_size; 103 }; 104 105 #else 106 107 class setcolor { 108 109 protected: set_console_color(std::ostream & os,WORD * attributes=NULL) const110 void set_console_color(std::ostream& os, WORD *attributes = NULL) const { 111 if (!m_is_color_output) { 112 return; 113 } 114 DWORD console_type; 115 if (&os == &std::cout) { 116 console_type = STD_OUTPUT_HANDLE; 117 } 118 else if (&os == &std::cerr) { 119 console_type = STD_ERROR_HANDLE; 120 } 121 else { 122 return; 123 } 124 HANDLE hConsole = GetStdHandle(console_type); 125 126 if(hConsole == INVALID_HANDLE_VALUE || hConsole == NULL ) 127 return; 128 129 if(attributes != NULL) { 130 SetConsoleTextAttribute(hConsole, *attributes); 131 return; 132 } 133 134 CONSOLE_SCREEN_BUFFER_INFO consoleInfo; 135 GetConsoleScreenBufferInfo(hConsole, &consoleInfo); 136 saved_attributes = consoleInfo.wAttributes; 137 138 WORD fg_attr = 0; 139 switch(m_fg) 140 { 141 case term_color::WHITE: 142 fg_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 143 break; 144 case term_color::BLACK: 145 fg_attr = 0; 146 break; 147 case term_color::RED: 148 fg_attr = FOREGROUND_RED; 149 break; 150 case term_color::GREEN: 151 fg_attr = FOREGROUND_GREEN; 152 break; 153 case term_color::CYAN: 154 fg_attr = FOREGROUND_GREEN | FOREGROUND_BLUE; 155 break; 156 case term_color::MAGENTA: 157 fg_attr = FOREGROUND_RED | FOREGROUND_BLUE; 158 break; 159 case term_color::BLUE: 160 fg_attr = FOREGROUND_BLUE; 161 break; 162 case term_color::YELLOW: 163 fg_attr = FOREGROUND_RED | FOREGROUND_GREEN; 164 break; 165 case term_color::ORIGINAL: 166 default: 167 fg_attr = saved_attributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 168 break; 169 } 170 171 WORD bg_attr = 0; 172 switch(m_bg) 173 { 174 case term_color::BLACK: 175 bg_attr = 0; 176 break; 177 case term_color::WHITE: 178 bg_attr = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; 179 break; 180 case term_color::RED: 181 bg_attr = BACKGROUND_RED; 182 break; 183 case term_color::GREEN: 184 bg_attr = BACKGROUND_GREEN; 185 break; 186 case term_color::BLUE: 187 bg_attr = BACKGROUND_BLUE; 188 break; 189 case term_color::ORIGINAL: 190 default: 191 bg_attr = saved_attributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); 192 break; 193 } 194 195 WORD text_attr = 0; 196 switch(m_attr) 197 { 198 case term_attr::BRIGHT: 199 text_attr = FOREGROUND_INTENSITY; 200 break; 201 case term_attr::UNDERLINE: 202 text_attr = COMMON_LVB_UNDERSCORE; 203 break; 204 default: 205 break; 206 } 207 208 SetConsoleTextAttribute(hConsole, fg_attr | bg_attr | text_attr); 209 return; 210 } 211 212 public: 213 // Constructor setcolor(bool is_color_output=false,term_attr::_ attr=term_attr::NORMAL,term_color::_ fg=term_color::ORIGINAL,term_color::_ bg=term_color::ORIGINAL)214 explicit setcolor( 215 bool is_color_output = false, 216 term_attr::_ attr = term_attr::NORMAL, 217 term_color::_ fg = term_color::ORIGINAL, 218 term_color::_ bg = term_color::ORIGINAL ) 219 : m_is_color_output(is_color_output) 220 , m_attr(attr) 221 , m_fg(fg) 222 , m_bg(bg) 223 {} 224 225 friend std::ostream& operator <<(std::ostream & os,setcolor const & sc)226 operator<<( std::ostream& os, setcolor const& sc ) 227 { 228 sc.set_console_color(os); 229 return os; 230 } 231 232 private: 233 bool m_is_color_output; 234 term_attr::_ m_attr; 235 term_color::_ m_fg; 236 term_color::_ m_bg; 237 238 protected: 239 // Data members 240 mutable WORD saved_attributes; 241 }; 242 243 #endif 244 // ************************************************************************** // 245 // ************** scope_setcolor ************** // 246 // ************************************************************************** // 247 248 #ifndef _WIN32 249 250 struct scope_setcolor { scope_setcolorboost::unit_test::utils::scope_setcolor251 scope_setcolor() : m_os( 0 ) {} scope_setcolorboost::unit_test::utils::scope_setcolor252 explicit scope_setcolor( bool is_color_output, 253 std::ostream& os, 254 term_attr::_ attr = term_attr::NORMAL, 255 term_color::_ fg = term_color::ORIGINAL, 256 term_color::_ bg = term_color::ORIGINAL ) 257 : m_os( &os ) 258 , m_is_color_output( is_color_output ) 259 { 260 os << setcolor( is_color_output, attr, fg, bg ); 261 } ~scope_setcolorboost::unit_test::utils::scope_setcolor262 ~scope_setcolor() 263 { 264 if( m_os ) 265 *m_os << setcolor( m_is_color_output ); 266 } 267 private: 268 scope_setcolor(const scope_setcolor& r); 269 scope_setcolor& operator=(const scope_setcolor& r); 270 // Data members 271 std::ostream* m_os; 272 bool m_is_color_output; 273 }; 274 275 #else 276 277 struct scope_setcolor : setcolor { scope_setcolorboost::unit_test::utils::scope_setcolor278 scope_setcolor() : m_os( 0 ) {} scope_setcolorboost::unit_test::utils::scope_setcolor279 explicit scope_setcolor( 280 bool is_color_output, 281 std::ostream& os, 282 term_attr::_ attr = term_attr::NORMAL, 283 term_color::_ fg = term_color::ORIGINAL, 284 term_color::_ bg = term_color::ORIGINAL ) 285 : setcolor(is_color_output, attr, fg, bg) 286 , m_os( &os ) 287 { 288 os << *this; 289 } 290 ~scope_setcolorboost::unit_test::utils::scope_setcolor291 ~scope_setcolor() 292 { 293 if (m_os) { 294 set_console_color(*m_os, &this->saved_attributes); 295 } 296 } 297 private: 298 scope_setcolor(const scope_setcolor& r); 299 scope_setcolor& operator=(const scope_setcolor& r); 300 // Data members 301 std::ostream* m_os; 302 }; 303 304 305 #endif 306 307 #define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \ 308 utils::scope_setcolor const sc(is_color_output, os, utils::attr, utils::color); \ 309 ut_detail::ignore_unused_variable_warning( sc ) \ 310 /**/ 311 312 } // namespace utils 313 } // namespace unit_test 314 } // namespace boost 315 316 #include <boost/test/detail/enable_warnings.hpp> 317 318 #endif // BOOST_TEST_UTILS_SETCOLOR_HPP 319