X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fconf-section.c;h=30f5898c6347197f17772bc0a9e244894ebd5ae8;hb=a6368763d08042207963c941b1c52b5fafcb0cb3;hp=4112d88883418cd2ffeae10ff9180948794fffb8;hpb=a4fe009d3366b0a3e119713b0ecc7fc0070efdfa;p=libucw.git diff --git a/ucw/conf-section.c b/ucw/conf-section.c index 4112d888..30f5898c 100644 --- a/ucw/conf-section.c +++ b/ucw/conf-section.c @@ -2,58 +2,49 @@ * UCW Library -- Configuration files: sections * * (c) 2001--2006 Robert Spalek - * (c) 2003--2006 Martin Mares + * (c) 2003--2014 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. */ -#include "ucw/lib.h" -#include "ucw/conf.h" -#include "ucw/conf-internal.h" -#include "ucw/clists.h" -#include "ucw/binsearch.h" +#include +#include +#include +#include +#include +#include #include /* Dirty sections */ -struct dirty_section { - struct cf_section *sec; - void *ptr; -}; -#define GBUF_TYPE struct dirty_section -#define GBUF_PREFIX(x) dirtsec_##x -#include "ucw/gbuf.h" -static dirtsec_t dirty; -static uns dirties; - void cf_add_dirty(struct cf_section *sec, void *ptr) { - dirtsec_grow(&dirty, dirties+1); - struct dirty_section *dest = dirty.ptr + dirties; - if (dirties && dest[-1].sec == sec && dest[-1].ptr == ptr) + struct cf_context *cc = cf_get_context(); + dirtsec_grow(&cc->dirty, cc->dirties+1); + struct dirty_section *dest = cc->dirty.ptr + cc->dirties; + if (cc->dirties && dest[-1].sec == sec && dest[-1].ptr == ptr) return; dest->sec = sec; dest->ptr = ptr; - dirties++; + cc->dirties++; } #define ASORT_PREFIX(x) dirtsec_##x #define ASORT_KEY_TYPE struct dirty_section -#define ASORT_ELT(i) dirty.ptr[i] #define ASORT_LT(x,y) x.sec < y.sec || x.sec == y.sec && x.ptr < y.ptr -#include "ucw/sorter/array-simple.h" +#include static void -sort_dirty(void) +sort_dirty(struct cf_context *cc) { - if (dirties <= 1) + if (cc->dirties <= 1) return; - dirtsec_sort(dirties); + dirtsec_sort(cc->dirty.ptr, cc->dirties); // and compress the list - struct dirty_section *read = dirty.ptr + 1, *write = dirty.ptr + 1, *limit = dirty.ptr + dirties; + struct dirty_section *read = cc->dirty.ptr + 1, *write = cc->dirty.ptr + 1, *limit = cc->dirty.ptr + cc->dirties; while (read < limit) { if (read->sec != read[-1].sec || read->ptr != read[-1].ptr) { if (read != write) @@ -62,13 +53,11 @@ sort_dirty(void) } read++; } - dirties = write - dirty.ptr; + cc->dirties = write - cc->dirty.ptr; } /* Initialization */ -struct cf_section cf_sections; // root section - struct cf_item * cf_find_subitem(struct cf_section *sec, const char *name) { @@ -104,35 +93,42 @@ inspect_section(struct cf_section *sec) } void -cf_declare_section(const char *name, struct cf_section *sec, uns allow_unknown) +cf_declare_rel_section(const char *name, struct cf_section *sec, void *ptr, uint allow_unknown) { - if (!cf_sections.cfg) + struct cf_context *cc = cf_obtain_context(); + if (!cc->sections.cfg) { - cf_sections.size = 50; - cf_sections.cfg = xmalloc_zero(cf_sections.size * sizeof(struct cf_item)); + cc->sections.size = 50; + cc->sections.cfg = xmalloc_zero(cc->sections.size * sizeof(struct cf_item)); } - struct cf_item *ci = cf_find_subitem(&cf_sections, name); + struct cf_item *ci = cf_find_subitem(&cc->sections, name); if (ci->cls) die("Cannot register section %s twice", name); ci->cls = CC_SECTION; ci->name = name; ci->number = 1; - ci->ptr = NULL; + ci->ptr = ptr; ci->u.sec = sec; inspect_section(sec); if (allow_unknown) sec->flags |= SEC_FLAG_UNKNOWN; ci++; - if (ci - cf_sections.cfg >= (int) cf_sections.size) + if (ci - cc->sections.cfg >= (int) cc->sections.size) { - cf_sections.cfg = xrealloc(cf_sections.cfg, 2*cf_sections.size * sizeof(struct cf_item)); - bzero(cf_sections.cfg + cf_sections.size, cf_sections.size * sizeof(struct cf_item)); - cf_sections.size *= 2; + cc->sections.cfg = xrealloc(cc->sections.cfg, 2*cc->sections.size * sizeof(struct cf_item)); + bzero(cc->sections.cfg + cc->sections.size, cc->sections.size * sizeof(struct cf_item)); + cc->sections.size *= 2; } } void -cf_init_section(const char *name, struct cf_section *sec, void *ptr, uns do_bzero) +cf_declare_section(const char *name, struct cf_section *sec, uint allow_unknown) +{ + cf_declare_rel_section(name, sec, NULL, allow_unknown); +} + +void +cf_init_section(const char *name, struct cf_section *sec, void *ptr, uint do_bzero) { if (do_bzero) { ASSERT(sec->size); @@ -145,10 +141,8 @@ cf_init_section(const char *name, struct cf_section *sec, void *ptr, uns do_bzer clist_init(ptr + (uintptr_t) ci->ptr); else if (ci->cls == CC_DYNAMIC) { void **dyn = ptr + (uintptr_t) ci->ptr; - if (!*dyn) { // replace NULL by an empty array - static uns zero = 0; - *dyn = (&zero) + 1; - } + if (!*dyn) // replace NULL by an empty array + *dyn = GARY_FOREVER_EMPTY; } if (sec->init) { char *msg = sec->init(ptr); @@ -158,9 +152,11 @@ cf_init_section(const char *name, struct cf_section *sec, void *ptr, uns do_bzer } static char * -commit_section(struct cf_section *sec, void *ptr, uns commit_all) +commit_section(struct cf_section *sec, void *ptr, uint commit_all) { + struct cf_context *cc = cf_get_context(); char *err; + for (struct cf_item *ci=sec->cfg; ci->cls; ci++) if (ci->cls == CC_SECTION) { if ((err = commit_section(ci->u.sec, ptr + (uintptr_t) ci->ptr, commit_all))) { @@ -168,7 +164,7 @@ commit_section(struct cf_section *sec, void *ptr, uns commit_all) return "commit of a subsection failed"; } } else if (ci->cls == CC_LIST) { - uns idx = 0; + uint idx = 0; CLIST_FOR_EACH(cnode *, n, * (clist*) (ptr + (uintptr_t) ci->ptr)) if (idx++, err = commit_section(ci->u.sec, n, commit_all)) { msg(L_ERROR, "Cannot commit node #%d of list %s: %s", idx, ci->name, err); @@ -181,10 +177,10 @@ commit_section(struct cf_section *sec, void *ptr, uns commit_all) * hence we need to call them in a fixed order. */ #define ARY_LT_X(ary,i,x) ary[i].sec < x.sec || ary[i].sec == x.sec && ary[i].ptr < x.ptr struct dirty_section comp = { sec, ptr }; - uns pos = BIN_SEARCH_FIRST_GE_CMP(dirty.ptr, dirties, comp, ARY_LT_X); + uint pos = BIN_SEARCH_FIRST_GE_CMP(cc->dirty.ptr, cc->dirties, comp, ARY_LT_X); if (commit_all - || (pos < dirties && dirty.ptr[pos].sec == sec && dirty.ptr[pos].ptr == ptr)) + || (pos < cc->dirties && cc->dirty.ptr[pos].sec == sec && cc->dirty.ptr[pos].ptr == ptr)) return sec->commit(ptr); } return 0; @@ -193,11 +189,12 @@ commit_section(struct cf_section *sec, void *ptr, uns commit_all) int cf_commit_all(enum cf_commit_mode cm) { - sort_dirty(); + struct cf_context *cc = cf_get_context(); + sort_dirty(cc); if (cm == CF_NO_COMMIT) return 0; - if (commit_section(&cf_sections, NULL, cm == CF_COMMIT_ALL)) + if (commit_section(&cc->sections, NULL, cm == CF_COMMIT_ALL)) return 1; - dirties = 0; + cc->dirties = 0; return 0; }