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.mon...@6wind.com> --- lib/automake.mk | 2 + lib/colors.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/colors.h | 42 +++++++++++++++ utilities/ovs-ofctl.c | 3 ++ 4 files changed, 193 insertions(+) create mode 100644 lib/colors.c create mode 100644 lib/colors.h diff --git a/lib/automake.mk b/lib/automake.mk index 27a16691ebda..1eeb5e48b19a 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -40,6 +40,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/classifier-private.h \ lib/cmap.c \ lib/cmap.h \ + lib/colors.c \ + lib/colors.h \ lib/command-line.c \ lib/command-line.h \ lib/compiler.h \ diff --git a/lib/colors.c b/lib/colors.c new file mode 100644 index 000000000000..2ed4bad69f71 --- /dev/null +++ b/lib/colors.c @@ -0,0 +1,146 @@ +/* + * 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; + char *s; + char *token; + + color_str = getenv("OVS_COLORS"); + if (color_str == NULL || *color_str == '\0') + { + return; + } + s = xstrdup(color_str); + + /* Loop on tokens: they are separated by columns ':' */ + for (token = strsep(&s, ":"); + token != NULL; + token = strsep(&s, ":")) { + char *ptr; + char *name = strsep(&token, "="); + for (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 = malloc(sizeof(char)*(11 + strlen(token))); + sprintf(*color_var_ptr, "\33[%sm\33[K", token); + } + } + } +} diff --git a/lib/colors.h b/lib/colors.h new file mode 100644 index 000000000000..4bfbf9671264 --- /dev/null +++ b/lib/colors.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +#ifndef COLORS_H +#define COLORS_H 1 + +#include <stdbool.h> + +struct colors { + /* Color codes for various situation. Each of these is a fully formed + * Select Graphic Rendition (SGR, "\33[...m") start string for the + * appropriate color. + */ + char *actions; + char *drop; + char *learn; + char *param; + char *paren; + char *special; + char *value; + + /* SGR end string. */ + char *end; +}; +extern struct colors colors; + +void colors_init(bool enable_color); + +#endif /* colors.h */ diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index c535005797af..bde9fa0654de 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -33,6 +33,7 @@ #include "classifier.h" #include "command-line.h" #include "daemon.h" +#include "colors.h" #include "compiler.h" #include "dirs.h" #include "dynamic-string.h" @@ -367,6 +368,8 @@ parse_options(int argc, char *argv[]) allowed_protocols &= version_protocols; mask_allowed_ofp_versions(ofputil_protocols_to_version_bitmap( allowed_protocols)); + + colors_init(enable_color); } static void -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev