|
@@ -15,8 +15,8 @@ void IZ_ListInitialize(IZ_List* list) { |
|
|
* @param list - The list to clean up. |
|
|
* @param list - The list to clean up. |
|
|
*/ |
|
|
*/ |
|
|
void IZ_ListTeardown(IZ_List* list) { |
|
|
void IZ_ListTeardown(IZ_List* list) { |
|
|
while (list->root) { |
|
|
|
|
|
IZ_ListDeleteNode(list, &list->root); |
|
|
|
|
|
|
|
|
while (list->length > 0) { |
|
|
|
|
|
IZ_ListDeleteNode(list->root); |
|
|
} |
|
|
} |
|
|
IZ_free(list); |
|
|
IZ_free(list); |
|
|
} |
|
|
} |
|
@@ -30,61 +30,51 @@ IZ_ListNode** IZ_ListAppendNode(IZ_List* list, void* node_value) { |
|
|
IZ_ListNode* new_node = IZ_malloc(sizeof(IZ_ListNode)); |
|
|
IZ_ListNode* new_node = IZ_malloc(sizeof(IZ_ListNode)); |
|
|
new_node->value = node_value; |
|
|
new_node->value = node_value; |
|
|
new_node->next = NULL; |
|
|
new_node->next = NULL; |
|
|
list->length += 1; |
|
|
|
|
|
|
|
|
new_node->list = list; |
|
|
|
|
|
new_node->list->length += 1; |
|
|
|
|
|
|
|
|
if (!(list->root)) { |
|
|
if (!(list->root)) { |
|
|
list->root = new_node; |
|
|
|
|
|
return &list->root; |
|
|
|
|
|
|
|
|
new_node->previous = NULL; |
|
|
|
|
|
new_node->list->root = new_node; |
|
|
|
|
|
return &new_node->list->root; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
IZ_ListNode *last_node = list->root; |
|
|
|
|
|
|
|
|
IZ_ListNode *last_node = new_node->list->root; |
|
|
while (last_node->next) { |
|
|
while (last_node->next) { |
|
|
last_node = last_node->next; |
|
|
last_node = last_node->next; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
new_node->previous = last_node; |
|
|
last_node->next = new_node; |
|
|
last_node->next = new_node; |
|
|
return &last_node->next; |
|
|
return &last_node->next; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Deletes the first node in the list that matches the filter. |
|
|
* Deletes the first node in the list that matches the filter. |
|
|
* @param list - The list to delete from. |
|
|
|
|
|
* @param node - The node to delete. |
|
|
* @param node - The node to delete. |
|
|
*/ |
|
|
*/ |
|
|
void IZ_ListDeleteNode(IZ_List* list, IZ_ListNode** node) { |
|
|
|
|
|
if (!(list && list->root && node)) { |
|
|
|
|
|
|
|
|
void IZ_ListDeleteNode(IZ_ListNode* node) { |
|
|
|
|
|
if (!node) { |
|
|
// should we raise warnings here? |
|
|
// should we raise warnings here? |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// FIXME Teardown having problems here |
|
|
|
|
|
list->iterator = &list->root; |
|
|
|
|
|
IZ_ListNode** previous_node = NULL; |
|
|
|
|
|
do { |
|
|
|
|
|
if (list->iterator != node) { |
|
|
|
|
|
previous_node = list->iterator; |
|
|
|
|
|
list->iterator = &((*list->iterator)->next); |
|
|
|
|
|
// we haven't found the node we're looking for, go to the next one |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
if (node->previous) { |
|
|
|
|
|
node->previous->next = node->next; |
|
|
|
|
|
} else { |
|
|
|
|
|
if (node->next) { |
|
|
|
|
|
node->next->previous = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (previous_node) { |
|
|
|
|
|
// this is not the first node in the list |
|
|
|
|
|
(*previous_node)->next = (*list->iterator)->next; |
|
|
|
|
|
} else { |
|
|
|
|
|
// this is the first node, set it as new root |
|
|
|
|
|
list->root = (*list->iterator)->next; |
|
|
|
|
|
// if there is only one item in the list, root, gets set to NULL |
|
|
|
|
|
|
|
|
if (node->list) { |
|
|
|
|
|
node->list->root = node->next; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
IZ_free(*list->iterator); |
|
|
|
|
|
list->iterator = NULL; |
|
|
|
|
|
if (list->length > 0) { |
|
|
|
|
|
// avoid underflow |
|
|
|
|
|
list->length -= 1; |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} while (*list->iterator); |
|
|
|
|
|
|
|
|
if (node->list && node->list->length > 0) { |
|
|
|
|
|
node->list->length -= 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
IZ_free(node); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|