iutest  1.17.99.14
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 #ifndef IUTEST_FORCE_COLORCONSOLE
42 # define IUTEST_FORCE_COLORCONSOLE 0
43 #endif
44 
45 //======================================================================
46 // class
51 class iuLogger
52 {
53 public:
54  virtual ~iuLogger() IUTEST_CXX_DEFAULT_FUNCTION
55  virtual void output(const char* fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 3)
56  {
57  va_list va;
58  va_start(va, fmt);
59  voutput(fmt, va);
60  va_end(va);
61  }
62  virtual void voutput(const char* fmt, va_list va) = 0;
63 };
64 
69 class iuConsole
70 {
71 public:
73  enum Color
74  {
75  black,
76  red,
77  green,
78  yellow,
79  blue,
80  magenta,
81  cyan,
82  white
83  };
84 public:
88  static inline void output(const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 2);
89 
93  static inline void voutput(const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 0);
94 
99  static inline void color_output(Color color, const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 3);
100 
101 public:
106  static inline void nl_output(const char *fmt, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 2);
107 
112  static inline void nl_voutput(const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 0);
113 
114 public:
116  static iuLogger* SetLogger(iuLogger* logger)
117  {
118  iuLogger* pre = GetLoggerInstanceVariable().pInstance;
119  GetLoggerInstanceVariable().pInstance = logger;
120  return pre;
121  }
122 
123 public:
128  static bool IsColorModeOff()
129  {
130 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
132 #else
133  return IUTEST_FLAG(color) == "no";
134 #endif
135  }
140  static bool IsColorModeOn()
141  {
142 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
144 #else
145  return IUTEST_FLAG(color) == "yes";
146 #endif
147  }
152  static bool IsColorModeAnsi()
153  {
154 #if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
156 #else
157  return false;
158 #endif
159  }
160 
161 private:
162  static inline void color_output_impl(Color color, const char* fmt, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(2, 0);
163  static inline bool IsShouldUseColor(bool use_color);
164  static inline bool HasColorConsole();
165 #if IUTEST_HAS_COLORCONSOLE && !IUTEST_FORCE_COLORCONSOLE
166  static inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }
167 #endif
168 
169 private:
170  struct LoggerInstanceVariable
171  {
172  iuLogger* pInstance;
173  };
174 
175  static LoggerInstanceVariable& GetLoggerInstanceVariable() { static LoggerInstanceVariable sLogger; return sLogger; }
176  static iuLogger* GetLogger() { return GetLoggerInstanceVariable().pInstance; }
177 };
178 
179 inline void iuConsole::output(const char *fmt, ...)
180 {
181  va_list va;
182  va_start(va, fmt);
183  voutput(fmt, va);
184  va_end(va);
185 }
186 inline void iuConsole::voutput(const char* fmt, va_list va)
187 {
188  iuLogger* pLogger = GetLogger();
189  if(pLogger != NULL)
190  {
191  pLogger->voutput(fmt, va);
192  }
193  else
194  {
195  nl_voutput(fmt, va);
196  }
197 }
198 inline void iuConsole::color_output(Color color, const char *fmt, ...)
199 {
200  va_list va;
201  va_start(va, fmt);
202 
203  if( IsShouldUseColor(true) )
204  {
205  color_output_impl(color, fmt, va);
206  }
207  else
208  {
209  voutput(fmt, va);
210  }
211 
212  va_end(va);
213 }
214 inline void iuConsole::nl_output(const char *fmt, ...)
215 {
216  va_list va;
217  va_start(va, fmt);
218  nl_voutput(fmt, va);
219  va_end(va);
220 }
221 inline void iuConsole::nl_voutput(const char* fmt, va_list va)
222 {
223  IUTEST_VPRINTF(fmt, va);
224 }
225 
226 inline void iuConsole::color_output_impl(Color color, const char* fmt, va_list va)
227 {
228  (void)(fmt);
229  (void)(va);
230 #if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) \
231  && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
232  if( !IsColorModeAnsi() )
233  {
234  const WORD attr[] = {
235  0,
236  FOREGROUND_RED,
237  FOREGROUND_GREEN,
238  FOREGROUND_GREEN | FOREGROUND_RED,
239  FOREGROUND_BLUE,
240  FOREGROUND_RED | FOREGROUND_BLUE,
241  FOREGROUND_GREEN | FOREGROUND_BLUE,
242  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
243  };
244  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
245  if( stdout_handle != INVALID_HANDLE_VALUE )
246  {
247  CONSOLE_SCREEN_BUFFER_INFO csbi;
248  if( ::GetConsoleScreenBufferInfo(stdout_handle, &csbi) )
249  {
250  const WORD wAttributes = csbi.wAttributes;
251 
252  fflush(stdout);
253  ::SetConsoleTextAttribute(stdout_handle, attr[color] | FOREGROUND_INTENSITY);
254 
255  voutput(fmt, va);
256 
257  fflush(stdout);
258  ::SetConsoleTextAttribute(stdout_handle, wAttributes);
259  return;
260  }
261  }
262  }
263 #endif
264  {
265  output("\033[1;3%cm", '0' + color);
266  voutput(fmt, va);
267  output("\033[m");
268  }
269 }
270 
271 inline bool iuConsole::IsShouldUseColor(bool use_color)
272 {
273  if( IsColorModeOn() )
274  {
275  return true;
276  }
277  else if( IsColorModeOff() )
278  {
279  return false;
280  }
281  static bool has_color = HasColorConsole();
282  return use_color && has_color;
283 }
284 
285 inline bool iuConsole::HasColorConsole()
286 {
287 #if !IUTEST_HAS_COLORCONSOLE
288  return false;
289 #elif IUTEST_FORCE_COLORCONSOLE
290  return true;
291 #else
292 #if defined(IUTEST_OS_WINDOWS)
293  {
294  CONSOLE_SCREEN_BUFFER_INFO csbi;
295  if( ::GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) )
296  {
297  return true;
298  }
299  }
300 #endif
301  const char* env = internal::posix::GetEnv("TERM");
302  const bool term_conf = (env != NULL) && (
303  IsStringEqual(env, "xterm")
304  || IsStringEqual(env, "xterm-color")
305  || IsStringEqual(env, "xterm-256color")
306  || IsStringEqual(env, "screen")
307  || IsStringEqual(env, "screen-256color")
308  || IsStringEqual(env, "tmux")
309  || IsStringEqual(env, "tmux-256color")
310  || IsStringEqual(env, "rxvt-unicode")
311  || IsStringEqual(env, "rxvt-unicode-256color")
312  || IsStringEqual(env, "linux")
313  || IsStringEqual(env, "cygwin")
314  );
315  if( term_conf )
316  {
317  return true;
318  }
319  // for CI
320  if( internal::posix::GetEnv("GITHUB_ACTIONS") != NULL )
321  {
322  return true;
323  }
324  return false;
325 #endif
326 }
327 
328 } // end of namespace detail
329 } // end of namespace iutest
330 
331 #endif // INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
@ CONSOLE_COLOR_ANSI
エスケープシーケンスで出力
Definition: iutest_env.hpp:155
@ CONSOLE_COLOR_OFF
色つき出力OFF
Definition: iutest_env.hpp:154
@ CONSOLE_COLOR_ON
色つき出力ON
Definition: iutest_env.hpp:153
static bool IsEnableFlag(int flag)
フラグが立っているかどうか
Definition: iutest_env.hpp:210
#define IUTEST_FLAG(name)
フラグセット
Definition: iutest_env.hpp:57
#define IUTEST_CXX_DEFAULT_FUNCTION
default function
Definition: iutest_compiler.hpp:494
#define IUTEST_VPRINTF(f, a)
vprintf 呼び出しマクロ
Definition: iutest_console.hpp:31
iutest root namespace
Definition: iutest_charcode.hpp:33