From f4ec52ffc80b673a0f7e848c568359abf4f3bc47 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 5 Jul 2018 21:12:54 +0200 Subject: [PATCH] replace generic child table by a node ops --- lib/ecoli_node.c | 68 ++++++----------------------------------- lib/ecoli_node.h | 7 +++-- lib/ecoli_node_cmd.c | 27 +++++++++++----- lib/ecoli_node_many.c | 24 ++++++++++++++- lib/ecoli_node_once.c | 26 ++++++++++++++-- lib/ecoli_node_option.c | 26 ++++++++++++++-- lib/ecoli_node_or.c | 24 ++++++++++++--- lib/ecoli_node_seq.c | 24 ++++++++++++--- lib/ecoli_node_subset.c | 24 ++++++++++++--- lib/todo.txt | 5 +++ 10 files changed, 168 insertions(+), 87 deletions(-) diff --git a/lib/ecoli_node.c b/lib/ecoli_node.c index d936302..9a21d63 100644 --- a/lib/ecoli_node.c +++ b/lib/ecoli_node.c @@ -135,7 +135,6 @@ void ec_node_free(struct ec_node *node) if (node->type != NULL && node->type->free_priv != NULL) node->type->free_priv(node); - ec_free(node->children); ec_free(node->id); ec_free(node->desc); ec_keyval_free(node->attrs); @@ -152,43 +151,17 @@ struct ec_node *ec_node_clone(struct ec_node *node) size_t ec_node_get_children_count(const struct ec_node *node) { - return node->n_children; + if (node->type->get_children_count == NULL) + return 0; + return node->type->get_children_count(node); } struct ec_node * ec_node_get_child(const struct ec_node *node, size_t i) { - if (i >= ec_node_get_children_count(node)) + if (node->type->get_child == NULL) return NULL; - return node->children[i]; -} - -int ec_node_add_child(struct ec_node *node, struct ec_node *child) -{ - struct ec_node **children = NULL; - size_t n; - - if (node == NULL || child == NULL) { - errno = EINVAL; - goto fail; - } - - n = node->n_children; - children = ec_realloc(node->children, - (n + 1) * sizeof(child)); - if (children == NULL) - goto fail; - - children[n] = child; - node->children = children; - node->n_children = n + 1; - - return 0; - -fail: - ec_free(children); - assert(errno != 0); - return -1; + return node->type->get_child(node, i); } int @@ -221,29 +194,6 @@ const struct ec_config *ec_node_get_config(struct ec_node *node) return node->config; } -#if 0 /* later */ -int ec_node_del_child(struct ec_node *node, struct ec_node *child) -{ - size_t i, n; - - if (node == NULL || child == NULL) - goto fail; - - n = node->n_children; - for (i = 0; i < n; i++) { - if (node->children[i] != child) - continue; - memcpy(&node->children[i], &node->children[i+1], - (n - i - 1) * sizeof(child)); - return 0; - } - -fail: - errno = EINVAL; - return -1; -} -#endif - struct ec_node *ec_node_find(struct ec_node *node, const char *id) { struct ec_node *child, *ret; @@ -253,9 +203,9 @@ struct ec_node *ec_node_find(struct ec_node *node, const char *id) if (id != NULL && node_id != NULL && !strcmp(node_id, id)) return node; - n = node->n_children; + n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = node->children[i]; + child = ec_node_get_child(node, i); ret = ec_node_find(child, id); if (ret != NULL) return ret; @@ -291,9 +241,9 @@ static void __ec_node_dump(FILE *out, fprintf(out, "%*s" "type=%s id=%s %p\n", (int)indent * 4, "", typename, id, node); - n = node->n_children; + n = ec_node_get_children_count(node); for (i = 0; i < n; i++) { - child = node->children[i]; + child = ec_node_get_child(node, i); __ec_node_dump(out, child, indent + 1); } } diff --git a/lib/ecoli_node.h b/lib/ecoli_node.h index 63178f7..6fede59 100644 --- a/lib/ecoli_node.h +++ b/lib/ecoli_node.h @@ -82,6 +82,9 @@ typedef int (*ec_node_complete_t)(const struct ec_node *node, typedef const char * (*ec_node_desc_t)(const struct ec_node *); typedef int (*ec_node_init_priv_t)(struct ec_node *); typedef void (*ec_node_free_priv_t)(struct ec_node *); +typedef size_t (*ec_node_get_children_count_t)(const struct ec_node *); +typedef struct ec_node * (*ec_node_get_child_t)(const struct ec_node *, + size_t i); /** * A structure describing a node type. @@ -99,6 +102,8 @@ struct ec_node_type { size_t size; ec_node_init_priv_t init_priv; ec_node_free_priv_t free_priv; + ec_node_get_children_count_t get_children_count; + ec_node_get_child_t get_child; }; /** @@ -134,8 +139,6 @@ struct ec_node { char *desc; struct ec_keyval *attrs; unsigned int refcnt; - struct ec_node **children; /* array of children */ - size_t n_children; /* number of children in the array */ }; /* create a new node when the type is known, typically called from the node diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index 070bb02..bd2f767 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -492,13 +492,6 @@ static int ec_node_cmd_set_config(struct ec_node *gen_node, 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; - } - ec_node_free(node->cmd); node->cmd = cmd; ec_free(node->cmd_str); @@ -516,6 +509,24 @@ fail: 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; + return node->len; +} + +static struct ec_node * +ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node; + + if (i >= node->len) + return NULL; + + return node->table[i]; +} + static struct ec_node_type ec_node_cmd_type = { .name = "cmd", .schema = ec_node_cmd_schema, @@ -525,6 +536,8 @@ static struct ec_node_type ec_node_cmd_type = { .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); diff --git a/lib/ecoli_node_many.c b/lib/ecoli_node_many.c index 60256ef..6a5f676 100644 --- a/lib/ecoli_node_many.c +++ b/lib/ecoli_node_many.c @@ -161,12 +161,35 @@ static void ec_node_many_free_priv(struct ec_node *gen_node) ec_node_free(node->child); } +static size_t +ec_node_many_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_many *node = (struct ec_node_many *)gen_node; + + if (node->child) + return 1; + return 0; +} + +static struct ec_node * +ec_node_many_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_many *node = (struct ec_node_many *)gen_node; + + if (i >= 1) + return NULL; + + return node->child; +} + static struct ec_node_type ec_node_many_type = { .name = "many", .parse = ec_node_many_parse, .complete = ec_node_many_complete, .size = sizeof(struct ec_node_many), .free_priv = ec_node_many_free_priv, + .get_children_count = ec_node_many_get_children_count, + .get_child = ec_node_many_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_many_type); @@ -179,7 +202,6 @@ struct ec_node *ec_node_many(const char *id, struct ec_node *child, if (child == NULL) return NULL; - // XXX ec_node_add_child() node = (struct ec_node_many *)__ec_node(&ec_node_many_type, id); if (node == NULL) { ec_node_free(child); diff --git a/lib/ecoli_node_once.c b/lib/ecoli_node_once.c index 8218a29..5248d13 100644 --- a/lib/ecoli_node_once.c +++ b/lib/ecoli_node_once.c @@ -95,12 +95,35 @@ static void ec_node_once_free_priv(struct ec_node *gen_node) ec_node_free(node->child); } +static size_t +ec_node_once_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_once *node = (struct ec_node_once *)gen_node; + + if (node->child) + return 1; + return 0; +} + +static struct ec_node * +ec_node_once_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_once *node = (struct ec_node_once *)gen_node; + + if (i >= 1) + return NULL; + + return node->child; +} + static struct ec_node_type ec_node_once_type = { .name = "once", .parse = ec_node_once_parse, .complete = ec_node_once_complete, .size = sizeof(struct ec_node_once), .free_priv = ec_node_once_free_priv, + .get_children_count = ec_node_once_get_children_count, + .get_child = ec_node_once_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_once_type); @@ -117,9 +140,6 @@ int ec_node_once_set(struct ec_node *gen_node, struct ec_node *child) if (ec_node_check_type(gen_node, &ec_node_once_type) < 0) goto fail; - if (ec_node_add_child(gen_node, child) < 0) - goto fail; - node->child = child; return 0; diff --git a/lib/ecoli_node_option.c b/lib/ecoli_node_option.c index 7509251..befbb2e 100644 --- a/lib/ecoli_node_option.c +++ b/lib/ecoli_node_option.c @@ -61,12 +61,35 @@ static void ec_node_option_free_priv(struct ec_node *gen_node) ec_node_free(node->child); } +static size_t +ec_node_option_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_option *node = (struct ec_node_option *)gen_node; + + if (node->child) + return 1; + return 0; +} + +static struct ec_node * +ec_node_option_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_option *node = (struct ec_node_option *)gen_node; + + if (i >= 1) + return NULL; + + return node->child; +} + static struct ec_node_type ec_node_option_type = { .name = "option", .parse = ec_node_option_parse, .complete = ec_node_option_complete, .size = sizeof(struct ec_node_option), .free_priv = ec_node_option_free_priv, + .get_children_count = ec_node_option_get_children_count, + .get_child = ec_node_option_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_option_type); @@ -83,9 +106,6 @@ int ec_node_option_set(struct ec_node *gen_node, struct ec_node *child) if (ec_node_check_type(gen_node, &ec_node_option_type) < 0) goto fail; - if (ec_node_add_child(gen_node, child) < 0) - goto fail; - node->child = child; return 0; diff --git a/lib/ecoli_node_or.c b/lib/ecoli_node_or.c index c72642c..ad3786e 100644 --- a/lib/ecoli_node_or.c +++ b/lib/ecoli_node_or.c @@ -75,12 +75,32 @@ static void ec_node_or_free_priv(struct ec_node *gen_node) ec_free(node->table); } +static size_t +ec_node_or_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_or *node = (struct ec_node_or *)gen_node; + return node->len; +} + +static struct ec_node * +ec_node_or_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_or *node = (struct ec_node_or *)gen_node; + + if (i >= node->len) + return NULL; + + return node->table[i]; +} + static struct ec_node_type ec_node_or_type = { .name = "or", .parse = ec_node_or_parse, .complete = ec_node_or_complete, .size = sizeof(struct ec_node_or), .free_priv = ec_node_or_free_priv, + .get_children_count = ec_node_or_get_children_count, + .get_child = ec_node_or_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_or_type); @@ -107,10 +127,6 @@ int ec_node_or_add(struct ec_node *gen_node, struct ec_node *child) goto fail; node->table = table; - - if (ec_node_add_child(gen_node, child) < 0) - goto fail; - table[node->len] = child; node->len++; diff --git a/lib/ecoli_node_seq.c b/lib/ecoli_node_seq.c index 77738ed..34512b6 100644 --- a/lib/ecoli_node_seq.c +++ b/lib/ecoli_node_seq.c @@ -164,12 +164,32 @@ static void ec_node_seq_free_priv(struct ec_node *gen_node) ec_free(node->table); } +static size_t +ec_node_seq_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_seq *node = (struct ec_node_seq *)gen_node; + return node->len; +} + +static struct ec_node * +ec_node_seq_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_seq *node = (struct ec_node_seq *)gen_node; + + if (i >= node->len) + return NULL; + + return node->table[i]; +} + static struct ec_node_type ec_node_seq_type = { .name = "seq", .parse = ec_node_seq_parse, .complete = ec_node_seq_complete, .size = sizeof(struct ec_node_seq), .free_priv = ec_node_seq_free_priv, + .get_children_count = ec_node_seq_get_children_count, + .get_child = ec_node_seq_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_seq_type); @@ -194,10 +214,6 @@ int ec_node_seq_add(struct ec_node *gen_node, struct ec_node *child) goto fail; node->table = table; - - if (ec_node_add_child(gen_node, child) < 0) - goto fail; - table[node->len] = child; node->len++; diff --git a/lib/ecoli_node_subset.c b/lib/ecoli_node_subset.c index cc3442b..a830344 100644 --- a/lib/ecoli_node_subset.c +++ b/lib/ecoli_node_subset.c @@ -241,12 +241,32 @@ static void ec_node_subset_free_priv(struct ec_node *gen_node) ec_free(node->table); } +static size_t +ec_node_subset_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_subset *node = (struct ec_node_subset *)gen_node; + return node->len; +} + +static struct ec_node * +ec_node_subset_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_subset *node = (struct ec_node_subset *)gen_node; + + if (i >= node->len) + return NULL; + + return node->table[i]; +} + static struct ec_node_type ec_node_subset_type = { .name = "subset", .parse = ec_node_subset_parse, .complete = ec_node_subset_complete, .size = sizeof(struct ec_node_subset), .free_priv = ec_node_subset_free_priv, + .get_children_count = ec_node_subset_get_children_count, + .get_child = ec_node_subset_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_subset_type); @@ -273,10 +293,6 @@ int ec_node_subset_add(struct ec_node *gen_node, struct ec_node *child) } node->table = table; - - if (ec_node_add_child(gen_node, child) < 0) - goto fail; - table[node->len] = child; node->len++; diff --git a/lib/todo.txt b/lib/todo.txt index b8c692b..be4ae3b 100644 --- a/lib/todo.txt +++ b/lib/todo.txt @@ -413,3 +413,8 @@ watch malloc_seq condition malloc_seq == run c + + +--------------- + + -- 2.20.1