Annotation of src/usr.bin/tmux/options.c, Revision 1.22
1.22 ! nicm 1: /* $OpenBSD: options.c,v 1.21 2017/01/11 14:56:44 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 *
1.22 ! nicm 68: options_new(struct options *oo, const char *name)
1.21 nicm 69: {
70: struct options_entry *o;
71:
72: if ((o = options_find1(oo, name)) == NULL) {
73: o = xmalloc(sizeof *o);
74: o->name = xstrdup(name);
75: RB_INSERT(options_tree, &oo->tree, o);
76: memcpy(&o->style, &grid_default_cell, sizeof o->style);
1.22 ! nicm 77: } else if (o->type == OPTIONS_STRING)
! 78: free(o->str);
1.21 nicm 79: return (o);
80: }
81:
1.1 nicm 82: void
83: options_free(struct options *oo)
84: {
1.17 nicm 85: struct options_entry *o, *o1;
1.1 nicm 86:
1.17 nicm 87: RB_FOREACH_SAFE (o, options_tree, &oo->tree, o1)
88: options_free1(oo, o);
1.13 nicm 89: free(oo);
90: }
91:
92: struct options_entry *
93: options_first(struct options *oo)
94: {
95: return (RB_MIN(options_tree, &oo->tree));
96: }
97:
98: struct options_entry *
99: options_next(struct options_entry *o)
100: {
101: return (RB_NEXT(options_tree, &oo->tree, o));
1.1 nicm 102: }
103:
104: struct options_entry *
105: options_find1(struct options *oo, const char *name)
106: {
107: struct options_entry p;
108:
1.17 nicm 109: p.name = (char *)name;
1.7 nicm 110: return (RB_FIND(options_tree, &oo->tree, &p));
1.1 nicm 111: }
112:
113: struct options_entry *
114: options_find(struct options *oo, const char *name)
115: {
116: struct options_entry *o, p;
117:
1.17 nicm 118: p.name = (char *)name;
1.7 nicm 119: o = RB_FIND(options_tree, &oo->tree, &p);
1.1 nicm 120: while (o == NULL) {
121: oo = oo->parent;
122: if (oo == NULL)
123: break;
1.7 nicm 124: o = RB_FIND(options_tree, &oo->tree, &p);
1.1 nicm 125: }
126: return (o);
127: }
128:
1.2 nicm 129: void
1.1 nicm 130: options_remove(struct options *oo, const char *name)
131: {
132: struct options_entry *o;
133:
1.17 nicm 134: if ((o = options_find1(oo, name)) != NULL)
135: options_free1(oo, o);
1.1 nicm 136: }
137:
1.11 nicm 138: struct options_entry *
1.22 ! nicm 139: options_set_string(struct options *oo, const char *name, int append,
! 140: const char *fmt, ...)
1.1 nicm 141: {
142: struct options_entry *o;
143: va_list ap;
1.22 ! nicm 144: char *s, *value;
1.1 nicm 145:
1.21 nicm 146: va_start(ap, fmt);
1.22 ! nicm 147: xvasprintf(&s, fmt, ap);
! 148: va_end(ap);
1.1 nicm 149:
1.22 ! nicm 150: o = options_find1(oo, name);
! 151: if (o == NULL || !append)
! 152: value = s;
! 153: else {
! 154: xasprintf(&value, "%s%s", s, o->str);
! 155: free(s);
! 156: }
! 157:
! 158: o = options_new(oo, name);
1.1 nicm 159: o->type = OPTIONS_STRING;
1.22 ! nicm 160: o->str = value;
1.21 nicm 161:
1.4 nicm 162: return (o);
1.1 nicm 163: }
164:
165: char *
166: options_get_string(struct options *oo, const char *name)
167: {
168: struct options_entry *o;
169:
170: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 171: fatalx("missing option %s", name);
1.1 nicm 172: if (o->type != OPTIONS_STRING)
1.15 nicm 173: fatalx("option %s not a string", name);
1.3 nicm 174: return (o->str);
1.1 nicm 175: }
176:
1.4 nicm 177: struct options_entry *
1.1 nicm 178: options_set_number(struct options *oo, const char *name, long long value)
179: {
180: struct options_entry *o;
181:
1.22 ! nicm 182: o = options_new(oo, name);
1.1 nicm 183: o->type = OPTIONS_NUMBER;
1.3 nicm 184: o->num = value;
1.21 nicm 185:
1.4 nicm 186: return (o);
1.1 nicm 187: }
188:
189: long long
190: options_get_number(struct options *oo, const char *name)
191: {
192: struct options_entry *o;
193:
194: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 195: fatalx("missing option %s", name);
1.1 nicm 196: if (o->type != OPTIONS_NUMBER)
1.15 nicm 197: fatalx("option %s not a number", name);
1.3 nicm 198: return (o->num);
1.10 nicm 199: }
200:
201: struct options_entry *
1.22 ! nicm 202: options_set_style(struct options *oo, const char *name, int append,
! 203: const char *value)
1.10 nicm 204: {
205: struct options_entry *o;
1.12 nicm 206: struct grid_cell tmpgc;
1.10 nicm 207:
1.12 nicm 208: o = options_find1(oo, name);
209: if (o == NULL || !append)
210: memcpy(&tmpgc, &grid_default_cell, sizeof tmpgc);
211: else
212: memcpy(&tmpgc, &o->style, sizeof tmpgc);
213:
214: if (style_parse(&grid_default_cell, &tmpgc, value) == -1)
215: return (NULL);
216:
1.22 ! nicm 217: o = options_new(oo, name);
1.10 nicm 218: o->type = OPTIONS_STYLE;
1.12 nicm 219: memcpy(&o->style, &tmpgc, sizeof o->style);
1.21 nicm 220:
1.10 nicm 221: return (o);
222: }
223:
224: struct grid_cell *
225: options_get_style(struct options *oo, const char *name)
226: {
227: struct options_entry *o;
228:
229: if ((o = options_find(oo, name)) == NULL)
1.15 nicm 230: fatalx("missing option %s", name);
1.10 nicm 231: if (o->type != OPTIONS_STYLE)
1.15 nicm 232: fatalx("option %s not a style", name);
1.10 nicm 233: return (&o->style);
1.1 nicm 234: }