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 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 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