From 1cc5ae1c0c60e990562bbeb8e9356f0a141efe7f Mon Sep 17 00:00:00 2001 From: a bellenir Date: Wed, 30 Jul 2014 07:54:49 +0000 Subject: [PATCH] list_delete_node function & tests --- source/list/list.c | 22 ++++++++++ source/list/list.h | 14 ++++++ tests/test_list.c | 107 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/source/list/list.c b/source/list/list.c index b2a0e92..52ade37 100644 --- a/source/list/list.c +++ b/source/list/list.c @@ -203,6 +203,28 @@ list_node_t* list_delete( list_t* list, size_t index) return node; } +void list_delete_node(list_t* list, list_node_t* node) +{ + if (NULL != list && NULL != node) + { + /* not using list_prev so node not found case can be handled properly */ + list_node_t* prev = NULL; + list_node_t* edon = list->head; + while(NULL != edon && edon != node) + { + prev = edon; + edon = edon->next; + } + if( NULL != edon) + { + if(NULL != prev) prev->next = node->next; + if(list->head == node) list->head = node->next; + if(list->tail == node) list->tail = prev; + node->next = NULL; + } /* else node not found, do nothing. */ + } +} + void list_clear(list_t* list) { if (NULL != list->head) diff --git a/source/list/list.h b/source/list/list.h index 3fc787f..bd8d086 100644 --- a/source/list/list.h +++ b/source/list/list.h @@ -184,6 +184,20 @@ list_node_t* list_insert( list_t* list, size_t index, void* contents); **/ list_node_t* list_delete(list_t* list, size_t index); +/** + * @brief Delete a node from the supplied list. + * + * This function differs from the above list_delete in that it is given a + * pointer to a node to be deleted instead of an index. + * //TODO: verify node->next should be set to NULL following successful deletion + * //TODO: verify node->next should not be touched if node not present in list + * //TODO: verify node should not be freed following deletion + * + * @param list The list to operate on. + * @param node A pointer to the node to delete. + */ +void list_delete_node(list_t* list, list_node_t* node); + /** * @brief Deletes all elements in the provided list * diff --git a/tests/test_list.c b/tests/test_list.c index d616865..2347e28 100644 --- a/tests/test_list.c +++ b/tests/test_list.c @@ -468,6 +468,113 @@ TEST_SUITE(List) { mem_release(list); } + //------------------------------------------------------------------------- + // Test list_delete_node function + //------------------------------------------------------------------------- + TEST(Verify_delete_node_does_nothing_if_list_is_empty) + { + list_t list = { NULL, NULL }; + list_node_t bogus = { NULL, NULL }; + list_delete_node(&list, NULL); + CHECK( NULL == list.head); + CHECK( NULL == list.tail); + list_delete_node(&list, &bogus); + CHECK( NULL == list.head); + CHECK( NULL == list.tail); + } + + TEST(Verify_delete_node_does_nothing_if_given_node_not_in_list) + { + list_node_t node3 = { NULL, NULL }; + list_node_t node2 = { NULL, &node3 }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node3 }; + list_node_t bogus = { NULL, &node2 }; + list_delete_node(&list, &bogus); + CHECK( &node2 == bogus.next ); + CHECK( &node1 == list.head ); + CHECK( &node2 == node1.next ); + CHECK( &node3 == node2.next ); + CHECK( NULL == node3.next ); + CHECK( &node3 == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_head_node_of_a_list_of_length_1) + { + list_node_t node1 = { NULL, NULL }; + list_t list = { &node1, &node1 }; + list_delete_node(&list, &node1); + CHECK( NULL == node1.next ); + CHECK( NULL == list.head ); + CHECK( NULL == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_first_element_of_a_list_of_length_2) + { + list_node_t node2 = { NULL, NULL }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node2 }; + list_delete_node(&list, &node1); + CHECK( NULL == node1.next ); + CHECK( &node2 == list.head ); + CHECK( NULL == node2.next ); + CHECK( &node2 == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_second_element_of_a_list_of_length_2) + { + list_node_t node2 = { NULL, NULL }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node2 }; + list_delete_node(&list, &node2); + CHECK( NULL == node2.next ); + CHECK( &node1 == list.head ); + CHECK( NULL == node1.next ); + CHECK( &node1 == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_first_element_of_a_list_of_length_3) + { + list_node_t node3 = { NULL, NULL }; + list_node_t node2 = { NULL, &node3 }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node3 }; + list_delete_node(&list, &node1); + CHECK( NULL == node1.next ); + CHECK( &node2 == list.head ); + CHECK( &node3 == node2.next ); + CHECK( NULL == node3.next ); + CHECK( &node3 == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_second_element_of_a_list_of_length_3) + { + list_node_t node3 = { NULL, NULL }; + list_node_t node2 = { NULL, &node3 }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node3 }; + list_delete_node(&list, &node2); + CHECK( NULL == node2.next ); + CHECK( &node1 == list.head ); + CHECK( &node3 == node1.next ); + CHECK( NULL == node3.next ); + CHECK( &node3 == list.tail ); + } + + TEST(Verify_delete_node_deletes_the_third_element_of_a_list_of_length_3) + { + list_node_t node3 = { NULL, NULL }; + list_node_t node2 = { NULL, &node3 }; + list_node_t node1 = { NULL, &node2 }; + list_t list = { &node1, &node3 }; + list_delete_node(&list, &node3); + CHECK( NULL == node3.next ); + CHECK( &node1 == list.head ); + CHECK( &node2 == node1.next ); + CHECK( NULL == node2.next ); + CHECK( &node2 == list.tail ); + } + //------------------------------------------------------------------------- // Test list_clear function //------------------------------------------------------------------------- -- 2.55.0