void graph_free_all(Graph *g, FreeFn vertex_data_freefn) { unsigned long index; Vertex *v; assert(g != NULL); if(NULL == vertex_data_freefn) { /* Default to stdlib free */ vertex_data_freefn = free; } /* Free edge lists and vertex data */ for(index = 0; index < darray_size(g->vertices); index++) { v = (Vertex *)darray_index(g->vertices, index); vertex_data_freefn(v->data); darray_free_all(v->edges, NULL); } /* Free vertex list */ darray_free_all(g->vertices, NULL); /* Free graph container */ free(g); }
void vertex_free(Vertex *v) { assert(v != NULL); darray_free_all(v->edges, NULL); free(v); }
/* Complexity: O(n) */ void heap_free_all(Heap *heap, FreeFn freefn) { assert(heap != NULL); /* Free heap and darray containers, and all data */ darray_free_all(heap->h, freefn); free(heap); }
void vertex_free_all(Vertex *v, FreeFn data_freefn) { assert(v != NULL); if(NULL == data_freefn) { /* Default to stdlib free */ data_freefn = free; } data_freefn(v->data); darray_free_all(v->edges, NULL); free(v); }
int main(void) { darray(long) arr = darray_new(); darray_char str = darray_new(); darray(long*) arrp = darray_new(); arrp.onFree = _arr_free_handler; #define reset(arr) do {darray_free(arr); darray_init(arr);} while(0) size_t i; trace("Generating amalgams (internal)"); generateAmalgams(); plan_tests(54); testLits(); testing(darray_pushptr); { int vMaxCount = 10;//ARRAY_SIZE(lotsOfNumbers); for (int k=0; k < vMaxCount; k++) { long* p = malloc(sizeof(long)); *p = lotsOfNumbers[k]; darray_push(arrp, p); } ok1(darray_size(arrp) == vMaxCount); ok1(darray_alloc(arrp) >= darray_size(arrp)); long **i; size_t j = 0; darray_foreach(i, arrp) { if (i - arrp.item != j) break; if (**i != (long)lotsOfNumbers[j]) break; j++; }; ok1(j == vMaxCount); darray_free_all(arrp); ok1(_free_count == vMaxCount); } testing(darray_push); { for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) darray_push(arr, lotsOfNumbers[i]); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); } testing(darray_insert); { darray_insert(arr, 0, 123456); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)+1); ok1(!memcmp(arr.item+1, lotsOfNumbers, sizeof(lotsOfNumbers))); ok1(darray_item(arr, 0) == 123456); darray_insert(arr, 15, 0x112233); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)+2); ok1(darray_item(arr, 15) == 0x112233); ok1(!memcmp(arr.item+1, lotsOfNumbers, 14*sizeof(long))); ok1(!memcmp(arr.item+16, &lotsOfNumbers[14], ARRAY_SIZE(lotsOfNumbers)-(15*sizeof(long)))); } testing(darray_del); { darray_del(arr, 15); darray_del(arr, 0); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); } reset(arr); testing(darray_prepend, darray_pop); { for (i = ARRAY_SIZE(lotsOfNumbers); i;) darray_prepend(arr, lotsOfNumbers[--i]); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); for (i = ARRAY_SIZE(lotsOfNumbers); i;) { if (darray_pop(arr) != (long)lotsOfNumbers[--i]) { i++; break; } } ok1(i==0); ok1(darray_size(arr) == 0); } reset(arr); testing(darray_from_c, darray_foreach, darray_foreach_reverse); { long *i; size_t j; darray_from_c(arr, lotsOfNumbers); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers)) == 0); j = 0; darray_foreach(i, arr) { if (i - arr.item != j) break; if (*i != (long)lotsOfNumbers[j]) break; j++; }; ok1(j == ARRAY_SIZE(lotsOfNumbers)); j = 0; darray_foreach_reverse(i, arr) { if (i - arr.item != darray_size(arr)-j-1) break; if (*i != (long)lotsOfNumbers[darray_size(arr)-j-1]) break; j++; }; ok1(j == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_append_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) darray_append_string(str, lotsOfStrings[i]); ok1(str.size == amalgams.stringsSize); ok1(str.alloc > str.size); ok1(str.item[str.size] == 0); ok1(!strcmp(str.item, amalgams.stringsF)); } reset(str); testing(darray_prepend_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) darray_prepend_string(str, lotsOfStrings[i]); ok1(str.size == amalgams.stringsSize); ok1(str.alloc > str.size); ok1(str.item[str.size] == 0); ok1(!strcmp(str.item, amalgams.stringsB)); } reset(str); testing(darray_from_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) { darray_from_string(str, lotsOfStrings[i]); if (str.size != strlen(lotsOfStrings[i])) break; if (str.alloc < strlen(lotsOfStrings[i])+1) break; if (strcmp(str.item, lotsOfStrings[i])) break; } ok1(i == ARRAY_SIZE(lotsOfStrings)); } reset(str); testing(darray_resize0); { size_t prevSize=0, size; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++, prevSize=size) { size = lotsOfNumbers[i] & 0xFFFF; darray_resize0(arr, size); if (darray_size(arr) != size) break; if (darray_alloc(arr) < size) break; if (size>prevSize) { if (!isZeros(arr.item+prevSize, (size-prevSize)*sizeof(*arr.item))) break; } //fill the darray with lotsOfNumbers garbage memtile(arr.item, darray_size(arr)*sizeof(*arr.item), lotsOfNumbers, sizeof(lotsOfNumbers)); } ok1(i == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_realloc); { size_t s,a; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) { arr.size = (s = lotsOfNumbers[i] >> 16); //give size a nonsense value to make sure darray_realloc doesn't care about it a = amalgams.stringsSize/sizeof(*arr.item)+2; darray_realloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); if (a*sizeof(*arr.item) > amalgams.stringsSize) break; if (darray_alloc(arr) != a) break; if (darray_size(arr) != 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 == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_growalloc); { size_t prevA, s, a; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) { arr.size = (s = lotsOfNumbers[i] >> 16); //give size a nonsense value to make sure darray_growalloc doesn't care about it a = amalgams.stringsSize/sizeof(*arr.item)+2; prevA = darray_alloc(arr); darray_growalloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); if (a*sizeof(*arr.item) > amalgams.stringsSize) break; if (darray_alloc(arr) < a) break; if (darray_alloc(arr) < prevA) break; if (darray_size(arr) != 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 darray every now and then if (!(lotsOfNumbers[i] & 15)) { reset(arr); } } ok1(i == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_make_room); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) { char *dest = darray_make_room(str, strlen(lotsOfStrings[i])); if (str.alloc < str.size+strlen(lotsOfStrings[i])) break; if (dest != str.item+str.size) break; memcpy(dest, lotsOfStrings[i], strlen(lotsOfStrings[i])); str.size += strlen(lotsOfStrings[i]); } ok1(i == ARRAY_SIZE(lotsOfStrings)); ok1(str.size == amalgams.stringsSize); darray_append(str, 0); ok1(!strcmp(str.item, amalgams.stringsF)); } reset(str); testing(darray_appends, darray_prepends, darray_pop_check); { darray(const char*) arr = darray_new(); const char *n[9] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight"}; #if HAVE_TYPEOF darray_appends(arr, n[5], n[6], n[7], n[8]); #else darray_appends_t(arr, const char *, n[5], n[6], n[7], n[8]); #endif ok1(darray_size(arr)==4 && darray_alloc(arr)>=4); #if HAVE_TYPEOF darray_prepends(arr, n[0], n[1], n[2], n[3], n[4]); #else darray_prepends_t(arr, const char *, n[0], n[1], n[2], n[3], n[4]); #endif ok1(darray_size(arr)==9 && darray_alloc(arr)>=9); ok1(arr.item[0]==n[0] && arr.item[1]==n[1] && arr.item[2]==n[2] && arr.item[3]==n[3] && arr.item[4]==n[4] && arr.item[5]==n[5] && arr.item[6]==n[6] && arr.item[7]==n[7] && arr.item[8]==n[8]); ok1(darray_pop_check(arr)==n[8] && darray_pop_check(arr)==n[7] && darray_pop_check(arr)==n[6] && darray_pop_check(arr)==n[5] && darray_pop_check(arr)==n[4] && darray_pop_check(arr)==n[3] && darray_pop_check(arr)==n[2] && darray_pop_check(arr)==n[1] && darray_pop_check(arr)==n[0]); ok1(darray_size(arr)==0); ok1(darray_pop_check(arr)==NULL && darray_pop_check(arr)==NULL && darray_pop_check(arr)==NULL); darray_free(arr); } trace("Freeing amalgams (internal)"); freeAmalgams(); return exit_status(); }