Use single stdout and stderr for control clients.
[tmux-openbsd.git] / options.c
blobec036741292248fd8a7e24f8c2a8215973c3fd49
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 <stdlib.h>
23 #include <string.h>
25 #include "tmux.h"
28 * Option handling; each option has a name, type and value and is stored in
29 * a splay tree.
32 RB_GENERATE(options_tree, options_entry, entry, options_cmp);
34 int
35 options_cmp(struct options_entry *o1, struct options_entry *o2)
37 return (strcmp(o1->name, o2->name));
40 void
41 options_init(struct options *oo, struct options *parent)
43 RB_INIT(&oo->tree);
44 oo->parent = parent;
47 void
48 options_free(struct options *oo)
50 struct options_entry *o;
52 while (!RB_EMPTY(&oo->tree)) {
53 o = RB_ROOT(&oo->tree);
54 RB_REMOVE(options_tree, &oo->tree, o);
55 free(o->name);
56 if (o->type == OPTIONS_STRING)
57 free(o->str);
58 free(o);
62 struct options_entry *
63 options_find1(struct options *oo, const char *name)
65 struct options_entry p;
67 p.name = (char *) name;
68 return (RB_FIND(options_tree, &oo->tree, &p));
71 struct options_entry *
72 options_find(struct options *oo, const char *name)
74 struct options_entry *o, p;
76 p.name = (char *) name;
77 o = RB_FIND(options_tree, &oo->tree, &p);
78 while (o == NULL) {
79 oo = oo->parent;
80 if (oo == NULL)
81 break;
82 o = RB_FIND(options_tree, &oo->tree, &p);
84 return (o);
87 void
88 options_remove(struct options *oo, const char *name)
90 struct options_entry *o;
92 if ((o = options_find1(oo, name)) == NULL)
93 return;
95 RB_REMOVE(options_tree, &oo->tree, o);
96 free(o->name);
97 if (o->type == OPTIONS_STRING)
98 free(o->str);
99 free(o);
102 struct options_entry *printflike3
103 options_set_string(struct options *oo, const char *name, const char *fmt, ...)
105 struct options_entry *o;
106 va_list ap;
108 if ((o = options_find1(oo, name)) == NULL) {
109 o = xmalloc(sizeof *o);
110 o->name = xstrdup(name);
111 RB_INSERT(options_tree, &oo->tree, o);
112 } else if (o->type == OPTIONS_STRING)
113 free(o->str);
115 va_start(ap, fmt);
116 o->type = OPTIONS_STRING;
117 xvasprintf(&o->str, fmt, ap);
118 va_end(ap);
119 return (o);
122 char *
123 options_get_string(struct options *oo, const char *name)
125 struct options_entry *o;
127 if ((o = options_find(oo, name)) == NULL)
128 fatalx("missing option");
129 if (o->type != OPTIONS_STRING)
130 fatalx("option not a string");
131 return (o->str);
134 struct options_entry *
135 options_set_number(struct options *oo, const char *name, long long value)
137 struct options_entry *o;
139 if ((o = options_find1(oo, name)) == NULL) {
140 o = xmalloc(sizeof *o);
141 o->name = xstrdup(name);
142 RB_INSERT(options_tree, &oo->tree, o);
143 } else if (o->type == OPTIONS_STRING)
144 free(o->str);
146 o->type = OPTIONS_NUMBER;
147 o->num = value;
148 return (o);
151 long long
152 options_get_number(struct options *oo, const char *name)
154 struct options_entry *o;
156 if ((o = options_find(oo, name)) == NULL)
157 fatalx("missing option");
158 if (o->type != OPTIONS_NUMBER)
159 fatalx("option not a number");
160 return (o->num);