reorganize sources
[protos/libecoli.git] / libecoli / ecoli_node_helper.c
diff --git a/libecoli/ecoli_node_helper.c b/libecoli/ecoli_node_helper.c
new file mode 100644 (file)
index 0000000..9ec7e89
--- /dev/null
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018, Olivier MATZ <zer0@droids-corp.org>
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include <ecoli_malloc.h>
+#include <ecoli_config.h>
+#include <ecoli_node.h>
+#include <ecoli_node_helper.h>
+
+struct ec_node **
+ec_node_config_node_list_to_table(const struct ec_config *config,
+                               size_t *len)
+{
+       struct ec_node **table = NULL;
+       struct ec_config *child;
+       size_t n, i;
+
+       *len = 0;
+
+       if (config == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (ec_config_get_type(config) != EC_CONFIG_TYPE_LIST) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       n = 0;
+       TAILQ_FOREACH(child, &config->list, next) {
+               if (ec_config_get_type(child) != EC_CONFIG_TYPE_NODE) {
+                       errno = EINVAL;
+                       return NULL;
+               }
+               n++;
+       }
+
+       table = ec_malloc(n * sizeof(*table));
+       if (table == NULL)
+               goto fail;
+
+       n = 0;
+       TAILQ_FOREACH(child, &config->list, next) {
+               table[n] = ec_node_clone(child->node);
+               n++;
+       }
+
+       *len = n;
+
+       return table;
+
+fail:
+       if (table != NULL) {
+               for (i = 0; i < n; i++)
+                       ec_node_free(table[i]);
+       }
+       ec_free(table);
+
+       return NULL;
+}
+
+struct ec_config *
+ec_node_config_node_list_from_vargs(va_list ap)
+{
+       struct ec_config *list = NULL;
+       struct ec_node *node = va_arg(ap, struct ec_node *);
+
+       list = ec_config_list();
+       if (list == NULL)
+               goto fail;
+
+       for (; node != EC_NODE_ENDLIST; node = va_arg(ap, struct ec_node *)) {
+               if (node == NULL)
+                       goto fail;
+
+               if (ec_config_list_add(list, ec_config_node(node)) < 0)
+                       goto fail;
+       }
+
+       return list;
+
+fail:
+       for (; node != EC_NODE_ENDLIST; node = va_arg(ap, struct ec_node *))
+               ec_node_free(node);
+       ec_config_free(list);
+
+       return NULL;
+}