Sun, 03 Oct 2021 16:30:47 +0200
change cx_linked_list_last() and add a test for it
src/cx/linked_list.h | file | annotate | diff | comparison | revisions | |
src/linked_list.c | file | annotate | diff | comparison | revisions | |
test/test_list.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cx/linked_list.h Sun Oct 03 16:02:53 2021 +0200 1.2 +++ b/src/cx/linked_list.h Sun Oct 03 16:30:47 2021 +0200 1.3 @@ -74,19 +74,15 @@ 1.4 /** 1.5 * Finds the last node in a linked list. 1.6 * 1.7 - * If a pointer to \p end is provided, the result is just \c *end. 1.8 - * Otherwise, this function starts with the pointer denoted by \c *begin and 1.9 - * traverses the list along a next pointer whose location within the node struct is 1.10 + * The function starts with the pointer denoted by \p begin and traverses the list 1.11 + * along a next pointer whose location within the node struct is 1.12 * denoted by \p loc_next. 1.13 * 1.14 - * If both \p begin and \p end are \c NULL, an empty list is assumed and this function returns \c NULL. 1.15 - * 1.16 - * @param begin a pointer to the begin node pointer (optional) 1.17 - * @param end a pointer to the end node pointer (optional) 1.18 - * @param loc_next the location of the \c next pointer (only required when \p end is \c NULL) 1.19 - * @return a pointer to the last node or \c NULL if the list is empty 1.20 + * @param begin a pointer to the begin node 1.21 + * @param loc_next the location of the \c next pointer 1.22 + * @return a pointer to the last node or \c NULL if \p begin is \c NULL 1.23 */ 1.24 -void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next); 1.25 +void *cx_linked_list_last(void *begin, ptrdiff_t loc_next); 1.26 1.27 /** 1.28 * Adds a new node to a linked list.
2.1 --- a/src/linked_list.c Sun Oct 03 16:02:53 2021 +0200 2.2 +++ b/src/linked_list.c Sun Oct 03 16:30:47 2021 +0200 2.3 @@ -45,25 +45,27 @@ 2.4 return cur; 2.5 } 2.6 2.7 -void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next) { 2.8 - if (end != NULL) { 2.9 - return *end; 2.10 - } else { 2.11 - if (begin == NULL || *begin == NULL) 2.12 - return NULL; 2.13 +void *cx_linked_list_last(void *begin, ptrdiff_t loc_next) { 2.14 + if (begin == NULL) 2.15 + return NULL; 2.16 2.17 - void *cur = *begin; 2.18 - void *last; 2.19 - do { 2.20 - last = cur; 2.21 - } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL); 2.22 + void *cur = begin; 2.23 + void *last; 2.24 + do { 2.25 + last = cur; 2.26 + } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL); 2.27 2.28 - return last; 2.29 - } 2.30 + return last; 2.31 } 2.32 2.33 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { 2.34 - void *last = cx_linked_list_last(begin, end, loc_next); 2.35 + void *last; 2.36 + if (end == NULL) { 2.37 + assert(begin != NULL); 2.38 + last = cx_linked_list_last(*begin, loc_next); 2.39 + } else { 2.40 + last = *end; 2.41 + } 2.42 if (last == NULL) { 2.43 assert(begin != NULL); 2.44 *begin = new_node; 2.45 @@ -75,7 +77,7 @@ 2.46 2.47 // if there is an end pointer, update it 2.48 if (end != NULL) { 2.49 - *end = cx_linked_list_last(&new_node, NULL, loc_next); 2.50 + *end = cx_linked_list_last(new_node, loc_next); 2.51 } 2.52 2.53 // if the nodes use a prev pointer, update it 2.54 @@ -224,8 +226,8 @@ 2.55 2.56 static void *cx_ll_last(cx_list_s *list) { 2.57 cx_linked_list *ll = (cx_linked_list *) list; 2.58 - cx_linked_list_node *last = cx_linked_list_last(NULL, (void **) &ll->end, CX_LL_LOC_NEXT); 2.59 - return &last->payload; 2.60 + cx_linked_list_node *last = ll->end; 2.61 + return last == NULL ? NULL : &last->payload; 2.62 } 2.63 2.64 static cx_list_class cx_linked_list_class = {
3.1 --- a/test/test_list.c Sun Oct 03 16:02:53 2021 +0200 3.2 +++ b/test/test_list.c Sun Oct 03 16:30:47 2021 +0200 3.3 @@ -127,8 +127,27 @@ 3.4 CU_ASSERT_PTR_NULL(nodes[1].prev) 3.5 } 3.6 3.7 +void test_linked_list_last(void) { 3.8 + CU_ASSERT_PTR_NULL(cx_linked_list_last(NULL, -1)) 3.9 + CU_ASSERT_PTR_NULL(cx_linked_list_last(NULL, 0)) 3.10 3.11 -void test_linked_list_create(void) { 3.12 + struct node { 3.13 + int data; 3.14 + void *next; 3.15 + }; 3.16 + ptrdiff_t loc = offsetof(struct node, next); 3.17 + 3.18 + struct node third = {3, NULL}; 3.19 + struct node second = {2, &third}; 3.20 + struct node first = {1, &second}; 3.21 + 3.22 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&first, loc), &third) 3.23 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&second, loc), &third) 3.24 + CU_ASSERT_PTR_EQUAL(cx_linked_list_last(&third, loc), &third) 3.25 +} 3.26 + 3.27 + 3.28 +void test_hl_linked_list_create(void) { 3.29 cxTestingAllocatorReset(); 3.30 3.31 CxList list = cxLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int)); 3.32 @@ -166,10 +185,17 @@ 3.33 3.34 cu_add_test(suite, test_linked_list_at); 3.35 cu_add_test(suite, test_linked_list_add); 3.36 + cu_add_test(suite, test_linked_list_last); 3.37 3.38 suite = CU_add_suite("high level linked list suite", NULL, NULL); 3.39 3.40 - cu_add_test(suite, test_linked_list_create); 3.41 + cu_add_test(suite, test_hl_linked_list_create); 3.42 + /* 3.43 + cu_add_test(suite, test_hl_linked_list_add); 3.44 + cu_add_test(suite, test_hl_linked_list_last); 3.45 + cu_add_test(suite, test_hl_linked_list_insert); 3.46 + cu_add_test(suite, test_hl_linked_list_remove); 3.47 + cu_add_test(suite, test_hl_linked_list_find);*/ 3.48 3.49 CU_basic_set_mode(UCX_CU_BRM); 3.50