0001
0002 #include <linux/kernel.h>
0003 #include <subcmd/pager.h>
0004 #include <stdlib.h>
0005 #include <stdio.h>
0006 #include <string.h>
0007 #include "color.h"
0008 #include <math.h>
0009 #include <unistd.h>
0010
0011 int perf_use_color_default = -1;
0012
0013 static int __color_vsnprintf(char *bf, size_t size, const char *color,
0014 const char *fmt, va_list args, const char *trail)
0015 {
0016 int r = 0;
0017
0018
0019
0020
0021 if (perf_use_color_default < 0) {
0022 if (isatty(1) || pager_in_use())
0023 perf_use_color_default = 1;
0024 else
0025 perf_use_color_default = 0;
0026 }
0027
0028 if (perf_use_color_default && *color)
0029 r += scnprintf(bf, size, "%s", color);
0030 r += vscnprintf(bf + r, size - r, fmt, args);
0031 if (perf_use_color_default && *color)
0032 r += scnprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
0033 if (trail)
0034 r += scnprintf(bf + r, size - r, "%s", trail);
0035 return r;
0036 }
0037
0038
0039 static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
0040 va_list args)
0041 {
0042 int r = 0;
0043
0044
0045
0046
0047 if (perf_use_color_default < 0) {
0048 if (isatty(fileno(fp)) || pager_in_use())
0049 perf_use_color_default = 1;
0050 else
0051 perf_use_color_default = 0;
0052 }
0053
0054 if (perf_use_color_default && *color)
0055 fprintf(fp, "%s", color);
0056 r += vfprintf(fp, fmt, args);
0057 if (perf_use_color_default && *color)
0058 fprintf(fp, "%s", PERF_COLOR_RESET);
0059 return r;
0060 }
0061
0062 int color_vsnprintf(char *bf, size_t size, const char *color,
0063 const char *fmt, va_list args)
0064 {
0065 return __color_vsnprintf(bf, size, color, fmt, args, NULL);
0066 }
0067
0068 int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
0069 {
0070 return __color_vfprintf(fp, color, fmt, args);
0071 }
0072
0073 int color_snprintf(char *bf, size_t size, const char *color,
0074 const char *fmt, ...)
0075 {
0076 va_list args;
0077 int r;
0078
0079 va_start(args, fmt);
0080 r = color_vsnprintf(bf, size, color, fmt, args);
0081 va_end(args);
0082 return r;
0083 }
0084
0085 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
0086 {
0087 va_list args;
0088 int r;
0089
0090 va_start(args, fmt);
0091 r = color_vfprintf(fp, color, fmt, args);
0092 va_end(args);
0093 return r;
0094 }
0095
0096
0097
0098
0099
0100
0101 int color_fwrite_lines(FILE *fp, const char *color,
0102 size_t count, const char *buf)
0103 {
0104 if (!*color)
0105 return fwrite(buf, count, 1, fp) != 1;
0106
0107 while (count) {
0108 char *p = memchr(buf, '\n', count);
0109
0110 if (p != buf && (fputs(color, fp) < 0 ||
0111 fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 ||
0112 fputs(PERF_COLOR_RESET, fp) < 0))
0113 return -1;
0114 if (!p)
0115 return 0;
0116 if (fputc('\n', fp) < 0)
0117 return -1;
0118 count -= p + 1 - buf;
0119 buf = p + 1;
0120 }
0121 return 0;
0122 }
0123
0124 const char *get_percent_color(double percent)
0125 {
0126 const char *color = PERF_COLOR_NORMAL;
0127
0128
0129
0130
0131
0132
0133 if (fabs(percent) >= MIN_RED)
0134 color = PERF_COLOR_RED;
0135 else {
0136 if (fabs(percent) > MIN_GREEN)
0137 color = PERF_COLOR_GREEN;
0138 }
0139 return color;
0140 }
0141
0142 int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
0143 {
0144 int r;
0145 const char *color;
0146
0147 color = get_percent_color(percent);
0148 r = color_fprintf(fp, color, fmt, percent);
0149
0150 return r;
0151 }
0152
0153 int value_color_snprintf(char *bf, size_t size, const char *fmt, double value)
0154 {
0155 const char *color = get_percent_color(value);
0156 return color_snprintf(bf, size, color, fmt, value);
0157 }
0158
0159 int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
0160 {
0161 va_list args;
0162 double percent;
0163
0164 va_start(args, fmt);
0165 percent = va_arg(args, double);
0166 va_end(args);
0167 return value_color_snprintf(bf, size, fmt, percent);
0168 }
0169
0170 int percent_color_len_snprintf(char *bf, size_t size, const char *fmt, ...)
0171 {
0172 va_list args;
0173 int len;
0174 double percent;
0175 const char *color;
0176
0177 va_start(args, fmt);
0178 len = va_arg(args, int);
0179 percent = va_arg(args, double);
0180 va_end(args);
0181
0182 color = get_percent_color(percent);
0183 return color_snprintf(bf, size, color, fmt, len, percent);
0184 }