# HG changeset patch # User Mike Becker # Date 1633271447 -7200 # Node ID 227c2eabbef83aa5c6465a1f09cb4f29f9b2b3f2 # Parent 8168e16cd1e953cc24ab6a552a6f02209458c438 change cx_linked_list_last() and add a test for it diff -r 8168e16cd1e9 -r 227c2eabbef8 src/cx/linked_list.h --- a/src/cx/linked_list.h Sun Oct 03 16:02:53 2021 +0200 +++ b/src/cx/linked_list.h Sun Oct 03 16:30:47 2021 +0200 @@ -74,19 +74,15 @@ /** * Finds the last node in a linked list. * - * If a pointer to \p end is provided, the result is just \c *end. - * Otherwise, this function starts with the pointer denoted by \c *begin and - * traverses the list along a next pointer whose location within the node struct is + * The function starts with the pointer denoted by \p begin and traverses the list + * along a next pointer whose location within the node struct is * denoted by \p loc_next. * - * If both \p begin and \p end are \c NULL, an empty list is assumed and this function returns \c NULL. - * - * @param begin a pointer to the begin node pointer (optional) - * @param end a pointer to the end node pointer (optional) - * @param loc_next the location of the \c next pointer (only required when \p end is \c NULL) - * @return a pointer to the last node or \c NULL if the list is empty + * @param begin a pointer to the begin node + * @param loc_next the location of the \c next pointer + * @return a pointer to the last node or \c NULL if \p begin is \c NULL */ -void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next); +void *cx_linked_list_last(void *begin, ptrdiff_t loc_next); /** * Adds a new node to a linked list. diff -r 8168e16cd1e9 -r 227c2eabbef8 src/linked_list.c --- a/src/linked_list.c Sun Oct 03 16:02:53 2021 +0200 +++ b/src/linked_list.c Sun Oct 03 16:30:47 2021 +0200 @@ -45,25 +45,27 @@ return cur; } -void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next) { - if (end != NULL) { - return *end; - } else { - if (begin == NULL || *begin == NULL) - return NULL; +void *cx_linked_list_last(void *begin, ptrdiff_t loc_next) { + if (begin == NULL) + return NULL; - void *cur = *begin; - void *last; - do { - last = cur; - } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL); + void *cur = begin; + void *last; + do { + last = cur; + } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL); - return last; - } + return last; } void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { - void *last = cx_linked_list_last(begin, end, loc_next); + void *last; + if (end == NULL) { + assert(begin != NULL); + last = cx_linked_list_last(*begin, loc_next); + } else { + last = *end; + } if (last == NULL) { assert(begin != NULL); *begin = new_node; @@ -75,7 +77,7 @@ // if there is an end pointer, update it if (end != NULL) { - *end = cx_linked_list_last(&new_node, NULL, loc_next); + *end = cx_linked_list_last(new_node, loc_next); } // if the nodes use a prev pointer, update it @@ -224,8 +226,8 @@ static void *cx_ll_last(cx_list_s *list) { cx_linked_list *ll = (cx_linked_list *) list; - cx_linked_list_node *last = cx_linked_list_last(NULL, (void **) &ll->end, CX_LL_LOC_NEXT); - return &last->payload; + cx_linked_list_node *last = ll->end; + return last == NULL ? NULL : &last->payload; } static cx_list_class cx_linked_list_class = { diff -r 8168e16cd1e9 -r 227c2eabbef8 test/test_list.c --- a/test/test_list.c Sun Oct 03 16:02:53 2021 +0200 +++ b/test/test_list.c Sun Oct 03 16:30:47 2021 +0200 @@ -127,8 +127,27 @@ CU_ASSERT_PTR_NULL(nodes[1].prev) } +void test_linked_list_last(void) { + CU_ASSERT_PTR_NULL(cx_linked_list_last(NULL, -1)) + CU_ASSERT_PTR_NULL(cx_linked_list_last(NULL, 0)) -void test_linked_list_create(void) { + struct node { + int data; + void *next; + }; + ptrdiff_t loc = offsetof(struct node, next); + + struct node third = {3, NULL}; + struct node second = {2, &third}; + struct node first = {1, &second}; + + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&first, loc), &third) + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&second, loc), &third) + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&third, loc), &third) +} + + +void test_hl_linked_list_create(void) { cxTestingAllocatorReset(); CxList list = cxLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int)); @@ -166,10 +185,17 @@ cu_add_test(suite, test_linked_list_at); cu_add_test(suite, test_linked_list_add); + cu_add_test(suite, test_linked_list_last); suite = CU_add_suite("high level linked list suite", NULL, NULL); - cu_add_test(suite, test_linked_list_create); + cu_add_test(suite, test_hl_linked_list_create); + /* + cu_add_test(suite, test_hl_linked_list_add); + cu_add_test(suite, test_hl_linked_list_last); + cu_add_test(suite, test_hl_linked_list_insert); + cu_add_test(suite, test_hl_linked_list_remove); + cu_add_test(suite, test_hl_linked_list_find);*/ CU_basic_set_mode(UCX_CU_BRM);