diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2015-05-02 21:10:39 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-05-02 21:10:39 +0200 |
commit | f7c08fdace3a632f60b225cd2146ee806401203c (patch) | |
tree | 5f1e7fb202626b083eaee8adbb71b552af484d2a | |
parent | 5a6b12245b10e5ca3acb4add42198ccecb5a492c (diff) | |
download | xK-f7c08fdace3a632f60b225cd2146ee806401203c.tar.gz xK-f7c08fdace3a632f60b225cd2146ee806401203c.tar.xz xK-f7c08fdace3a632f60b225cd2146ee806401203c.zip |
config: simplify and mostly finish
What still sucks:
- "on_change" callbacks have little information;
maybe we could add a user-defined field to the schema;
also config_schema_apply_to_object() might assign "user_data"
- no idea how to generate the default configuration file
-rw-r--r-- | common.c | 104 |
1 files changed, 55 insertions, 49 deletions
@@ -553,14 +553,11 @@ struct config_schema const char *default_; ///< Default as a configuration snippet /// Check if the new value can be accepted. - /// If this is not defined, only "type" and having a default is considered. - bool (*validate) (struct config_item_ *, const struct config_item_ *); + /// In addition to this, "type" and having a default is considered. + bool (*validate) (const struct config_item_ *, struct error **e); - /// The value has changed. Only appliable to objects. + /// The value has changed void (*on_changed) (struct config_item_ *); - - /// Free any resources located in "item->user_data" - void (*on_destroy) (struct config_item_ *item); }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -608,9 +605,6 @@ config_item_free (struct config_item_ *self) static void config_item_destroy (struct config_item_ *self) { - if (self->schema && self->schema->on_destroy) - self->schema->on_destroy (self); - config_item_free (self); free (self); } @@ -703,16 +697,18 @@ config_schema_accepts_type static bool config_item_validate_by_schema (struct config_item_ *self, - struct config_item_ *source, struct config_schema *schema, struct error **e) + struct config_schema *schema, struct error **e) { - // Otherwise we check the type and validate the item - if (!config_schema_accepts_type (schema, source->type)) + struct error *error = NULL; + if (!config_schema_accepts_type (schema, self->type)) error_set (e, "invalid type of value, expected: %s%s", config_item_type_name (schema->type), !schema->default_ ? " (or null)" : ""); - else if (schema->validate && !schema->validate (self, source)) - // XXX: perhaps "schema->validate" could provide a message for us? - error_set (e, "invalid value"); + else if (schema->validate && !schema->validate (self, &error)) + { + error_set (e, "%s: %s", "invalid value", error->message); + error_free (error); + } else return true; return false; @@ -730,7 +726,7 @@ config_item_set_from (struct config_item_ *self, struct config_item_ *source, return true; } - if (!config_item_validate_by_schema (self, source, schema, e)) + if (!config_item_validate_by_schema (source, schema, e)) return false; // Make sure the string subtype fits the schema @@ -1415,48 +1411,58 @@ end: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// XXX: this thing is ugly in concept + static void -config_schema_apply_to_object - (struct config_schema *schema_array, struct config_item_ *object) +config_schema_fix_value + (struct config_schema *schema, struct config_item_ *object) { - hard_assert (object->type == CONFIG_ITEM_OBJECT); - while (schema_array->name) - { - struct config_schema *schema = schema_array++; - struct config_item_ *item = - str_map_find (&object->value.object, schema->name); + struct config_item_ *item = + str_map_find (&object->value.object, schema->name); - bool make_new = true; - if (item) + bool replace = true; + if (item) + { + struct error *e = NULL; + replace = !config_item_validate_by_schema (item, schema, &e); + if (e) { - struct error *e = NULL; - make_new = !config_item_validate_by_schema - (NULL, item, schema, &e); - if (e) - { - print_error ("resetting configuration item " - "`%s' to defaults: %s", schema->name, e->message); - error_free (e); - } + print_error ("resetting configuration item " + "`%s' to default: %s", schema->name, e->message); + error_free (e); } + } - if (make_new) - { - struct error *e = NULL; - struct config_item_ *default_ = config_item_parse - (schema->default_, strlen (schema->default_), true, &e); - if (e) - exit_fatal ("invalid default: %s", e->message); - - config_item_move (item, default_); - } + if (replace) + { + struct error *e = NULL; + struct config_item_ *default_ = config_item_parse + (schema->default_, strlen (schema->default_), true, &e); + if (e || !config_item_validate_by_schema (default_, schema, &e)) + exit_fatal ("invalid default for `%s': %s", + schema->name, e->message); + + config_item_move (item, default_); + str_map_set (&object->value.object, schema->name, default_); + } + // Make sure the string subtype fits the schema + if (config_item_type_is_string (item->type) + && config_item_type_is_string (schema->type)) item->type = schema->type; - item->schema = schema; - if (schema->on_changed) - schema->on_changed (item); - } + item->schema = schema; + if (schema->on_changed) + schema->on_changed (item); +} + +static void +config_schema_apply_to_object + (struct config_schema *schema_array, struct config_item_ *object) +{ + hard_assert (object->type == CONFIG_ITEM_OBJECT); + while (schema_array->name) + config_schema_fix_value (schema_array++, object); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |