summaryrefslogtreecommitdiffstats
path: root/libcnary/node_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcnary/node_list.c')
-rw-r--r--libcnary/node_list.c99
1 files changed, 45 insertions, 54 deletions
diff --git a/libcnary/node_list.c b/libcnary/node_list.c
index f6c2c70..218c81d 100644
--- a/libcnary/node_list.c
+++ b/libcnary/node_list.c
@@ -49,7 +49,7 @@ node_list_t node_list_create()
49 49
50int node_list_add(node_list_t list, node_t node) 50int node_list_add(node_list_t list, node_t node)
51{ 51{
52 if (!list || !node) return -1; 52 if (!list || !node) return NODE_ERR_INVALID_ARG;
53 53
54 // Find the last element in the list 54 // Find the last element in the list
55 node_t last = list->end; 55 node_t last = list->end;
@@ -72,89 +72,80 @@ int node_list_add(node_list_t list, node_t node)
72 72
73 // Increment our node count for this list 73 // Increment our node count for this list
74 list->count++; 74 list->count++;
75 return 0; 75 return NODE_ERR_SUCCESS;
76} 76}
77 77
78int node_list_insert(node_list_t list, unsigned int node_index, node_t node) 78int node_list_insert(node_list_t list, unsigned int node_index, node_t node)
79{ 79{
80 if (!list || !node) return -1; 80 if (!list || !node) return NODE_ERR_INVALID_ARG;
81 if (node_index >= list->count) { 81 if (node_index > list->count) return NODE_ERR_INVALID_ARG;
82 if (node_index == list->count) {
82 return node_list_add(list, node); 83 return node_list_add(list, node);
83 } 84 }
84 85
85 // Get the first element in the list 86 // Get the first element in the list
86 node_t cur = list->begin; 87 node_t cur = list->begin;
87
88 unsigned int pos = 0;
89 node_t prev = NULL; 88 node_t prev = NULL;
90 89
91 if (node_index > 0) { 90 for (unsigned int pos = 0; pos < node_index; pos++) {
92 while (pos < node_index) { 91 if (!cur) return NODE_ERR_INVALID_ARG;
93 prev = cur; 92 prev = cur;
94 cur = cur->next; 93 cur = cur->next;
95 pos++;
96 }
97 } 94 }
98 95
96 // insert node before cur
97 node->prev = prev;
98 node->next = cur;
99
99 if (prev) { 100 if (prev) {
100 // Set previous node
101 node->prev = prev;
102 // Set next node of our new node to next node of the previous node
103 node->next = prev->next;
104 // Set next node of previous node to our new node
105 prev->next = node; 101 prev->next = node;
106 } else { 102 } else {
107 node->prev = NULL;
108 // get old first element in list
109 node->next = list->begin;
110 // set new node as first element in list
111 list->begin = node; 103 list->begin = node;
112 } 104 }
113 105
114 if (node->next == NULL) { 106 if (cur) {
115 // Set the lists prev to the new last element 107 cur->prev = node;
116 list->end = node;
117 } else { 108 } else {
118 // set prev of the new next element to our node 109 // should not happen with bounds above, but keeps things consistent
119 node->next->prev = node; 110 list->end = node;
120 } 111 }
121 112
122 // Increment our node count for this list 113 // Increment our node count for this list
123 list->count++; 114 list->count++;
124 return 0; 115 return NODE_ERR_SUCCESS;
125} 116}
126 117
118// Returns removed index (>=0) on success, or NODE_ERR_* (<0) on failure.
127int node_list_remove(node_list_t list, node_t node) 119int node_list_remove(node_list_t list, node_t node)
128{ 120{
129 if (!list || !node) return -1; 121 if (!list || !node) return NODE_ERR_INVALID_ARG;
130 if (list->count == 0) return -1; 122 if (list->count == 0) return NODE_ERR_NOT_FOUND;
131 123
132 int node_index = 0; 124 int node_index = 0;
133 node_t n; 125 for (node_t n = list->begin; n; n = n->next, node_index++) {
134 for (n = list->begin; n; n = n->next) { 126 if (node != n) continue;
135 if (node == n) { 127
136 node_t newnode = node->next; 128 node_t newnode = node->next;
137 if (node->prev) { 129 if (node->prev) {
138 node->prev->next = newnode; 130 node->prev->next = newnode;
139 if (newnode) { 131 } else {
140 newnode->prev = node->prev; 132 // we just removed the first element
141 } else { 133 list->begin = newnode;
142 // last element in the list
143 list->end = node->prev;
144 }
145 } else {
146 // we just removed the first element
147 if (newnode) {
148 newnode->prev = NULL;
149 } else {
150 list->end = NULL;
151 }
152 list->begin = newnode;
153 }
154 list->count--;
155 return node_index;
156 } 134 }
157 node_index++; 135
136 if (newnode) {
137 newnode->prev = node->prev;
138 } else {
139 // we removed the last element, set new end
140 list->end = node->prev;
141 }
142
143 // fully detach node from list
144 node->prev = NULL;
145 node->next = NULL;
146
147 list->count--;
148 return node_index;
158 } 149 }
159 return -1; 150 return NODE_ERR_NOT_FOUND;
160} 151}