diff --git a/src/contrib/dynarray.h b/src/contrib/dynarray.h index 900eb6672..4125da525 100644 --- a/src/contrib/dynarray.h +++ b/src/contrib/dynarray.h @@ -42,43 +42,56 @@ typedef struct prefix ## _dynarray { \ ssize_t capacity; \ ssize_t size; \ + ntype *(*arr)(struct prefix ## _dynarray *dynarray); \ ntype init[initial_capacity]; \ - ntype *arr; \ + ntype *_arr; \ } prefix ## _dynarray_t; \ \ - visibility void prefix ## _dynarray_fix(prefix ## _dynarray_t *dynarray); \ + visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \ visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \ ntype const *to_add); \ visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray); #define dynarray_foreach(prefix, ntype, ptr, array) \ - for (ntype *ptr = (prefix ## _dynarray_fix(&(array)), (array).arr); \ - ptr < (array).arr + (array).size; ptr++) + for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \ + ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++) #define dynarray_define(prefix, ntype, visibility, initial_capacity) \ \ static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \ { \ - if (dynarray->capacity > initial_capacity) { \ - free(dynarray->arr); \ + if (dynarray->capacity > (initial_capacity)) { \ + free(dynarray->_arr); \ } \ } \ \ __attribute__((unused)) \ - visibility void prefix ## _dynarray_fix(struct prefix ## _dynarray *dynarray) \ + visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \ { \ assert(dynarray->size <= dynarray->capacity); \ - if (dynarray->capacity <= initial_capacity) { \ - dynarray->capacity = initial_capacity; \ - dynarray->arr = dynarray->init; \ - } \ + return (dynarray->capacity <= (initial_capacity) ? dynarray->init : dynarray->_arr); \ + } \ + \ + static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \ + { \ + assert(dynarray->capacity == (initial_capacity)); \ + return dynarray->init; \ + } \ + \ + static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \ + { \ + assert(dynarray->capacity > (initial_capacity)); \ + return dynarray->_arr; \ } \ \ __attribute__((unused)) \ visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \ ntype const *to_add) \ { \ - prefix ## _dynarray_fix(dynarray); \ + if (dynarray->capacity == 0) { \ + dynarray->capacity = (initial_capacity); \ + dynarray->arr = prefix ## _dynarray_arr_init__; \ + } \ if (dynarray->size >= dynarray->capacity) { \ ssize_t new_capacity = dynarray->capacity * 2 + 1; \ ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \ @@ -88,14 +101,15 @@ return; \ } \ if (dynarray->capacity > 0) { \ - memcpy(new_arr, dynarray->arr, \ + memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \ dynarray->capacity * sizeof(ntype)); \ } \ prefix ## _dynarray_free__(dynarray); \ - dynarray->arr = new_arr; \ + dynarray->_arr = new_arr; \ dynarray->capacity = new_capacity; \ + dynarray->arr = prefix ## _dynarray_arr_arr__; \ } \ - dynarray->arr[dynarray->size++] = *to_add; \ + prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \ } \ \ __attribute__((unused)) \ diff --git a/src/knot/conf/module.c b/src/knot/conf/module.c index 8d97dbbb5..dbb0a96ed 100644 --- a/src/knot/conf/module.c +++ b/src/knot/conf/module.c @@ -289,7 +289,7 @@ void conf_mod_load_purge( // Switch the current temporary schema with the initial one. if (temporary && conf->old_schemas.size > 0) { yp_item_t **current_schema = &conf->schema; - yp_item_t **initial = &(conf->old_schemas.arr)[0]; + yp_item_t **initial = &(conf->old_schemas.arr(&conf->old_schemas))[0]; yp_item_t *old_schema = rcu_xchg_pointer(current_schema, *initial); synchronize_rcu(); diff --git a/src/knot/dnssec/zone-sign.c b/src/knot/dnssec/zone-sign.c index a393632cb..f984da1f0 100644 --- a/src/knot/dnssec/zone-sign.c +++ b/src/knot/dnssec/zone-sign.c @@ -685,14 +685,13 @@ static bool is_from_keyset(zone_keyset_t *keyset, bool found = false; struct keyptr_dynarray keys = get_zone_keys(keyset, tag); - keyptr_dynarray_fix(&keys); for (size_t i = 0; i < keys.size; i++) { - bool usekey = (is_cds_cdnskey ? (keys.arr[i]->is_ready && !keys.arr[i]->is_active) : keys.arr[i]->is_public); - if (usekey && match_fce(keys.arr[i], &rdata)) { + bool usekey = (is_cds_cdnskey ? (keys.arr(&keys)[i]->is_ready && !keys.arr(&keys)[i]->is_active) : keys.arr(&keys)[i]->is_public); + if (usekey && match_fce(keys.arr(&keys)[i], &rdata)) { found = true; if (matching_key != NULL) { - *matching_key = keys.arr[i]; + *matching_key = keys.arr(&keys)[i]; } break; } diff --git a/tests/contrib/test_dynarray.c b/tests/contrib/test_dynarray.c index b355cc10c..e91839696 100644 --- a/tests/contrib/test_dynarray.c +++ b/tests/contrib/test_dynarray.c @@ -19,42 +19,61 @@ #include "contrib/dynarray.h" -#define test_capacity 2 +#define test_capacity 5 +// minimum 3 -#define test_type(type, prefix) \ - dynarray_declare(prefix, type, DYNARRAY_VISIBILITY_STATIC, test_capacity) \ - dynarray_define(prefix, type, DYNARRAY_VISIBILITY_STATIC, test_capacity) \ - static void prefix ## _test(type const first, type const second) { \ - struct prefix ## _dynarray array = { 0 }; \ - prefix ## _dynarray_fix(&array); \ - ok(array.capacity == test_capacity && array.size == 0 && array.init == array.arr, \ - "%s: Fix - initial capacity set", #prefix); \ - prefix ## _dynarray_add(&array, &first); \ - ok(array.capacity == test_capacity && array.size == 1 && array.arr[0] == first && \ - array.init == array.arr, "%s: Add item", #prefix); \ - prefix ## _dynarray_add(&array, &second); \ - ok(array.capacity == test_capacity && array.size == 2 && array.arr[1] == second && \ - array.init == array.arr, "%s: Array filled (size not changed yet)", #prefix); \ - prefix ## _dynarray_add(&array, &first); \ - ok(array.capacity == 2 * test_capacity + 1 && array.size == 3 && array.arr[2] == first && \ - array.init != array.arr, "%s: Array extended", #prefix); \ - prefix ## _dynarray_free(&array); \ - prefix ## _dynarray_add(&array, &first); \ - ok(array.capacity == test_capacity && array.size == 1 && array.arr[0] == first && \ - array.init == array.arr, "%s: Free & add first- initial capacity set", #prefix); \ +typedef struct { + int x; + int x2; +} quadrate_t; + +dynarray_declare(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity); +dynarray_define(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity); + +static q_dynarray_t q_fill(size_t howmany) +{ + quadrate_t q = { 0 }; + q_dynarray_t qd = { 0 }; + + for (size_t i = 0; i < howmany; i++) { + q.x2 = q.x * q.x; + q_dynarray_add(&qd, &q); + q.x++; } + return qd; +} -test_type(int, int) -test_type(char *, string) +static void check_arr(q_dynarray_t *q, size_t index, const char *msg) +{ + quadrate_t *arr = q->arr(q); + ok(arr[index].x == index && arr[index].x2 == index * index, + "%s check: index %zu", msg, index); + + size_t i = 0; + dynarray_foreach(q, quadrate_t, p, *q) { + ok(p->x == i && p->x2 == i * i, "%s foreach: index %zu", msg, i); + i++; + } +} int main(int argc, char *argv[]) { plan_lazy(); - int_test(4, 2); + // first fill + q_dynarray_t q = q_fill(test_capacity - 1); + check_arr(&q, test_capacity - 3, "initial"); + q_dynarray_free(&q); - char a = 'a', b = 'b'; - string_test(&a, &b); + // second fill + q = q_fill(test_capacity + 3); + check_arr(&q, test_capacity + 1, "second"); + q_dynarray_free(&q); + + // third fill + q = q_fill(test_capacity * 5); + check_arr(&q, test_capacity * 4, "third"); + q_dynarray_free(&q); return 0; }