2012-03-14 19:29:29 +04:00
# include <linux/kernel.h>
2009-06-04 17:19:47 +04:00
# include "cache.h"
2016-06-23 11:55:17 +03:00
# include "config.h"
2016-07-07 21:42:33 +03:00
# include <stdlib.h>
# include <stdio.h>
2009-06-04 17:19:47 +04:00
# include "color.h"
2013-12-30 11:34:18 +04:00
# include <math.h>
2016-07-07 17:37:08 +03:00
# include <unistd.h>
2009-06-04 17:19:47 +04:00
2009-06-04 17:40:25 +04:00
int perf_use_color_default = - 1 ;
2009-06-04 17:19:47 +04:00
int perf_config_colorbool ( const char * var , const char * value , int stdout_is_tty )
{
if ( value ) {
if ( ! strcasecmp ( value , " never " ) )
return 0 ;
if ( ! strcasecmp ( value , " always " ) )
return 1 ;
if ( ! strcasecmp ( value , " auto " ) )
goto auto_color ;
}
/* Missing or explicit false to turn off colorization */
if ( ! perf_config_bool ( var , value ) )
return 0 ;
/* any normal truth value defaults to 'auto' */
auto_color :
if ( stdout_is_tty < 0 )
stdout_is_tty = isatty ( 1 ) ;
2015-12-08 07:21:43 +03:00
if ( stdout_is_tty | | pager_in_use ( ) ) {
2009-06-04 17:19:47 +04:00
char * term = getenv ( " TERM " ) ;
if ( term & & strcmp ( term , " dumb " ) )
return 1 ;
}
return 0 ;
}
2016-02-26 12:31:51 +03:00
int perf_color_default_config ( const char * var , const char * value ,
void * cb __maybe_unused )
2009-06-04 17:19:47 +04:00
{
if ( ! strcmp ( var , " color.ui " ) ) {
perf_use_color_default = perf_config_colorbool ( var , value , - 1 ) ;
return 0 ;
}
2016-02-26 12:31:51 +03:00
return 0 ;
2009-06-04 17:19:47 +04:00
}
2010-03-31 18:33:40 +04:00
static int __color_vsnprintf ( char * bf , size_t size , const char * color ,
const char * fmt , va_list args , const char * trail )
{
int r = 0 ;
/*
* Auto - detect :
*/
if ( perf_use_color_default < 0 ) {
if ( isatty ( 1 ) | | pager_in_use ( ) )
perf_use_color_default = 1 ;
else
perf_use_color_default = 0 ;
}
if ( perf_use_color_default & & * color )
2012-03-14 19:29:29 +04:00
r + = scnprintf ( bf , size , " %s " , color ) ;
r + = vscnprintf ( bf + r , size - r , fmt , args ) ;
2010-03-31 18:33:40 +04:00
if ( perf_use_color_default & & * color )
2012-03-14 19:29:29 +04:00
r + = scnprintf ( bf + r , size - r , " %s " , PERF_COLOR_RESET ) ;
2010-03-31 18:33:40 +04:00
if ( trail )
2012-03-14 19:29:29 +04:00
r + = scnprintf ( bf + r , size - r , " %s " , trail ) ;
2010-03-31 18:33:40 +04:00
return r ;
}
2015-08-04 03:50:02 +03:00
/* Colors are not included in return value */
2009-08-17 00:05:48 +04:00
static int __color_vfprintf ( FILE * fp , const char * color , const char * fmt ,
2015-08-04 03:50:01 +03:00
va_list args )
2009-06-04 17:19:47 +04:00
{
int r = 0 ;
2009-06-04 17:40:25 +04:00
/*
* Auto - detect :
*/
if ( perf_use_color_default < 0 ) {
2011-08-16 00:22:33 +04:00
if ( isatty ( fileno ( fp ) ) | | pager_in_use ( ) )
2009-06-04 17:40:25 +04:00
perf_use_color_default = 1 ;
else
perf_use_color_default = 0 ;
}
if ( perf_use_color_default & & * color )
2015-08-04 03:50:02 +03:00
fprintf ( fp , " %s " , color ) ;
2009-06-04 17:19:47 +04:00
r + = vfprintf ( fp , fmt , args ) ;
2009-06-04 17:40:25 +04:00
if ( perf_use_color_default & & * color )
2015-08-04 03:50:02 +03:00
fprintf ( fp , " %s " , PERF_COLOR_RESET ) ;
2009-06-04 17:19:47 +04:00
return r ;
}
2010-03-31 18:33:40 +04:00
int color_vsnprintf ( char * bf , size_t size , const char * color ,
const char * fmt , va_list args )
{
return __color_vsnprintf ( bf , size , color , fmt , args , NULL ) ;
}
2009-08-17 00:05:48 +04:00
int color_vfprintf ( FILE * fp , const char * color , const char * fmt , va_list args )
{
2015-08-04 03:50:01 +03:00
return __color_vfprintf ( fp , color , fmt , args ) ;
2009-08-17 00:05:48 +04:00
}
2009-06-04 17:19:47 +04:00
2010-03-31 18:33:40 +04:00
int color_snprintf ( char * bf , size_t size , const char * color ,
const char * fmt , . . . )
{
va_list args ;
int r ;
va_start ( args , fmt ) ;
r = color_vsnprintf ( bf , size , color , fmt , args ) ;
va_end ( args ) ;
return r ;
}
2009-06-04 17:19:47 +04:00
int color_fprintf ( FILE * fp , const char * color , const char * fmt , . . . )
{
va_list args ;
int r ;
2009-06-04 17:40:25 +04:00
2009-06-04 17:19:47 +04:00
va_start ( args , fmt ) ;
2010-03-31 18:33:40 +04:00
r = color_vfprintf ( fp , color , fmt , args ) ;
2009-06-04 17:19:47 +04:00
va_end ( args ) ;
return r ;
}
/*
* This function splits the buffer by newlines and colors the lines individually .
*
* Returns 0 on success .
*/
int color_fwrite_lines ( FILE * fp , const char * color ,
size_t count , const char * buf )
{
if ( ! * color )
return fwrite ( buf , count , 1 , fp ) ! = 1 ;
2009-07-01 14:37:06 +04:00
2009-06-04 17:19:47 +04:00
while ( count ) {
char * p = memchr ( buf , ' \n ' , count ) ;
2009-07-01 14:37:06 +04:00
2009-06-04 17:19:47 +04:00
if ( p ! = buf & & ( fputs ( color , fp ) < 0 | |
2009-07-01 14:37:06 +04:00
fwrite ( buf , p ? ( size_t ) ( p - buf ) : count , 1 , fp ) ! = 1 | |
2009-06-04 17:19:47 +04:00
fputs ( PERF_COLOR_RESET , fp ) < 0 ) )
return - 1 ;
if ( ! p )
return 0 ;
if ( fputc ( ' \n ' , fp ) < 0 )
return - 1 ;
count - = p + 1 - buf ;
buf = p + 1 ;
}
return 0 ;
}
2009-08-15 14:26:57 +04:00
const char * get_percent_color ( double percent )
2009-07-02 22:14:34 +04:00
{
2009-08-15 14:26:57 +04:00
const char * color = PERF_COLOR_NORMAL ;
2009-07-02 22:14:34 +04:00
/*
* We color high - overhead entries in red , mid - overhead
* entries in green - and keep the low overhead places
* normal :
*/
2013-12-30 11:34:18 +04:00
if ( fabs ( percent ) > = MIN_RED )
2009-07-02 22:14:34 +04:00
color = PERF_COLOR_RED ;
else {
2013-12-30 11:34:18 +04:00
if ( fabs ( percent ) > MIN_GREEN )
2009-07-02 22:14:34 +04:00
color = PERF_COLOR_GREEN ;
}
return color ;
}
2009-06-04 17:19:47 +04:00
2009-07-02 22:14:34 +04:00
int percent_color_fprintf ( FILE * fp , const char * fmt , double percent )
{
int r ;
2009-08-15 14:26:57 +04:00
const char * color ;
2009-07-02 22:14:34 +04:00
color = get_percent_color ( percent ) ;
r = color_fprintf ( fp , color , fmt , percent ) ;
return r ;
}
2010-03-31 18:33:40 +04:00
2013-12-30 11:34:20 +04:00
int value_color_snprintf ( char * bf , size_t size , const char * fmt , double value )
{
const char * color = get_percent_color ( value ) ;
return color_snprintf ( bf , size , color , fmt , value ) ;
}
2013-11-01 03:47:45 +04:00
int percent_color_snprintf ( char * bf , size_t size , const char * fmt , . . . )
2010-03-31 18:33:40 +04:00
{
2013-11-01 03:47:45 +04:00
va_list args ;
double percent ;
va_start ( args , fmt ) ;
percent = va_arg ( args , double ) ;
va_end ( args ) ;
2013-12-30 11:34:20 +04:00
return value_color_snprintf ( bf , size , fmt , percent ) ;
2010-03-31 18:33:40 +04:00
}
2014-07-31 09:47:36 +04:00
int percent_color_len_snprintf ( char * bf , size_t size , const char * fmt , . . . )
{
va_list args ;
int len ;
double percent ;
const char * color ;
va_start ( args , fmt ) ;
len = va_arg ( args , int ) ;
percent = va_arg ( args , double ) ;
va_end ( args ) ;
color = get_percent_color ( percent ) ;
return color_snprintf ( bf , size , color , fmt , len , percent ) ;
}