Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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      * Auto-detect:
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 /* Colors are not included in return value */
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      * Auto-detect:
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  * This function splits the buffer by newlines and colors the lines individually.
0098  *
0099  * Returns 0 on success.
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      * We color high-overhead entries in red, mid-overhead
0130      * entries in green - and keep the low overhead places
0131      * normal:
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 }