diff --git a/src/util/list.c b/src/util/list.c index 1bd6970..443fcf2 100644 --- a/src/util/list.c +++ b/src/util/list.c @@ -132,16 +132,14 @@ void for_each_list(list_t *list, listIterator iterator) list_node_t *head_list(list_t *list, bool removeFromList) // Warning: When node is removed caller is responsible for freeing it. { -// assert(list->head != NULL); - - if (list) { - list_node_t *node = list->head; - if (removeFromList) { - // Disconnecting head node - list->head = node->next; - list->logicalLength--; - } - return node; + if (list) { + list_node_t *node = list->head; + if (removeFromList) { + // Disconnecting head node + list->head = node->next; + list->logicalLength--; + } + return node; } return NULL; } @@ -154,14 +152,14 @@ list_node_t *tail_list(list_t *list) list_node_t *get_nth_list(list_t *list, int index) { - int n; - list_node_t *lnode; + int n; + list_node_t *lnode; - for (n = 1, lnode = first_list(list); n < index && done_list(lnode); n++, lnode = next_list(lnode)); - if (n != index) - return NULL; - else - return lnode; + for (n = 1, lnode = first_list(list); n < index && done_list(lnode); n++, lnode = next_list(lnode)); + if (n != index) + return NULL; + else + return lnode; } list_node_t *search_list(list_t *list, int key) @@ -170,15 +168,45 @@ list_node_t *search_list(list_t *list, int key) list_node_t *lnode = first_list(list); while (done_list(lnode)) { - if (get_key(lnode) == key) return lnode; - lnode = next_list(lnode); } return NULL; } +void remove_node(list_t *list, int key) +{ + list_node_t *temp; + list_node_t *target = search_list(list, key); + + if (target == list->head) + delete_node(list, head_list(list, true)); + + else if (target == list->tail) { + // find next to last node + temp = list->head; + while (temp != NULL) { + if (temp->next == target) + break; + temp = temp->next; + } + // detatch tail + temp->next = NULL; + delete_node(list, list->tail); + } + else { + temp = target->next; + list->freeFn(target->data); + free(target->data); + + target->data = temp->data; + target->next = temp->next; + + free(temp); + } +} + int size_list(list_t *list) { return list->logicalLength; diff --git a/src/util/list.h b/src/util/list.h index b3583b3..599acde 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -108,6 +108,11 @@ list_node_t *get_nth_list(list_t *list, int index); */ list_node_t *search_list(list_t *list, int key); +/** +@brief Removes the list node with the given key from the list. +*/ +void remove_node(list_t *list, int key); + // // Iterator first/done/next operations // http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Iterators.html diff --git a/tests/util/test_list.cpp b/tests/util/test_list.cpp index 7c592a5..86fcd29 100644 --- a/tests/util/test_list.cpp +++ b/tests/util/test_list.cpp @@ -195,14 +195,14 @@ char *get_name(list_node_t *lnode) BOOST_AUTO_TEST_CASE(test_struct_list){ - int key; + int key, head_key, tail_key; list_t *list = NULL; list = create_list(sizeof(test_data_t *), delete_test_data); test_data_t *data = create_test_data(1, "David"); - append_list(list, &data); + head_key = append_list(list, &data); data = create_test_data(2, "Kevin"); key = append_list(list, &data); @@ -210,8 +210,13 @@ BOOST_AUTO_TEST_CASE(test_struct_list){ data = create_test_data(3, "Michael"); append_list(list, &data); + data = create_test_data(4, "Craig"); + append_list(list, &data); - BOOST_CHECK(size_list(list) == 3); + data = create_test_data(5, "Jimi"); + tail_key = append_list(list, &data); + + BOOST_CHECK(size_list(list) == 5); listIterator iterator = (listIterator)iterate_test_data; for_each_list(list, iterator); @@ -220,6 +225,17 @@ BOOST_AUTO_TEST_CASE(test_struct_list){ // locate a list node by a key printf("Found %s!\n", get_name(search_list(list, key))); + printf("Removing Kevin\n"); + remove_node(list, key); + for_each_list(list, iterator); + + printf("Removing David\n"); + remove_node(list, head_key); + for_each_list(list, iterator); + + printf("Removing Jimi\n"); + remove_node(list, tail_key); + for_each_list(list, iterator); list_node_t *lnode = head_list(list, true); delete_node(list, lnode);