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 RB_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
)
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
);
55 if (o
->type
== OPTIONS_STRING
)
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
);
81 o
= RB_FIND(options_tree
, &oo
->tree
, &p
);
87 options_remove(struct options
*oo
, const char *name
)
89 struct options_entry
*o
;
91 if ((o
= options_find1(oo
, name
)) == NULL
)
94 RB_REMOVE(options_tree
, &oo
->tree
, o
);
96 if (o
->type
== OPTIONS_STRING
)
101 struct options_entry
*printflike3
102 options_set_string(struct options
*oo
, const char *name
, const char *fmt
, ...)
104 struct options_entry
*o
;
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
)
115 o
->type
= OPTIONS_STRING
;
116 xvasprintf(&o
->str
, fmt
, ap
);
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");
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
)
145 o
->type
= OPTIONS_NUMBER
;
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");