2 #include <ccan/tap/tap.h>
3 #include <ccan/array/array.h>
4 #include <ccan/array/array.c>
6 #define countof(array...) (sizeof(array)/sizeof(*(array)))
7 #include "lotsOfNumbers.h"
8 #include "lotsOfStrings.h"
11 char *stringsF, *stringsB;
12 //items of lotsOfStrings glued together
13 size_t stringsSize; //total strlen of all strings combined
16 static void generateAmalgams(void);
17 static void freeAmalgams(void);
18 static int isZeros(void *ptr, size_t size);
19 static void memtile(void *dest, size_t destWidth, const void *src, size_t srcWidth);
23 #define testing(...) printf("Testing %s...\n", #__VA_ARGS__)
24 #define trace(...) do {printf(__VA_ARGS__); puts("");} while(0)
26 #define testing(...) do {} while(0)
27 #define trace(...) do {} while(0)
33 #ifndef ARRAY_USE_TALLOC
34 array(long) arr = array_new();
35 array_char str = array_new();
36 #define reset(array) do {array_free(array); array_init(array);} while(0)
38 array(long) arr = array_new(NULL);
39 array_char str = array_new(NULL);
40 #define reset(array) do {array_free(array); array_init(array, NULL);} while(0)
44 trace("Generating amalgams (internal)");
53 for (i=0; i<countof(lotsOfNumbers); i++)
54 array_push(arr, lotsOfNumbers[i]);
55 ok1(arr.size == countof(lotsOfNumbers));
56 ok1(arr.alloc >= arr.size);
57 ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers)));
61 testing(array_prepend, array_pop);
63 for (i=countof(lotsOfNumbers); i;)
64 array_prepend(arr, lotsOfNumbers[--i]);
65 ok1(arr.size == countof(lotsOfNumbers));
66 ok1(arr.alloc >= arr.size);
67 ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers)));
69 for (i=countof(lotsOfNumbers); i;) {
70 if (array_pop(arr) != (long)lotsOfNumbers[--i]) {
80 testing(array_from_c, array_for, array_rof);
82 size_t i_correct, r_correct;
84 array_from_c(arr, lotsOfNumbers);
85 ok1(arr.size == countof(lotsOfNumbers));
86 ok1(arr.alloc >= arr.size);
87 ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers)));
90 r_correct = countof(lotsOfNumbers)-1;
98 if (*i != (long)lotsOfNumbers[_i])
103 ok1(i_correct == countof(lotsOfNumbers));
105 i_correct = countof(lotsOfNumbers)-1;
112 if (i != arr.item+_i)
114 if (*i != (long)lotsOfNumbers[_i])
119 ok1(r_correct == countof(lotsOfNumbers));
123 testing(array_append_string);
125 for (i=0; i<countof(lotsOfStrings); i++)
126 array_append_string(str, lotsOfStrings[i]);
127 ok1(str.size == amalgams.stringsSize);
128 ok1(str.alloc > str.size);
129 ok1(str.item[str.size] == 0);
130 ok1(!strcmp(str.item, amalgams.stringsF));
134 testing(array_prepend_string);
136 for (i=0; i<countof(lotsOfStrings); i++)
137 array_prepend_string(str, lotsOfStrings[i]);
138 ok1(str.size == amalgams.stringsSize);
139 ok1(str.alloc > str.size);
140 ok1(str.item[str.size] == 0);
141 ok1(!strcmp(str.item, amalgams.stringsB));
145 testing(array_from_string);
147 for (i=0; i<countof(lotsOfStrings); i++) {
148 array_from_string(str, lotsOfStrings[i]);
149 if (str.size != strlen(lotsOfStrings[i]))
151 if (str.alloc < strlen(lotsOfStrings[i])+1)
153 if (strcmp(str.item, lotsOfStrings[i]))
156 ok1(i == countof(lotsOfStrings));
160 testing(array_resize0);
162 size_t prevSize=0, size;
163 for (i=0; i<countof(lotsOfNumbers); i++, prevSize=size) {
164 size = lotsOfNumbers[i] & 0xFFFF;
165 array_resize0(arr, size);
166 if (arr.size != size)
168 if (arr.alloc < size)
171 if (!isZeros(arr.item+prevSize, (size-prevSize)*sizeof(*arr.item)))
174 //fill the array with lotsOfNumbers garbage
175 memtile(arr.item, arr.size*sizeof(*arr.item), lotsOfNumbers, sizeof(lotsOfNumbers));
177 ok1(i==countof(lotsOfNumbers));
181 testing(array_realloc);
184 for (i=0; i<countof(lotsOfNumbers); i++) {
185 arr.size = (s = lotsOfNumbers[i] >> 16);
186 //give size a nonsense value to make sure array_realloc doesn't care about it
187 a = amalgams.stringsSize/sizeof(*arr.item)+2;
188 array_realloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1));
189 if (a*sizeof(*arr.item) > amalgams.stringsSize)
195 memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item));
196 if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item)))
199 ok1(i==countof(lotsOfNumbers));
203 testing(array_growalloc);
206 for (i=0; i<countof(lotsOfNumbers); i++) {
207 arr.size = (s = lotsOfNumbers[i] >> 16);
208 //give size a nonsense value to make sure array_growalloc doesn't care about it
209 a = amalgams.stringsSize/sizeof(*arr.item)+2;
211 array_growalloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1));
212 if (a*sizeof(*arr.item) > amalgams.stringsSize)
216 if (arr.alloc < prevA)
221 memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item));
222 if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item)))
225 //clear the array every now and then
226 if (!(lotsOfNumbers[i] & 15)) {
230 ok1(i==countof(lotsOfNumbers));
234 testing(array_make_room);
236 for (i=0; i<countof(lotsOfStrings); i++) {
237 char *dest = array_make_room(str, strlen(lotsOfStrings[i]));
238 if (str.alloc < str.size+strlen(lotsOfStrings[i]))
240 if (dest != str.item+str.size)
243 memcpy(dest, lotsOfStrings[i], strlen(lotsOfStrings[i]));
244 str.size += strlen(lotsOfStrings[i]);
246 ok1(i==countof(lotsOfStrings));
247 ok1(str.size == amalgams.stringsSize);
249 array_append(str, 0);
250 ok1(!strcmp(str.item, amalgams.stringsF));
254 testing(array_appends, array_prepends, array_pop_check);
256 #ifndef ARRAY_USE_TALLOC
257 array(const char*) array = array_new();
259 array(const char*) array = array_new(NULL);
261 const char *n[9] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight"};
263 array_appends(array, n[5], n[6], n[7], n[8]);
264 ok1(array.size==4 && array.alloc>=4);
266 array_prepends(array, n[0], n[1], n[2], n[3], n[4]);
267 ok1(array.size==9 && array.alloc>=9);
269 ok1(array.item[0]==n[0] &&
270 array.item[1]==n[1] &&
271 array.item[2]==n[2] &&
272 array.item[3]==n[3] &&
273 array.item[4]==n[4] &&
274 array.item[5]==n[5] &&
275 array.item[6]==n[6] &&
276 array.item[7]==n[7] &&
277 array.item[8]==n[8]);
279 ok1(array_pop_check(array)==n[8] &&
280 array_pop_check(array)==n[7] &&
281 array_pop_check(array)==n[6] &&
282 array_pop_check(array)==n[5] &&
283 array_pop_check(array)==n[4] &&
284 array_pop_check(array)==n[3] &&
285 array_pop_check(array)==n[2] &&
286 array_pop_check(array)==n[1] &&
287 array_pop_check(array)==n[0]);
291 ok1(array_pop_check(array)==NULL && array_pop_check(array)==NULL && array_pop_check(array)==NULL);
296 trace("Freeing amalgams (internal)");
299 return exit_status();
302 static void generateAmalgams(void) {
304 size_t lotsOfStringsLen = 0;
308 for (i=0; i<countof(lotsOfStrings); i++)
309 lotsOfStringsLen += strlen(lotsOfStrings[i]);
310 amalgams.stringsSize = lotsOfStringsLen;
312 amalgams.stringsF = malloc(lotsOfStringsLen+1);
313 amalgams.stringsB = malloc(lotsOfStringsLen+1);
315 for (i=0,p=amalgams.stringsF; i<countof(lotsOfStrings); i++) {
316 size_t len = strlen(src=lotsOfStrings[i]);
321 ok1(p-amalgams.stringsF == (long)lotsOfStringsLen);
322 ok1(strlen(amalgams.stringsF) == lotsOfStringsLen);
324 for (i=countof(lotsOfStrings),p=amalgams.stringsB; i--;) {
325 size_t len = strlen(src=lotsOfStrings[i]);
330 ok1(p-amalgams.stringsB == (long)lotsOfStringsLen);
331 ok1(strlen(amalgams.stringsB) == lotsOfStringsLen);
334 static void freeAmalgams(void) {
335 free(amalgams.stringsF);
336 free(amalgams.stringsB);
339 static int isZeros(void *ptr, size_t size) {
340 unsigned char *pc = ptr;
343 //test one byte at a time until we have an aligned size_t pointer
344 while ((size_t)pc & (sizeof(size_t)-1))
348 size -= pc-(unsigned char*)ptr;
349 while (size >= sizeof(size_t)) {
350 size -= sizeof(size_t);
354 pc = (unsigned char*)pl;
362 static void memtile(void *dest, size_t destWidth, const void *src, size_t srcWidth) {
364 while (destWidth > srcWidth) {
365 destWidth -= srcWidth;
366 memcpy(d, src, srcWidth);
369 memcpy(d, src, destWidth);