implement cx_tree_add_node()

Sun, 26 Sep 2021 14:41:49 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 26 Sep 2021 14:41:49 +0200
changeset 426
9aa38cd4c992
parent 425
a75b808d653b
child 427
ec92b4ed23aa

implement cx_tree_add_node()

src/cx/tree.h file | annotate | diff | comparison | revisions
src/tree.c file | annotate | diff | comparison | revisions
--- a/src/cx/tree.h	Sun Sep 26 14:21:20 2021 +0200
+++ b/src/cx/tree.h	Sun Sep 26 14:41:49 2021 +0200
@@ -37,6 +37,8 @@
 extern "C" {
 #endif
 
+void* cx_tree_last(void *node, ptrdiff_t loc_next);
+    
 int cx_tree_add_node(void *node, ptrdiff_t loc_parent, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node);
 
 int cx_tree_add_child_node(
--- a/src/tree.c	Sun Sep 26 14:21:20 2021 +0200
+++ b/src/tree.c	Sun Sep 26 14:41:49 2021 +0200
@@ -28,9 +28,33 @@
 
 #include "cx/tree.h"
 
+#define CX_TR_PTR(cur, off) ((void**)(((char*)cur)+off))
+
+void* cx_tree_last(void *node, ptrdiff_t loc_next) {
+    void *last;
+    do {
+        last = node;
+    } while ((node = *CX_TR_PTR(node, loc_next)) != NULL);
+    return last;
+}
 
 int cx_tree_add_node(void *node, ptrdiff_t loc_parent, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) {
-    return 1;
+    void *last = cx_tree_last(node, loc_next);
+    if(!last)
+        return 1;
+    
+    // next pointer must be present
+    *CX_TR_PTR(last, loc_next) = new_node;
+    
+    // optional fields
+    if(loc_parent >= 0) {
+        *CX_TR_PTR(new_node, loc_parent) = *CX_TR_PTR(node, loc_parent);
+    }
+    if(loc_prev >= 0) {
+        *CX_TR_PTR(new_node, loc_prev) = last;
+    }
+    
+    return 0;
 }
 
 int cx_tree_add_child_node(

mercurial