replace generic child table by a node ops
authorOlivier Matz <zer0@droids-corp.org>
Thu, 5 Jul 2018 19:12:54 +0000 (21:12 +0200)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 5 Jul 2018 19:12:54 +0000 (21:12 +0200)
lib/ecoli_node.c
lib/ecoli_node.h
lib/ecoli_node_cmd.c
lib/ecoli_node_many.c
lib/ecoli_node_once.c
lib/ecoli_node_option.c
lib/ecoli_node_or.c
lib/ecoli_node_seq.c
lib/ecoli_node_subset.c
lib/todo.txt

index d936302..9a21d63 100644 (file)
@@ -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);
        }
 }
index 63178f7..6fede59 100644 (file)
@@ -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
index 070bb02..bd2f767 100644 (file)
@@ -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);
index 60256ef..6a5f676 100644 (file)
@@ -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);
index 8218a29..5248d13 100644 (file)
@@ -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;
index 7509251..befbb2e 100644 (file)
@@ -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;
index c72642c..ad3786e 100644 (file)
@@ -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++;
 
index 77738ed..34512b6 100644 (file)
@@ -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++;
 
index cc3442b..a830344 100644 (file)
@@ -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++;
 
index b8c692b..be4ae3b 100644 (file)
@@ -413,3 +413,8 @@ watch malloc_seq
 condition <watchpoint num> malloc_seq == <value + 1>
 run <args...>
 c
+
+
+---------------
+
+