]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/conf-section.c
Merge remote-tracking branch 'origin/master'
[libucw.git] / ucw / conf-section.c
index 4112d88883418cd2ffeae10ff9180948794fffb8..30f5898c6347197f17772bc0a9e244894ebd5ae8 100644 (file)
@@ -2,58 +2,49 @@
  *     UCW Library -- Configuration files: sections
  *
  *     (c) 2001--2006 Robert Spalek <robert@ucw.cz>
  *     UCW Library -- Configuration files: sections
  *
  *     (c) 2001--2006 Robert Spalek <robert@ucw.cz>
- *     (c) 2003--2006 Martin Mares <mj@ucw.cz>
+ *     (c) 2003--2014 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  */
 
  *
  *     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 <ucw/lib.h>
+#include <ucw/conf.h>
+#include <ucw/conf-internal.h>
+#include <ucw/clists.h>
+#include <ucw/binsearch.h>
+#include <ucw/gary.h>
 
 #include <string.h>
 
 /* Dirty sections */
 
 
 #include <string.h>
 
 /* 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)
 {
 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;
     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_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
 #define ASORT_LT(x,y)  x.sec < y.sec || x.sec == y.sec && x.ptr < y.ptr
-#include "ucw/sorter/array-simple.h"
+#include <ucw/sorter/array-simple.h>
 
 static void
 
 static void
-sort_dirty(void)
+sort_dirty(struct cf_context *cc)
 {
 {
-  if (dirties <= 1)
+  if (cc->dirties <= 1)
     return;
     return;
-  dirtsec_sort(dirties);
+  dirtsec_sort(cc->dirty.ptr, cc->dirties);
   // and compress the list
   // 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)
   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++;
   }
     }
     read++;
   }
-  dirties = write - dirty.ptr;
+  cc->dirties = write - cc->dirty.ptr;
 }
 
 /* Initialization */
 
 }
 
 /* Initialization */
 
-struct cf_section cf_sections; // root section
-
 struct cf_item *
 cf_find_subitem(struct cf_section *sec, const char *name)
 {
 struct cf_item *
 cf_find_subitem(struct cf_section *sec, const char *name)
 {
@@ -104,35 +93,42 @@ inspect_section(struct cf_section *sec)
 }
 
 void
 }
 
 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;
   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++;
   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
   }
 }
 
 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);
 {
   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;
       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);
     }
   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 *
 }
 
 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;
   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))) {
   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) {
        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);
       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 };
      * 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
 
     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;
       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)
 {
 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 (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;
     return 1;
-  dirties = 0;
+  cc->dirties = 0;
   return 0;
 }
   return 0;
 }