X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fecoli_node_cmd.c;h=428f453e5def5fb7845d92573cf2cbc3140110ba;hb=15718f19cbf3868bf6fba79f4e26b5254c57873e;hp=070bb028576484d55c5c93feae66c59efd21ce0d;hpb=a4ccdcb24d718ab72bde5eb7233a1d74566a846c;p=protos%2Flibecoli.git diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index 070bb02..428f453 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -411,11 +412,14 @@ ec_node_cmd_complete(const struct ec_node *gen_node, static void ec_node_cmd_free_priv(struct ec_node *gen_node) { struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; + size_t i; ec_free(node->cmd_str); - ec_node_free(node->cmd); ec_node_free(node->expr); ec_node_free(node->parser); + ec_node_free(node->cmd); + for (i = 0; i < node->len; i++) + ec_node_free(node->table[i]); ec_free(node->table); } @@ -424,6 +428,9 @@ static const struct ec_config_schema ec_node_cmd_subschema[] = { .desc = "A child node whose id is referenced in the expression.", .type = EC_CONFIG_TYPE_NODE, }, + { + .type = EC_CONFIG_TYPE_NONE, + }, }; static const struct ec_config_schema ec_node_cmd_schema[] = { @@ -442,7 +449,9 @@ static const struct ec_config_schema ec_node_cmd_schema[] = { .desc = "The list of children nodes.", .type = EC_CONFIG_TYPE_LIST, .subschema = ec_node_cmd_subschema, - .subschema_len = EC_COUNT_OF(ec_node_cmd_subschema), + }, + { + .type = EC_CONFIG_TYPE_NONE, }, }; @@ -450,11 +459,11 @@ static int ec_node_cmd_set_config(struct ec_node *gen_node, const struct ec_config *config) { struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; - const struct ec_config *expr = NULL, *children = NULL, *child; + const struct ec_config *expr = NULL; struct ec_node *cmd = NULL; struct ec_node **table = NULL; char *cmd_str = NULL; - size_t n; + size_t len = 0, i; /* retrieve config locally */ expr = ec_config_dict_get(config, "expr"); @@ -463,68 +472,76 @@ static int ec_node_cmd_set_config(struct ec_node *gen_node, goto fail; } - children = ec_config_dict_get(config, "children"); - if (children == NULL) { - errno = EINVAL; + table = ec_node_config_node_list_to_table( + ec_config_dict_get(config, "children"), &len); + if (table == NULL) goto fail; - } cmd_str = ec_strdup(expr->string); if (cmd_str == NULL) goto fail; - n = 0; - TAILQ_FOREACH(child, &children->list, next) - n++; - - table = ec_malloc(n * sizeof(*table)); - if (table == NULL) - goto fail; - - n = 0; - TAILQ_FOREACH(child, &children->list, next) { - table[n] = child->node; - n++; - } - /* parse expression to build the cmd child node */ - cmd = ec_node_cmd_build(node, cmd_str, table, n); + cmd = ec_node_cmd_build(node, cmd_str, table, len); if (cmd == NULL) goto fail; - gen_node->n_children = 0; /* XXX */ - TAILQ_FOREACH(child, &children->list, next) { - /* XXX if it fails... too late */ - if (ec_node_add_child(gen_node, child->node) < 0) - goto fail; - } - + /* ok, store the config */ ec_node_free(node->cmd); node->cmd = cmd; ec_free(node->cmd_str); node->cmd_str = cmd_str; + for (i = 0; i < node->len; i++) + ec_node_free(node->table[i]); ec_free(node->table); node->table = table; - node->len = n; + node->len = len; return 0; fail: + for (i = 0; i < len; i++) + ec_node_free(table[i]); ec_free(table); ec_free(cmd_str); ec_node_free(cmd); return -1; } +static size_t +ec_node_cmd_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; + + if (node->cmd == NULL) + return 0; + return 1; +} + +static int +ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i, + struct ec_node **child, unsigned int *refs) +{ + struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; + + if (i > 0) + return -1; + + *child = node->cmd; + *refs = 1; + return 0; +} + static struct ec_node_type ec_node_cmd_type = { .name = "cmd", .schema = ec_node_cmd_schema, - .schema_len = EC_COUNT_OF(ec_node_cmd_schema), .set_config = ec_node_cmd_set_config, .parse = ec_node_cmd_parse, .complete = ec_node_cmd_complete, .size = sizeof(struct ec_node_cmd), .free_priv = ec_node_cmd_free_priv, + .get_children_count = ec_node_cmd_get_children_count, + .get_child = ec_node_cmd_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_cmd_type); @@ -534,43 +551,35 @@ struct ec_node *__ec_node_cmd(const char *id, const char *cmd, ...) struct ec_config *config = NULL, *children = NULL; struct ec_node *gen_node = NULL; struct ec_node_cmd *node = NULL; - struct ec_node *child; va_list ap; + int ret; + /* this block must stay first, it frees the nodes on error */ va_start(ap, cmd); - child = va_arg(ap, struct ec_node *); + children = ec_node_config_node_list_from_vargs(ap); + va_end(ap); + if (children == NULL) + goto fail; - gen_node = __ec_node(&ec_node_cmd_type, id); + gen_node = ec_node_from_type(&ec_node_cmd_type, id); if (gen_node == NULL) - goto fail_free_children; + goto fail; node = (struct ec_node_cmd *)gen_node; node->expr = ec_node_cmd_build_expr(); if (node->expr == NULL) - goto fail_free_children; + goto fail; node->parser = ec_node_cmd_build_parser(node->expr); if (node->parser == NULL) - goto fail_free_children; + goto fail; config = ec_config_dict(); if (config == NULL) - goto fail_free_children; + goto fail; if (ec_config_dict_set(config, "expr", ec_config_string(cmd)) < 0) - goto fail_free_children; - - children = ec_config_list(); - if (children == NULL) - goto fail_free_children; - - for (; child != EC_NODE_ENDLIST; child = va_arg(ap, struct ec_node *)) { - if (child == NULL) - goto fail_free_children; - - if (ec_config_list_add(children, ec_config_node(child)) < 0) - goto fail_free_children; - } + goto fail; if (ec_config_dict_set(config, "children", children) < 0) { children = NULL; /* freed */ @@ -578,20 +587,17 @@ struct ec_node *__ec_node_cmd(const char *id, const char *cmd, ...) } children = NULL; - if (ec_node_set_config(gen_node, config) < 0) + ret = ec_node_set_config(gen_node, config); + config = NULL; /* freed */ + if (ret < 0) goto fail; - va_end(ap); - return gen_node; -fail_free_children: - for (; child != EC_NODE_ENDLIST; child = va_arg(ap, struct ec_node *)) - ec_node_free(child); fail: ec_node_free(gen_node); /* will also free added children */ + ec_config_free(children); ec_config_free(config); - va_end(ap); return NULL; } @@ -607,9 +613,6 @@ static int ec_node_cmd_testcase(void) ec_node_int("x", 0, 10, 10), ec_node_int("y", 20, 30, 10) ); - ec_node_free(node); - return 0; - if (node == NULL) { EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1;