]> mj.ucw.cz Git - libucw.git/commitdiff
conf2: implemented list operation duplicate
authorRobert Spalek <robert@ucw.cz>
Thu, 27 Apr 2006 10:32:37 +0000 (12:32 +0200)
committerRobert Spalek <robert@ucw.cz>
Thu, 27 Apr 2006 10:32:37 +0000 (12:32 +0200)
lib/conf2-test.c
lib/conf2.c
lib/conf2.h
lib/conf2.t

index 6d3578604ae91fc6837105db417719dff8047fed..8ebb1b36ddfeb94b7079e6a2293a856c92befbe7 100644 (file)
@@ -19,12 +19,13 @@ static int verbose;
 struct sub_sect_1 {
   struct cnode n;
   byte *name;
+  time_t t;
   byte *level;
   int confidence[2];
   double *list;
 };
 
-static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1}, DARY_ALLOC(double, 3, 1e4, -1e-4, 8) };
+static struct sub_sect_1 sec1 = { {}, "Charlie", 0, "WBAFC", { 0, -1}, DARY_ALLOC(double, 3, 1e4, -1e-4, 8) };
 
 static byte *
 init_sec_1(struct sub_sect_1 *s)
@@ -49,6 +50,13 @@ commit_sec_1(struct sub_sect_1 *s)
   return NULL;
 }
 
+static byte *
+time_parser(uns number, byte **pars, time_t *ptr)
+{
+  *ptr = number ? atoi(pars[0]) : time(NULL);
+  return NULL;
+}
+
 static struct cf_section cf_sec_1 = {
   CF_TYPE(struct sub_sect_1),
   CF_INIT(init_sec_1),
@@ -56,6 +64,7 @@ static struct cf_section cf_sec_1 = {
 #define F(x)   PTR_TO(struct sub_sect_1, x)
   CF_ITEMS {
     CF_STRING("name", F(name)),
+    //CF_PARSER("t", F(t), time_parser, 0),
     CF_STRING("level", F(level)),
     CF_INT_ARY("confidence", F(confidence[0]), 2),             // XXX: the [0] is needed for the sake of type checking
     CF_DOUBLE_DYN("list", F(list), 100),
@@ -124,13 +133,6 @@ commit_top(void *ptr UNUSED)
   return NULL;
 }
 
-static byte *
-time_parser(uns number, byte **pars, time_t *ptr)
-{
-  *ptr = number ? atoi(pars[0]) : time(NULL);
-  return NULL;
-}
-
 static byte *alphabet[] = { "alpha", "beta", "gamma", "delta", NULL };
 static struct cf_section cf_top = {
   CF_INIT(init_top),
index 3201286cbb2939ce9fcb508ab3a6ffcb094c64c9..d5405d441fed7ba152f22ff347bc8c7898719020 100644 (file)
@@ -201,6 +201,7 @@ sort_dirty(void)
 
 #define SEC_FLAG_DYNAMIC       0x80000000      // contains a dynamic attribute
 #define SEC_FLAG_UNKNOWN       0x40000000      // ignore unknown entriies
+#define SEC_FLAG_CANT_DUPLICATE        0x20000000      // contains lists or parsers
 #define SEC_FLAG_NUMBER                0x0fffffff      // number of entries
 
 static struct cf_section sections;     // root section
@@ -223,12 +224,17 @@ inspect_section(struct cf_section *sec)
   for (ci=sec->cfg; ci->cls; ci++)
     if (ci->cls == CC_SECTION) {
       inspect_section(ci->u.sec);
-      sec->flags |= ci->u.sec->flags & SEC_FLAG_DYNAMIC;
+      sec->flags |= ci->u.sec->flags & (SEC_FLAG_DYNAMIC | SEC_FLAG_CANT_DUPLICATE);
     } else if (ci->cls == CC_LIST) {
       inspect_section(ci->u.sec);
+      sec->flags |= SEC_FLAG_DYNAMIC | SEC_FLAG_CANT_DUPLICATE;
+    } else if (ci->cls == CC_DYNAMIC)
       sec->flags |= SEC_FLAG_DYNAMIC;
-    } else if (ci->cls == CC_DYNAMIC || ci->cls == CC_PARSER && ci->number < 0)
-      sec->flags |= SEC_FLAG_DYNAMIC;
+    else if (ci->cls == CC_PARSER) {
+      sec->flags |= SEC_FLAG_CANT_DUPLICATE;
+      if (ci->number < 0)
+       sec->flags |= SEC_FLAG_DYNAMIC;
+    }
   sec->flags |= ci - sec->cfg;         // record the number of entries
 }
 
@@ -747,6 +753,7 @@ add_to_list(struct cnode *where, struct cnode *new_node, enum cf_operation op)
       break;
     case OP_AFTER:             // implementation dependend (prepend_head = after(list)), and where==list, see clists.h:74
     case OP_PREPEND:
+    case OP_DUPLICATE:
       cf_journal_block(&where->next->prev, sizeof(void*));
       cf_journal_block(&where->next, sizeof(void*));
       clist_insert_after(new_node, where);
@@ -964,7 +971,11 @@ closing_brace(struct item_stack *st, enum cf_operation op, int number, byte **pa
        st->base_ptr = st->list;
       else if (pure_op == OP_AFTER || pure_op == OP_BEFORE)
        cf_init_section(st->item->name, st->sec, st->base_ptr, 1);
-      else
+      else if (pure_op == OP_DUPLICATE) {
+       if (st->sec->flags & SEC_FLAG_CANT_DUPLICATE)
+         return cf_printf("Item %s cannot be duplicated", st->item->name);
+       memcpy(st->base_ptr, st->list, st->sec->size);  // strings and dynamic arrays are shared
+      } else
        ASSERT(0);
       if (op & OP_OPEN) {      // stay at the same recursion level
        st->op = (st->op | OP_2ND) & ~OP_1ST;
@@ -1317,6 +1328,7 @@ parse_fastbuf(byte *name_fb, struct fastbuf *fb, uns depth)
        case 'r': op = OP_REMOVE; break;
        case 'e': op = OP_EDIT; break;
        case 'b': op = OP_BEFORE; break;
+       case 'd': op = OP_DUPLICATE; break;
        default: op = OP_SET; break;
       }
       if (strcasecmp(c, op_names[op])) {
index 3da4ce6c40bede4afdd2b72b717d44bc4e63577d..4e4db4462cf6a7e340735df89e4dc0d0c3d37c04 100644 (file)
@@ -167,7 +167,7 @@ byte *cf_parse_ip(byte *p, u32 *varp);
 /* Direct access to configuration items */
 
 #define CF_OPERATIONS T(CLOSE) T(SET) T(CLEAR) T(APPEND) T(PREPEND) \
-  T(REMOVE) T(EDIT) T(AFTER) T(BEFORE)
+  T(REMOVE) T(EDIT) T(AFTER) T(BEFORE) T(DUPLICATE)
   /* Closing brace finishes previous block.
    * Basic attributes (static, dynamic, parsed) can be used with SET.
    * Dynamic arrays can be used with SET, APPEND, PREPEND.
index 037ed70b0f74b4f76fb52f222aa7ed611c7892a4..dc5788d317de6ad45059dc1e05bcadab513a09dd 100644 (file)
@@ -41,6 +41,7 @@ top.slaveS:before {level pum}{
   confidence 2
   list 123 456 789
 }
+top.slaves:duplicate {name coogee} Coogee2 PUM
 
 topp.a=15
 top.nr1=   ' 15'