add node helpers
[protos/libecoli.git] / lib / ecoli_node_helper.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #include <sys/types.h>
6 #include <sys/queue.h>
7 #include <stdarg.h>
8 #include <stddef.h>
9 #include <errno.h>
10
11 #include <ecoli_malloc.h>
12 #include <ecoli_config.h>
13 #include <ecoli_node.h>
14 #include <ecoli_node_helper.h>
15
16 struct ec_node **
17 ec_node_config_node_list_to_table(const struct ec_config *config,
18                                 size_t *len)
19 {
20         struct ec_node **table = NULL;
21         struct ec_config *child;
22         size_t n, i;
23
24         *len = 0;
25
26         if (config == NULL) {
27                 errno = EINVAL;
28                 return NULL;
29         }
30
31         if (ec_config_get_type(config) != EC_CONFIG_TYPE_LIST) {
32                 errno = EINVAL;
33                 return NULL;
34         }
35
36         n = 0;
37         TAILQ_FOREACH(child, &config->list, next) {
38                 if (ec_config_get_type(child) != EC_CONFIG_TYPE_NODE) {
39                         errno = EINVAL;
40                         return NULL;
41                 }
42                 n++;
43         }
44
45         table = ec_malloc(n * sizeof(*table));
46         if (table == NULL)
47                 goto fail;
48
49         n = 0;
50         TAILQ_FOREACH(child, &config->list, next) {
51                 table[n] = ec_node_clone(child->node);
52                 n++;
53         }
54
55         *len = n;
56
57         return table;
58
59 fail:
60         if (table != NULL) {
61                 for (i = 0; i < n; i++)
62                         ec_node_free(table[i]);
63         }
64         ec_free(table);
65
66         return NULL;
67 }
68
69 struct ec_config *
70 ec_node_config_node_list_from_vargs(va_list ap)
71 {
72         struct ec_config *list = NULL;
73         struct ec_node *node;
74
75         list = ec_config_list();
76         if (list == NULL)
77                 goto fail;
78
79         for (; node != EC_NODE_ENDLIST; node = va_arg(ap, struct ec_node *)) {
80                 if (node == NULL)
81                         goto fail;
82
83                 if (ec_config_list_add(list, ec_config_node(node)) < 0)
84                         goto fail;
85         }
86
87         return list;
88
89 fail:
90         for (; node != EC_NODE_ENDLIST; node = va_arg(ap, struct ec_node *))
91                 ec_node_free(node);
92         ec_config_free(list);
93
94         return NULL;
95 }