X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fvoid_list.c;h=e36b4517688248af5a3f4000364dcecb58b76588;hp=af8e6a3c1390fa08f7e24fff628b6af5da18f803;hb=480538737a8a9be074a1848f2e52cf2d1ff4709f;hpb=4b0b7ca249bfa4ecc099c2ca56527eb91776f198 diff --git a/libopkg/void_list.c b/libopkg/void_list.c index af8e6a3..e36b451 100644 --- a/libopkg/void_list.c +++ b/libopkg/void_list.c @@ -1,4 +1,4 @@ -/* void_list.c - the itsy package management system +/* void_list.c - the opkg package management system Carl D. Worth @@ -15,31 +15,38 @@ General Public License for more details. */ -#include "opkg.h" +#include "includes.h" #include #include "void_list.h" +#include "libbb/libbb.h" int void_list_elt_init(void_list_elt_t *elt, void *data) { - elt->next = NULL; + INIT_LIST_HEAD(&elt->node); elt->data = data; return 0; } +void_list_elt_t * void_list_elt_new (void *data) { + void_list_elt_t *elt; + /* freed in void_list_elt_deinit */ + elt = xcalloc(1, sizeof(void_list_elt_t)); + void_list_elt_init(elt, data); + return elt; +} + void void_list_elt_deinit(void_list_elt_t *elt) { + list_del_init(&elt->node); void_list_elt_init(elt, NULL); + free(elt); } int void_list_init(void_list_t *list) { - void_list_elt_init(&list->pre_head, NULL); - list->head = NULL; - list->pre_head.next = list->head; - list->tail = NULL; - + INIT_LIST_HEAD(&list->head); return 0; } @@ -47,108 +54,64 @@ void void_list_deinit(void_list_t *list) { void_list_elt_t *elt; - while (list->head) { + while (!void_list_empty(list)) { elt = void_list_pop(list); void_list_elt_deinit(elt); - /* malloced in void_list_append */ - free(elt); } + INIT_LIST_HEAD(&list->head); } int void_list_append(void_list_t *list, void *data) { - void_list_elt_t *elt; - - /* freed in void_list_deinit */ - elt = malloc(sizeof(void_list_elt_t)); - if (elt == NULL) { - fprintf(stderr, "%s: out of memory\n", __FUNCTION__); - return ENOMEM; - } - - void_list_elt_init(elt, data); - - if (list->tail) { - list->tail->next = elt; - list->tail = elt; - } else { - list->head = elt; - list->pre_head.next = list->head; - list->tail = elt; - } + void_list_elt_t *elt = void_list_elt_new(data); + + list_add_tail(&elt->node, &list->head); return 0; } int void_list_push(void_list_t *list, void *data) { - void_list_elt_t *elt; - - elt = malloc(sizeof(void_list_elt_t)); - if (elt == NULL) { - fprintf(stderr, "%s: out of memory\n", __FUNCTION__); - return ENOMEM; - } + void_list_elt_t *elt = void_list_elt_new(data); - void_list_elt_init(elt, data); - - elt->next = list->head; - list->head->next = elt; - if (list->tail == NULL) { - list->tail = list->head; - } + list_add(&elt->node, &list->head); return 0; } void_list_elt_t *void_list_pop(void_list_t *list) { - void_list_elt_t *elt; + struct list_head *node; - elt = list->head; - - if (list->head) { - list->head = list->head->next; - list->pre_head.next = list->head; - if (list->head == NULL) { - list->tail = NULL; - } - } - - return elt; + if (void_list_empty(list)) + return NULL; + node = list->head.next; + list_del_init(node); + return list_entry(node, void_list_elt_t, node); } void *void_list_remove(void_list_t *list, void_list_elt_t **iter) { - void_list_elt_t *prior; + void_list_elt_t *pos, *n; void_list_elt_t *old_elt; - void *old_data; + void *old_data = NULL; old_elt = *iter; + if (!old_elt) + return old_data; old_data = old_elt->data; - if (old_elt == list->head) { - prior = &list->pre_head; - void_list_pop(list); - } else { - for (prior = list->head; prior; prior = prior->next) { - if (prior->next == old_elt) { - break; - } - } - if (prior == NULL || prior->next != old_elt) { - fprintf(stderr, "%s: ERROR: element not found in list\n", __FUNCTION__); - return NULL; - } - prior->next = old_elt->next; - - if (old_elt == list->tail) { - list->tail = prior; - } + list_for_each_entry_safe(pos, n, &list->head, node) { + if (pos == old_elt) + break; + } + if ( pos != old_elt) { + fprintf(stderr, "%s: ERROR: element not found in list\n", __FUNCTION__); + return NULL; } - void_list_elt_deinit(old_elt); - *iter = prior; + *iter = list_entry(pos->node.prev, void_list_elt_t, node); + void_list_elt_deinit(pos); return old_data; } @@ -156,39 +119,59 @@ void *void_list_remove(void_list_t *list, void_list_elt_t **iter) /* remove element containing elt data, using cmp(elt->data, target_data) == 0. */ void *void_list_remove_elt(void_list_t *list, const void *target_data, void_list_cmp_t cmp) { - void_list_elt_t *prior; - void_list_elt_t *old_elt = NULL; - void *old_data = NULL; - - /* first element */ - if (list->head && list->head->data && (cmp(list->head->data, target_data) == 0)) { - old_elt = list->head; - old_data = list->head->data; - void_list_pop(list); - } else { - int found = 0; - for (prior = list->head; prior && prior->next; prior = prior->next) { - if (prior->next->data && (cmp(prior->next->data, target_data) == 0)) { - old_elt = prior->next; - old_data = old_elt->data; - found = 1; - break; - } - } - if (!found) { - return NULL; - } - prior->next = old_elt->next; - - if (old_elt == list->tail) { - list->tail = prior; - } - } - if (old_elt) - void_list_elt_deinit(old_elt); - - if (old_data) - return old_data; - else - return NULL; + void_list_elt_t *pos, *n; + void *old_data = NULL; + list_for_each_entry_safe(pos, n, &list->head, node) { + if ( pos->data && cmp(pos->data, target_data)==0 ){ + old_data = pos->data; + void_list_elt_deinit(pos); + break; + } + } + return old_data; +} + +void_list_elt_t *void_list_first(void_list_t *list) { + struct list_head *elt; + if (!list) + return NULL; + elt = list->head.next; + if (elt == &list->head ) { + return NULL; + } + return list_entry(elt, void_list_elt_t, node); } + +void_list_elt_t *void_list_prev(void_list_t *list, void_list_elt_t *node) { + struct list_head *elt; + if (!list || !node) + return NULL; + elt = node->node.prev; + if (elt == &list->head ) { + return NULL; + } + return list_entry(elt, void_list_elt_t, node); +} + +void_list_elt_t *void_list_next(void_list_t *list, void_list_elt_t *node) { + struct list_head *elt; + if (!list || !node) + return NULL; + elt = node->node.next; + if (elt == &list->head ) { + return NULL; + } + return list_entry(elt, void_list_elt_t, node); +} + +void_list_elt_t *void_list_last(void_list_t *list) { + struct list_head *elt; + if (!list) + return NULL; + elt = list->head.prev; + if (elt == &list->head ) { + return NULL; + } + return list_entry(elt, void_list_elt_t, node); +} +