From: Michael D. Lowis Date: Thu, 31 Jul 2014 11:29:32 +0000 (-0400) Subject: Implementation of list_insert_after X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=8a4c8b9e4772d84f6b73f8abdb67753bf804bbaf;p=projs%2Flibcds.git Implementation of list_insert_after --- diff --git a/source/list/list.c b/source/list/list.c index d31a449..4adcdb4 100644 --- a/source/list/list.c +++ b/source/list/list.c @@ -50,9 +50,9 @@ bool list_empty(list_t* list) } list_node_t* list_prev(list_t* list, list_node_t* node){ - list_node_t* prev = (NULL != list && NULL != node && list->head != node) ? list->head : NULL; - while(NULL != prev && prev->next != node) prev = prev->next; - return prev; + list_node_t* prev = (NULL != list && NULL != node && list->head != node) ? list->head : NULL; + while(NULL != prev && prev->next != node) prev = prev->next; + return prev; } list_node_t* list_at(list_t* list, size_t index) @@ -181,6 +181,22 @@ list_node_t* list_insert( list_t* list, size_t index, void* contents) return new_node; } +list_node_t* list_insert_after( list_t* list, list_node_t* node, void* contents) +{ + list_node_t* new_node = NULL; + if (node != NULL) + { + new_node = list_new_node(contents); + new_node->next = node->next; + node->next = new_node; + if (node == list->tail) + { + list->tail = new_node; + } + } + return new_node; +} + list_node_t* list_delete( list_t* list, size_t index) { list_node_t* node = NULL; diff --git a/source/list/list.h b/source/list/list.h index 8ee0b29..36d8cbb 100644 --- a/source/list/list.h +++ b/source/list/list.h @@ -185,6 +185,21 @@ list_node_t* list_pop_back( list_t* list ); **/ list_node_t* list_insert( list_t* list, size_t index, void* contents); +/** + * @brief Inserts a new node in a linked list at the specified index. + * + * This function traverses the list to the desired index and inserts a new node + * with the given contents at that position. The node previously at the desired + * index becomes the child of the new node. + * + * @param list The list to operate on. + * @param node The node after which the item should be inserted. + * @param contents The contents of the new node. + * + * @return Pointer to the newly inserted node, NULL if index is out of range. + **/ +list_node_t* list_insert_after( list_t* list, list_node_t* node, void* contents); + /** * @brief Deletes a node from the supplied list. * @@ -202,7 +217,7 @@ 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 + * 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 diff --git a/tests/test_list.c b/tests/test_list.c index f74f62b..483d3ef 100644 --- a/tests/test_list.c +++ b/tests/test_list.c @@ -477,6 +477,57 @@ TEST_SUITE(List) { mem_release(list); } + //------------------------------------------------------------------------- + // Test list_insert_after function + //------------------------------------------------------------------------- + TEST(Verify_insert_after_should_fail_to_insert_if_node_is_null) + { + list_t* list = list_new(); + list_node_t* node = list_insert_after( list, NULL, mem_box(0x1234) ); + CHECK( node == NULL ); + mem_release(list); + } + + TEST(Verify_insert_after_should_insert_after_the_head_node) + { + list_node_t* node; + list_t* list = list_new(); + list_push_back(list, mem_box(0x1234)); + node = list_insert_after( list, list_front(list), mem_box(0x1235) ); + CHECK( node != NULL ); + CHECK( node->next == NULL ); + CHECK( list->tail == node ); + mem_release(list); + } + + TEST(Verify_insert_after_should_insert_after_the_tail_node) + { + list_node_t* node; + list_t* list = list_new(); + list_push_back(list, mem_box(0x1234)); + list_push_back(list, mem_box(0x1234)); + node = list_insert_after( list, list_back(list), mem_box(0x1234) ); + CHECK( node != NULL ); + CHECK( node->next == NULL ); + CHECK( list_at(list, 2) == node ); + CHECK( list->tail == node ); + mem_release(list); + } + + TEST(Verify_insert_after_should_insert_after_an_inner_node) + { + list_node_t* node; + list_t* list = list_new(); + list_push_back(list, mem_box(0x1234)); + node = list_push_back(list, mem_box(0x1234)); + list_push_back(list, mem_box(0x1234)); + node = list_insert_after( list, node, mem_box(0x1234) ); + CHECK( node != NULL ); + CHECK( node->next == list->tail ); + CHECK( node == list_at(list,2) ); + mem_release(list); + } + //------------------------------------------------------------------------- // Test list_delete function //-------------------------------------------------------------------------