diff -r 311cac04d079 -r 540d99722f1f ucx/dlist.c --- a/ucx/dlist.c Mon Jul 22 11:39:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2013 Olaf Wintermann. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "dlist.h" - -UcxDlist *ucx_dlist_clone(UcxDlist *l, copy_func fnc, void *data) { - UcxDlist *ret = NULL; - while (l != NULL) { - if (fnc != NULL) { - ret = ucx_dlist_append(ret, fnc(l->data, data)); - } else { - ret = ucx_dlist_append(ret, l->data); - } - l = l->next; - } - return ret; -} - -int ucx_dlist_equals(const UcxDlist *l1, const UcxDlist *l2, - cmp_func fnc, void* data) { - if (l1 == l2) return 1; - - while (l1 != NULL && l2 != NULL) { - if (fnc == NULL) { - if (l1->data != l2->data) return 0; - } else { - if (fnc(l1->data, l2->data, data) != 0) return 0; - } - l1 = l1->next; - l2 = l2->next; - } - - return (l1 == NULL && l2 == NULL); -} - -void ucx_dlist_free(UcxDlist *l) { - UcxDlist *e = l, *f; - while (e != NULL) { - f = e; - e = e->next; - free(f); - } -} - -UcxDlist *ucx_dlist_append(UcxDlist *l, void *data) { - UcxDlist *nl = (UcxDlist*) malloc(sizeof(UcxDlist)); - if (nl == NULL) return NULL; - - nl->data = data; - nl->next = NULL; - if (l == NULL) { - nl->prev = NULL; - return nl; - } else { - UcxDlist *t = ucx_dlist_last(l); - t->next = nl; - nl->prev = t; - return l; - } -} - -UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data) { - UcxDlist *nl = ucx_dlist_append(NULL, data); - if (nl == NULL) return NULL; - - if (l != NULL) { - nl->next = l; - l->prev = nl; - } - return nl; -} - -UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2) { - if (l1 == NULL) { - return l2; - } else { - UcxDlist *last = ucx_dlist_last(l1); - last->next = l2; - l2->prev = last; - return l1; - } -} - -UcxDlist *ucx_dlist_last(const UcxDlist *l) { - if (l == NULL) return NULL; - - const UcxDlist *e = l; - while (e->next != NULL) { - e = e->next; - } - return (UcxDlist*)e; -} - -UcxDlist *ucx_dlist_get(const UcxDlist *l, int index) { - if (l == NULL) return NULL; - - const UcxDlist *e = l; - while (e->next != NULL && index > 0) { - e = e->next; - index--; - } - - return (UcxDlist*)(index == 0 ? e : NULL); -} - -int ucx_dlist_contains(UcxDlist *l, void *elem, cmp_func fnc, void *cmpdata) { - UCX_FOREACH(l, e) { - if (!fnc(elem, e->data, cmpdata)) { - return 1; - } - } - return 0; -} - -size_t ucx_dlist_size(const UcxDlist *l) { - if (l == NULL) return 0; - - const UcxDlist *e = l; - size_t s = 1; - while (e->next != NULL) { - e = e->next; - s++; - } - - return s; -} - -UcxDlist *ucx_dlist_sort_merge(int length, - UcxDlist* restrict ls, UcxDlist* restrict le, UcxDlist* restrict re, - cmp_func fnc, void* data) { - - UcxDlist** sorted = (UcxDlist**) malloc(sizeof(UcxDlist*)*length); - UcxDlist *rc, *lc; - - lc = ls; rc = le; - int n = 0; - while (lc && lc != le && rc != re) { - if (fnc(lc->data, rc->data, data) <= 0) { - sorted[n] = lc; - lc = lc->next; - } else { - sorted[n] = rc; - rc = rc->next; - } - n++; - } - while (lc && lc != le) { - sorted[n] = lc; - lc = lc->next; - n++; - } - while (rc && rc != re) { - sorted[n] = rc; - rc = rc->next; - n++; - } - - // Update pointer - sorted[0]->prev = NULL; - for (int i = 0 ; i < length-1 ; i++) { - sorted[i]->next = sorted[i+1]; - sorted[i+1]->prev = sorted[i]; - } - sorted[length-1]->next = NULL; - - UcxDlist *ret = sorted[0]; - free(sorted); - return ret; -} - -UcxDlist *ucx_dlist_sort(UcxDlist *l, cmp_func fnc, void *data) { - if (l == NULL) { - return NULL; - } - - UcxDlist *lc; - int ln = 1; - - UcxDlist *restrict ls = l, *restrict le, *restrict re; - lc = ls; - while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { - lc = lc->next; - ln++; - } - le = lc->next; - - if (le == NULL) { - return l; // this list is already sorted :) - } else { - UcxDlist *rc; - int rn = 1; - rc = le; - while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { - rc = rc->next; - rn++; - } - re = rc->next; - - // Something left? Sort it! - UcxDlist *remainder = re; - size_t remainder_length = ucx_dlist_size(remainder); - if (remainder != NULL) { - remainder = ucx_dlist_sort(remainder, fnc, data); - } - - // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them - UcxDlist *sorted = ucx_dlist_sort_merge(ln+rn, - ls, le, re, - fnc, data); - - // merge sorted list with (also sorted) remainder - l = ucx_dlist_sort_merge(ln+rn+remainder_length, - sorted, remainder, NULL, fnc, data); - - return l; - } -} - -/* dlist specific functions */ -UcxDlist *ucx_dlist_first(const UcxDlist *l) { - if (l == NULL) return NULL; - - const UcxDlist *e = l; - while (e->prev != NULL) { - e = e->prev; - } - return (UcxDlist *)e; -} - -UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e) { - if (e->prev == NULL) { - if(e->next != NULL) { - e->next->prev = NULL; - l = e->next; - } else { - l = NULL; - } - - } else { - e->prev->next = e->next; - e->next->prev = e->prev; - } - free(e); - return l; -}