From: Olivier Matz Date: Thu, 2 Aug 2018 20:03:04 +0000 (+0200) Subject: add node helpers X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=da3c7c9f2aaf48e5eb69d649733c5e85bca50624;p=protos%2Flibecoli.git add node helpers --- diff --git a/lib/Makefile b/lib/Makefile index 0d5f1e1..6808c97 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -37,6 +37,7 @@ srcs += ecoli_node_expr.c srcs += ecoli_node_expr_test.c srcs += ecoli_node_dynamic.c srcs += ecoli_node_file.c +srcs += ecoli_node_helper.c srcs += ecoli_node_int.c srcs += ecoli_node_many.c srcs += ecoli_node_none.c diff --git a/lib/ecoli_node_helper.c b/lib/ecoli_node_helper.c new file mode 100644 index 0000000..b2be8f7 --- /dev/null +++ b/lib/ecoli_node_helper.c @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018, Olivier MATZ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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; + + 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; +} diff --git a/lib/ecoli_node_helper.h b/lib/ecoli_node_helper.h new file mode 100644 index 0000000..9dbf519 --- /dev/null +++ b/lib/ecoli_node_helper.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018, Olivier MATZ + */ + +/** + * Helpers that are commonly used in nodes. + */ + +#ifndef ECOLI_NODE_HELPERS_ +#define ECOLI_NODE_HELPERS + +struct ec_node; + +/** + * Build a node table from a node list in a ec_config. + * + * The function takes a node configuration as parameter, which must be a + * node list. From it, a node table is built. A reference is taken for + * each node. + * + * On error, no reference is taken. + * + * @param config + * The configuration (type must be a list of nodes). If it is + * NULL, an error is returned. + * @param len + * The length of the allocated table on success, or 0 on error. + * @return + * The allocated node table, that must be freed by the caller: + * each entry must be freed with ec_node_free() and the table + * with ec_free(). On error, NULL is returned and errno is set. + */ +struct ec_node ** +ec_node_config_node_list_to_table(const struct ec_config *config, + size_t *len); + +/** + * Build a list of config nodes from variable arguments. + * + * The va_list argument is a list of pointer to ec_node structures, + * terminated with EC_NODE_ENDLIST. + * + * This helper is used by nodes that contain a list of nodes, + * like "seq", "or", ... + * + * @param ap + * List of pointer to ec_node structures, terminated with + * EC_NODE_ENDLIST. + * @return + * A pointer to an ec_config structure. In this case, the + * nodes will be freed when the config structure will be freed. + * On error, NULL is returned (and errno is set), and the + * nodes are freed. + */ +struct ec_config * +ec_node_config_node_list_from_vargs(va_list ap); + +#endif