Don't die if fail to get root directory, from Ben Boeckel.
[tmux-openbsd.git] / options.c
blob9298ab11ffeac23f1b7ec7c46b392d7e0410c6ec
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
21 #include <stdarg.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Option handling; each option has a name, type and value and is stored in
28 * a splay tree.
31 RB_GENERATE(options_tree, options_entry, entry, options_cmp);
33 int
34 options_cmp(struct options_entry *o1, struct options_entry *o2)
36 return (strcmp(o1->name, o2->name));
39 void
40 options_init(struct options *oo, struct options *parent)
42 RB_INIT(&oo->tree);
43 oo->parent = parent;
46 void
47 options_free(struct options *oo)
49 struct options_entry *o;
51 while (!RB_EMPTY(&oo->tree)) {
52 o = RB_ROOT(&oo->tree);
53 RB_REMOVE(options_tree, &oo->tree, o);
54 xfree(o->name);
55 if (o->type == OPTIONS_STRING)
56 xfree(o->str);
57 xfree(o);
61 struct options_entry *
62 options_find1(struct options *oo, const char *name)
64 struct options_entry p;
66 p.name = (char *) name;
67 return (RB_FIND(options_tree, &oo->tree, &p));
70 struct options_entry *
71 options_find(struct options *oo, const char *name)
73 struct options_entry *o, p;
75 p.name = (char *) name;
76 o = RB_FIND(options_tree, &oo->tree, &p);
77 while (o == NULL) {
78 oo = oo->parent;
79 if (oo == NULL)
80 break;
81 o = RB_FIND(options_tree, &oo->tree, &p);
83 return (o);
86 void
87 options_remove(struct options *oo, const char *name)
89 struct options_entry *o;
91 if ((o = options_find1(oo, name)) == NULL)
92 return;
94 RB_REMOVE(options_tree, &oo->tree, o);
95 xfree(o->name);
96 if (o->type == OPTIONS_STRING)
97 xfree(o->str);
98 xfree(o);
101 struct options_entry *printflike3
102 options_set_string(struct options *oo, const char *name, const char *fmt, ...)
104 struct options_entry *o;
105 va_list ap;
107 if ((o = options_find1(oo, name)) == NULL) {
108 o = xmalloc(sizeof *o);
109 o->name = xstrdup(name);
110 RB_INSERT(options_tree, &oo->tree, o);
111 } else if (o->type == OPTIONS_STRING)
112 xfree(o->str);
114 va_start(ap, fmt);
115 o->type = OPTIONS_STRING;
116 xvasprintf(&o->str, fmt, ap);
117 va_end(ap);
118 return (o);
121 char *
122 options_get_string(struct options *oo, const char *name)
124 struct options_entry *o;
126 if ((o = options_find(oo, name)) == NULL)
127 fatalx("missing option");
128 if (o->type != OPTIONS_STRING)
129 fatalx("option not a string");
130 return (o->str);
133 struct options_entry *
134 options_set_number(struct options *oo, const char *name, long long value)
136 struct options_entry *o;
138 if ((o = options_find1(oo, name)) == NULL) {
139 o = xmalloc(sizeof *o);
140 o->name = xstrdup(name);
141 RB_INSERT(options_tree, &oo->tree, o);
142 } else if (o->type == OPTIONS_STRING)
143 xfree(o->str);
145 o->type = OPTIONS_NUMBER;
146 o->num = value;
147 return (o);
150 long long
151 options_get_number(struct options *oo, const char *name)
153 struct options_entry *o;
155 if ((o = options_find(oo, name)) == NULL)
156 fatalx("missing option");
157 if (o->type != OPTIONS_NUMBER)
158 fatalx("option not a number");
159 return (o->num);