Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:43

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 //  File        : $RCSfile$
0009 //
0010 //  Version     : $Revision$
0011 //
0012 //  Description : contains definition for setcolor iostream manipulator
0013 // ***************************************************************************
0014 
0015 #ifndef BOOST_TEST_UTILS_SETCOLOR_HPP
0016 #define BOOST_TEST_UTILS_SETCOLOR_HPP
0017 
0018 // Boost.Test
0019 #include <boost/test/detail/config.hpp>
0020 
0021 #include <boost/core/ignore_unused.hpp>
0022 #include <boost/core/snprintf.hpp>
0023 
0024 // STL
0025 #include <iostream>
0026 #include <cstdio>
0027 #include <cassert>
0028 
0029 #include <boost/test/detail/suppress_warnings.hpp>
0030 
0031 #ifdef _WIN32
0032   #include <windows.h>
0033 
0034   #if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE)
0035     // mingw badly mimicking windows.h
0036     #define COMMON_LVB_UNDERSCORE 0x8000
0037   #endif
0038 #endif
0039 
0040 //____________________________________________________________________________//
0041 
0042 namespace boost {
0043 namespace unit_test {
0044 namespace utils {
0045 
0046 // ************************************************************************** //
0047 // **************                    term_attr                 ************** //
0048 // ************************************************************************** //
0049 
0050 struct term_attr { enum _ {
0051     NORMAL    = 0,
0052     BRIGHT    = 1,
0053     DIM       = 2,
0054     UNDERLINE = 4,
0055     BLINK     = 5,
0056     REVERSE   = 7,
0057     CROSSOUT  = 9
0058 }; };
0059 
0060 // ************************************************************************** //
0061 // **************                   term_color                 ************** //
0062 // ************************************************************************** //
0063 
0064 struct term_color { enum _ {
0065     BLACK    = 0,
0066     RED      = 1,
0067     GREEN    = 2,
0068     YELLOW   = 3,
0069     BLUE     = 4,
0070     MAGENTA  = 5,
0071     CYAN     = 6,
0072     WHITE    = 7,
0073     ORIGINAL = 9
0074 }; };
0075 
0076 // ************************************************************************** //
0077 // **************                    setcolor                  ************** //
0078 // ************************************************************************** //
0079 
0080 #ifndef _WIN32
0081 class setcolor {
0082 public:
0083     typedef int state;
0084 
0085     // Constructor
0086     explicit    setcolor( bool is_color_output = false,
0087                           term_attr::_  attr = term_attr::NORMAL,
0088                           term_color::_ fg   = term_color::ORIGINAL,
0089                           term_color::_ bg   = term_color::ORIGINAL,
0090                           state* /* unused */= NULL)
0091     : m_is_color_output(is_color_output)
0092     {
0093         #ifdef BOOST_MSVC
0094         m_command_size = std::sprintf( m_control_command,
0095         #else
0096         m_command_size = boost::core::snprintf( m_control_command, sizeof(m_control_command), 
0097         #endif
0098           "%c[%c;3%c;4%cm",
0099           0x1B,
0100           static_cast<char>(attr + '0'),
0101           static_cast<char>(fg + '0'),
0102           static_cast<char>(bg + '0'));
0103     }
0104 
0105     explicit    setcolor(bool is_color_output,
0106                          state* /* unused */)
0107     : m_is_color_output(is_color_output)
0108     {
0109         #ifdef BOOST_MSVC
0110         m_command_size = std::sprintf( m_control_command, 
0111         #else
0112         m_command_size = boost::core::snprintf(m_control_command, sizeof(m_control_command), 
0113         #endif
0114           "%c[%c;3%c;4%cm",
0115           0x1B,
0116           static_cast<char>(term_attr::NORMAL + '0'),
0117           static_cast<char>(term_color::ORIGINAL + '0'),
0118           static_cast<char>(term_color::ORIGINAL + '0'));
0119     }
0120 
0121     friend std::ostream&
0122     operator<<( std::ostream& os, setcolor const& sc )
0123     {
0124        if (sc.m_is_color_output && (&os == &std::cout || &os == &std::cerr)) {
0125           return os.write( sc.m_control_command, sc.m_command_size );
0126        }
0127        return os;
0128     }
0129 
0130 private:
0131     // Data members
0132     bool        m_is_color_output;
0133     char        m_control_command[13];
0134     int         m_command_size;
0135 };
0136 
0137 #else
0138 
0139 class setcolor {
0140 
0141 protected:
0142   void set_console_color(std::ostream& os, WORD *attributes = NULL) const {
0143     if (!m_is_color_output || m_state_saved) {
0144       return;
0145     }
0146     DWORD console_type;
0147     if (&os == &std::cout) {
0148       console_type = STD_OUTPUT_HANDLE;
0149     }
0150     else if (&os == &std::cerr) {
0151       console_type =  STD_ERROR_HANDLE;
0152     }
0153     else {
0154       return;
0155     }
0156     HANDLE hConsole = GetStdHandle(console_type);
0157 
0158     if(hConsole == INVALID_HANDLE_VALUE || hConsole == NULL )
0159       return;
0160 
0161     state console_attributes;
0162     if(attributes != NULL || (m_restore_state && m_s)) {
0163       if (attributes != NULL) {
0164         console_attributes = *attributes;
0165       }
0166       else {
0167         console_attributes = *m_s;
0168         *m_s = state();
0169       }
0170       SetConsoleTextAttribute(hConsole, console_attributes);
0171       return;
0172     }
0173 
0174     CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
0175     GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
0176     console_attributes = consoleInfo.wAttributes;
0177 
0178     if (!m_state_saved && m_s) {
0179       assert(!m_restore_state);
0180       // we can save the state only the first time this object is used
0181       // for modifying the console.
0182       *m_s = console_attributes;
0183       m_state_saved = true;
0184     }
0185 
0186     WORD fg_attr = 0;
0187     switch(m_fg)
0188     {
0189     case term_color::WHITE:
0190       fg_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
0191       break;
0192     case term_color::BLACK:
0193       fg_attr = 0;
0194       break;
0195     case term_color::RED:
0196       fg_attr = FOREGROUND_RED;
0197       break;
0198     case term_color::GREEN:
0199       fg_attr = FOREGROUND_GREEN;
0200       break;
0201     case term_color::CYAN:
0202       fg_attr = FOREGROUND_GREEN | FOREGROUND_BLUE;
0203       break;
0204     case term_color::MAGENTA:
0205       fg_attr = FOREGROUND_RED | FOREGROUND_BLUE;
0206       break;
0207     case term_color::BLUE:
0208       fg_attr = FOREGROUND_BLUE;
0209       break;
0210     case term_color::YELLOW:
0211       fg_attr = FOREGROUND_RED | FOREGROUND_GREEN;
0212       break;
0213     case term_color::ORIGINAL:
0214     default:
0215       fg_attr = console_attributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
0216       break;
0217     }
0218 
0219     WORD bg_attr = 0;
0220     switch(m_bg)
0221     {
0222     case term_color::BLACK:
0223       bg_attr = 0;
0224       break;
0225     case term_color::WHITE:
0226       bg_attr = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
0227       break;
0228     case term_color::RED:
0229       bg_attr = BACKGROUND_RED;
0230       break;
0231     case term_color::GREEN:
0232       bg_attr = BACKGROUND_GREEN;
0233       break;
0234     case term_color::BLUE:
0235       bg_attr = BACKGROUND_BLUE;
0236       break;
0237     case term_color::ORIGINAL:
0238     default:
0239       bg_attr = console_attributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
0240       break;
0241     }
0242 
0243     WORD text_attr = 0;
0244     switch(m_attr)
0245     {
0246     case term_attr::BRIGHT:
0247       text_attr = FOREGROUND_INTENSITY;
0248       break;
0249     case term_attr::UNDERLINE:
0250       text_attr = COMMON_LVB_UNDERSCORE;
0251       break;
0252     default:
0253       break;
0254     }
0255 
0256     SetConsoleTextAttribute(hConsole, fg_attr | bg_attr | text_attr);
0257     return;
0258   }
0259 
0260 public:
0261   typedef WORD state;
0262 
0263   // Constructor
0264   explicit    setcolor( 
0265     bool is_color_output = false,
0266     term_attr::_  attr = term_attr::NORMAL,
0267     term_color::_ fg   = term_color::ORIGINAL,
0268     term_color::_ bg   = term_color::ORIGINAL,
0269     state* s           = NULL)
0270   : m_is_color_output(is_color_output)
0271   , m_attr(attr)
0272   , m_fg(fg)
0273   , m_bg(bg)
0274   , m_s(s)
0275   , m_restore_state(false)
0276   , m_state_saved(false)
0277   {}
0278 
0279   explicit    setcolor(
0280     bool is_color_output,
0281     state* s)
0282   : m_is_color_output(is_color_output)
0283   , m_attr(term_attr::NORMAL)
0284   , m_fg(term_color::ORIGINAL)
0285   , m_bg(term_color::ORIGINAL)
0286   , m_s(s)
0287   , m_restore_state(true)
0288   , m_state_saved(false)
0289   {}
0290 
0291   friend std::ostream&
0292     operator<<( std::ostream& os, setcolor const& sc )
0293   {
0294     sc.set_console_color(os);
0295     return os;
0296   }
0297 
0298 private:
0299   bool m_is_color_output;
0300   term_attr::_ m_attr;
0301   term_color::_ m_fg;
0302   term_color::_ m_bg;
0303   state* m_s;
0304   // indicates that the instance has been initialized to restore a previously
0305   // stored state
0306   bool m_restore_state; 
0307   // indicates the first time we pull and set the console information.
0308   mutable bool m_state_saved;
0309 };
0310 
0311 #endif
0312 // ************************************************************************** //
0313 // **************                 scope_setcolor               ************** //
0314 // ************************************************************************** //
0315 
0316 struct scope_setcolor {
0317   scope_setcolor() 
0318   : m_os( 0 )
0319   , m_state()
0320   , m_is_color_output(false)
0321   {}
0322   
0323   explicit    scope_setcolor(
0324     bool is_color_output,
0325     std::ostream& os,
0326     term_attr::_  attr = term_attr::NORMAL,
0327     term_color::_ fg   = term_color::ORIGINAL,
0328     term_color::_ bg   = term_color::ORIGINAL )
0329   : m_os( &os )
0330   , m_is_color_output(is_color_output)
0331   {
0332     os << setcolor(is_color_output, attr, fg, bg, &m_state);
0333   }
0334 
0335   ~scope_setcolor()
0336   {
0337     if (m_os) {
0338       *m_os << setcolor(m_is_color_output, &m_state);
0339     }
0340   }
0341 private:
0342   scope_setcolor(const scope_setcolor& r);
0343   scope_setcolor& operator=(const scope_setcolor& r);
0344   // Data members
0345   std::ostream* m_os;
0346   setcolor::state m_state;
0347   bool m_is_color_output;
0348 };
0349 
0350 
0351 #define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color )               \
0352     utils::scope_setcolor const sc(is_color_output, os, utils::attr, utils::color); \
0353     boost::ignore_unused( sc )                                                      \
0354 /**/
0355 
0356 } // namespace utils
0357 } // namespace unit_test
0358 } // namespace boost
0359 
0360 #include <boost/test/detail/enable_warnings.hpp>
0361 
0362 #endif // BOOST_TEST_UTILS_SETCOLOR_HPP