change cx_linked_list_last() and add a test for it

Sun, 03 Oct 2021 16:30:47 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 03 Oct 2021 16:30:47 +0200
changeset 456
227c2eabbef8
parent 455
8168e16cd1e9
child 457
8f7d3fe9ca40

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
--- 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.
--- 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 = {
--- 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);
 

mercurial