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>
28 * Option handling; each option has a name, type and value and is stored in
32 RB_GENERATE(options_tree
, options_entry
, entry
, options_cmp
);
35 options_cmp(struct options_entry
*o1
, struct options_entry
*o2
)
37 return (strcmp(o1
->name
, o2
->name
));
41 options_init(struct options
*oo
, struct options
*parent
)
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
);
56 if (o
->type
== OPTIONS_STRING
)
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
);
82 o
= RB_FIND(options_tree
, &oo
->tree
, &p
);
88 options_remove(struct options
*oo
, const char *name
)
90 struct options_entry
*o
;
92 if ((o
= options_find1(oo
, name
)) == NULL
)
95 RB_REMOVE(options_tree
, &oo
->tree
, o
);
97 if (o
->type
== OPTIONS_STRING
)
102 struct options_entry
*printflike3
103 options_set_string(struct options
*oo
, const char *name
, const char *fmt
, ...)
105 struct options_entry
*o
;
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
)
116 o
->type
= OPTIONS_STRING
;
117 xvasprintf(&o
->str
, fmt
, ap
);
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");
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
)
146 o
->type
= OPTIONS_NUMBER
;
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");