GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/tmux/style.c Lines: 39 79 49.4 %
Date: 2017-11-07 Branches: 21 60 35.0 %

Line Branch Exec Source
1
/* $OpenBSD: style.c,v 1.14 2017/03/22 07:16:54 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
180
	struct grid_cell	savedgc;
32
	const char		delimiters[] = " ,";
33
90
	char			tmp[32];
34
	int			val, fg, bg, attr, flags;
35
	size_t			end;
36
37
90
	if (*in == '\0')
38
		return (0);
39
90
	if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
40
		return (-1);
41
90
	memcpy(&savedgc, gc, sizeof savedgc);
42
43
90
	fg = gc->fg;
44
90
	bg = gc->bg;
45
90
	attr = gc->attr;
46
90
	flags = gc->flags;
47
90
	do {
48
114
		end = strcspn(in, delimiters);
49
114
		if (end > (sizeof tmp) - 1)
50
			goto error;
51
114
		memcpy(tmp, in, end);
52
114
		tmp[end] = '\0';
53
54
114
		if (strcasecmp(tmp, "default") == 0) {
55
48
			fg = defgc->fg;
56
48
			bg = defgc->bg;
57
48
			attr = defgc->attr;
58
48
			flags = defgc->flags;
59

180
		} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
60
54
			if ((val = colour_fromstring(tmp + 3)) == -1)
61
				goto error;
62

78
			if (*in == 'f' || *in == 'F') {
63
30
				if (val != 8)
64
30
					fg = val;
65
				else
66
					fg = defgc->fg;
67

24
			} else if (*in == 'b' || *in == 'B') {
68
24
				if (val != 8)
69
24
					bg = val;
70
				else
71
					bg = defgc->bg;
72
			} else
73
				goto error;
74
12
		} else if (strcasecmp(tmp, "none") == 0)
75
			attr = 0;
76

24
		else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
77
			if ((val = attributes_fromstring(tmp + 2)) == -1)
78
				goto error;
79
			attr &= ~val;
80
		} else {
81
12
			if ((val = attributes_fromstring(tmp)) == -1)
82
				goto error;
83
12
			attr |= val;
84
		}
85
86
114
		in += end + strspn(in + end, delimiters);
87
114
	} while (*in != '\0');
88
90
	gc->fg = fg;
89
90
	gc->bg = bg;
90
90
	gc->attr = attr;
91
90
	gc->flags = flags;
92
93
90
	return (0);
94
95
error:
96
	memcpy(gc, &savedgc, sizeof *gc);
97
	return (-1);
98
90
}
99
100
/* Convert style to a string. */
101
const char *
102
style_tostring(struct grid_cell *gc)
103
{
104
	int		 off = 0, comma = 0;
105
	static char	 s[256];
106
107
	*s = '\0';
108
109
	if (gc->fg != 8) {
110
		off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(gc->fg));
111
		comma = 1;
112
	}
113
114
	if (gc->bg != 8) {
115
		off += xsnprintf(s + off, sizeof s - off, "%sbg=%s",
116
		    comma ? "," : "", colour_tostring(gc->bg));
117
		comma = 1;
118
	}
119
120
	if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) {
121
		xsnprintf(s + off, sizeof s - off, "%s%s",
122
		    comma ? "," : "", attributes_tostring(gc->attr));
123
	}
124
125
	if (*s == '\0')
126
		return ("default");
127
	return (s);
128
}
129
130
/* Apply a style. */
131
void
132
style_apply(struct grid_cell *gc, struct options *oo, const char *name)
133
{
134
	const struct grid_cell	*gcp;
135
136
	memcpy(gc, &grid_default_cell, sizeof *gc);
137
	gcp = options_get_style(oo, name);
138
	gc->fg = gcp->fg;
139
	gc->bg = gcp->bg;
140
	gc->attr |= gcp->attr;
141
}
142
143
/* Apply a style, updating if default. */
144
void
145
style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
146
{
147
	const struct grid_cell	*gcp;
148
149
	gcp = options_get_style(oo, name);
150
	if (gcp->fg != 8)
151
		gc->fg = gcp->fg;
152
	if (gcp->bg != 8)
153
		gc->bg = gcp->bg;
154
	if (gcp->attr != 0)
155
		gc->attr |= gcp->attr;
156
}
157
158
/* Check if two styles are the same. */
159
int
160
style_equal(const struct grid_cell *gc1, const struct grid_cell *gc2)
161
{
162
	return (gc1->fg == gc2->fg &&
163
	    gc1->bg == gc2->bg &&
164
	    (gc1->flags & ~GRID_FLAG_PADDING) ==
165
	    (gc2->flags & ~GRID_FLAG_PADDING) &&
166
	    (gc1->attr & ~GRID_ATTR_CHARSET) ==
167
	    (gc2->attr & ~GRID_ATTR_CHARSET));
168
}