#include #include #include #include #include "tools/dynarray.h" #define dynarr_init(tp, defaul) \ { \ tp dflt = defaul; \ d = dynarray_init(sizeof (tp), &dflt); \ } #define dynarr_test(tp, func, sz, val) \ { \ tp *item = (tp *)func; \ for (i = 0; i < sz; i++) \ assert(item[i] == val); \ free(item); \ } #define dynarr_peek_test(tp, sz, val) { \ for (i = 0; i < sz; i++) \ assert(*(const tp *)dynarray_peek(d, i) == val); \ } int main(int argc, char **argv) { dynarray *d; uint32_t tarrsize; int *tarr; /* int tarr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; */ uint32_t i; unsigned int seed; if (argc == 2) seed = (unsigned int)strtoul(argv[1], NULL, 10); else seed = (unsigned int)time(NULL); srand(seed); tarrsize = (uint16_t)rand() + 1; /* Generate a random table */ if (!(tarr = (int *)malloc(tarrsize * sizeof(int)))) { printf("Couldn't allocate a random array!"); return 1; } for (i = 0; i < tarrsize; i++) tarr[i] = (int)rand(); /* tarrsize = 8; */ printf("\nTesting dynarray:\n"); printf("Random seed: %u\n", seed); printf("Test array size: %u\n", tarrsize); printf("Test item size in bytes: %lu\n\n", sizeof tarr[0]); printf("Allocating array\n"); dynarr_init(int, 0); assert(d); printf("Trying to get a nonexistent element\n"); assert(!dynarray_get(d, 0, 1)); printf("Adding some elements\n"); assert(dynarray_append(d, tarr, tarrsize)); printf("Putting the elements at position 3*array size\n"); assert(dynarray_put(d, 3*tarrsize, tarr, tarrsize)); printf("Array currently allocates %u bytes\n", d->avail); printf("Checking length\n"); assert(d->count == 4*tarrsize); /* Additional debug - not needed for (i = 0; i < d->count; i++) printf("%d: %lf\n", i, *(const int *)dynarray_peek(d, i)); */ printf("Checking element 2*array size - should be zero\n"); dynarr_test(int, dynarray_get(d, 2*tarrsize, 1), 1, 0); printf("Checking elements at 3*array size\n"); dynarr_test(int, dynarray_get(d, 3*tarrsize, tarrsize), tarrsize, tarr[i]); printf("Checking elements at beginning\n"); dynarr_test(int, dynarray_get(d, 0, tarrsize), tarrsize, tarr[i]); printf("Peeking at elements at beginning\n"); dynarr_peek_test(int, tarrsize, tarr[i]); printf("Removing first items\n"); dynarray_del(d, 0, tarrsize); printf("Checking elements at beginning again - should be zeroes\n"); dynarr_test(int, dynarray_get(d, 0, tarrsize), tarrsize, 0); printf("Checking length\n"); assert(d->count = 3*tarrsize); printf("Resizing array to 1*array size\n"); assert(dynarray_resize(d, tarrsize)); printf("Checking length\n"); assert(d->count == tarrsize); printf("Trying to get a nonexistent element\n"); assert(!dynarray_get(d, 2*tarrsize, 1)); printf("Inserting elements at beginning\n"); assert(dynarray_insert(d, 0, tarr, tarrsize)); printf("Checking length\n"); assert(d->count = 2*tarrsize); printf("Inserting elements at 4*array size\n"); assert(dynarray_insert(d, 4*tarrsize, tarr, tarrsize)); printf("Inserting elements at 2*array size\n"); assert(dynarray_insert(d, 2*tarrsize, tarr, tarrsize)); printf("Checking length\n"); assert(d->count = 6*tarrsize); printf("Array currently allocates %u bytes\n", d->avail); printf("Checking the elements at beginning\n"); dynarr_test(int, dynarray_get(d, 0, tarrsize), tarrsize, tarr[i]); printf("Checking the elements at 1*array size - should be zeroes\n"); dynarr_test(int, dynarray_get(d, 1*tarrsize, tarrsize), tarrsize, 0); printf("Checking the elements at 2*array size\n"); dynarr_test(int, dynarray_get(d, 2*tarrsize, tarrsize), tarrsize, tarr[i]); printf("Checking the elements at 3*array size - should be zeroes\n"); dynarr_test(int, dynarray_get(d, 3*tarrsize, tarrsize), tarrsize, 0); printf("Checking the elements at 4*array size - should be zeroes\n"); dynarr_test(int, dynarray_get(d, 4*tarrsize, tarrsize), tarrsize, 0); printf("Checking the elements at 5*array size\n"); dynarr_test(int, dynarray_get(d, 5*tarrsize, tarrsize), tarrsize, tarr[i]); printf("Deallocating array\n"); dynarray_free(&d); printf("Checking for null state\n"); assert(!d); printf("Allocating another array\n"); dynarr_init(int, 0); { int p = 666; printf("Testing many small allocations\n"); for (i = 0; i < 65536; i++) dynarray_append(d, &p, 1); } printf("Array currently allocates %u bytes\n", d->avail); printf("Checking length\n"); assert(d->count = 65536); printf("Deallocating array\n"); dynarray_free(&d); printf("Checking for null state\n"); assert(!d); { uint32_t maxloop = (uint16_t)rand(); uint32_t maxalloc = 100000; uint32_t delmod = 10; printf("Allocating another array\n"); dynarr_init(int, 0); printf("Testing %u allocations and deletions\n", maxloop); printf("Starting size: %u\n", d->avail); printf("Maximum allocation: %u bytes\n", maxalloc); printf("Deletion chance: 1/%u\n", delmod); if (!(tarr = (int *)realloc(tarr, maxalloc * sizeof (int)))) { printf("Memory allocation error!\n"); return 1; } for (i = 0; i < maxloop; i++) { uint32_t prevavail; tarrsize = (uint16_t)rand() + 1; prevavail = d->avail; dynarray_append(d, tarr, tarrsize); if (d->avail != prevavail) { printf("Array auto-resized on step %u, ", i); printf("new size: %u\n", d->avail); } if (!(rand() % delmod)) { /* chance of deletion */ uint32_t pos, amount; pos = (uint32_t)(d->count * (rand()/(RAND_MAX + 1.0))); amount = (uint32_t)((d->count-pos) * \ (rand()/(RAND_MAX + 1.0))); dynarray_del(d, pos, amount); } } } printf("Deallocating array\n"); dynarray_free(&d); printf("Checking for null state\n"); assert(!d); /* Make valgrind happy */ free(tarr); return 0; }