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 27DECLARE_bool(color_print); 28 29namespace benchmark { 30namespace { 31#ifdef BENCHMARK_OS_WINDOWS 32typedef WORD PlatformColorCode; 33#else 34typedef const char* PlatformColorCode; 35#endif 36 37PlatformColorCode 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 79void 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