29 #include "cx/tree.h" |
29 #include "cx/tree.h" |
30 #include "cx/linked_list.h" |
30 #include "cx/linked_list.h" |
31 |
31 |
32 #define CX_TR_PTR(cur, off) ((void**)(((char*)cur)+off)) |
32 #define CX_TR_PTR(cur, off) ((void**)(((char*)cur)+off)) |
33 |
33 |
34 void* cx_tree_last(void *node, ptrdiff_t loc_next) { |
34 void *cx_tree_last(void *node, ptrdiff_t loc_next) { |
35 void *last; |
35 void *last; |
36 do { |
36 do { |
37 last = node; |
37 last = node; |
38 } while ((node = *CX_TR_PTR(node, loc_next)) != NULL); |
38 } while ((node = *CX_TR_PTR(node, loc_next)) != NULL); |
39 return last; |
39 return last; |
40 } |
40 } |
41 |
41 |
42 int cx_tree_add_node(void *node, ptrdiff_t loc_parent, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { |
42 void cx_tree_add_sibling(void *node, ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_parent, void *new_node) { |
43 void *last = cx_tree_last(node, loc_next); |
43 cx_linked_list_add(&node, NULL, loc_prev, loc_next, new_node); |
44 if(!last) |
44 |
45 return 1; |
45 // optional parent link |
46 |
46 if (loc_parent >= 0) { |
47 // next pointer must be present |
|
48 *CX_TR_PTR(last, loc_next) = new_node; |
|
49 |
|
50 // optional fields |
|
51 if(loc_parent >= 0) { |
|
52 *CX_TR_PTR(new_node, loc_parent) = *CX_TR_PTR(node, loc_parent); |
47 *CX_TR_PTR(new_node, loc_parent) = *CX_TR_PTR(node, loc_parent); |
53 } |
48 } |
54 if(loc_prev >= 0) { |
|
55 *CX_TR_PTR(new_node, loc_prev) = last; |
|
56 } |
|
57 |
|
58 return 0; |
|
59 } |
49 } |
60 |
50 |
61 int cx_tree_add_child_node( |
51 void cx_tree_add_child(void **children_begin, void **children_end, |
62 void *parent, |
52 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, |
63 ptrdiff_t loc_parent, |
53 ptrdiff_t loc_parent, void *parent) { |
64 ptrdiff_t loc_prev, |
54 cx_linked_list_add(children_begin, children_end, loc_prev, loc_next, new_node); |
65 ptrdiff_t loc_next, |
55 |
66 void **children_begin, |
56 // optional parent link |
67 void **children_end, |
57 if (loc_parent >= 0) { |
68 void *new_node) |
|
69 { |
|
70 if(cx_linked_list_add(children_begin, children_end, loc_prev, loc_next, new_node)) { |
|
71 return 1; |
|
72 } |
|
73 // optional field |
|
74 if(loc_parent >= 0) { |
|
75 *CX_TR_PTR(new_node, loc_parent) = parent; |
58 *CX_TR_PTR(new_node, loc_parent) = parent; |
76 } |
59 } |
77 return 0; |
|
78 } |
60 } |