Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016 6WIND S.A.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : /* Handle color setup for output. */
18 : :
19 : : #include <config.h>
20 : :
21 : : #include "colors.h"
22 : :
23 : : #include <stdlib.h>
24 : : #include <string.h>
25 : :
26 : : #include "util.h"
27 : :
28 : : struct color_key {
29 : : const char *name;
30 : : char **var_ptr;
31 : : };
32 : :
33 : : /* Returns a pointer to the variable containing a given color. */
34 : : static char **get_color(const struct color_key color_dic[], const char * name);
35 : :
36 : : /* Extract user-defined colors from OVS_COLORS environment variable. */
37 : : static void colors_parse_from_env(const struct color_key color_dic[]);
38 : :
39 : : /* Global holder for colors. Declared in header file. */
40 : : struct colors colors = { "", "", "", "", "", "", "", "" };
41 : :
42 : : static char **
43 : 0 : get_color(const struct color_key color_dic[], const char *name)
44 : : {
45 : : const struct color_key *color;
46 [ # # ]: 0 : for (color = color_dic; color->name; color++) {
47 [ # # ]: 0 : if (!strcmp(color->name, name)) {
48 : 0 : return color->var_ptr;
49 : : }
50 : : }
51 : 0 : return NULL;
52 : : }
53 : :
54 : : void
55 : 3885 : colors_init(bool enable_color)
56 : : {
57 : : /* If colored output is not enabled, just keep empty strings for color
58 : : * markers, including end marker.
59 : : */
60 [ + - ]: 3885 : if (!enable_color) {
61 : 3885 : return;
62 : : }
63 : :
64 : : /* Color IDs to use in OVS_COLORS environment variable to overwrite
65 : : * defaults with custom colors.
66 : : */
67 : 0 : const struct color_key color_dic[] = {
68 : : { "ac", &colors.actions },
69 : : { "dr", &colors.drop },
70 : : { "le", &colors.learn },
71 : : { "pm", &colors.param },
72 : : { "pr", &colors.paren },
73 : : { "sp", &colors.special },
74 : : { "vl", &colors.value },
75 : : { NULL, NULL }
76 : : };
77 : :
78 : : /* Actual color to use. First we define default values. */
79 : 0 : colors.actions = "\33[1;31m\33[K"; /* bold red */
80 : 0 : colors.drop = "\33[34m\33[K"; /* blue */
81 : 0 : colors.learn = "\33[31m\33[K"; /* red */
82 : 0 : colors.param = "\33[36m\33[K"; /* cyan */
83 : 0 : colors.paren = "\33[35m\33[K"; /* magenta */
84 : 0 : colors.special = "\33[33m\33[K"; /* yellow */
85 : 0 : colors.value = "\33[32m\33[K"; /* green */
86 : 0 : colors.end = "\33[m\33[K"; /* end marker */
87 : :
88 : : /* Now, overwrite with user-defined color markers. */
89 : 0 : colors_parse_from_env(color_dic);
90 : : }
91 : :
92 : : /* Colorized output: get user-defined colors from OVS_COLORS environment
93 : : * variable. This must be a string of the form:
94 : : * ac=01;31:r=34:le=:pm=02;32:pr=01;30
95 : : * (see color_dic[] in colors_init() function for all color names)
96 : : * If a color is missing from this string, default value is used instead.
97 : : * If a color name is assigned an empty or incorrect value (i.e. something
98 : : * containing characters other than decimals and ';'), fields using this color
99 : : * will not be highlighted.
100 : : * If a color is assigned more than once, the last (rightmost) value appearing
101 : : * in the string is kept.
102 : : * Unknown color names are ignored so as to ensure forward compatibility.
103 : : * (Feeling adventurous? Try combining markers: "ac=1;3;5;7;38;2;30;150;100".)
104 : : */
105 : : static void
106 : 0 : colors_parse_from_env(const struct color_key color_dic[])
107 : : {
108 : 0 : const char *color_str = getenv("OVS_COLORS");
109 [ # # ][ # # ]: 0 : if (color_str == NULL || *color_str == '\0') {
110 : 0 : return;
111 : : }
112 : :
113 : : /* Loop on tokens: they are separated by columns ':' */
114 : 0 : char *s = xstrdup(color_str);
115 [ # # ]: 0 : for (char *token = strsep(&s, ":");
116 : 0 : token != NULL;
117 : 0 : token = strsep(&s, ":")) {
118 : 0 : char *name = strsep(&token, "=");
119 [ # # ][ # # ]: 0 : for (char *ptr = token; ptr != NULL && *ptr != '\0'; ptr++) {
120 : : /* We accept only decimals and ';' for color marker. */
121 [ # # ][ # # ]: 0 : if (*ptr == ';' || (*ptr >= '0' && *ptr <= '9')) {
[ # # ]
122 : 0 : continue;
123 : : }
124 : 0 : name = NULL;
125 : 0 : break;
126 : : }
127 [ # # ]: 0 : if (name != NULL) {
128 : : /* We found a name and marker contains only decimals and ';'.
129 : : * Try to get a pointer to associated color variable. */
130 : 0 : char **color_var_ptr = get_color(color_dic, name);
131 : : /* If we know that color, update its value. */
132 [ # # ]: 0 : if (color_var_ptr != NULL) {
133 : 0 : *color_var_ptr = xasprintf("\33[%sm\33[K", token);
134 : : }
135 : : }
136 : : }
137 : 0 : free(s);
138 : : }
|