Annotation of src/usr.bin/tmux/options.c, Revision 1.21
1.21 ! nicm 1: /* $OpenBSD: options.c,v 1.20 2016/10/10 21:29:23 nicm Exp $ */
1.1 nicm 2:
3: /*
1.18 nicm 4: * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <stdarg.h>
1.8 nicm 22: #include <stdlib.h>
1.1 nicm 23: #include <string.h>
24:
25: #include "tmux.h"
26:
27: /*
28: * Option handling; each option has a name, type and value and is stored in
1.9 nicm 29: * a red-black tree.
1.1 nicm 30: */
31:
1.13 nicm 32: struct options {
33: RB_HEAD(options_tree, options_entry) tree;
34: struct options *parent;
35: };
36:
1.17 nicm 37: static int options_cmp(struct options_entry *, struct options_entry *);
1.20 nicm 38: RB_GENERATE_STATIC(options_tree, options_entry, entry, options_cmp);
1.1 nicm 39:
1.17 nicm 40: static int
1.1 nicm 41: options_cmp(struct options_entry *o1, struct options_entry *o2)
42: {
43: return (strcmp(o1->name, o2->name));
44: }
45:
1.13 nicm 46: struct options *
47: options_create(struct options *parent)
1.1 nicm 48: {
1.16 nicm 49: struct options *oo;
1.13 nicm 50:
51: oo = xcalloc(1, sizeof *oo);
1.7 nicm 52: RB_INIT(&oo->tree);
1.1 nicm 53: oo->parent = parent;
1.13 nicm 54: return (oo);
1.1 nicm 55: }
56:
1.17 nicm 57: static void
58: options_free1(struct options *oo, struct options_entry *o)
59: {
60: RB_REMOVE(options_tree, &oo->tree, o);
61: free((char *)o->name);
62: if (o->type == OPTIONS_STRING)
63: free(o->str);
64: free(o);
65: }
66:
1.21 ! nicm 67: static struct options_entry *
! 68: options_new(struct options *oo, const char *name, char **s)
! 69: {
! 70: struct options_entry *o;
! 71:
! 72: if (s != NULL)
! 73: *s = NULL;
! 74:
! 75: if ((o = options_find1(oo, name)) == NULL) {
! 76: o = xmalloc(sizeof *o);
! 77: o->name = xstrdup(name);
! 78: RB_INSERT(options_tree, &oo->tree, o);
! 79: memcpy(&o->style, &grid_default_cell, sizeof o->style);
! 80: } else if (o->type == OPTIONS_STRING) {
! 81: if (s != NULL)
! 82: *s = o->str;
! 83: else
! 84: free(o->str);
! 85: }
! 86: return (o);
! 87: }
! 88:
1.1 nicm 89: void
90: options_free(struct options *oo)
91: {
1.17 nicm 92: struct options_entry *o, *o1;
1.1 nicm 93:
1.17 nicm 94: RB_FOREACH_SAFE (o, options_tree, &oo->tree, o1)
95: options_free1(oo, o);
1.13 nicm 96: free(oo);
97: }
98:
99: struct options_entry *
100: options_first(struct options *oo)
101: {
102: return (RB_MIN(options_tree, &oo->tree));
103: }
104:
105: struct options_entry *
106: options_next(struct options_entry *o)
107: {
108: return (RB_NEXT(options_tree, &oo->tree, o));
1.1 nicm 109: }
110:
111: struct options_entry *
112: options_find1(struct options *oo, const char *name)
113: {
114: struct options_entry p;
115:
1.17 nicm 116: p.name = (char *)name;
1.7 nicm 117: return (RB_FIND(options_tree, &oo->tree, &p));
1.1 nicm 118: }
119:
120: struct options_entry *
121: options_find(struct options *oo, const char *name)
122: {
123: struct options_entry *o, p;
124:
1.17 nicm 125: p.name = (char *)name;
1.7 nicm 126: o = RB_FIND(options_tree, &oo->tree, &p);
1.1 nicm 127: while (o == NULL) {
128: oo = oo->parent;
129: if (oo == NULL)
130: break;
1.7 nicm 131: o = RB_FIND(options_tree, &oo->tree, &p);
1.1 nicm 132: }
133: return (o);
134: }
135:
1.2 nicm 136: void
1.1 nicm 137: options_remove(struct options *oo, const char *name)
138: {
139: struct options_entry *o;
140:
1.17 nicm 141: if ((o = options_find1(oo, name)) != NULL)
142: options_free1(oo, o);
1.1 nicm 143: }
144:
1.11 nicm 145: struct options_entry *
1.1 nicm 146: options_set_string(struct options *oo, const char *name, const char *fmt, ...)
147: {
148: struct options_entry *o;
149: va_list ap;
1.19 nicm 150: char *s;
1.1 nicm 151:
1.21 ! nicm 152: va_start(ap, fmt);
1.1 nicm 153:
1.21 ! nicm 154: o = options_new(oo, name, &s);
1.1 nicm 155: o->type = OPTIONS_STRING;
1.3 nicm 156: xvasprintf(&o->str, fmt, ap);
1.21 ! nicm 157: free(s);
! 158:
1.1 nicm 159: va_end(ap);
1.4 nicm 160: return (o);
1.1 nicm 161: }
162:
163: char *
164: options_get_string(struct options *oo, const char *name)
165: {
166: struct options_entry *o;
167:
168: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 169: fatalx("missing option %s", name);
1.1 nicm 170: if (o->type != OPTIONS_STRING)
1.15 nicm 171: fatalx("option %s not a string", name);
1.3 nicm 172: return (o->str);
1.1 nicm 173: }
174:
1.4 nicm 175: struct options_entry *
1.1 nicm 176: options_set_number(struct options *oo, const char *name, long long value)
177: {
178: struct options_entry *o;
179:
1.21 ! nicm 180: o = options_new(oo, name, NULL);
1.1 nicm 181: o->type = OPTIONS_NUMBER;
1.3 nicm 182: o->num = value;
1.21 ! nicm 183:
1.4 nicm 184: return (o);
1.1 nicm 185: }
186:
187: long long
188: options_get_number(struct options *oo, const char *name)
189: {
190: struct options_entry *o;
191:
192: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 193: fatalx("missing option %s", name);
1.1 nicm 194: if (o->type != OPTIONS_NUMBER)
1.15 nicm 195: fatalx("option %s not a number", name);
1.3 nicm 196: return (o->num);
1.10 nicm 197: }
198:
199: struct options_entry *
200: options_set_style(struct options *oo, const char *name, const char *value,
201: int append)
202: {
203: struct options_entry *o;
1.12 nicm 204: struct grid_cell tmpgc;
1.10 nicm 205:
1.12 nicm 206: o = options_find1(oo, name);
207: if (o == NULL || !append)
208: memcpy(&tmpgc, &grid_default_cell, sizeof tmpgc);
209: else
210: memcpy(&tmpgc, &o->style, sizeof tmpgc);
211:
212: if (style_parse(&grid_default_cell, &tmpgc, value) == -1)
213: return (NULL);
214:
1.21 ! nicm 215: o = options_new(oo, name, NULL);
1.10 nicm 216: o->type = OPTIONS_STYLE;
1.12 nicm 217: memcpy(&o->style, &tmpgc, sizeof o->style);
1.21 ! nicm 218:
1.10 nicm 219: return (o);
220: }
221:
222: struct grid_cell *
223: options_get_style(struct options *oo, const char *name)
224: {
225: struct options_entry *o;
226:
227: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 228: fatalx("missing option %s", name);
1.10 nicm 229: if (o->type != OPTIONS_STYLE)
1.15 nicm 230: fatalx("option %s not a style", name);
1.10 nicm 231: return (&o->style);
1.1 nicm 232: }