This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
neco/src/config-process.c

135 lines
2.6 KiB
C

#include "config-process.h"
#include "device.h"
#include "keywords.h"
#include "util.h"
#include <libubox/avl-cmp.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
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;
}