]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/conf-intr.c
Merge branch 'dev-xtypes'
[libucw.git] / ucw / conf-intr.c
index 3e9445f2240131511998beda66faa2ba6d038e17..741cd80b44abc626139b94fba80bf01a3337577d 100644 (file)
@@ -2,7 +2,8 @@
  *     UCW Library -- Configuration files: interpreter
  *
  *     (c) 2001--2006 Robert Spalek <robert@ucw.cz>
  *     UCW Library -- Configuration files: interpreter
  *
  *     (c) 2001--2006 Robert Spalek <robert@ucw.cz>
- *     (c) 2003--2012 Martin Mares <mj@ucw.cz>
+ *     (c) 2003--2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014 Pavel Charvat <pchar@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.
@@ -13,6 +14,9 @@
 #include <ucw/getopt.h>
 #include <ucw/conf-internal.h>
 #include <ucw/clists.h>
 #include <ucw/getopt.h>
 #include <ucw/conf-internal.h>
 #include <ucw/clists.h>
+#include <ucw/gary.h>
+#include <ucw/mempool.h>
+#include <ucw/xtypes.h>
 
 #include <string.h>
 #include <stdio.h>
 
 #include <string.h>
 #include <stdio.h>
@@ -30,7 +34,7 @@ cf_parse_string(char *str, char **ptr)
 
 typedef char *cf_basic_parser(char *str, void *ptr);
 static struct {
 
 typedef char *cf_basic_parser(char *str, void *ptr);
 static struct {
-  uns size;
+  uint size;
   void *parser;
 } parsers[] = {
   { sizeof(int), cf_parse_int },
   void *parser;
 } parsers[] = {
   { sizeof(int), cf_parse_int },
@@ -42,20 +46,26 @@ static struct {
   { 0, NULL },                                 // user-defined types are parsed extra
 };
 
   { 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;
 }
 
 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++;
   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 *
 }
 
 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; i<number; i++)
+  for (uint i=0; i<number; i++)
   {
     char *msg;
   {
     char *msg;
-    uns size = cf_type_size(type, u->utype);
+    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);
     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)
     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
 #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;
 
 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
   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);
 }
 
   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;
 {
   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
   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) {
   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]);
 }
 
     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 *
 
 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;
 {
   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;
     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);
   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; i<number; i++) {
     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; i<number; i++) {
-    uns idx;
+    uint idx;
     if (item->type == CT_INT)
       TRY( cf_parse_int(pars[i], &idx) );
     else
     if (item->type == 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 *
 }
 
 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)
 {
   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;
        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:
       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 {
       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);
       }
        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 *));
     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*));
   } 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
   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 *
 }
 
 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)
   {
 {
   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<<i))
        if (cmp_items(n, query, sec->cfg+i))
        {
       if (mask & (1<<i))
        if (cmp_items(n, query, sec->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)
 {
 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
   {
   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)
     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)
 {
 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);
 }
 }