get config
[protos/libecoli.git] / lib / ecoli_node.c
index 20f90b3..a181835 100644 (file)
@@ -14,6 +14,7 @@
 #include <ecoli_strvec.h>
 #include <ecoli_keyval.h>
 #include <ecoli_log.h>
+#include <ecoli_config.h>
 #include <ecoli_test.h>
 #include <ecoli_node.h>
 
@@ -35,15 +36,18 @@ ec_node_type_lookup(const char *name)
                        return type;
        }
 
+       errno = ENOENT;
        return NULL;
 }
 
 int ec_node_type_register(struct ec_node_type *type)
 {
-       if (ec_node_type_lookup(type->name) != NULL)
-               return -EEXIST;
-       if (type->size < sizeof(struct ec_node))
-               return -EINVAL;
+       EC_CHECK_ARG(type->size >= sizeof(struct ec_node), -1, EINVAL);
+
+       if (ec_node_type_lookup(type->name) != NULL) {
+               errno = EEXIST;
+               return -1;
+       }
 
        TAILQ_INSERT_TAIL(&node_type_list, type, next);
 
@@ -135,6 +139,7 @@ void ec_node_free(struct ec_node *node)
        ec_free(node->id);
        ec_free(node->desc);
        ec_keyval_free(node->attrs);
+       ec_config_free(node->config);
        ec_free(node);
 }
 
@@ -182,9 +187,39 @@ int ec_node_add_child(struct ec_node *node, struct ec_node *child)
 
 fail:
        ec_free(children);
+       assert(errno != 0);
        return -1;
 }
 
+int
+ec_node_set_config(struct ec_node *node, struct ec_config *config)
+{
+       if (node->type->schema == NULL) {
+               errno = EINVAL;
+               goto fail;
+       }
+       if (ec_config_validate(config, node->type->schema,
+                               node->type->schema_len) < 0)
+               goto fail;
+       if (node->type->set_config != NULL) {
+               if (node->type->set_config(node, config) < 0)
+                       goto fail;
+       }
+
+       ec_config_free(node->config);
+       node->config = config;
+
+       return 0;
+
+fail:
+       return -1;
+}
+
+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)
 {
@@ -289,6 +324,7 @@ int ec_node_check_type(const struct ec_node *node,
                errno = EINVAL;
                return -1;
        }
+
        return 0;
 }
 
@@ -330,6 +366,7 @@ static int ec_node_testcase(void)
                        "type=str id=id_y"),
                "bad dump\n");
        free(buf);
+       buf = NULL;
 
        testres |= EC_TEST_CHECK(
                !strcmp(ec_node_type(node)->name, "seq") &&
@@ -390,7 +427,9 @@ fail:
        ec_node_free(node);
        if (f != NULL)
                fclose(f);
+       free(buf);
 
+       assert(errno != 0);
        return -1;
 }
 /* LCOV_EXCL_STOP */