From: Robert Spalek Date: Sun, 30 Apr 2006 16:53:19 +0000 (+0200) Subject: conf: redesign dynamic arrays; things get cleaner and start to work now X-Git-Tag: holmes-import~645^2~3 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=894ab13170a1f14ec1920976c531fe02ffb5a2ab;p=libucw.git conf: redesign dynamic arrays; things get cleaner and start to work now --- diff --git a/lib/conf-dump.c b/lib/conf-dump.c index fe4a7c24..ee137ab1 100644 --- a/lib/conf-dump.c +++ b/lib/conf-dump.c @@ -75,7 +75,7 @@ dump_item(struct fastbuf *fb, struct cf_item *item, int level, void *ptr) } else if (item->cls == CC_DYNAMIC) { ptr = * (void**) ptr; if (ptr) { - int real_nr = * (int*) (ptr - size); + int real_nr = DARY_LEN(ptr); bprintf(fb, "N%d ", real_nr); for (i=0; iu); diff --git a/lib/conf-internal.h b/lib/conf-internal.h index b31fc8c1..3760d0e5 100644 --- a/lib/conf-internal.h +++ b/lib/conf-internal.h @@ -20,7 +20,6 @@ enum cf_operation; extern byte *cf_op_names[]; uns cf_type_size(enum cf_type type, struct cf_user_type *utype); -byte *cf_interpret_clear(struct cf_item *item, void *ptr); byte *cf_interpret_line(byte *name, enum cf_operation op, int number, byte **pars); void cf_init_stack(void); int cf_check_stack(void); diff --git a/lib/conf-intr.c b/lib/conf-intr.c index 0b84707e..7b1564e2 100644 --- a/lib/conf-intr.c +++ b/lib/conf-intr.c @@ -109,8 +109,8 @@ interpret_set_dynamic(struct cf_item *item, int number, byte **pars, void **ptr) // boundary checks done by the caller uns size = cf_type_size(item->type, item->u.utype); ASSERT(size >= sizeof(uns)); - *ptr = cf_malloc((number+1) * size) + size; - * (uns*) (*ptr - size) = number; + *ptr = cf_malloc(sizeof(uns) + number * size) + sizeof(uns); + DARY_LEN(*ptr) = number; return cf_parse_ary(number, pars, *ptr, type, &item->u); } @@ -121,12 +121,12 @@ interpret_add_dynamic(struct cf_item *item, int number, byte **pars, int *proces void *old_p = *ptr; uns size = cf_type_size(item->type, item->u.utype); ASSERT(size >= sizeof(uns)); - int old_nr = old_p ? * (int*) (old_p - size) : 0; + int old_nr = old_p ? DARY_LEN(old_p) : 0; int taken = MIN(number, ABS(item->number)-old_nr); *processed = taken; // stretch the dynamic array - void *new_p = cf_malloc((old_nr + taken + 1) * size) + size; - * (uns*) (new_p - size) = old_nr + taken; + void *new_p = cf_malloc(sizeof(uns) + (old_nr + taken) * size) + sizeof(uns); + DARY_LEN(new_p) = old_nr + taken; cf_journal_block(ptr, sizeof(void*)); *ptr = new_p; if (op == OP_APPEND) { @@ -264,20 +264,16 @@ interpret_set_item(struct cf_item *item, int number, byte **pars, int *processed } } -byte * -cf_interpret_clear(struct cf_item *item, void *ptr) +static byte * +interpret_clear(struct cf_item *item, void *ptr) { if (item->cls == CC_LIST) { cf_journal_block(ptr, sizeof(clist)); clist_init(ptr); } else if (item->cls == CC_DYNAMIC) { cf_journal_block(ptr, sizeof(void *)); - uns size = cf_type_size(item->type, item->u.utype); - static u64 zero = 0; - if (size <= sizeof(zero)) - *(void**)ptr = (&zero) + 1; - else - *(void**)ptr = cf_malloc_zero(size) + size; + static uns zero = 0; + * (void**) ptr = (&zero) + 1; } else if (item->cls == CC_STATIC && item->type == CT_STRING) { cf_journal_block(ptr, item->number * sizeof(byte*)); bzero(ptr, item->number * sizeof(byte*)); @@ -492,7 +488,7 @@ cf_interpret_line(byte *name, enum cf_operation op, int number, byte **pars) int taken; // process as many parameters as possible if (op == OP_CLEAR) - taken = 0, msg = cf_interpret_clear(item, ptr); + taken = 0, msg = interpret_clear(item, ptr); else if (op == OP_SET) msg = interpret_set_item(item, number, pars, &taken, ptr, 1); else if (item->cls == CC_DYNAMIC) @@ -536,7 +532,7 @@ cf_write_item(struct cf_item *item, enum cf_operation op, int number, byte **par break; case OP_CLEAR: taken = 0; - msg = cf_interpret_clear(item, item->ptr); + msg = interpret_clear(item, item->ptr); break; case OP_APPEND: case OP_PREPEND: diff --git a/lib/conf-section.c b/lib/conf-section.c index b3d16ed2..a916d7d8 100644 --- a/lib/conf-section.c +++ b/lib/conf-section.c @@ -170,8 +170,10 @@ commit_section(struct cf_section *sec, void *ptr, uns commit_all) } } else if (ci->cls == CC_DYNAMIC) { void **dyn = ptr + (addr_int_t) ci->ptr; - if (!*dyn) // replace NULL by an empty array - cf_interpret_clear(ci, dyn); + if (!*dyn) { // replace NULL by an empty array + static uns zero = 0; + *dyn = (&zero) + 1; + } } if (sec->commit) { /* We have to process the whole tree of sections even if just a few changes diff --git a/lib/conf-test.c b/lib/conf-test.c index 0a4209da..cefaa212 100644 --- a/lib/conf-test.c +++ b/lib/conf-test.c @@ -30,10 +30,8 @@ static struct sub_sect_1 sec1 = { {}, "Charlie", 0, "WBAFC", { 0, -1}, DARY_ALLO static byte * init_sec_1(struct sub_sect_1 *s) { - if (s == &sec1) { // this is a static variable; skip clearing - DARY_LEN(sec1.list) = 3; // XXX: fix for the bug in DARY_ALLOC() + if (s == &sec1) // this is a static variable; skip clearing return NULL; - } s->name = "unknown"; s->level = "default"; s->confidence[0] = 5; diff --git a/lib/conf.h b/lib/conf.h index beb4c449..82b46dd0 100644 --- a/lib/conf.h +++ b/lib/conf.h @@ -129,10 +129,10 @@ struct cf_section { /* If you aren't picky about the number of parameters */ #define CF_ANY_NUM -0x7fffffff -#define DARY_LEN(a) *(uns*)(a-1) +#define DARY_LEN(a) ((uns*)a)[-1] // length of a dynamic array -#define DARY_ALLOC(type,len,val...) (type[]) { (type)len, ##val } + 1 - // creates a static instance of a dynamic array, works only for integer and pointer types +#define DARY_ALLOC(type,len,val...) ((struct { uns l; type a[len]; }) { .l = len, .a = { val } }).a + // creates a static instance of a dynamic array /* Memory allocation: conf-alloc.c */ struct mempool;