GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/tmux/style.c Lines: 0 100 0.0 %
Date: 2016-12-06 Branches: 0 72 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: style.c,v 1.10 2016/07/15 00:42:56 nicm Exp $ */
2
3
/*
4
 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5
 * Copyright (c) 2014 Tiago Cunha <tcunha@users.sourceforge.net>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
22
#include <string.h>
23
24
#include "tmux.h"
25
26
/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
27
int
28
style_parse(const struct grid_cell *defgc, struct grid_cell *gc,
29
    const char *in)
30
{
31
	struct grid_cell	savedgc;
32
	const char		delimiters[] = " ,";
33
	char			tmp[32];
34
	int			val;
35
	size_t			end;
36
	int			fg, bg;
37
	u_char			attr, flags;
38
39
	if (*in == '\0')
40
		return (0);
41
	if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
42
		return (-1);
43
	memcpy(&savedgc, gc, sizeof savedgc);
44
45
	fg = gc->fg;
46
	bg = gc->bg;
47
	attr = gc->attr;
48
	flags = gc->flags;
49
	do {
50
		end = strcspn(in, delimiters);
51
		if (end > (sizeof tmp) - 1)
52
			goto error;
53
		memcpy(tmp, in, end);
54
		tmp[end] = '\0';
55
56
		if (strcasecmp(tmp, "default") == 0) {
57
			fg = defgc->fg;
58
			bg = defgc->bg;
59
			attr = defgc->attr;
60
			flags = defgc->flags;
61
		} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
62
			if ((val = colour_fromstring(tmp + 3)) == -1)
63
				goto error;
64
			if (*in == 'f' || *in == 'F') {
65
				if (val != 8)
66
					fg = val;
67
				else
68
					fg = defgc->fg;
69
			} else if (*in == 'b' || *in == 'B') {
70
				if (val != 8)
71
					bg = val;
72
				else
73
					bg = defgc->bg;
74
			} else
75
				goto error;
76
		} else if (strcasecmp(tmp, "none") == 0)
77
			attr = 0;
78
		else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
79
			if ((val = attributes_fromstring(tmp + 2)) == -1)
80
				goto error;
81
			attr &= ~val;
82
		} else {
83
			if ((val = attributes_fromstring(tmp)) == -1)
84
				goto error;
85
			attr |= val;
86
		}
87
88
		in += end + strspn(in + end, delimiters);
89
	} while (*in != '\0');
90
	gc->fg = fg;
91
	gc->bg = bg;
92
	gc->attr = attr;
93
	gc->flags = flags;
94
95
	return (0);
96
97
error:
98
	memcpy(gc, &savedgc, sizeof *gc);
99
	return (-1);
100
}
101
102
/* Convert style to a string. */
103
const char *
104
style_tostring(struct grid_cell *gc)
105
{
106
	int		 off = 0, comma = 0;
107
	static char	 s[256];
108
109
	*s = '\0';
110
111
	if (gc->fg != 8) {
112
		off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(gc->fg));
113
		comma = 1;
114
	}
115
116
	if (gc->bg != 8) {
117
		off += xsnprintf(s + off, sizeof s - off, "%sbg=%s",
118
		    comma ? "," : "", colour_tostring(gc->bg));
119
		comma = 1;
120
	}
121
122
	if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) {
123
		xsnprintf(s + off, sizeof s - off, "%s%s",
124
		    comma ? "," : "", attributes_tostring(gc->attr));
125
	}
126
127
	if (*s == '\0')
128
		return ("default");
129
	return (s);
130
}
131
132
/* Synchronize new -style option with the old one. */
133
void
134
style_update_new(struct options *oo, const char *name, const char *newname)
135
{
136
	int			 value;
137
	struct grid_cell	*gc;
138
	struct options_entry	*o;
139
140
	/* It's a colour or attribute, but with no -style equivalent. */
141
	if (newname == NULL)
142
		return;
143
144
	o = options_find1(oo, newname);
145
	if (o == NULL)
146
		o = options_set_style(oo, newname, "default", 0);
147
	gc = &o->style;
148
149
	o = options_find1(oo, name);
150
	if (o == NULL)
151
		o = options_set_number(oo, name, 8);
152
	value = o->num;
153
154
	if (strstr(name, "-bg") != NULL)
155
		gc->bg = value;
156
	else if (strstr(name, "-fg") != NULL)
157
		gc->fg = value;
158
	else if (strstr(name, "-attr") != NULL)
159
		gc->attr = value;
160
}
161
162
/* Synchronize all the old options with the new -style one. */
163
void
164
style_update_old(struct options *oo, const char *name, struct grid_cell *gc)
165
{
166
	char	newname[128];
167
	int	size;
168
169
	size = strrchr(name, '-') - name;
170
171
	xsnprintf(newname, sizeof newname, "%.*s-bg", size, name);
172
	options_set_number(oo, newname, gc->bg);
173
174
	xsnprintf(newname, sizeof newname, "%.*s-fg", size, name);
175
	options_set_number(oo, newname, gc->fg);
176
177
	xsnprintf(newname, sizeof newname, "%.*s-attr", size, name);
178
	options_set_number(oo, newname, gc->attr);
179
}
180
181
/* Apply a style. */
182
void
183
style_apply(struct grid_cell *gc, struct options *oo, const char *name)
184
{
185
	struct grid_cell	*gcp;
186
187
	memcpy(gc, &grid_default_cell, sizeof *gc);
188
	gcp = options_get_style(oo, name);
189
	gc->fg = gcp->fg;
190
	gc->bg = gcp->bg;
191
	gc->attr |= gcp->attr;
192
}
193
194
/* Apply a style, updating if default. */
195
void
196
style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
197
{
198
	struct grid_cell	*gcp;
199
200
	gcp = options_get_style(oo, name);
201
	if (gcp->fg != 8)
202
		gc->fg = gcp->fg;
203
	if (gcp->bg != 8)
204
		gc->bg = gcp->bg;
205
	if (gcp->attr != 0)
206
		gc->attr |= gcp->attr;
207
}
208
209
/* Check if two styles are the same. */
210
int
211
style_equal(const struct grid_cell *gc1, const struct grid_cell *gc2)
212
{
213
	return (gc1->fg == gc2->fg &&
214
	    gc1->bg == gc2->bg &&
215
	    (gc1->flags & ~GRID_FLAG_PADDING) ==
216
	    (gc2->flags & ~GRID_FLAG_PADDING) &&
217
	    (gc1->attr & ~GRID_ATTR_CHARSET) ==
218
	    (gc2->attr & ~GRID_ATTR_CHARSET));
219
}