#include "objconf.h"
#include <string.h>
ObjectConfig *load_object_config(
char *file) {
FILE *in = fopen(file,
"r");
if(in ==
NULL) {
return NULL;
}
ObjectConfig *conf = malloc(
sizeof(ObjectConfig));
conf->parser.parse = objconf_parse;
conf->file = file;
conf->conditions =
NULL;
conf->levels =
NULL;
conf->objects =
NULL;
int r = cfg_parse_basic_file((ConfigParser*)conf, in);
if(r !=
0) {
return NULL;
}
fclose(in);
return conf;
}
void free_object_config(ObjectConfig *conf) {
if(conf->levels) {
}
ucx_mempool_destroy(conf->parser.mp->pool);
free(conf);
}
int objconf_parse(
void *p, ConfigLine *begin, ConfigLine *end,
sstr_t line) {
ObjectConfig *conf = p;
begin->type = cfg_get_line_type(line);
switch(begin->type) {
case LINE_BEGIN_TAG: {
ConfigTag *tag = cfg_parse_begin_tag(line, conf->parser.mp);
if(tag ==
NULL) {
log_ereport(
LOG_FAILURE,
"Parse error in %s", conf->file);
exit(-
1);
}
tag->begin = begin;
tag->end = end;
tag->type_num = cfg_get_tag_type(tag->name);
if(objconf_on_begin_tag(conf, tag) !=
0) {
fprintf(stderr,
"1error\n");
exit(-
1);
}
break;
}
case LINE_END_TAG: {
sstr_t tag = cfg_get_end_tag_name(line);
if(objconf_on_end_tag(conf, tag) !=
0) {
fprintf(stderr,
"2error\n");
exit(-
1);
}
break;
}
case LINE_DIRECTIVE: {
ConfigDirective *dir = cfg_parse_directive(
line,
conf->parser.mp);
dir->begin = begin;
dir->end = end;
if(objconf_on_directive(conf, dir) !=
0) {
fprintf(stderr,
"3error\n");
exit(-
1);
}
}
}
return 0;
}
int objconf_on_begin_tag(ObjectConfig *conf, ConfigTag *tag) {
UcxAllocator *mp = conf->parser.mp;
if(tag->type_num !=
TAG_OBJECT) {
ConfigParserLevel *l = conf->levels->data;
if(l->tag->type_num !=
TAG_OBJECT) {
tag->parent = l->tag;
}
}
switch(tag->type_num) {
case TAG_OBJECT: {
ConfigObject *obj =
OBJ_NEW_N(mp, ConfigObject);
obj->begin = tag->begin;
obj->end = tag->end;
obj->name = cfg_param_get(tag->param, sstr(
"name"));
obj->ppath = cfg_param_get(tag->param, sstr(
"ppath"));
conf->obj = obj;
conf->objects = ucx_list_append_a(mp, conf->objects, obj);
ConfigParserLevel *lvl =
OBJ_NEW(mp, ConfigParserLevel);
lvl->iftag =
NULL;
lvl->levelnum =
1;
lvl->tag = tag;
conf->levels = ucx_list_prepend_a(mp, conf->levels, lvl);
break;
}
case TAG_IF: {
ConfigParserLevel *last_lvl = conf->levels->data;
ConfigParserLevel *lvl =
OBJ_NEW(mp, ConfigParserLevel);
lvl->iftag =
NULL;
lvl->levelnum = last_lvl->levelnum +
1;
lvl->tag = tag;
conf->levels = ucx_list_prepend_a(mp, conf->levels, lvl);
last_lvl->iftag = tag;
break;
}
case TAG_ELSEIF: {
}
case TAG_ELSE: {
ConfigParserLevel *last_lvl = conf->levels->data;
tag->iftag = last_lvl->iftag;
ConfigParserLevel *lvl =
OBJ_NEW(
conf->parser.mp,
ConfigParserLevel);
lvl->iftag = last_lvl->tag;
lvl->levelnum = last_lvl->levelnum +
1;
lvl->tag = tag;
conf->levels = ucx_list_prepend(conf->levels, lvl);
break;
}
case TAG_CLIENT: {
break;
}
default: {
log_ereport(
LOG_FAILURE,
"objconf: unknown tag");
return 1;
}
}
return 0;
}
int objconf_on_end_tag(ObjectConfig *conf,
sstr_t tagname) {
int type = cfg_get_tag_type(tagname);
if(type == -
1) {
log_ereport(
LOG_FAILURE,
"objconf: unknown tag");
return 1;
}
else {
if(type ==
TAG_OBJECT) {
conf->obj =
NULL;
}
conf->levels = ucx_list_remove_a(
conf->parser.mp,
conf->levels,
conf->levels);
}
return 0;
}
int objconf_on_directive(ObjectConfig *conf, ConfigDirective *dir) {
ConfigParserLevel *lvl = conf->levels->data;
if(lvl->tag->type_num !=
TAG_OBJECT) {
dir->condition = lvl->tag;
}
conf->obj->directives[dir->type_num] = ucx_list_append_a(
conf->parser.mp,
conf->obj->directives[dir->type_num],
dir);
return 0;
}