#include #include #include "linkedlist.h" void ll_init(List *list, void (*destroy)(void *data)) { list->size = 0; list->destroy = destroy; list->head = NULL; list->tail = NULL; } void ll_destroy(List *list) { void *data; while (list->size > 0) { if (ll_remove(list, list->tail, (void **) &data) == 0 && list->destroy != NULL) { list->destroy(data); } } memset(list, 0, sizeof(List)); } int ll_ins_next(List *list, ListNode *node, const void *data) { ListNode *new_node; if (node == NULL && list->size != 0) { return -1; } if ((new_node = malloc(sizeof(ListNode))) == NULL) { return -1; } new_node->data = (void *) data; if (list->size == 0) { list->head = new_node; list->head->prev = NULL; list->head->next = NULL; list->tail = new_node; } else { new_node->next = node->next; new_node->prev = node; if (node->next == NULL) { list->tail = new_node; } else { node->next->prev = new_node; } node->next = new_node; } list->size++; return 0; } int ll_ins_prev(List *list, ListNode *node, const void *data) { ListNode *new_node; if (node == NULL && list->size != 0) { return -1; } if ((new_node = malloc(sizeof(ListNode))) == NULL) { return -1; } new_node->data = (void *) data; if (list->size == 0) { list->head = new_node; list->head->prev = NULL; list->head->next = NULL; list->tail = new_node; } else { new_node->next = node; new_node->prev = node->prev; if (node->prev == NULL) { list->head = new_node; } else { node->prev->next = new_node; } node->prev = new_node; } list->size++; return 0; } int ll_remove(List *list, ListNode *node, void **data) { if (node == NULL || list->size == 0) { return -1; } *data = node->data; if (node == list->head) { list->head = node->next; if (list->head == NULL) { list->tail = NULL; } else { node->next->prev = NULL; } } else { node->prev->next = node->next; if (node->next == NULL) { list->tail = node->prev; } else { node->next->prev = node->prev; } } free(node); list->size--; return 0; } int ll_remove_next(List *list, ListNode *node, void **data) { if (node->next == NULL) { return -1; } return ll_remove(list, node->next, data); } int ll_remove_prev(List *list, ListNode *node, void **data) { if (node->prev == NULL) { return -1; } return ll_remove(list, node->prev, data); }