linux/tools/perf/util/color.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include "cache.h"
   3#include "config.h"
   4#include <stdlib.h>
   5#include <stdio.h>
   6#include "color.h"
   7#include <math.h>
   8#include <unistd.h>
   9
  10int perf_use_color_default = -1;
  11
  12int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty)
  13{
  14        if (value) {
  15                if (!strcasecmp(value, "never"))
  16                        return 0;
  17                if (!strcasecmp(value, "always"))
  18                        return 1;
  19                if (!strcasecmp(value, "auto"))
  20                        goto auto_color;
  21        }
  22
  23        /* Missing or explicit false to turn off colorization */
  24        if (!perf_config_bool(var, value))
  25                return 0;
  26
  27        /* any normal truth value defaults to 'auto' */
  28 auto_color:
  29        if (stdout_is_tty < 0)
  30                stdout_is_tty = isatty(1);
  31        if (stdout_is_tty || pager_in_use()) {
  32                char *term = getenv("TERM");
  33                if (term && strcmp(term, "dumb"))
  34                        return 1;
  35        }
  36        return 0;
  37}
  38
  39int perf_color_default_config(const char *var, const char *value,
  40                              void *cb __maybe_unused)
  41{
  42        if (!strcmp(var, "color.ui")) {
  43                perf_use_color_default = perf_config_colorbool(var, value, -1);
  44                return 0;
  45        }
  46
  47        return 0;
  48}
  49
  50static int __color_vsnprintf(char *bf, size_t size, const char *color,
  51                             const char *fmt, va_list args, const char *trail)
  52{
  53        int r = 0;
  54
  55        /*
  56         * Auto-detect:
  57         */
  58        if (perf_use_color_default < 0) {
  59                if (isatty(1) || pager_in_use())
  60                        perf_use_color_default = 1;
  61                else
  62                        perf_use_color_default = 0;
  63        }
  64
  65        if (perf_use_color_default && *color)
  66                r += scnprintf(bf, size, "%s", color);
  67        r += vscnprintf(bf + r, size - r, fmt, args);
  68        if (perf_use_color_default && *color)
  69                r += scnprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
  70        if (trail)
  71                r += scnprintf(bf + r, size - r, "%s", trail);
  72        return r;
  73}
  74
  75/* Colors are not included in return value */
  76static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
  77                va_list args)
  78{
  79        int r = 0;
  80
  81        /*
  82         * Auto-detect:
  83         */
  84        if (perf_use_color_default < 0) {
  85                if (isatty(fileno(fp)) || pager_in_use())
  86                        perf_use_color_default = 1;
  87                else
  88                        perf_use_color_default = 0;
  89        }
  90
  91        if (perf_use_color_default && *color)
  92                fprintf(fp, "%s", color);
  93        r += vfprintf(fp, fmt, args);
  94        if (perf_use_color_default && *color)
  95                fprintf(fp, "%s", PERF_COLOR_RESET);
  96        return r;
  97}
  98
  99int color_vsnprintf(char *bf, size_t size, const char *color,
 100                    const char *fmt, va_list args)
 101{
 102        return __color_vsnprintf(bf, size, color, fmt, args, NULL);
 103}
 104
 105int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
 106{
 107        return __color_vfprintf(fp, color, fmt, args);
 108}
 109
 110int color_snprintf(char *bf, size_t size, const char *color,
 111                   const char *fmt, ...)
 112{
 113        va_list args;
 114        int r;
 115
 116        va_start(args, fmt);
 117        r = color_vsnprintf(bf, size, color, fmt, args);
 118        va_end(args);
 119        return r;
 120}
 121
 122int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
 123{
 124        va_list args;
 125        int r;
 126
 127        va_start(args, fmt);
 128        r = color_vfprintf(fp, color, fmt, args);
 129        va_end(args);
 130        return r;
 131}
 132
 133/*
 134 * This function splits the buffer by newlines and colors the lines individually.
 135 *
 136 * Returns 0 on success.
 137 */
 138int color_fwrite_lines(FILE *fp, const char *color,
 139                size_t count, const char *buf)
 140{
 141        if (!*color)
 142                return fwrite(buf, count, 1, fp) != 1;
 143
 144        while (count) {
 145                char *p = memchr(buf, '\n', count);
 146
 147                if (p != buf && (fputs(color, fp) < 0 ||
 148                                fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 ||
 149                                fputs(PERF_COLOR_RESET, fp) < 0))
 150                        return -1;
 151                if (!p)
 152                        return 0;
 153                if (fputc('\n', fp) < 0)
 154                        return -1;
 155                count -= p + 1 - buf;
 156                buf = p + 1;
 157        }
 158        return 0;
 159}
 160
 161const char *get_percent_color(double percent)
 162{
 163        const char *color = PERF_COLOR_NORMAL;
 164
 165        /*
 166         * We color high-overhead entries in red, mid-overhead
 167         * entries in green - and keep the low overhead places
 168         * normal:
 169         */
 170        if (fabs(percent) >= MIN_RED)
 171                color = PERF_COLOR_RED;
 172        else {
 173                if (fabs(percent) > MIN_GREEN)
 174                        color = PERF_COLOR_GREEN;
 175        }
 176        return color;
 177}
 178
 179int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
 180{
 181        int r;
 182        const char *color;
 183
 184        color = get_percent_color(percent);
 185        r = color_fprintf(fp, color, fmt, percent);
 186
 187        return r;
 188}
 189
 190int value_color_snprintf(char *bf, size_t size, const char *fmt, double value)
 191{
 192        const char *color = get_percent_color(value);
 193        return color_snprintf(bf, size, color, fmt, value);
 194}
 195
 196int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
 197{
 198        va_list args;
 199        double percent;
 200
 201        va_start(args, fmt);
 202        percent = va_arg(args, double);
 203        va_end(args);
 204        return value_color_snprintf(bf, size, fmt, percent);
 205}
 206
 207int percent_color_len_snprintf(char *bf, size_t size, const char *fmt, ...)
 208{
 209        va_list args;
 210        int len;
 211        double percent;
 212        const char *color;
 213
 214        va_start(args, fmt);
 215        len = va_arg(args, int);
 216        percent = va_arg(args, double);
 217        va_end(args);
 218
 219        color = get_percent_color(percent);
 220        return color_snprintf(bf, size, color, fmt, len, percent);
 221}
 222