X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Farray%2Ftest%2Frun.c;h=f999b213ea30e775c4b0b3612fbc77b07aa6aa5b;hp=718522b94e0cdeabe16ebcc18cd7c03e10d46c4d;hb=c1daa044b22fce3ca80d3430e3e1ad9360f8a4f1;hpb=ee7d1a1c0bcc551acf85df893914f054bc61842d diff --git a/ccan/array/test/run.c b/ccan/array/test/run.c index 718522b9..f999b213 100644 --- a/ccan/array/test/run.c +++ b/ccan/array/test/run.c @@ -1,25 +1,370 @@ #include #include #include "array/array.h" +#include "array/array.c" #define countof(array...) (sizeof(array)/sizeof(*(array))) #include "lotsOfNumbers.h" +#include "lotsOfStrings.h" + +struct { + char *stringsF, *stringsB; + //items of lotsOfStrings glued together + size_t stringsSize; //total strlen of all strings combined +} amalgams; + +static void generateAmalgams(void); +static void freeAmalgams(void); +static int isZeros(void *ptr, size_t size); +static void memtile(void *dest, size_t destWidth, const void *src, size_t srcWidth); + + +#if 0 +#define testing(...) printf("Testing %s...\n", #__VA_ARGS__) +#define trace(...) do {printf(__VA_ARGS__); puts("");} while(0) +#else +#define testing(...) do {} while(0) +#define trace(...) do {} while(0) +#endif + +#include "testLits.h" int main(void) { - Array(long) array = NewArray(); + #ifndef ARRAY_USE_TALLOC + array(long) arr = array_new(); + array_char str = array_new(); + #define reset(array) do {array_free(array); array_init(array);} while(0) + #else + array(long) arr = array_new(NULL); + array_char str = array_new(NULL); + #define reset(array) do {array_free(array); array_init(array, NULL);} while(0) + #endif size_t i; - plan_tests(3); + trace("Generating amalgams (internal)"); + generateAmalgams(); + + plan_tests(41); + + testLits(); + testing(array_push); { for (i=0; i= array.size); - ok1(!memcmp(array.item, lotsOfNumbers, sizeof(lotsOfNumbers))); + array_push(arr, lotsOfNumbers[i]); + ok1(arr.size == countof(lotsOfNumbers)); + ok1(arr.alloc >= arr.size); + ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); + } + reset(arr); + + testing(array_prepend, array_pop_nocheck); + { + for (i=countof(lotsOfNumbers); i;) + array_prepend(arr, lotsOfNumbers[--i]); + ok1(arr.size == countof(lotsOfNumbers)); + ok1(arr.alloc >= arr.size); + ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); + + for (i=countof(lotsOfNumbers); i;) { + if (array_pop_nocheck(arr) != (long)lotsOfNumbers[--i]) { + i++; + break; + } + } + ok1(i==0); + ok1(arr.size == 0); + } + reset(arr); + + testing(array_from_c, array_for, array_rof); + { + size_t i_correct, r_correct; + + array_from_c(arr, lotsOfNumbers); + ok1(arr.size == countof(lotsOfNumbers)); + ok1(arr.alloc >= arr.size); + ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); + + i_correct = 0; + r_correct = countof(lotsOfNumbers)-1; + array_for(i, arr, + if (i_correct != _i) + break; + if (r_correct != _r) + break; + if (i != arr.item+_i) + break; + if (*i != (long)lotsOfNumbers[_i]) + break; + i_correct++; + r_correct--; + ); + ok1(i_correct == countof(lotsOfNumbers)); + + i_correct = countof(lotsOfNumbers)-1; + r_correct = 0; + array_rof(i, arr, + if (i_correct != _i) + break; + if (r_correct != _r) + break; + if (i != arr.item+_i) + break; + if (*i != (long)lotsOfNumbers[_i]) + break; + i_correct--; + r_correct++; + ); + ok1(r_correct == countof(lotsOfNumbers)); + } + reset(arr); + + testing(array_append_string); + { + for (i=0; i str.size); + ok1(str.item[str.size] == 0); + ok1(!strcmp(str.item, amalgams.stringsF)); + } + reset(str); + + testing(array_prepend_string); + { + for (i=0; i str.size); + ok1(str.item[str.size] == 0); + ok1(!strcmp(str.item, amalgams.stringsB)); + } + reset(str); + + testing(array_from_string); + { + for (i=0; iprevSize) { + if (!isZeros(arr.item+prevSize, (size-prevSize)*sizeof(*arr.item))) + break; + } + //fill the array with lotsOfNumbers garbage + memtile(arr.item, arr.size*sizeof(*arr.item), lotsOfNumbers, sizeof(lotsOfNumbers)); + } + ok1(i==countof(lotsOfNumbers)); + } + reset(arr); + + testing(array_realloc); + { + size_t s,a; + for (i=0; i> 16); + //give size a nonsense value to make sure array_realloc doesn't care about it + a = amalgams.stringsSize/sizeof(*arr.item)+2; + array_realloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); + if (a*sizeof(*arr.item) > amalgams.stringsSize) + break; + if (arr.alloc != a) + break; + if (arr.size != s) + break; + memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item)); + if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item))) + break; + } + ok1(i==countof(lotsOfNumbers)); } - AFree(array); - AInit(array); + reset(arr); + + testing(array_growalloc); + { + size_t prevA, s, a; + for (i=0; i> 16); + //give size a nonsense value to make sure array_growalloc doesn't care about it + a = amalgams.stringsSize/sizeof(*arr.item)+2; + prevA = arr.alloc; + array_growalloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); + if (a*sizeof(*arr.item) > amalgams.stringsSize) + break; + if (arr.alloc < a) + break; + if (arr.alloc < prevA) + break; + if (arr.size != s) + break; + + memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item)); + if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item))) + break; + + //clear the array every now and then + if (!(lotsOfNumbers[i] & 15)) { + reset(arr); + } + } + ok1(i==countof(lotsOfNumbers)); + } + reset(arr); + + testing(array_make_room); + { + for (i=0; i=4); + + array_prepends(array, n[0], n[1], n[2], n[3], n[4]); + ok1(array.size==9 && array.alloc>=9); + + ok1(array.item[0]==n[0] && + array.item[1]==n[1] && + array.item[2]==n[2] && + array.item[3]==n[3] && + array.item[4]==n[4] && + array.item[5]==n[5] && + array.item[6]==n[6] && + array.item[7]==n[7] && + array.item[8]==n[8]); + + ok1(array_pop(array)==n[8] && + array_pop(array)==n[7] && + array_pop(array)==n[6] && + array_pop(array)==n[5] && + array_pop(array)==n[4] && + array_pop(array)==n[3] && + array_pop(array)==n[2] && + array_pop(array)==n[1] && + array_pop(array)==n[0]); + + ok1(array.size==0); + + ok1(array_pop(array)==NULL && array_pop(array)==NULL && array_pop(array)==NULL); + + array_free(array); + } + + trace("Freeing amalgams (internal)"); + freeAmalgams(); return 0; } + +static void generateAmalgams(void) { + size_t i; + size_t lotsOfStringsLen = 0; + const char *src; + char *p; + + for (i=0; i8) { + //test one byte at a time until we have an aligned size_t pointer + while ((size_t)pc & (sizeof(size_t)-1)) + if (*pc++) + return 0; + pl = (size_t*)pc; + size -= pc-(unsigned char*)ptr; + while (size >= sizeof(size_t)) { + size -= sizeof(size_t); + if (*pl++) + return 0; + } + pc = (unsigned char*)pl; + } + while (size--) + if (*pc++) + return 0; + return 1; +} + +static void memtile(void *dest, size_t destWidth, const void *src, size_t srcWidth) { + char *d = dest; + while (destWidth > srcWidth) { + destWidth -= srcWidth; + memcpy(d, src, srcWidth); + d += srcWidth; + } + memcpy(d, src, destWidth); +}