diff options
Diffstat (limited to 'libcnary/node_list.c')
| -rw-r--r-- | libcnary/node_list.c | 99 |
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() int node_list_add(node_list_t list, node_t node) { - if (!list || !node) return -1; + if (!list || !node) return NODE_ERR_INVALID_ARG; // Find the last element in the list node_t last = list->end; @@ -72,89 +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 node_index, node_t node) { - if (!list || !node) return -1; - if (node_index >= list->count) { + 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; - if (node_index > 0) { - while (pos < node_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; } +// 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 -1; - if (list->count == 0) return -1; + if (!list || !node) return NODE_ERR_INVALID_ARG; + if (list->count == 0) return NODE_ERR_NOT_FOUND; int node_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; - } else { - list->end = NULL; - } - list->begin = newnode; - } - list->count--; - return node_index; + 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; } - node_index++; + + if (newnode) { + newnode->prev = node->prev; + } else { + // we removed the last element, set new end + list->end = node->prev; + } + + // fully detach node from list + node->prev = NULL; + node->next = NULL; + + list->count--; + return node_index; } - return -1; + return NODE_ERR_NOT_FOUND; } |
