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.c141
1 files changed, 69 insertions, 72 deletions
diff --git a/libcnary/node_list.c b/libcnary/node_list.c
index 5b291e7..218c81d 100644
--- a/libcnary/node_list.c
+++ b/libcnary/node_list.c
@@ -25,34 +25,34 @@
#include <stdlib.h>
#include <string.h>
-#include "list.h"
#include "node.h"
#include "node_list.h"
-void node_list_destroy(node_list_t* list) {
- if(list != NULL) {
- list_destroy((list_t*) list);
- }
+void node_list_destroy(node_list_t list)
+{
+ free(list);
}
-node_list_t* node_list_create(node_t* node) {
- node_list_t* list = (node_list_t*) malloc(sizeof(node_list_t));
- if(list == NULL) {
+node_list_t node_list_create()
+{
+ node_list_t list = (node_list_t)calloc(1, sizeof(struct node_list));
+ if (list == NULL) {
return NULL;
}
- memset(list, '\0', sizeof(node_list_t));
// Initialize structure
- list_init((list_t*) list);
+ list->begin = NULL;
+ list->end = NULL;
list->count = 0;
return list;
}
-int node_list_add(node_list_t* list, node_t* node) {
- if (!list || !node) return -1;
+int node_list_add(node_list_t list, node_t node)
+{
+ if (!list || !node) return NODE_ERR_INVALID_ARG;
// Find the last element in the list
- node_t* last = list->end;
+ node_t last = list->end;
// Setup our new node as the new last element
node->next = NULL;
@@ -62,6 +62,9 @@ int node_list_add(node_list_t* list, node_t* node) {
if (last) {
// but only if the node list is not empty
last->next = node;
+ } else {
+ // otherwise this is the start of the list
+ list->begin = node;
}
// Set the lists prev to the new last element
@@ -69,86 +72,80 @@ int node_list_add(node_list_t* list, node_t* node) {
// Increment our node count for this list
list->count++;
- return 0;
+ return NODE_ERR_SUCCESS;
}
-int node_list_insert(node_list_t* list, unsigned int index, node_t* node) {
- if (!list || !node) return -1;
- if (index >= list->count) {
+int node_list_insert(node_list_t list, unsigned int node_index, node_t node)
+{
+ if (!list || !node) return NODE_ERR_INVALID_ARG;
+ if (node_index > list->count) return NODE_ERR_INVALID_ARG;
+ if (node_index == list->count) {
return node_list_add(list, node);
}
// Get the first element in the list
- node_t* cur = list->begin;
-
- unsigned int pos = 0;
- node_t* prev = NULL;
+ node_t cur = list->begin;
+ node_t prev = NULL;
- if (index > 0) {
- while (pos < index) {
- prev = cur;
- cur = cur->next;
- pos++;
- }
+ for (unsigned int pos = 0; pos < node_index; pos++) {
+ if (!cur) return NODE_ERR_INVALID_ARG;
+ prev = cur;
+ cur = cur->next;
}
+ // insert node before cur
+ node->prev = prev;
+ node->next = cur;
+
if (prev) {
- // Set previous node
- node->prev = prev;
- // Set next node of our new node to next node of the previous node
- node->next = prev->next;
- // Set next node of previous node to our new node
prev->next = node;
} else {
- node->prev = NULL;
- // get old first element in list
- node->next = list->begin;
- // set new node as first element in list
list->begin = node;
}
- if (node->next == NULL) {
- // Set the lists prev to the new last element
- list->end = node;
+ if (cur) {
+ cur->prev = node;
} else {
- // set prev of the new next element to our node
- node->next->prev = node;
+ // should not happen with bounds above, but keeps things consistent
+ list->end = node;
}
// Increment our node count for this list
list->count++;
- return 0;
+ return NODE_ERR_SUCCESS;
}
-int node_list_remove(node_list_t* list, node_t* node) {
- if (!list || !node) return -1;
- if (list->count == 0) return -1;
-
- int index = 0;
- node_t* n;
- for (n = list->begin; n; n = n->next) {
- if (node == n) {
- node_t* newnode = node->next;
- if (node->prev) {
- node->prev->next = newnode;
- if (newnode) {
- newnode->prev = node->prev;
- } else {
- // last element in the list
- list->end = node->prev;
- }
- } else {
- // we just removed the first element
- if (newnode) {
- newnode->prev = NULL;
- }
- list->begin = newnode;
- }
- list->count--;
- return index;
+// Returns removed index (>=0) on success, or NODE_ERR_* (<0) on failure.
+int node_list_remove(node_list_t list, node_t node)
+{
+ if (!list || !node) return NODE_ERR_INVALID_ARG;
+ if (list->count == 0) return NODE_ERR_NOT_FOUND;
+
+ int node_index = 0;
+ for (node_t n = list->begin; n; n = n->next, node_index++) {
+ if (node != n) continue;
+
+ node_t newnode = node->next;
+ if (node->prev) {
+ node->prev->next = newnode;
+ } else {
+ // we just removed the first element
+ list->begin = newnode;
+ }
+
+ if (newnode) {
+ newnode->prev = node->prev;
+ } else {
+ // we removed the last element, set new end
+ list->end = node->prev;
}
- index++;
- }
- return -1;
-}
+ // fully detach node from list
+ node->prev = NULL;
+ node->next = NULL;
+
+ list->count--;
+ return node_index;
+ }
+ return NODE_ERR_NOT_FOUND;
+}