aboutsummaryrefslogtreecommitdiffstats
path: root/lib/color.c
blob: 8d049a01ec0e462acbef11d60f86812070625ffc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if.h>

#include "color.h"

enum color {
	C_RED,
	C_GREEN,
	C_YELLOW,
	C_BLUE,
	C_MAGENTA,
	C_CYAN,
	C_WHITE,
	C_BOLD_RED,
	C_BOLD_GREEN,
	C_BOLD_YELLOW,
	C_BOLD_BLUE,
	C_BOLD_MAGENTA,
	C_BOLD_CYAN,
	C_BOLD_WHITE,
	C_CLEAR
};

static const char * const color_codes[] = {
	"\e[31m",
	"\e[32m",
	"\e[33m",
	"\e[34m",
	"\e[35m",
	"\e[36m",
	"\e[37m",
	"\e[1;31m",
	"\e[1;32m",
	"\e[1;33m",
	"\e[1;34m",
	"\e[1;35m",
	"\e[1;36m",
	"\e[1;37m",
	"\e[0m",
	NULL,
};

/* light background */
static enum color attr_colors_light[] = {
	C_CYAN,
	C_YELLOW,
	C_MAGENTA,
	C_BLUE,
	C_GREEN,
	C_RED,
	C_CLEAR,
};

/* dark background */
static enum color attr_colors_dark[] = {
	C_BOLD_CYAN,
	C_BOLD_YELLOW,
	C_BOLD_MAGENTA,
	C_BOLD_BLUE,
	C_BOLD_GREEN,
	C_BOLD_RED,
	C_CLEAR
};

static int is_dark_bg;
static int color_is_enabled;

void enable_color(void)
{
	color_is_enabled = 1;
	set_color_palette();
}

void set_color_palette(void)
{
	char *p = getenv("COLORFGBG");

	/*
	 * COLORFGBG environment variable usually contains either two or three
	 * values separated by semicolons; we want the last value in either case.
	 * If this value is 0-6 or 8, background is dark.
	 */
	if (p && (p = strrchr(p, ';')) != NULL
		&& ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
		&& p[2] == '\0')
		is_dark_bg = 1;
}

void check_if_color_enabled(void)
{
	if (color_is_enabled) {
		fprintf(stderr, "Option \"-json\" conflicts with \"-color\".\n");
		exit(1);
	}
}

int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
{
	int ret = 0;
	va_list args;

	va_start(args, fmt);

	if (!color_is_enabled || attr == COLOR_NONE) {
		ret = vfprintf(fp, fmt, args);
		goto end;
	}

	ret += fprintf(fp, "%s", color_codes[is_dark_bg ?
		attr_colors_dark[attr] : attr_colors_light[attr]]);

	ret += vfprintf(fp, fmt, args);
	ret += fprintf(fp, "%s", color_codes[C_CLEAR]);

end:
	va_end(args);
	return ret;
}

enum color_attr ifa_family_color(__u8 ifa_family)
{
	switch (ifa_family) {
	case AF_INET:
		return COLOR_INET;
	case AF_INET6:
		return COLOR_INET6;
	default:
		return COLOR_NONE;
	}
}

enum color_attr oper_state_color(__u8 state)
{
	switch (state) {
	case IF_OPER_UP:
		return COLOR_OPERSTATE_UP;
	case IF_OPER_DOWN:
		return COLOR_OPERSTATE_DOWN;
	default:
		return COLOR_NONE;
	}
}