From: Robert Spalek Date: Thu, 27 Apr 2006 10:32:37 +0000 (+0200) Subject: conf2: implemented list operation duplicate X-Git-Tag: holmes-import~645^2~11^2~25 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e252107f2f661ded0c58b0fb281767f1764ca8d2;p=libucw.git conf2: implemented list operation duplicate --- diff --git a/lib/conf2-test.c b/lib/conf2-test.c index 6d357860..8ebb1b36 100644 --- a/lib/conf2-test.c +++ b/lib/conf2-test.c @@ -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), diff --git a/lib/conf2.c b/lib/conf2.c index 3201286c..d5405d44 100644 --- a/lib/conf2.c +++ b/lib/conf2.c @@ -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])) { diff --git a/lib/conf2.h b/lib/conf2.h index 3da4ce6c..4e4db446 100644 --- a/lib/conf2.h +++ b/lib/conf2.h @@ -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. diff --git a/lib/conf2.t b/lib/conf2.t index 037ed70b..dc5788d3 100644 --- a/lib/conf2.t +++ b/lib/conf2.t @@ -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'