diff -r 4e6e812c1d97 -r 069c152f6272 src/server/ucx/list.c --- a/src/server/ucx/list.c Thu Jun 20 14:07:46 2013 +0200 +++ b/src/server/ucx/list.c Fri Jun 21 12:10:44 2013 +0200 @@ -1,3 +1,31 @@ +/* + * 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 "list.h" UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) { @@ -13,7 +41,8 @@ return ret; } -int ucx_list_equals(UcxList *l1, UcxList *l2, cmp_func fnc, void* data) { +int ucx_list_equals(const UcxList *l1, const UcxList *l2, + cmp_func fnc, void* data) { if (l1 == l2) return 1; while (l1 != NULL && l2 != NULL) { @@ -73,32 +102,41 @@ } } -UcxList *ucx_list_last(UcxList *l) { +UcxList *ucx_list_last(const UcxList *l) { if (l == NULL) return NULL; - UcxList *e = l; + const UcxList *e = l; while (e->next != NULL) { e = e->next; } - return e; + return (UcxList*)e; } -UcxList *ucx_list_get(UcxList *l, int index) { +UcxList *ucx_list_get(const UcxList *l, int index) { if (l == NULL) return NULL; - UcxList *e = l; + const UcxList *e = l; while (e->next != NULL && index > 0) { e = e->next; index--; } - return index == 0 ? e : NULL; + return (UcxList*)(index == 0 ? e : NULL); } -size_t ucx_list_size(UcxList *l) { +int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) { + UCX_FOREACH(UcxList*, l, e) { + if (!fnc(elem, e->data, cmpdata)) { + return 1; + } + } + return 0; +} + +size_t ucx_list_size(const UcxList *l) { if (l == NULL) return 0; - UcxList *e = l; + const UcxList *e = l; size_t s = 1; while (e->next != NULL) { e = e->next; @@ -109,14 +147,15 @@ } UcxList *ucx_list_sort_merge(int length, - UcxList* ls, UcxList* rs, UcxList* le, UcxList* re, + UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re, cmp_func fnc, void* data) { - UcxList *sorted[length]; + + UcxList** sorted = (UcxList**) malloc(sizeof(UcxList*)*length); UcxList *rc, *lc; - lc = ls; rc = rs; + lc = ls; rc = le; int n = 0; - while (lc != le && rc != re) { + while (lc && lc != le && rc != re) { if (fnc(lc->data, rc->data, data) <= 0) { sorted[n] = lc; lc = lc->next; @@ -126,12 +165,12 @@ } n++; } - while (lc != le) { + while (lc && lc != le) { sorted[n] = lc; lc = lc->next; n++; } - while (rc != re) { + while (rc && rc != re) { sorted[n] = rc; rc = rc->next; n++; @@ -143,7 +182,9 @@ } sorted[length-1]->next = NULL; - return sorted[0]; + UcxList *ret = sorted[0]; + free(sorted); + return ret; } UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) { @@ -154,7 +195,7 @@ UcxList *lc; int ln = 1; - UcxList *ls = l, *le; + UcxList *restrict ls = l, *restrict le, *restrict re; lc = ls; while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { lc = lc->next; @@ -162,13 +203,12 @@ } le = lc->next; - UcxList *rs = le, *re; - if (rs == NULL) { + if (le == NULL) { return l; // this list is already sorted :) } else { UcxList *rc; int rn = 1; - rc = rs; + rc = le; while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { rc = rc->next; rn++; @@ -184,13 +224,12 @@ // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them UcxList *sorted = ucx_list_sort_merge(ln+rn, - ls, rs, le, re, + ls, le, re, fnc, data); // merge sorted list with (also sorted) remainder l = ucx_list_sort_merge(ln+rn+remainder_length, - sorted, remainder, NULL, NULL, - fnc, data); + sorted, remainder, NULL, fnc, data); return l; }