From 8bf49d16a637cca0cd116450dfcabc4c941baf6c Mon Sep 17 00:00:00 2001 From: ticktock35 Date: Sun, 14 Dec 2008 23:10:56 -0500 Subject: * Add ipkg for future development git-svn-id: http://opkg.googlecode.com/svn/trunk@3 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- (limited to 'void_list.c') diff --git a/void_list.c b/void_list.c new file mode 100644 index 0000000..099268c --- /dev/null +++ b/void_list.c @@ -0,0 +1,194 @@ +/* void_list.c - the itsy 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 "ipkg.h" +#include + +#include "void_list.h" + +int void_list_elt_init(void_list_elt_t *elt, void *data) +{ + elt->next = NULL; + elt->data = data; + + return 0; +} + +void void_list_elt_deinit(void_list_elt_t *elt) +{ + void_list_elt_init(elt, NULL); +} + +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; + + return 0; +} + +void void_list_deinit(void_list_t *list) +{ + void_list_elt_t *elt; + + while (list->head) { + elt = void_list_pop(list); + void_list_elt_deinit(elt); + /* malloced in void_list_append */ + free(elt); + } +} + +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; + } + + 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_init(elt, data); + + elt->next = list->head; + list->head->next = elt; + if (list->tail == NULL) { + list->tail = list->head; + } + + return 0; +} + +void_list_elt_t *void_list_pop(void_list_t *list) +{ + void_list_elt_t *elt; + + 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; +} + +void *void_list_remove(void_list_t *list, void_list_elt_t **iter) +{ + void_list_elt_t *prior; + void_list_elt_t *old_elt; + void *old_data; + + old_elt = *iter; + 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; + } + } + + void_list_elt_deinit(old_elt); + *iter = prior; + + 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 *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; +} -- cgit v0.9.1