From cca69a81c514416a4640edd331c9f2ad095f837b Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 29 Nov 2018 19:51:08 +0100 Subject: [PATCH] use config for option node --- libecoli/ecoli_node_option.c | 72 +++++++++++++++++++++++++++++++----- libecoli/ecoli_node_option.h | 2 +- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/libecoli/ecoli_node_option.c b/libecoli/ecoli_node_option.c index ab4f352..4b26001 100644 --- a/libecoli/ecoli_node_option.c +++ b/libecoli/ecoli_node_option.c @@ -17,6 +17,7 @@ #include #include #include +#include #include EC_LOG_TYPE_REGISTER(node_option); @@ -81,12 +82,49 @@ ec_node_option_get_child(const struct ec_node *gen_node, size_t i, return -1; *child = node->child; - *refs = 1; + *refs = 2; return 0; } +static const struct ec_config_schema ec_node_option_schema[] = { + { + .key = "child", + .desc = "The child node.", + .type = EC_CONFIG_TYPE_NODE, + }, + { + .type = EC_CONFIG_TYPE_NONE, + }, +}; + +static int ec_node_option_set_config(struct ec_node *gen_node, + const struct ec_config *config) +{ + struct ec_node_option *node = (struct ec_node_option *)gen_node; + const struct ec_config *child; + + child = ec_config_dict_get(config, "child"); + if (child == NULL) + goto fail; + if (ec_config_get_type(child) != EC_CONFIG_TYPE_NODE) { + errno = EINVAL; + goto fail; + } + + if (node->child != NULL) + ec_node_free(node->child); + node->child = ec_node_clone(child->node); + + return 0; + +fail: + return -1; +} + static struct ec_node_type ec_node_option_type = { .name = "option", + .schema = ec_node_option_schema, + .set_config = ec_node_option_set_config, .parse = ec_node_option_parse, .complete = ec_node_option_complete, .size = sizeof(struct ec_node_option), @@ -97,23 +135,39 @@ static struct ec_node_type ec_node_option_type = { EC_NODE_TYPE_REGISTER(ec_node_option_type); -int ec_node_option_set(struct ec_node *gen_node, struct ec_node *child) +int +ec_node_option_set_child(struct ec_node *gen_node, struct ec_node *child) { - struct ec_node_option *node = (struct ec_node_option *)gen_node; + const struct ec_config *cur_config = NULL; + struct ec_config *config = NULL; + int ret; - if (gen_node == NULL || child == NULL) { - errno = EINVAL; + if (ec_node_check_type(gen_node, &ec_node_option_type) < 0) goto fail; - } - if (ec_node_check_type(gen_node, &ec_node_option_type) < 0) + cur_config = ec_node_get_config(gen_node); + if (cur_config == NULL) + config = ec_config_dict(); + else + config = ec_config_dup(cur_config); + if (config == NULL) goto fail; - node->child = child; + if (ec_config_dict_set(config, "child", ec_config_node(child)) < 0) { + child = NULL; /* freed */ + goto fail; + } + child = NULL; /* freed */ + + ret = ec_node_set_config(gen_node, config); + config = NULL; /* freed */ + if (ret < 0) + goto fail; return 0; fail: + ec_config_free(config); ec_node_free(child); return -1; } @@ -129,7 +183,7 @@ struct ec_node *ec_node_option(const char *id, struct ec_node *child) if (gen_node == NULL) goto fail; - ec_node_option_set(gen_node, child); + ec_node_option_set_child(gen_node, child); child = NULL; return gen_node; diff --git a/libecoli/ecoli_node_option.h b/libecoli/ecoli_node_option.h index 9d67480..9f06d5f 100644 --- a/libecoli/ecoli_node_option.h +++ b/libecoli/ecoli_node_option.h @@ -8,6 +8,6 @@ #include struct ec_node *ec_node_option(const char *id, struct ec_node *node); -int ec_node_option_set(struct ec_node *gen_node, struct ec_node *child); +int ec_node_option_set_child(struct ec_node *gen_node, struct ec_node *child); #endif -- 2.39.5