1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "colorprint.h"
16
17 #include <cstdarg>
18 #include <cstdio>
19
20 #include "commandlineflags.h"
21 #include "internal_macros.h"
22
23 #ifdef BENCHMARK_OS_WINDOWS
24 #include <Windows.h>
25 #endif
26
27 DECLARE_bool(color_print);
28
29 namespace benchmark {
30 namespace {
31 #ifdef BENCHMARK_OS_WINDOWS
32 typedef WORD PlatformColorCode;
33 #else
34 typedef const char* PlatformColorCode;
35 #endif
36
GetPlatformColorCode(LogColor color)37 PlatformColorCode GetPlatformColorCode(LogColor color) {
38 #ifdef BENCHMARK_OS_WINDOWS
39 switch (color) {
40 case COLOR_RED:
41 return FOREGROUND_RED;
42 case COLOR_GREEN:
43 return FOREGROUND_GREEN;
44 case COLOR_YELLOW:
45 return FOREGROUND_RED | FOREGROUND_GREEN;
46 case COLOR_BLUE:
47 return FOREGROUND_BLUE;
48 case COLOR_MAGENTA:
49 return FOREGROUND_BLUE | FOREGROUND_RED;
50 case COLOR_CYAN:
51 return FOREGROUND_BLUE | FOREGROUND_GREEN;
52 case COLOR_WHITE: // fall through to default
53 default:
54 return 0;
55 }
56 #else
57 switch (color) {
58 case COLOR_RED:
59 return "1";
60 case COLOR_GREEN:
61 return "2";
62 case COLOR_YELLOW:
63 return "3";
64 case COLOR_BLUE:
65 return "4";
66 case COLOR_MAGENTA:
67 return "5";
68 case COLOR_CYAN:
69 return "6";
70 case COLOR_WHITE:
71 return "7";
72 default:
73 return nullptr;
74 };
75 #endif
76 }
77 } // end namespace
78
ColorPrintf(LogColor color,const char * fmt,...)79 void ColorPrintf(LogColor color, const char* fmt, ...) {
80 va_list args;
81 va_start(args, fmt);
82
83 if (!FLAGS_color_print) {
84 vprintf(fmt, args);
85 va_end(args);
86 return;
87 }
88
89 #ifdef BENCHMARK_OS_WINDOWS
90 const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
91
92 // Gets the current text color.
93 CONSOLE_SCREEN_BUFFER_INFO buffer_info;
94 GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
95 const WORD old_color_attrs = buffer_info.wAttributes;
96
97 // We need to flush the stream buffers into the console before each
98 // SetConsoleTextAttribute call lest it affect the text that is already
99 // printed but has not yet reached the console.
100 fflush(stdout);
101 SetConsoleTextAttribute(stdout_handle,
102 GetPlatformColorCode(color) | FOREGROUND_INTENSITY);
103 vprintf(fmt, args);
104
105 fflush(stdout);
106 // Restores the text color.
107 SetConsoleTextAttribute(stdout_handle, old_color_attrs);
108 #else
109 const char* color_code = GetPlatformColorCode(color);
110 if (color_code) fprintf(stdout, "\033[0;3%sm", color_code);
111 vprintf(fmt, args);
112 printf("\033[m"); // Resets the terminal to default.
113 #endif
114 va_end(args);
115 }
116 } // end namespace benchmark
117