diff options
Diffstat (limited to 'options.c')
-rw-r--r-- | options.c | 209 |
1 files changed, 115 insertions, 94 deletions
@@ -32,10 +32,9 @@ struct options_array_item { u_int index; - char *value; + union options_value value; RB_ENTRY(options_array_item) entry; }; -RB_HEAD(options_array, options_array_item); static int options_array_cmp(struct options_array_item *a1, struct options_array_item *a2) { @@ -48,19 +47,13 @@ options_array_cmp(struct options_array_item *a1, struct options_array_item *a2) RB_GENERATE_STATIC(options_array, options_array_item, entry, options_array_cmp); struct options_entry { - struct options *owner; + struct options *owner; - const char *name; - const struct options_table_entry *tableentry; + const char *name; + const struct options_table_entry *tableentry; + union options_value value; - union { - char *string; - long long number; - struct style style; - struct options_array array; - }; - - RB_ENTRY(options_entry) entry; + RB_ENTRY(options_entry) entry; }; struct options { @@ -83,9 +76,10 @@ static struct options_entry *options_add(struct options *, const char *); #define OPTIONS_IS_STYLE(o) \ ((o)->tableentry != NULL && \ (o)->tableentry->type == OPTIONS_TABLE_STYLE) -#define OPTIONS_IS_ARRAY(o) \ + +#define OPTIONS_IS_ARRAY(o) \ ((o)->tableentry != NULL && \ - (o)->tableentry->type == OPTIONS_TABLE_ARRAY) + ((o)->tableentry->flags & OPTIONS_TABLE_IS_ARRAY)) static int options_cmp(struct options_entry *, struct options_entry *); RB_GENERATE_STATIC(options_tree, options_entry, entry, options_cmp); @@ -109,6 +103,56 @@ options_parent_table_entry(struct options *oo, const char *s) return (o->tableentry); } +static void +options_value_free(struct options_entry *o, union options_value *ov) +{ + if (OPTIONS_IS_STRING(o)) + free(ov->string); +} + +static const char * +options_value_tostring(struct options_entry *o, union options_value *ov, + int numeric) +{ + static char s[1024]; + const char *tmp; + + if (OPTIONS_IS_STYLE(o)) + return (style_tostring(&ov->style)); + if (OPTIONS_IS_NUMBER(o)) { + tmp = NULL; + switch (o->tableentry->type) { + case OPTIONS_TABLE_NUMBER: + xsnprintf(s, sizeof s, "%lld", ov->number); + break; + case OPTIONS_TABLE_KEY: + tmp = key_string_lookup_key(ov->number); + break; + case OPTIONS_TABLE_COLOUR: + tmp = colour_tostring(ov->number); + break; + case OPTIONS_TABLE_FLAG: + if (numeric) + xsnprintf(s, sizeof s, "%lld", ov->number); + else + tmp = (ov->number ? "on" : "off"); + break; + case OPTIONS_TABLE_CHOICE: + tmp = o->tableentry->choices[ov->number]; + break; + case OPTIONS_TABLE_STRING: + case OPTIONS_TABLE_STYLE: + break; + } + if (tmp != NULL) + xsnprintf(s, sizeof s, "%s", tmp); + return (s); + } + if (OPTIONS_IS_STRING(o)) + return (ov->string); + return (""); +} + struct options * options_create(struct options *parent) { @@ -174,8 +218,11 @@ options_empty(struct options *oo, const struct options_table_entry *oe) o = options_add(oo, oe->name); o->tableentry = oe; - if (oe->type == OPTIONS_TABLE_ARRAY) - RB_INIT(&o->array); + if (oe->flags & OPTIONS_TABLE_IS_ARRAY) { + if (oe->type != OPTIONS_TABLE_STRING) + fatalx("arrays can only be strings"); + RB_INIT(&o->value.array); + } return (o); } @@ -183,23 +230,34 @@ options_empty(struct options *oo, const struct options_table_entry *oe) struct options_entry * options_default(struct options *oo, const struct options_table_entry *oe) { - struct options_entry *o; - u_int i; + struct options_entry *o; + union options_value *ov; + u_int i; o = options_empty(oo, oe); - if (oe->type == OPTIONS_TABLE_ARRAY) { + ov = &o->value; + + if (oe->flags & OPTIONS_TABLE_IS_ARRAY) { if (oe->default_arr != NULL) { for (i = 0; oe->default_arr[i] != NULL; i++) options_array_set(o, i, oe->default_arr[i], 0); } else options_array_assign(o, oe->default_str); - } else if (oe->type == OPTIONS_TABLE_STRING) - o->string = xstrdup(oe->default_str); - else if (oe->type == OPTIONS_TABLE_STYLE) { - style_set(&o->style, &grid_default_cell); - style_parse(&o->style, &grid_default_cell, oe->default_str); - } else - o->number = oe->default_num; + return (o); + } + + switch (oe->type) { + case OPTIONS_TABLE_STRING: + ov->string = xstrdup(oe->default_str); + break; + case OPTIONS_TABLE_STYLE: + style_set(&ov->style, &grid_default_cell); + style_parse(&ov->style, &grid_default_cell, oe->default_str); + break; + default: + ov->number = oe->default_num; + break; + } return (o); } @@ -225,11 +283,10 @@ options_remove(struct options_entry *o) { struct options *oo = o->owner; - if (OPTIONS_IS_STRING(o)) - free(o->string); - else if (OPTIONS_IS_ARRAY(o)) + if (OPTIONS_IS_ARRAY(o)) options_array_clear(o); - + else + options_value_free(o, &o->value); RB_REMOVE(options_tree, &oo->tree, o); free(o); } @@ -252,14 +309,14 @@ options_array_item(struct options_entry *o, u_int idx) struct options_array_item a; a.index = idx; - return (RB_FIND(options_array, &o->array, &a)); + return (RB_FIND(options_array, &o->value.array, &a)); } static void options_array_free(struct options_entry *o, struct options_array_item *a) { - free(a->value); - RB_REMOVE(options_array, &o->array, a); + options_value_free(o, &a->value); + RB_REMOVE(options_array, &o->value.array, a); free(a); } @@ -271,11 +328,11 @@ options_array_clear(struct options_entry *o) if (!OPTIONS_IS_ARRAY(o)) return; - RB_FOREACH_SAFE(a, options_array, &o->array, a1) + RB_FOREACH_SAFE(a, options_array, &o->value.array, a1) options_array_free(o, a); } -const char * +union options_value * options_array_get(struct options_entry *o, u_int idx) { struct options_array_item *a; @@ -285,7 +342,7 @@ options_array_get(struct options_entry *o, u_int idx) a = options_array_item(o, idx); if (a == NULL) return (NULL); - return (a->value); + return (&a->value); } int @@ -308,15 +365,15 @@ options_array_set(struct options_entry *o, u_int idx, const char *value, if (a == NULL) { a = xcalloc(1, sizeof *a); a->index = idx; - a->value = xstrdup(value); - RB_INSERT(options_array, &o->array, a); + a->value.string = xstrdup(value); + RB_INSERT(options_array, &o->value.array, a); } else { - free(a->value); + options_value_free(o, &a->value); if (a != NULL && append) - xasprintf(&new, "%s%s", a->value, value); + xasprintf(&new, "%s%s", a->value.string, value); else new = xstrdup(value); - a->value = new; + a->value.string = new; } return (0); @@ -353,13 +410,13 @@ options_array_first(struct options_entry *o) { if (!OPTIONS_IS_ARRAY(o)) return (NULL); - return (RB_MIN(options_array, &o->array)); + return (RB_MIN(options_array, &o->value.array)); } struct options_array_item * options_array_next(struct options_array_item *a) { - return (RB_NEXT(options_array, &o->array, a)); + return (RB_NEXT(options_array, &o->value.array, a)); } u_int @@ -368,10 +425,10 @@ options_array_item_index(struct options_array_item *a) return (a->index); } -const char * +union options_value * options_array_item_value(struct options_array_item *a) { - return (a->value); + return (&a->value); } int @@ -383,14 +440,12 @@ options_isarray(struct options_entry *o) int options_isstring(struct options_entry *o) { - return (OPTIONS_IS_STRING(o) || OPTIONS_IS_ARRAY(o)); + return (OPTIONS_IS_STRING(o)); } const char * options_tostring(struct options_entry *o, int idx, int numeric) { - static char s[1024]; - const char *tmp; struct options_array_item *a; if (OPTIONS_IS_ARRAY(o)) { @@ -399,43 +454,9 @@ options_tostring(struct options_entry *o, int idx, int numeric) a = options_array_item(o, idx); if (a == NULL) return (""); - return (a->value); - } - if (OPTIONS_IS_STYLE(o)) - return (style_tostring(&o->style)); - if (OPTIONS_IS_NUMBER(o)) { - tmp = NULL; - switch (o->tableentry->type) { - case OPTIONS_TABLE_NUMBER: - xsnprintf(s, sizeof s, "%lld", o->number); - break; - case OPTIONS_TABLE_KEY: - tmp = key_string_lookup_key(o->number); - break; - case OPTIONS_TABLE_COLOUR: - tmp = colour_tostring(o->number); - break; - case OPTIONS_TABLE_FLAG: - if (numeric) - xsnprintf(s, sizeof s, "%lld", o->number); - else - tmp = (o->number ? "on" : "off"); - break; - case OPTIONS_TABLE_CHOICE: - tmp = o->tableentry->choices[o->number]; - break; - case OPTIONS_TABLE_STRING: - case OPTIONS_TABLE_STYLE: - case OPTIONS_TABLE_ARRAY: - break; - } - if (tmp != NULL) - xsnprintf(s, sizeof s, "%s", tmp); - return (s); + return (options_value_tostring(o, &a->value, numeric)); } - if (OPTIONS_IS_STRING(o)) - return (o->string); - return (NULL); + return (options_value_tostring(o, &o->value, numeric)); } char * @@ -549,7 +570,7 @@ options_get_string(struct options *oo, const char *name) fatalx("missing option %s", name); if (!OPTIONS_IS_STRING(o)) fatalx("option %s is not a string", name); - return (o->string); + return (o->value.string); } long long @@ -562,7 +583,7 @@ options_get_number(struct options *oo, const char *name) fatalx("missing option %s", name); if (!OPTIONS_IS_NUMBER(o)) fatalx("option %s is not a number", name); - return (o->number); + return (o->value.number); } struct style * @@ -575,7 +596,7 @@ options_get_style(struct options *oo, const char *name) fatalx("missing option %s", name); if (!OPTIONS_IS_STYLE(o)) fatalx("option %s is not a style", name); - return (&o->style); + return (&o->value.style); } struct options_entry * @@ -592,7 +613,7 @@ options_set_string(struct options *oo, const char *name, int append, o = options_get_only(oo, name); if (o != NULL && append && OPTIONS_IS_STRING(o)) { - xasprintf(&value, "%s%s", o->string, s); + xasprintf(&value, "%s%s", o->value.string, s); free(s); } else value = s; @@ -606,8 +627,8 @@ options_set_string(struct options *oo, const char *name, int append, if (!OPTIONS_IS_STRING(o)) fatalx("option %s is not a string", name); - free(o->string); - o->string = value; + free(o->value.string); + o->value.string = value; return (o); } @@ -628,7 +649,7 @@ options_set_number(struct options *oo, const char *name, long long value) if (!OPTIONS_IS_NUMBER(o)) fatalx("option %s is not a number", name); - o->number = value; + o->value.number = value; return (o); } @@ -644,7 +665,7 @@ options_set_style(struct options *oo, const char *name, int append, o = options_get_only(oo, name); if (o != NULL && append && OPTIONS_IS_STYLE(o)) - style_copy(&sy, &o->style); + style_copy(&sy, &o->value.style); else style_set(&sy, &grid_default_cell); if (style_parse(&sy, &grid_default_cell, value) == -1) @@ -657,7 +678,7 @@ options_set_style(struct options *oo, const char *name, int append, if (!OPTIONS_IS_STYLE(o)) fatalx("option %s is not a style", name); - style_copy(&o->style, &sy); + style_copy(&o->value.style, &sy); return (o); } |