From 7a44a03f2c72f1cb6b5f50b5f824d9bcb29dd999 Mon Sep 17 00:00:00 2001 From: Robert Spalek Date: Thu, 27 Apr 2006 12:48:55 +0200 Subject: [PATCH] conf2: list operation duplicate -> copy, and support for copying all nodes --- lib/conf2.c | 23 +++++++++++++---------- lib/conf2.h | 8 +++++++- lib/conf2.t | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/conf2.c b/lib/conf2.c index d5405d44..5e13328e 100644 --- a/lib/conf2.c +++ b/lib/conf2.c @@ -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])) { diff --git a/lib/conf2.h b/lib/conf2.h index 4e4db446..99f15122 100644 --- a/lib/conf2.h +++ b/lib/conf2.h @@ -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. diff --git a/lib/conf2.t b/lib/conf2.t index dc5788d3..1ba70aeb 100644 --- a/lib/conf2.t +++ b/lib/conf2.t @@ -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' -- 2.39.2