From 889c7c942e23c77118ed5cdb610f53c13a5bfea8 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 17 Aug 2018 18:38:45 +0200 Subject: [PATCH] Make colored output configurable Allow for -color={never,auto,always} to have colored output disabled, enabled only if stdout is a terminal or enabled regardless of stdout state. Signed-off-by: Phil Sutter Reviewed-by: David Ahern Signed-off-by: Stephen Hemminger (cherry picked from commit ff1ab8edf827f55b86c6487c90b7454975d52236) Signed-off-by: Phil Sutter --- bridge/bridge.c | 3 +-- include/color.h | 9 +++++++++ ip/ip.c | 3 +-- lib/color.c | 33 ++++++++++++++++++++++++++++++++- man/man8/bridge.8 | 13 +++++++++++-- man/man8/ip.8 | 13 +++++++++++-- man/man8/tc.8 | 13 +++++++++++-- tc/tc.c | 3 +-- 8 files changed, 77 insertions(+), 13 deletions(-) diff --git a/bridge/bridge.c b/bridge/bridge.c index 451d684e0bcfd..263fa5397a623 100644 --- a/bridge/bridge.c +++ b/bridge/bridge.c @@ -173,8 +173,7 @@ main(int argc, char **argv) NEXT_ARG(); if (netns_switch(argv[1])) exit(-1); - } else if (matches(opt, "-color") == 0) { - ++color; + } else if (matches_color(opt, &color)) { } else if (matches(opt, "-compressvlans") == 0) { ++compress_vlans; } else if (matches(opt, "-force") == 0) { diff --git a/include/color.h b/include/color.h index 4f2c918db7e43..a22a00c2277e0 100644 --- a/include/color.h +++ b/include/color.h @@ -2,6 +2,8 @@ #ifndef __COLOR_H__ #define __COLOR_H__ 1 +#include + enum color_attr { COLOR_IFNAME, COLOR_MAC, @@ -12,8 +14,15 @@ enum color_attr { COLOR_NONE }; +enum color_opt { + COLOR_OPT_NEVER = 0, + COLOR_OPT_AUTO = 1, + COLOR_OPT_ALWAYS = 2 +}; + void enable_color(void); int check_enable_color(int color, int json); +bool matches_color(const char *arg, int *val); void set_color_palette(void); int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...); enum color_attr ifa_family_color(__u8 ifa_family); diff --git a/ip/ip.c b/ip/ip.c index 38eac5ec1e17d..4fe471d99dc97 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -283,8 +283,7 @@ int main(int argc, char **argv) exit(-1); } rcvbuf = size; - } else if (matches(opt, "-color") == 0) { - ++color; + } else if (matches_color(opt, &color)) { } else if (matches(opt, "-help") == 0) { usage(); } else if (matches(opt, "-netns") == 0) { diff --git a/lib/color.c b/lib/color.c index edf96e5c6ecd7..9c9023587748f 100644 --- a/lib/color.c +++ b/lib/color.c @@ -3,11 +3,13 @@ #include #include #include +#include #include #include #include #include "color.h" +#include "utils.h" enum color { C_RED, @@ -79,13 +81,42 @@ void enable_color(void) int check_enable_color(int color, int json) { - if (color && !json) { + if (json || color == COLOR_OPT_NEVER) + return 1; + + if (color == COLOR_OPT_ALWAYS || isatty(fileno(stdout))) { enable_color(); return 0; } return 1; } +bool matches_color(const char *arg, int *val) +{ + char *dup, *p; + + if (!val) + return false; + + dup = strdupa(arg); + p = strchrnul(dup, '='); + if (*p) + *(p++) = '\0'; + + if (matches(dup, "-color")) + return false; + + if (*p == '\0' || !strcmp(p, "always")) + *val = COLOR_OPT_ALWAYS; + else if (!strcmp(p, "auto")) + *val = COLOR_OPT_AUTO; + else if (!strcmp(p, "never")) + *val = COLOR_OPT_NEVER; + else + return false; + return true; +} + void set_color_palette(void) { char *p = getenv("COLORFGBG"); diff --git a/man/man8/bridge.8 b/man/man8/bridge.8 index e7f7148315e19..9684169844f36 100644 --- a/man/man8/bridge.8 +++ b/man/man8/bridge.8 @@ -170,8 +170,17 @@ If there were any errors during execution of the commands, the application return code will be non zero. .TP -.BR "\-c" , " -color" -Use color output. +.BR \-c [ color ][ = { always | auto | never } +Configure color output. If parameter is omitted or +.BR always , +color output is enabled regardless of stdout state. If parameter is +.BR auto , +stdout is checked to be a terminal before enabling color output. If parameter is +.BR never , +color output is disabled. If specified multiple times, the last one takes +precedence. This flag is ignored if +.B \-json +is also given. .TP .BR "\-j", " \-json" diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 0087d18b74706..1d358879ec39c 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -187,8 +187,17 @@ to executes specified command over all objects, it depends if command supports this option. .TP -.BR "\-c" , " -color" -Use color output. +.BR \-c [ color ][ = { always | auto | never } +Configure color output. If parameter is omitted or +.BR always , +color output is enabled regardless of stdout state. If parameter is +.BR auto , +stdout is checked to be a terminal before enabling color output. If parameter is +.BR never , +color output is disabled. If specified multiple times, the last one takes +precedence. This flag is ignored if +.B \-json +is also given. .TP .BR "\-t" , " \-timestamp" diff --git a/man/man8/tc.8 b/man/man8/tc.8 index 840880fbdba63..a5849a776c592 100644 --- a/man/man8/tc.8 +++ b/man/man8/tc.8 @@ -729,8 +729,17 @@ option was specified. Classes can be filtered only by option. .TP -.BR "\ -color" -Use color output. +.BR \-c [ color ][ = { always | auto | never } +Configure color output. If parameter is omitted or +.BR always , +color output is enabled regardless of stdout state. If parameter is +.BR auto , +stdout is checked to be a terminal before enabling color output. If parameter is +.BR never , +color output is disabled. If specified multiple times, the last one takes +precedence. This flag is ignored if +.B \-json +is also given. .TP .BR "\-j", " \-json" diff --git a/tc/tc.c b/tc/tc.c index e775550174473..586db30cb87c2 100644 --- a/tc/tc.c +++ b/tc/tc.c @@ -493,8 +493,7 @@ int main(int argc, char **argv) matches(argv[1], "-conf") == 0) { NEXT_ARG(); conf_file = argv[1]; - } else if (matches(argv[1], "-color") == 0) { - ++color; + } else if (matches_color(argv[1], &color)) { } else if (matches(argv[1], "-timestamp") == 0) { timestamp++; } else if (matches(argv[1], "-tshort") == 0) { -- 2.18.0