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>
27 * Option handling; each option has a name, type and value and is stored in
31 SPLAY_GENERATE(options_tree
, options_entry
, entry
, options_cmp
);
34 options_cmp(struct options_entry
*o1
, struct options_entry
*o2
)
36 return (strcmp(o1
->name
, o2
->name
));
40 options_init(struct options
*oo
, struct options
*parent
)
42 SPLAY_INIT(&oo
->tree
);
47 options_free(struct options
*oo
)
49 struct options_entry
*o
;
51 while (!SPLAY_EMPTY(&oo
->tree
)) {
52 o
= SPLAY_ROOT(&oo
->tree
);
53 SPLAY_REMOVE(options_tree
, &oo
->tree
, o
);
55 if (o
->type
== OPTIONS_STRING
)
57 else if (o
->type
== OPTIONS_DATA
)
63 struct options_entry
*
64 options_find1(struct options
*oo
, const char *name
)
66 struct options_entry p
;
68 p
.name
= (char *) name
;
69 return (SPLAY_FIND(options_tree
, &oo
->tree
, &p
));
72 struct options_entry
*
73 options_find(struct options
*oo
, const char *name
)
75 struct options_entry
*o
, p
;
77 p
.name
= (char *) name
;
78 o
= SPLAY_FIND(options_tree
, &oo
->tree
, &p
);
83 o
= SPLAY_FIND(options_tree
, &oo
->tree
, &p
);
89 options_remove(struct options
*oo
, const char *name
)
91 struct options_entry
*o
;
93 if ((o
= options_find1(oo
, name
)) == NULL
)
96 SPLAY_REMOVE(options_tree
, &oo
->tree
, o
);
98 if (o
->type
== OPTIONS_STRING
)
100 else if (o
->type
== OPTIONS_DATA
)
105 struct options_entry
*printflike3
106 options_set_string(struct options
*oo
, const char *name
, const char *fmt
, ...)
108 struct options_entry
*o
;
111 if ((o
= options_find1(oo
, name
)) == NULL
) {
112 o
= xmalloc(sizeof *o
);
113 o
->name
= xstrdup(name
);
114 SPLAY_INSERT(options_tree
, &oo
->tree
, o
);
115 } else if (o
->type
== OPTIONS_STRING
)
117 else if (o
->type
== OPTIONS_DATA
)
121 o
->type
= OPTIONS_STRING
;
122 xvasprintf(&o
->str
, fmt
, ap
);
128 options_get_string(struct options
*oo
, const char *name
)
130 struct options_entry
*o
;
132 if ((o
= options_find(oo
, name
)) == NULL
)
133 fatalx("missing option");
134 if (o
->type
!= OPTIONS_STRING
)
135 fatalx("option not a string");
139 struct options_entry
*
140 options_set_number(struct options
*oo
, const char *name
, long long value
)
142 struct options_entry
*o
;
144 if ((o
= options_find1(oo
, name
)) == NULL
) {
145 o
= xmalloc(sizeof *o
);
146 o
->name
= xstrdup(name
);
147 SPLAY_INSERT(options_tree
, &oo
->tree
, o
);
148 } else if (o
->type
== OPTIONS_STRING
)
150 else if (o
->type
== OPTIONS_DATA
)
153 o
->type
= OPTIONS_NUMBER
;
159 options_get_number(struct options
*oo
, const char *name
)
161 struct options_entry
*o
;
163 if ((o
= options_find(oo
, name
)) == NULL
)
164 fatalx("missing option");
165 if (o
->type
!= OPTIONS_NUMBER
)
166 fatalx("option not a number");
170 struct options_entry
*
172 struct options
*oo
, const char *name
, void *value
, void (*freefn
)(void *))
174 struct options_entry
*o
;
176 if ((o
= options_find1(oo
, name
)) == NULL
) {
177 o
= xmalloc(sizeof *o
);
178 o
->name
= xstrdup(name
);
179 SPLAY_INSERT(options_tree
, &oo
->tree
, o
);
180 } else if (o
->type
== OPTIONS_STRING
)
182 else if (o
->type
== OPTIONS_DATA
)
185 o
->type
= OPTIONS_DATA
;
192 options_get_data(struct options
*oo
, const char *name
)
194 struct options_entry
*o
;
196 if ((o
= options_find(oo
, name
)) == NULL
)
197 fatalx("missing option");
198 if (o
->type
!= OPTIONS_DATA
)
199 fatalx("option not data");