|  | #include "dynarray.h" | 
|  | #include <limits.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  |  | 
|  | void | 
|  | dynarray_init( dynarray_t *a ) | 
|  | { | 
|  | a->count = a->capacity = 0; | 
|  | a->items = NULL; | 
|  | } | 
|  |  | 
|  |  | 
|  | static void | 
|  | dynarray_reserve_more( dynarray_t *a, int count ) | 
|  | { | 
|  | int old_cap = a->capacity; | 
|  | int new_cap = old_cap; | 
|  | const int max_cap = INT_MAX/sizeof(void*); | 
|  | void** new_items; | 
|  | int new_count = a->count + count; | 
|  |  | 
|  | if (count <= 0) | 
|  | return; | 
|  |  | 
|  | if (count > max_cap - a->count) | 
|  | abort(); | 
|  |  | 
|  | new_count = a->count + count; | 
|  |  | 
|  | while (new_cap < new_count) { | 
|  | old_cap = new_cap; | 
|  | new_cap += (new_cap >> 2) + 4; | 
|  | if (new_cap < old_cap || new_cap > max_cap) { | 
|  | new_cap = max_cap; | 
|  | } | 
|  | } | 
|  | new_items = realloc(a->items, new_cap*sizeof(void*)); | 
|  | if (new_items == NULL) | 
|  | abort(); | 
|  |  | 
|  | a->items = new_items; | 
|  | a->capacity = new_cap; | 
|  | } | 
|  |  | 
|  | void | 
|  | dynarray_append( dynarray_t *a, void* item ) | 
|  | { | 
|  | if (a->count >= a->capacity) | 
|  | dynarray_reserve_more(a, 1); | 
|  |  | 
|  | a->items[a->count++] = item; | 
|  | } | 
|  |  | 
|  | void | 
|  | dynarray_done( dynarray_t *a ) | 
|  | { | 
|  | free(a->items); | 
|  | a->items = NULL; | 
|  | a->count = a->capacity = 0; | 
|  | } | 
|  |  | 
|  | // string arrays | 
|  |  | 
|  | void strlist_init( strlist_t *list ) | 
|  | { | 
|  | dynarray_init(list); | 
|  | } | 
|  |  | 
|  | void strlist_append_b( strlist_t *list, const void* str, size_t  slen ) | 
|  | { | 
|  | char *copy = malloc(slen+1); | 
|  | memcpy(copy, str, slen); | 
|  | copy[slen] = '\0'; | 
|  | dynarray_append(list, copy); | 
|  | } | 
|  |  | 
|  | void strlist_append_dup( strlist_t *list, const char *str) | 
|  | { | 
|  | strlist_append_b(list, str, strlen(str)); | 
|  | } | 
|  |  | 
|  | void strlist_done( strlist_t *list ) | 
|  | { | 
|  | STRLIST_FOREACH(list, string, free(string)); | 
|  | dynarray_done(list); | 
|  | } | 
|  |  | 
|  | static int strlist_compare_strings(const void* a, const void* b) | 
|  | { | 
|  | const char *sa = *(const char **)a; | 
|  | const char *sb = *(const char **)b; | 
|  | return strcmp(sa, sb); | 
|  | } | 
|  |  | 
|  | void strlist_sort( strlist_t *list ) | 
|  | { | 
|  | if (list->count > 0) { | 
|  | qsort(list->items, | 
|  | (size_t)list->count, | 
|  | sizeof(void*), | 
|  | strlist_compare_strings); | 
|  | } | 
|  | } |