X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fecoli_node_cmd.c;h=b08db0b1ca46019e02a6d4228f92a252617e6a35;hb=51028779e0a8772091aec5ab96bcf2519cf2f1ad;hp=d298c14712df04a11e93df417400775eed37b7e7;hpb=eaaf443bad651bd0b01f0bde3668a0f7d7f2dff0;p=protos%2Flibecoli.git diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index d298c14..b08db0b 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -413,11 +414,10 @@ 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; - /* node->cmd is freed automatically, because it is returned - * by ec_node_cmd_get_child() */ ec_free(node->cmd_str); 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); @@ -454,11 +454,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, i; + size_t len = 0, i; /* retrieve config locally */ expr = ec_config_dict_get(config, "expr"); @@ -467,35 +467,21 @@ 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] = ec_node_clone(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; + /* ok, store the config */ ec_node_free(node->cmd); node->cmd = cmd; ec_free(node->cmd_str); @@ -504,15 +490,13 @@ static int ec_node_cmd_set_config(struct ec_node *gen_node, ec_node_free(node->table[i]); ec_free(node->table); node->table = table; - node->len = n; + node->len = len; return 0; fail: - if (table != NULL) { - for (i = 0; i < n; i++) - ec_node_free(table[i]); - } + for (i = 0; i < len; i++) + ec_node_free(table[i]); ec_free(table); ec_free(cmd_str); ec_node_free(cmd); @@ -529,15 +513,18 @@ ec_node_cmd_get_children_count(const struct ec_node *gen_node) return 1; } -static struct ec_node * -ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i) +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 NULL; + return -1; - return node->cmd; + *child = node->cmd; + *refs = 1; + return 0; } static struct ec_node_type ec_node_cmd_type = { @@ -560,44 +547,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); 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 */ @@ -610,18 +588,12 @@ struct ec_node *__ec_node_cmd(const char *id, const char *cmd, ...) 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; }