#include "ll.h" #include void ll_init(ll* ll) { ll->head = NULL; ll->tail = NULL; } void ll_free(ll* ll) { ll_node* head = ll->head; while (head) { ll_node* to_free = head; head = head->next; free(to_free); } ll->tail = NULL; ll->head = NULL; } libds_result ll_append(ll* ll, void* data) { libds_result result = LIBDS_SUCCESS; ll_node** to_set = ll->head ? &ll->tail->next : &ll->head; ll_node* new_node = malloc(sizeof(*new_node)); if (new_node) { new_node->next = NULL; new_node->prev = ll->tail; new_node->data = data; *to_set = new_node; ll->tail = new_node; } else { result = LIBDS_MALLOC; } return result; } libds_result ll_prepend(ll* ll, void* data) { libds_result result = LIBDS_SUCCESS; ll_node** to_set = ll->tail ? &ll->head->prev : &ll->tail; ll_node* new_node = malloc(sizeof(*new_node)); if (new_node) { new_node->next = ll->head; new_node->prev = NULL; new_node->data = data; *to_set = new_node; ll->head = new_node; } return result; } void ll_remove(ll* ll, void* data) { ll_node* head = ll->head; while (head) { if (head->data == data) { ll_node* to_delete = head; head = head->next; *(to_delete->prev ? &to_delete->prev->next : &ll->head) = to_delete->next; *(to_delete->next ? &to_delete->next->prev : &ll->tail) = to_delete->prev; free(to_delete); } else { head = head->next; } } } void* ll_find(ll* ll, void* data, compare_func compare) { void* to_return = NULL; ll_node* head = ll->head; while (head && to_return == NULL) { if (compare(data, head->data)) { to_return = head->data; } head = head->next; } return to_return; } int ll_foreach(ll* ll, void* data, compare_func compare, foreach_func foreach, ...) { int return_code = 0; ll_node* head = ll->head; va_list args; while (head && return_code == 0) { if (compare(data, head->data)) { va_start(args, foreach); return_code = foreach (head->data, args); va_end(args); } head = head->next; } return return_code; } void* ll_head(ll* ll) { return ll->head ? ll->head->data : NULL; } void* ll_tail(ll* ll) { return ll->tail ? ll->tail->data : NULL; } void* ll_pophead(ll* ll) { void* to_return = NULL; if (ll->head) { ll_node* to_delete = ll->head; to_return = to_delete->data; *(to_delete->next ? &to_delete->next->prev : &ll->tail) = NULL; ll->head = to_delete->next; free(to_delete); } return to_return; } void* ll_poptail(ll* ll) { void* to_return = NULL; if (ll->tail) { ll_node* to_delete = ll->tail; to_return = to_delete->data; *(to_delete->prev ? &to_delete->prev->next : &ll->head) = NULL; ll->tail = to_delete->prev; free(to_delete); } return to_return; } void ll_clear(ll* ll){ ll_node* head = ll->head; while(head){ ll_node* to_free = head; head = head->next; free(to_free); } ll->head = NULL; ll->tail = NULL; }