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
= __UNCONST(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
= __UNCONST(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 memcpy(&o
->style
, &grid_default_cell
, sizeof o
->style
);
113 } else if (o
->type
== OPTIONS_STRING
)
117 o
->type
= OPTIONS_STRING
;
118 xvasprintf(&o
->str
, fmt
, ap
);
124 options_get_string(struct options
*oo
, const char *name
)
126 struct options_entry
*o
;
128 if ((o
= options_find(oo
, name
)) == NULL
)
129 fatalx("missing option");
130 if (o
->type
!= OPTIONS_STRING
)
131 fatalx("option not a string");
135 struct options_entry
*
136 options_set_number(struct options
*oo
, const char *name
, long long value
)
138 struct options_entry
*o
;
140 if ((o
= options_find1(oo
, name
)) == NULL
) {
141 o
= xmalloc(sizeof *o
);
142 o
->name
= xstrdup(name
);
143 RB_INSERT(options_tree
, &oo
->tree
, o
);
144 memcpy(&o
->style
, &grid_default_cell
, sizeof o
->style
);
145 } else if (o
->type
== OPTIONS_STRING
)
148 o
->type
= OPTIONS_NUMBER
;
154 options_get_number(struct options
*oo
, const char *name
)
156 struct options_entry
*o
;
158 if ((o
= options_find(oo
, name
)) == NULL
)
159 fatalx("missing option");
160 if (o
->type
!= OPTIONS_NUMBER
)
161 fatalx("option not a number");
165 struct options_entry
*
166 options_set_style(struct options
*oo
, const char *name
, const char *value
,
169 struct options_entry
*o
;
171 if ((o
= options_find1(oo
, name
)) == NULL
) {
172 o
= xmalloc(sizeof *o
);
173 o
->name
= xstrdup(name
);
174 RB_INSERT(options_tree
, &oo
->tree
, o
);
175 } else if (o
->type
== OPTIONS_STRING
)
179 memcpy(&o
->style
, &grid_default_cell
, sizeof o
->style
);
181 o
->type
= OPTIONS_STYLE
;
182 if (style_parse(&grid_default_cell
, &o
->style
, value
) == -1)
188 options_get_style(struct options
*oo
, const char *name
)
190 struct options_entry
*o
;
192 if ((o
= options_find(oo
, name
)) == NULL
)
193 fatalx("missing option");
194 if (o
->type
!= OPTIONS_STYLE
)
195 fatalx("option not a style");