iutest  1.17.1.0
iutest_console.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
16 #define INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
17 
18 //======================================================================
19 // include
20 #include <stdio.h>
21 #include <stdarg.h>
22 
23 namespace iutest {
24 namespace detail
25 {
26 
27 //======================================================================
28 // define
29 #ifndef IUTEST_VPRINTF
30 # define IUTEST_VPRINTF(f, a) vprintf(f, a)
31 #endif
32 
33 #ifndef IUTEST_HAS_COLORCONSOLE
34 # if defined(IUTEST_OS_WINDOWS_MOBILE) || defined(IUTEST_OS_NACL)
35 # define IUTEST_HAS_COLORCONSOLE 0
36 # else
37 # define IUTEST_HAS_COLORCONSOLE 1
38 # endif
39 #endif
40 
41 //======================================================================
42 // class
47 class iuLogger
48 {
49 public:
50  virtual ~iuLogger() IUTEST_CXX_DEFAULT_FUNCTION
51  virtual void output(const char* fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 3)
52  {
53  va_list va;
54  va_start(va, fmt);
55  voutput(fmt, va);
56  va_end(va);
57  }
58  virtual void voutput(const char* fmt, va_list va) = 0;
59 };
60 
65 class iuConsole
66 {
67 public:
69  enum Color
70  {
71  black,
72  red,
73  green,
74  yellow,
75  blue,
76  magenta,
77  cyan,
78  white
79  };
80 public:
84  static inline void output(const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 2);
85 
89  static inline void voutput(const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 0);
90 
95  static inline void color_output(Color color, const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 3);
96 
97 public:
102  static inline void nl_output(const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 2);
103 
108  static inline void nl_voutput(const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 0);
109 
110 public:
112  static iuLogger* SetLogger(iuLogger* logger)
113  {
114  iuLogger* pre = GetLoggerInstanceVariable().pInstance;
115  GetLoggerInstanceVariable().pInstance = logger;
116  return pre;
117  }
118 
119 public:
124  static bool IsColorModeOff()
125  {
126 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
128 #else
129  return IUTEST_FLAG(color) == "no";
130 #endif
131  }
136  static bool IsColorModeOn()
137  {
138 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
140 #else
141  return IUTEST_FLAG(color) == "yes";
142 #endif
143  }
148  static bool IsColorModeAnsi()
149  {
150 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
152 #else
153  return false;
154 #endif
155  }
156 
157 private:
158  static inline void color_output_impl(Color color, const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 0);
159  static inline bool IsShouldUseColor(bool use_color);
160  static inline bool HasColorConsole();
161  static inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }
162 
163 private:
164  struct LoggerInstanceVariable
165  {
166  iuLogger* pInstance;
167  };
168 
169  static LoggerInstanceVariable& GetLoggerInstanceVariable() { static LoggerInstanceVariable sLogger; return sLogger; }
170  static iuLogger* GetLogger() { return GetLoggerInstanceVariable().pInstance; }
171 };
172 
173 inline void iuConsole::output(const char *fmt, ...)
174 {
175  va_list va;
176  va_start(va, fmt);
177  voutput(fmt, va);
178  va_end(va);
179 }
180 inline void iuConsole::voutput(const char* fmt, va_list va)
181 {
182  iuLogger* pLogger = GetLogger();
183  if(pLogger != NULL)
184  {
185  pLogger->voutput(fmt, va);
186  }
187  else
188  {
189  nl_voutput(fmt, va);
190  }
191 }
192 inline void iuConsole::color_output(Color color, const char *fmt, ...)
193 {
194  va_list va;
195  va_start(va, fmt);
196 
197  if( IsShouldUseColor(true) )
198  {
199  color_output_impl(color, fmt, va);
200  }
201  else
202  {
203  voutput(fmt, va);
204  }
205 
206  va_end(va);
207 }
208 inline void iuConsole::nl_output(const char *fmt, ...)
209 {
210  va_list va;
211  va_start(va, fmt);
212  nl_voutput(fmt, va);
213  va_end(va);
214 }
215 inline void iuConsole::nl_voutput(const char* fmt, va_list va)
216 {
217  IUTEST_VPRINTF(fmt, va);
218 }
219 
220 inline void iuConsole::color_output_impl(Color color, const char* fmt, va_list va)
221 {
222  (void)(fmt);
223  (void)(va);
224 #if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) \
225  && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
226  if( !IsColorModeAnsi() )
227  {
228  const WORD attr[] = {
229  0,
230  FOREGROUND_RED,
231  FOREGROUND_GREEN,
232  FOREGROUND_GREEN | FOREGROUND_RED,
233  FOREGROUND_BLUE,
234  FOREGROUND_RED | FOREGROUND_BLUE,
235  FOREGROUND_GREEN | FOREGROUND_BLUE,
236  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
237  };
238  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
239  if( stdout_handle != INVALID_HANDLE_VALUE )
240  {
241  CONSOLE_SCREEN_BUFFER_INFO csbi;
242  if( ::GetConsoleScreenBufferInfo(stdout_handle, &csbi) )
243  {
244  const WORD wAttributes = csbi.wAttributes;
245 
246  fflush(stdout);
247  ::SetConsoleTextAttribute(stdout_handle, attr[color] | FOREGROUND_INTENSITY);
248 
249  voutput(fmt, va);
250 
251  fflush(stdout);
252  ::SetConsoleTextAttribute(stdout_handle, wAttributes);
253  return;
254  }
255  }
256  }
257 #endif
258  {
259  output("\033[1;3%cm", '0' + color);
260  voutput(fmt, va);
261  output("\033[m");
262  }
263 }
264 
265 inline bool iuConsole::IsShouldUseColor(bool use_color)
266 {
267  if( IsColorModeOn() )
268  {
269  return true;
270  }
271  else if( IsColorModeOff() )
272  {
273  return false;
274  }
275  static bool has_color = HasColorConsole();
276  return use_color && has_color;
277 }
278 
279 inline bool iuConsole::HasColorConsole()
280 {
281 #if !IUTEST_HAS_COLORCONSOLE
282  return false;
283 #else
284 #if defined(IUTEST_OS_WINDOWS)
285  {
286  CONSOLE_SCREEN_BUFFER_INFO csbi;
287  if( ::GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) )
288  {
289  return true;
290  }
291  }
292 #endif
293  const char* env = internal::posix::GetEnv("TERM");
294  const bool term_conf = (env != NULL) && (
295  IsStringEqual(env, "xterm")
296  || IsStringEqual(env, "xterm-color")
297  || IsStringEqual(env, "xterm-256color")
298  || IsStringEqual(env, "screen")
299  || IsStringEqual(env, "screen-256color")
300  || IsStringEqual(env, "tmux")
301  || IsStringEqual(env, "tmux-256color")
302  || IsStringEqual(env, "rxvt-unicode")
303  || IsStringEqual(env, "rxvt-unicode-256color")
304  || IsStringEqual(env, "linux")
305  || IsStringEqual(env, "cygwin")
306  );
307  return term_conf;
308 #endif
309 }
310 
311 } // end of namespace detail
312 } // end of namespace iutest
313 
314 #endif // INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
IUTEST_CXX_DEFAULT_FUNCTION
#define IUTEST_CXX_DEFAULT_FUNCTION
default function
Definition: iutest_compiler.hpp:420
iutest::TestFlag::CONSOLE_COLOR_OFF
@ CONSOLE_COLOR_OFF
色つき出力OFF
Definition: iutest_env.hpp:152
iutest_config.hpp
iris unit test config
iutest::TestFlag::CONSOLE_COLOR_ANSI
@ CONSOLE_COLOR_ANSI
エスケープシーケンスで出力
Definition: iutest_env.hpp:153
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
IUTEST_FLAG
#define IUTEST_FLAG(name)
フラグセット
Definition: iutest_env.hpp:55
IUTEST_VPRINTF
#define IUTEST_VPRINTF(f, a)
vprintf 呼び出しマクロ
Definition: iutest_console.hpp:31
iutest::TestFlag::CONSOLE_COLOR_ON
@ CONSOLE_COLOR_ON
色つき出力ON
Definition: iutest_env.hpp:151
iutest::TestFlag::IsEnableFlag
static bool IsEnableFlag(int flag)
フラグが立っているかどうか
Definition: iutest_env.hpp:208