diff options
author | Quentin Monnet <quentin.monnet@6wind.com> | 2016-03-02 15:56:17 +0100 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-03-18 14:02:41 -0700 |
commit | ef7b593bdd86ce9976aff3a7de985ad7dbae7ae4 (patch) | |
tree | 46f13973989b641a2851f5fecb5aca8f7a43963e /lib/colors.c | |
parent | 20174b74619bfe85fa8e4948a368e3600b557412 (diff) | |
download | openvswitch-ef7b593bdd86ce9976aff3a7de985ad7dbae7ae4.tar.gz |
ovs-ofctl: Declare / set up colors for command output.
OVS_COLORS environment variable is parsed to extract user-defined
preferences regarding colors (this is used to set up a color theme, not
to replace the `--color` option for activating color output).
The string should be of a format similar to LS_COLORS or GREP_COLORS,
with available colors being as follows:
* ac: action field
* dr: drop keyword
* le: learn keyword
* pm: parameters receiving attributes
* pr: keyword having parenthesis
* sp: some special keywords
* vl: lone values with no parameter name
For color whose idendifier does not appear in the string, the default
hardcoded value is used instead.
As an example, setting OVS_COLORS to the following string is equivalent
to using the default values:
OVS_COLORS="ac:01;31:dr=34:le=31:pm=36:pr=35:sp=33:vl=32"
Signed-off-by: Quentin Monnet <quentin.monnet@6wind.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/colors.c')
-rw-r--r-- | lib/colors.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/colors.c b/lib/colors.c new file mode 100644 index 000000000..4ea1880d8 --- /dev/null +++ b/lib/colors.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 6WIND S.A. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Handle color setup for output. */ + +#include <config.h> + +#include "colors.h" + +#include <stdlib.h> +#include <string.h> + +#include "util.h" + +struct color_key { + const char *name; + char **var_ptr; +}; + +/* Returns a pointer to the variable containing a given color. */ +static char **get_color(const struct color_key color_dic[], const char * name); + +/* Extract user-defined colors from OVS_COLORS environment variable. */ +static void colors_parse_from_env(const struct color_key color_dic[]); + +/* Global holder for colors. Declared in header file. */ +struct colors colors = { "", "", "", "", "", "", "", "" }; + +static char ** +get_color(const struct color_key color_dic[], const char *name) +{ + const struct color_key *color; + for (color = color_dic; color->name; color++) { + if (!strcmp(color->name, name)) { + return color->var_ptr; + } + } + return NULL; +} + +void +colors_init(bool enable_color) +{ + /* If colored output is not enabled, just keep empty strings for color + * markers, including end marker. + */ + if (!enable_color) { + return; + } + + /* Color IDs to use in OVS_COLORS environment variable to overwrite + * defaults with custom colors. + */ + const struct color_key color_dic[] = { + { "ac", &colors.actions }, + { "dr", &colors.drop }, + { "le", &colors.learn }, + { "pm", &colors.param }, + { "pr", &colors.paren }, + { "sp", &colors.special }, + { "vl", &colors.value }, + { NULL, NULL } + }; + + /* Actual color to use. First we define default values. */ + colors.actions = "\33[1;31m\33[K"; /* bold red */ + colors.drop = "\33[34m\33[K"; /* blue */ + colors.learn = "\33[31m\33[K"; /* red */ + colors.param = "\33[36m\33[K"; /* cyan */ + colors.paren = "\33[35m\33[K"; /* magenta */ + colors.special = "\33[33m\33[K"; /* yellow */ + colors.value = "\33[32m\33[K"; /* green */ + colors.end = "\33[m\33[K"; /* end marker */ + + /* Now, overwrite with user-defined color markers. */ + colors_parse_from_env(color_dic); +} + +/* Colorized output: get user-defined colors from OVS_COLORS environment + * variable. This must be a string of the form: + * ac=01;31:r=34:le=:pm=02;32:pr=01;30 + * (see color_dic[] in colors_init() function for all color names) + * If a color is missing from this string, default value is used instead. + * If a color name is assigned an empty or incorrect value (i.e. something + * containing characters other than decimals and ';'), fields using this color + * will not be highlighted. + * If a color is assigned more than once, the last (rightmost) value appearing + * in the string is kept. + * Unknown color names are ignored so as to ensure forward compatibility. + * (Feeling adventurous? Try combining markers: "ac=1;3;5;7;38;2;30;150;100".) + */ +static void +colors_parse_from_env(const struct color_key color_dic[]) +{ + const char *color_str = getenv("OVS_COLORS"); + if (color_str == NULL || *color_str == '\0') { + return; + } + + /* Loop on tokens: they are separated by columns ':' */ + char *s = xstrdup(color_str); + for (char *token = strsep(&s, ":"); + token != NULL; + token = strsep(&s, ":")) { + char *name = strsep(&token, "="); + for (char *ptr = token; ptr != NULL && *ptr != '\0'; ptr++) { + /* We accept only decimals and ';' for color marker. */ + if (*ptr == ';' || (*ptr >= '0' && *ptr <= '9')) { + continue; + } + name = NULL; + break; + } + if (name != NULL) { + /* We found a name and marker contains only decimals and ';'. + * Try to get a pointer to associated color variable. */ + char **color_var_ptr = get_color(color_dic, name); + /* If we know that color, update its value. */ + if (color_var_ptr != NULL) { + *color_var_ptr = xasprintf("\33[%sm\33[K", token); + } + } + } + free(s); +} |