]> mj.ucw.cz Git - libucw.git/commitdiff
conf2: list operation duplicate -> copy, and support for copying all nodes
authorRobert Spalek <robert@ucw.cz>
Thu, 27 Apr 2006 10:48:55 +0000 (12:48 +0200)
committerRobert Spalek <robert@ucw.cz>
Thu, 27 Apr 2006 10:48:55 +0000 (12:48 +0200)
lib/conf2.c
lib/conf2.h
lib/conf2.t

index d5405d441fed7ba152f22ff347bc8c7898719020..5e13328eeb0e578df8e885b01514c43f85543386 100644 (file)
@@ -201,7 +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_CANT_COPY     0x20000000      // contains lists or parsers
 #define SEC_FLAG_NUMBER                0x0fffffff      // number of entries
 
 static struct cf_section sections;     // root section
@@ -224,17 +224,19 @@ 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_FLAG_CANT_DUPLICATE);
+      sec->flags |= ci->u.sec->flags & (SEC_FLAG_DYNAMIC | SEC_FLAG_CANT_COPY);
     } else if (ci->cls == CC_LIST) {
       inspect_section(ci->u.sec);
-      sec->flags |= SEC_FLAG_DYNAMIC | SEC_FLAG_CANT_DUPLICATE;
+      sec->flags |= SEC_FLAG_DYNAMIC | SEC_FLAG_CANT_COPY;
     } else if (ci->cls == CC_DYNAMIC)
       sec->flags |= SEC_FLAG_DYNAMIC;
     else if (ci->cls == CC_PARSER) {
-      sec->flags |= SEC_FLAG_CANT_DUPLICATE;
+      sec->flags |= SEC_FLAG_CANT_COPY;
       if (ci->number < 0)
        sec->flags |= SEC_FLAG_DYNAMIC;
     }
+  if (sec->copy)
+    sec->flags &= ~SEC_FLAG_CANT_COPY;
   sec->flags |= ci - sec->cfg;         // record the number of entries
 }
 
@@ -753,7 +755,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:
+    case OP_COPY:
       cf_journal_block(&where->next->prev, sizeof(void*));
       cf_journal_block(&where->next, sizeof(void*));
       clist_insert_after(new_node, where);
@@ -971,10 +973,12 @@ 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 if (pure_op == OP_DUPLICATE) {
-       if (st->sec->flags & SEC_FLAG_CANT_DUPLICATE)
-         return cf_printf("Item %s cannot be duplicated", st->item->name);
+      else if (pure_op == OP_COPY) {
+       if (st->sec->flags & SEC_FLAG_CANT_COPY)
+         return cf_printf("Item %s cannot be copied", st->item->name);
        memcpy(st->base_ptr, st->list, st->sec->size);  // strings and dynamic arrays are shared
+       if (st->sec->copy)
+         TRY( st->sec->copy(st->base_ptr, st->list) );
       } else
        ASSERT(0);
       if (op & OP_OPEN) {      // stay at the same recursion level
@@ -1322,13 +1326,12 @@ parse_fastbuf(byte *name_fb, struct fastbuf *fb, uns depth)
       *c++ = 0;
       switch (Clocase(*c)) {
        case 's': op = OP_SET; break;
-       case 'c': op = OP_CLEAR; break;
+       case 'c': op = Clocase(c[1]) == 'l' ? OP_CLEAR: OP_COPY; break;
        case 'a': op = Clocase(c[1]) == 'p' ? OP_APPEND : OP_AFTER; break;
        case 'p': op = OP_PREPEND; break;
        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 4e4db4462cf6a7e340735df89e4dc0d0c3d37c04..99f151224b5d28ba66318b4fad3caa629517f7be 100644 (file)
@@ -50,6 +50,10 @@ typedef byte *cf_hook(void *ptr);
    * use cf_malloc() but normal xmalloc().  */
 typedef void cf_dumper1(struct fastbuf *fb, void *ptr);
   /* Dumps the contents of a variable of a user-defined type.  */
+typedef byte *cf_copier(void *dest, void *src);
+  /* Similar to init-hook, but it copies attributes from another list node
+   * instead of setting the attributes to default values.  You have to provide
+   * it if your node contains parsed values and/or sub-lists.  */
 
 struct cf_user_type {
   uns size;                            // of the parsed attribute
@@ -77,6 +81,7 @@ struct cf_section {
   uns size;                            // 0 for a global block, sizeof(struct) for a section
   cf_hook *init;                       // fills in default values (no need to bzero)
   cf_hook *commit;                     // verifies parsed data (optional)
+  cf_copier *copy;                     // copies values from another instance (optional, no need to copy basic attributes)
   struct cf_item *cfg;                 // CC_END-terminated array of items
   uns flags;                           // for internal use only
 };
@@ -85,6 +90,7 @@ struct cf_section {
 #define CF_TYPE(s)     .size = sizeof(s)
 #define CF_INIT(f)     .init = (cf_hook*) f
 #define CF_COMMIT(f)   .commit = (cf_hook*) f
+#define CF_COPY(f)     .copy = (cf_copier*) f
 #define CF_ITEMS       .cfg = ( struct cf_item[] )
 #define CF_END         { .cls = CC_END }
 /* Configuration items */
@@ -167,7 +173,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(DUPLICATE)
+  T(REMOVE) T(EDIT) T(AFTER) T(BEFORE) T(COPY)
   /* 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 dc5788d317de6ad45059dc1e05bcadab513a09dd..1ba70aebcfdc180467891d7de46b1d8ad52b86cf 100644 (file)
@@ -41,7 +41,7 @@ top.slaveS:before {level pum}{
   confidence 2
   list 123 456 789
 }
-top.slaves:duplicate {name coogee} Coogee2 PUM
+top.slaves:copy {name coogee} Coogee2 PUM
 
 topp.a=15
 top.nr1=   ' 15'