From daa68c4b2de9814b8331e7b9079d5fc49bee35c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Jan 2019 22:06:45 +0100 Subject: Add first parts of interface config handling --- src/config-process.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/config-process.c (limited to 'src/config-process.c') diff --git a/src/config-process.c b/src/config-process.c new file mode 100644 index 0000000..e71b228 --- /dev/null +++ b/src/config-process.c @@ -0,0 +1,135 @@ +#include "config-process.h" +#include "device.h" +#include "keywords.h" +#include "util.h" + +#include + +#include +#include +#include + +typedef struct _process_ctx { + struct avl_tree *ret; +} process_ctx_t; + +typedef struct _config_subtype { + struct avl_node node; +} config_subtype_t; + +void config_object_free(config_object_t *obj) { + free_ini_file(obj->data); + free(obj->type); + free(NODE_NAME(obj)); + free(obj); +} + +static bool subtype_supported(const process_ctx_t *ctx, const char *type) { + switch (lookup_keyword(type)) { + case KW_Properties: + case KW_Generate: + case KW_Static: + case KW_DHCP: + case KW_DHCPv6: + return true; + + default: + return avl_find(ctx->ret, type); + } +} + +static config_subtype_t * config_process_subtype(const process_ctx_t *ctx, config_object_t *obj) { + ini_section_t *section; + list_for_each_entry(section, &obj->data->sections, node) { + printf("%s %s %i\n", NODE_NAME(obj), section->name, subtype_supported(ctx, section->name)); + + if (!subtype_supported(ctx, section->name)) + return NULL; + } + + config_subtype_t *ret = calloc(1, sizeof(*ret)); + if (!ret) + return NULL; + + char *name = strdup(NODE_NAME(obj)); + if (!name) { + free(ret); + return NULL; + } + + NODE_NAME(ret) = name; + + return ret; +} + +struct avl_tree * config_process_subtypes(struct avl_tree *sub) { + process_ctx_t ctx; + ctx.ret = calloc(1, sizeof(*ctx.ret)); + if (!ctx.ret) + return NULL; + + avl_init(ctx.ret, avl_strcmp, false, NULL); + + while (true) { + size_t processed = 0; + + config_object_t *obj, *tmp; + avl_for_each_element_safe(sub, obj, node, tmp) { + config_subtype_t *t = config_process_subtype(&ctx, obj); + if (!t) + continue; + + avl_delete(sub, &obj->node); + config_object_free(obj); + + avl_insert(ctx.ret, &t->node); + + processed++; + } + + if (!processed) + break; + } + + return ctx.ret; +} + +static device_t * config_process_device(config_object_t *obj) { + const device_type_t *type = get_device_type(obj->type); + + assert(type != NULL); + + return type->process_config(NODE_NAME(obj), obj->data); +} + +struct avl_tree * config_process_devices(struct avl_tree *devices) { + process_ctx_t ctx; + ctx.ret = calloc(1, sizeof(*ctx.ret)); + if (!ctx.ret) + return NULL; + + avl_init(ctx.ret, avl_strcmp, false, NULL); + + while (true) { + size_t processed = 0; + + config_object_t *obj, *tmp; + avl_for_each_element_safe(devices, obj, node, tmp) { + device_t *device = config_process_device(obj); + if (!device) + continue; + + avl_delete(devices, &obj->node); + config_object_free(obj); + + avl_insert(ctx.ret, &device->node); + + processed++; + } + + if (!processed) + break; + } + + return ctx.ret; +} -- cgit v1.2.3