From f431cd1a48a6a5186633bf5f16a2d21cb4399e8c Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Thu, 09 Feb 2012 10:56:43 -0500 Subject: Initial commit. TODO: Copyright information. Including source code and a patch to add files generated by GNU Autoconf is not very pretty... Running 'make dist' in the SVN trunk to generate a source archive might be better. --- (limited to 'src/libopkg/void_list.c') diff --git a/src/libopkg/void_list.c b/src/libopkg/void_list.c new file mode 100644 index 0000000..4c9d897 --- /dev/null +++ b/src/libopkg/void_list.c @@ -0,0 +1,165 @@ +/* void_list.c - the opkg package management system + + Carl D. Worth + + Copyright (C) 2001 University of Southern California + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +*/ + +#include "void_list.h" +#include "libbb/libbb.h" + +void void_list_elt_init(void_list_elt_t *elt, void *data) +{ + INIT_LIST_HEAD(&elt->node); + elt->data = data; +} + +static 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); +} + +void void_list_init(void_list_t *list) +{ + INIT_LIST_HEAD(&list->head); +} + +void void_list_deinit(void_list_t *list) +{ + void_list_elt_t *elt; + + while (!void_list_empty(list)) { + elt = void_list_pop(list); + void_list_elt_deinit(elt); + } + INIT_LIST_HEAD(&list->head); +} + +void void_list_append(void_list_t *list, void *data) +{ + void_list_elt_t *elt = void_list_elt_new(data); + list_add_tail(&elt->node, &list->head); +} + +void void_list_push(void_list_t *list, void *data) +{ + void_list_elt_t *elt = void_list_elt_new(data); + list_add(&elt->node, &list->head); +} + +void_list_elt_t *void_list_pop(void_list_t *list) +{ + struct list_head *node; + + 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 *pos, *n; + void_list_elt_t *old_elt; + void *old_data = NULL; + + old_elt = *iter; + if (!old_elt) + return old_data; + old_data = old_elt->data; + + list_for_each_entry_safe(pos, n, &list->head, node) { + if (pos == old_elt) + break; + } + if ( pos != old_elt) { + opkg_msg(ERROR, "Internal error: element not found in list.\n"); + return NULL; + } + + *iter = list_entry(pos->node.prev, void_list_elt_t, node); + void_list_elt_deinit(pos); + + return old_data; +} + +/* 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 *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); +} + -- cgit v0.9.1