aboutsummaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-05-02 21:10:39 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2015-05-02 21:10:39 +0200
commitf7c08fdace3a632f60b225cd2146ee806401203c (patch)
tree5f1e7fb202626b083eaee8adbb71b552af484d2a /common.c
parent5a6b12245b10e5ca3acb4add42198ccecb5a492c (diff)
downloadxK-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
Diffstat (limited to 'common.c')
-rw-r--r--common.c104
1 files changed, 55 insertions, 49 deletions
diff --git a/common.c b/common.c
index 6d73130..8d8dcf6 100644
--- a/common.c
+++ b/common.c
@@ -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);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -