#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; }