X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fconf-intr.c;h=741cd80b44abc626139b94fba80bf01a3337577d;hb=24c1cdecfd5149ae3096340e3e317d4f127b1abf;hp=3e9445f2240131511998beda66faa2ba6d038e17;hpb=b3d3d2847cb34363c5e7a5a6bf8155b710d7afcd;p=libucw.git diff --git a/ucw/conf-intr.c b/ucw/conf-intr.c index 3e9445f2..741cd80b 100644 --- a/ucw/conf-intr.c +++ b/ucw/conf-intr.c @@ -2,7 +2,8 @@ * UCW Library -- Configuration files: interpreter * * (c) 2001--2006 Robert Spalek - * (c) 2003--2012 Martin Mares + * (c) 2003--2014 Martin Mares + * (c) 2014 Pavel Charvat * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -13,6 +14,9 @@ #include #include #include +#include +#include +#include #include #include @@ -30,7 +34,7 @@ cf_parse_string(char *str, char **ptr) typedef char *cf_basic_parser(char *str, void *ptr); static struct { - uns size; + uint size; void *parser; } parsers[] = { { sizeof(int), cf_parse_int }, @@ -42,20 +46,26 @@ static struct { { 0, NULL }, // user-defined types are parsed extra }; -inline uns -cf_type_size(enum cf_type type, struct cf_user_type *utype) +inline uint +cf_type_size(enum cf_type type, const union cf_union *u) { - if (type < CT_USER) - return parsers[type].size; - else - return utype->size; + switch (type) + { + case CT_USER: + return u->utype->size; + case CT_XTYPE: + return u->xtype->size; + default: + ASSERT(type < ARRAY_SIZE(parsers) - 1); + return parsers[type].size; + } } static char * cf_parse_lookup(char *str, int *ptr, const char * const *t) { const char * const *n = t; - uns total_len = 0; + uint total_len = 0; while (*n && strcasecmp(*n, str)) { total_len += strlen(*n) + 2; n++; @@ -75,18 +85,20 @@ cf_parse_lookup(char *str, int *ptr, const char * const *t) } static char * -cf_parse_ary(uns number, char **pars, void *ptr, enum cf_type type, union cf_union *u) +cf_parse_ary(uint number, char **pars, void *ptr, enum cf_type type, union cf_union *u) { - for (uns i=0; iutype); + uint size = cf_type_size(type, u); if (type < CT_LOOKUP) msg = ((cf_basic_parser*) parsers[type].parser) (pars[i], ptr + i * size); else if (type == CT_LOOKUP) msg = cf_parse_lookup(pars[i], ptr + i * size, u->lookup); else if (type == CT_USER) msg = u->utype->parser(pars[i], ptr + i * size); + else if (type == CT_XTYPE) + msg = (char *)u->xtype->parse(pars[i], ptr + i * size, cf_get_pool()); else ASSERT(0); if (msg) @@ -100,19 +112,16 @@ cf_parse_ary(uns number, char **pars, void *ptr, enum cf_type type, union cf_uni #define T(x) #x, char *cf_op_names[] = { CF_OPERATIONS }; #undef T -char *cf_type_names[] = { "int", "u64", "double", "ip", "string", "lookup", "user" }; - -#define DARY_HDR_SIZE ALIGN_TO(sizeof(uns), CPU_STRUCT_ALIGN) +char *cf_type_names[] = { "int", "u64", "double", "ip", "string", "lookup", "user", "xtype" }; static char * interpret_set_dynamic(struct cf_item *item, int number, char **pars, void **ptr) { enum cf_type type = item->type; + uint size = cf_type_size(type, &item->u); cf_journal_block(ptr, sizeof(void*)); // boundary checks done by the caller - uns size = cf_type_size(item->type, item->u.utype); - *ptr = cf_malloc(DARY_HDR_SIZE + number * size) + DARY_HDR_SIZE; - DARY_LEN(*ptr) = number; + *ptr = gary_init(size, number, mp_get_allocator(cf_get_pool())); return cf_parse_ary(number, pars, *ptr, type, &item->u); } @@ -121,14 +130,13 @@ interpret_add_dynamic(struct cf_item *item, int number, char **pars, int *proces { enum cf_type type = item->type; void *old_p = *ptr; - uns size = cf_type_size(item->type, item->u.utype); - ASSERT(size >= sizeof(uns)); - int old_nr = old_p ? DARY_LEN(old_p) : 0; + uint size = cf_type_size(item->type, &item->u); + ASSERT(size >= sizeof(uint)); + int old_nr = old_p ? GARY_SIZE(old_p) : 0; int taken = MIN(number, ABS(item->number)-old_nr); *processed = taken; // stretch the dynamic array - void *new_p = cf_malloc(DARY_HDR_SIZE + (old_nr + taken) * size) + DARY_HDR_SIZE; - DARY_LEN(new_p) = old_nr + taken; + void *new_p = gary_init(size, old_nr + taken, mp_get_allocator(cf_get_pool())); cf_journal_block(ptr, sizeof(void*)); *ptr = new_p; if (op == OP_APPEND) { @@ -141,10 +149,10 @@ interpret_add_dynamic(struct cf_item *item, int number, char **pars, int *proces return cf_printf("Dynamic arrays do not support operation %s", cf_op_names[op]); } -static char *interpret_set_item(struct cf_item *item, int number, char **pars, int *processed, void *ptr, uns allow_dynamic); +static char *interpret_set_item(struct cf_item *item, int number, char **pars, int *processed, void *ptr, uint allow_dynamic); static char * -interpret_section(struct cf_section *sec, int number, char **pars, int *processed, void *ptr, uns allow_dynamic) +interpret_section(struct cf_section *sec, int number, char **pars, int *processed, void *ptr, uint allow_dynamic) { cf_add_dirty(sec, ptr); *processed = 0; @@ -203,7 +211,7 @@ interpret_add_list(struct cf_item *item, int number, char **pars, int *processed return "Nothing to add to the list"; struct cf_section *sec = item->u.sec; *processed = 0; - uns index = 0; + uint index = 0; while (number > 0) { void *node = cf_malloc(sec->size); @@ -236,7 +244,7 @@ interpret_add_bitmap(struct cf_item *item, int number, char **pars, int *process return cf_printf("Type %s cannot be used with bitmaps", cf_type_names[item->type]); cf_journal_block(ptr, sizeof(u32)); for (int i=0; itype == CT_INT) TRY( cf_parse_int(pars[i], &idx) ); else @@ -253,7 +261,7 @@ interpret_add_bitmap(struct cf_item *item, int number, char **pars, int *process } static char * -interpret_set_item(struct cf_item *item, int number, char **pars, int *processed, void *ptr, uns allow_dynamic) +interpret_set_item(struct cf_item *item, int number, char **pars, int *processed, void *ptr, uint allow_dynamic) { int taken; switch (item->cls) @@ -263,7 +271,7 @@ interpret_set_item(struct cf_item *item, int number, char **pars, int *processed return "Missing value"; taken = MIN(number, item->number); *processed = taken; - uns size = cf_type_size(item->type, item->u.utype); + uint size = cf_type_size(item->type, &item->u); cf_journal_block(ptr, taken * size); return cf_parse_ary(taken, pars, ptr, item->type, &item->u); case CC_DYNAMIC: @@ -308,7 +316,7 @@ interpret_set_all(struct cf_item *item, void *ptr, enum cf_operation op) if (item->type == CT_INT) * (u32*) ptr = ~0u; else { - uns nr = -1; + uint nr = -1; while (item->u.lookup[++nr]); * (u32*) ptr = ~0u >> (32-nr); } @@ -321,8 +329,7 @@ interpret_set_all(struct cf_item *item, void *ptr, enum cf_operation op) clist_init(ptr); } else if (item->cls == CC_DYNAMIC) { cf_journal_block(ptr, sizeof(void *)); - static uns zero = 0; - * (void**) ptr = (&zero) + 1; + * (void**) ptr = GARY_FOREVER_EMPTY; } else if (item->cls == CC_STATIC && item->type == CT_STRING) { cf_journal_block(ptr, item->number * sizeof(char*)); bzero(ptr, item->number * sizeof(char*)); @@ -340,7 +347,7 @@ cmp_items(void *i1, void *i2, struct cf_item *item) if (item->type == CT_STRING) return strcmp(* (char**) i1, * (char**) i2); else // all numeric types - return memcmp(i1, i2, cf_type_size(item->type, item->u.utype)); + return memcmp(i1, i2, cf_type_size(item->type, &item->u)); } static void * @@ -348,8 +355,8 @@ find_list_node(clist *list, void *query, struct cf_section *sec, u32 mask) { CLIST_FOR_EACH(cnode *, n, *list) { - uns found = 1; - for (uns i=0; i<32; i++) + uint found = 1; + for (uint i=0; i<32; i++) if (mask & (1<cfg+i)) { @@ -365,10 +372,10 @@ find_list_node(clist *list, void *query, struct cf_section *sec, u32 mask) static char * record_selector(struct cf_item *item, struct cf_section *sec, u32 *mask) { - uns nr = sec->flags & SEC_FLAG_NUMBER; + uint nr = sec->flags & SEC_FLAG_NUMBER; if (item >= sec->cfg && item < sec->cfg + nr) // setting an attribute relative to this section { - uns i = item - sec->cfg; + uint i = item - sec->cfg; if (i >= 32) return "Cannot select list nodes by this attribute"; if (sec->cfg[i].cls != CC_STATIC) @@ -654,31 +661,5 @@ cf_init_stack(struct cf_context *cc) int cf_done_stack(struct cf_context *cc) { - if (cc->stack_level > 0) { - msg(L_ERROR, "Unterminated block"); // FIXME: Where? - return 1; - } - if (cf_commit_all(cc->postpone_commit ? CF_NO_COMMIT : cc->everything_committed ? CF_COMMIT : CF_COMMIT_ALL)) - return 1; - if (!cc->postpone_commit) - cc->everything_committed = 1; - return 0; -} - -void -cf_open_group(void) -{ - struct cf_context *cc = cf_get_context(); - cc->postpone_commit++; -} - -int -cf_close_group(void) -{ - struct cf_context *cc = cf_get_context(); - ASSERT(cc->postpone_commit); - if (!--cc->postpone_commit) - return cf_done_stack(cc); - else - return 0; + return (cc->stack_level > 0); }