1a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner#include "dynarray.h" 2a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner#include <stdlib.h> 3a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner#include <limits.h> 4a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 5a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid 6a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerdynarray_init( dynarray_t *a ) 7a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 8a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->count = a->capacity = 0; 9a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->items = NULL; 10a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 11a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 12a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 13a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerstatic void 14a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerdynarray_reserve_more( dynarray_t *a, int count ) 15a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 16a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner int old_cap = a->capacity; 17a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner int new_cap = old_cap; 18a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner const int max_cap = INT_MAX/sizeof(void*); 19a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner void** new_items; 20a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner int new_count = a->count + count; 21a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 22a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (count <= 0) 23a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner return; 24a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 25a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (count > max_cap - a->count) 26a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner abort(); 27a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 28a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner new_count = a->count + count; 29a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 30a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner while (new_cap < new_count) { 31a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner old_cap = new_cap; 32a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner new_cap += (new_cap >> 2) + 4; 33a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (new_cap < old_cap || new_cap > max_cap) { 34a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner new_cap = max_cap; 35a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner } 36a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner } 37a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner new_items = realloc(a->items, new_cap*sizeof(void*)); 38a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (new_items == NULL) 39a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner abort(); 40a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 41a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->items = new_items; 42a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->capacity = new_cap; 43a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 44a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 45a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid 46a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerdynarray_append( dynarray_t *a, void* item ) 47a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 48a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (a->count >= a->capacity) 49a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner dynarray_reserve_more(a, 1); 50a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 51a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->items[a->count++] = item; 52a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 53a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 54a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid 55a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerdynarray_done( dynarray_t *a ) 56a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 57a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner free(a->items); 58a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->items = NULL; 59a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner a->count = a->capacity = 0; 60a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 61a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 62a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner// string arrays 63a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 64a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid strlist_init( strlist_t *list ) 65a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 66a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner dynarray_init(list); 67a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 68a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 69a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid strlist_append_b( strlist_t *list, const void* str, size_t slen ) 70a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 71a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner char *copy = malloc(slen+1); 72a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner memcpy(copy, str, slen); 73a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner copy[slen] = '\0'; 74a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner dynarray_append(list, copy); 75a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 76a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 77a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid strlist_append_dup( strlist_t *list, const char *str) 78a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 79a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner strlist_append_b(list, str, strlen(str)); 80a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 81a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 82a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid strlist_done( strlist_t *list ) 83a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 84a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner STRLIST_FOREACH(list, string, free(string)); 85a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner dynarray_done(list); 86a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 87a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 88a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnerstatic int strlist_compare_strings(const void* a, const void* b) 89a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 90a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner const char *sa = *(const char **)a; 91a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner const char *sb = *(const char **)b; 92a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner return strcmp(sa, sb); 93a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 94a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner 95a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turnervoid strlist_sort( strlist_t *list ) 96a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner{ 97a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner if (list->count > 0) { 98a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner qsort(list->items, 99a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner (size_t)list->count, 100a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner sizeof(void*), 101a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner strlist_compare_strings); 102a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner } 103a8d1afb3e91b043fcd303a40ca4ac9293bbd2781David 'Digit' Turner} 104