1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "cache.h" 2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "color.h" 3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_use_color_default = -1; 5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int parse_color(const char *name, int len) 7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng static const char * const color_names[] = { 9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "normal", "black", "red", "green", "yellow", 10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "blue", "magenta", "cyan", "white" 11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng }; 12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *end; 13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < (int)ARRAY_SIZE(color_names); i++) { 16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *str = color_names[i]; 17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strncasecmp(name, str, len) && !str[len]) 18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return i - 1; 19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng i = strtol(name, &end, 10); 21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (end - name == len && i >= -1 && i <= 255) 22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return i; 23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -2; 24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int parse_attr(const char *name, int len) 27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng static const int attr_values[] = { 1, 2, 4, 5, 7 }; 29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng static const char * const attr_names[] = { 30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "bold", "dim", "ul", "blink", "reverse" 31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng }; 32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int i; 33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < ARRAY_SIZE(attr_names); i++) { 35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *str = attr_names[i]; 36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strncasecmp(name, str, len) && !str[len]) 37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return attr_values[i]; 38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid color_parse(const char *value, const char *var, char *dst) 43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng color_parse_mem(value, strlen(value), var, dst); 45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid color_parse_mem(const char *value, int value_len, const char *var, 48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *dst) 49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *ptr = value; 51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int len = value_len; 52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int attr = -1; 53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fg = -2; 54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int bg = -2; 55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strncasecmp(value, "reset", len)) { 57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng strcpy(dst, PERF_COLOR_RESET); 58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* [fg [bg]] [attr] */ 62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (len > 0) { 63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *word = ptr; 64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int val, wordlen = 0; 65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (len > 0 && !isspace(word[wordlen])) { 67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng wordlen++; 68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng len--; 69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ptr = word + wordlen; 72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (len > 0 && isspace(*ptr)) { 73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ptr++; 74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng len--; 75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng val = parse_color(word, wordlen); 78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (val >= -1) { 79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (fg == -2) { 80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fg = val; 81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng continue; 82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (bg == -2) { 84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng bg = val; 85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng continue; 86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto bad; 88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng val = parse_attr(word, wordlen); 90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (val < 0 || attr != -1) 91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto bad; 92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng attr = val; 93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (attr >= 0 || fg >= 0 || bg >= 0) { 96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int sep = 0; 97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '\033'; 99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '['; 100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (attr >= 0) { 101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '0' + attr; 102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sep++; 103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (fg >= 0) { 105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (sep++) 106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = ';'; 107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (fg < 8) { 108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '3'; 109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '0' + fg; 110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng dst += sprintf(dst, "38;5;%d", fg); 112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (bg >= 0) { 115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (sep++) 116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = ';'; 117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (bg < 8) { 118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '4'; 119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = '0' + bg; 120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng dst += sprintf(dst, "48;5;%d", bg); 122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst++ = 'm'; 125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng *dst = 0; 127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return; 128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengbad: 129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng die("bad color value '%.*s' for variable '%s'", value_len, value, var); 130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_config_colorbool(const char *var, const char *value, int stdout_is_tty) 133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (value) { 135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcasecmp(value, "never")) 136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcasecmp(value, "always")) 138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcasecmp(value, "auto")) 140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto auto_color; 141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* Missing or explicit false to turn off colorization */ 144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!perf_config_bool(var, value)) 145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* any normal truth value defaults to 'auto' */ 148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng auto_color: 149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (stdout_is_tty < 0) 150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng stdout_is_tty = isatty(1); 151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (stdout_is_tty || (pager_in_use() && pager_use_color)) { 152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *term = getenv("TERM"); 153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (term && strcmp(term, "dumb")) 154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 1; 155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_color_default_config(const char *var, const char *value, void *cb) 160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!strcmp(var, "color.ui")) { 162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_use_color_default = perf_config_colorbool(var, value, -1); 163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return perf_default_config(var, value, cb); 167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int __color_vsnprintf(char *bf, size_t size, const char *color, 170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *fmt, va_list args, const char *trail) 171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r = 0; 173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Auto-detect: 176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default < 0) { 178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (isatty(1) || pager_in_use()) 179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_use_color_default = 1; 180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_use_color_default = 0; 182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default && *color) 185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += snprintf(bf, size, "%s", color); 186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += vsnprintf(bf + r, size - r, fmt, args); 187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default && *color) 188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET); 189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trail) 190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += snprintf(bf + r, size - r, "%s", trail); 191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int __color_vfprintf(FILE *fp, const char *color, const char *fmt, 195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_list args, const char *trail) 196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r = 0; 198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Auto-detect: 201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default < 0) { 203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (isatty(1) || pager_in_use()) 204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_use_color_default = 1; 205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_use_color_default = 0; 207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default && *color) 210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += fprintf(fp, "%s", color); 211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += vfprintf(fp, fmt, args); 212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (perf_use_color_default && *color) 213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += fprintf(fp, "%s", PERF_COLOR_RESET); 214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (trail) 215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r += fprintf(fp, "%s", trail); 216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_vsnprintf(char *bf, size_t size, const char *color, 220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *fmt, va_list args) 221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return __color_vsnprintf(bf, size, color, fmt, args, NULL); 223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args) 226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return __color_vfprintf(fp, color, fmt, args, NULL); 228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_snprintf(char *bf, size_t size, const char *color, 231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *fmt, ...) 232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_list args; 234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r; 235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_start(args, fmt); 237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r = color_vsnprintf(bf, size, color, fmt, args); 238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_end(args); 239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_fprintf(FILE *fp, const char *color, const char *fmt, ...) 243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_list args; 245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r; 246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_start(args, fmt); 248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r = color_vfprintf(fp, color, fmt, args); 249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_end(args); 250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...) 254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_list args; 256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r; 257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_start(args, fmt); 258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r = __color_vfprintf(fp, color, fmt, args, "\n"); 259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_end(args); 260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* 264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * This function splits the buffer by newlines and colors the lines individually. 265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Returns 0 on success. 267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint color_fwrite_lines(FILE *fp, const char *color, 269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size_t count, const char *buf) 270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!*color) 272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return fwrite(buf, count, 1, fp) != 1; 273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (count) { 275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *p = memchr(buf, '\n', count); 276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (p != buf && (fputs(color, fp) < 0 || 278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 || 279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fputs(PERF_COLOR_RESET, fp) < 0)) 280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!p) 282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (fputc('\n', fp) < 0) 284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng count -= p + 1 - buf; 286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng buf = p + 1; 287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengconst char *get_percent_color(double percent) 292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *color = PERF_COLOR_NORMAL; 294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * We color high-overhead entries in red, mid-overhead 297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * entries in green - and keep the low overhead places 298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * normal: 299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (percent >= MIN_RED) 301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng color = PERF_COLOR_RED; 302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else { 303e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (percent > MIN_GREEN) 304e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng color = PERF_COLOR_GREEN; 305e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 306e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return color; 307e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 308e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 309e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint percent_color_fprintf(FILE *fp, const char *fmt, double percent) 310e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 311e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int r; 312e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *color; 313e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 314e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng color = get_percent_color(percent); 315e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng r = color_fprintf(fp, color, fmt, percent); 316e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 317e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return r; 318e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 319e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 320e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent) 321e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 322e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const char *color = get_percent_color(percent); 323e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return color_snprintf(bf, size, color, fmt, percent); 324e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 325