removal of single linked list implemenation - step 2: renamed UcxDlist to UcxList (new single implementation)

Mon, 22 Jul 2013 11:53:39 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 22 Jul 2013 11:53:39 +0200
changeset 122
540d99722f1f
parent 121
311cac04d079
child 123
7fb0f74517c5

removal of single linked list implemenation - step 2: renamed UcxDlist to UcxList (new single implementation)

test/Makefile file | annotate | diff | comparison | revisions
test/dlist_tests.c file | annotate | diff | comparison | revisions
test/dlist_tests.h file | annotate | diff | comparison | revisions
test/list_tests.c file | annotate | diff | comparison | revisions
test/list_tests.h file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
ucx/Makefile file | annotate | diff | comparison | revisions
ucx/dlist.c file | annotate | diff | comparison | revisions
ucx/dlist.h file | annotate | diff | comparison | revisions
ucx/list.c file | annotate | diff | comparison | revisions
ucx/list.h file | annotate | diff | comparison | revisions
--- a/test/Makefile	Mon Jul 22 11:39:06 2013 +0200
+++ b/test/Makefile	Mon Jul 22 11:53:39 2013 +0200
@@ -29,7 +29,7 @@
 include ../$(CONF).mk
 
 SRC  = main.c
-SRC += dlist_tests.c
+SRC += list_tests.c
 SRC += mpool_tests.c
 SRC += map_tests.c
 SRC += prop_tests.c
--- a/test/dlist_tests.c	Mon Jul 22 11:39:06 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +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_tests.h"
-#include "ucx/utils.h"
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_append) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Hello");
-    UCX_TEST_BEGIN
-    
-    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
-            "failed");
-    
-    list = ucx_dlist_append(list, (void*)" World!");
-    
-    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
-            "failed");
-    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
-    UCX_TEST_END
-    
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_prepend) {
-    UcxDlist *list = ucx_dlist_prepend(NULL, (void*)" World!");
-    UCX_TEST_BEGIN
-
-    list = ucx_dlist_prepend(list, (void*)"Hello");
-    
-    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
-            "failed");
-    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
-            "failed");
-    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_equals) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Hello");
-    list = ucx_dlist_append(list, (void*)" World!");
-    UcxDlist *list2 = ucx_dlist_prepend(NULL, (void*)" World!");
-    list2 = ucx_dlist_prepend(list2, (void*)"Hello");
-    UcxDlist *list3 = ucx_dlist_prepend(NULL, (void*)" Welt!");
-    list3 = ucx_dlist_prepend(list3, (void*)"Hallo");
-    UCX_TEST_BEGIN
-    
-    UCX_TEST_ASSERT(ucx_dlist_equals(list, list2, ucx_strcmp, NULL), "failed");
-    UCX_TEST_ASSERT(!ucx_dlist_equals(list, list3, ucx_strcmp, NULL), "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list3);
-    ucx_dlist_free(list2);
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_concat) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Hello");
-    UcxDlist *list2 = ucx_dlist_prepend(NULL, (void*)" World!");
-    UCX_TEST_BEGIN
-    
-    list = ucx_dlist_concat(list, list2);
-    
-    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
-            "failed");
-    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
-            "failed");
-    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_size) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"This ");
-    UCX_TEST_BEGIN
-    list = ucx_dlist_append(list, (void*)"list ");
-    list = ucx_dlist_append(list, (void*)"has ");
-    list = ucx_dlist_append(list, (void*)"size ");
-    list = ucx_dlist_append(list, (void*)"5!");
-    
-    UCX_TEST_ASSERT(ucx_dlist_size(list) == 5, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_first) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Find ");
-    UCX_TEST_BEGIN
-    list = ucx_dlist_append(list, (void*)"the ");
-    list = ucx_dlist_append(list, (void*)"first!");
-    
-    const char* first = (const char*) (ucx_dlist_first(list)->data);
-    
-    UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_last) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Find ");
-    UCX_TEST_BEGIN
-    list = ucx_dlist_append(list, (void*)"the ");
-    list = ucx_dlist_append(list, (void*)"last!");
-    
-    const char* last = (const char*) (ucx_dlist_last(list)->data);
-    
-    UCX_TEST_ASSERT(strncmp(last, "last!", 5) == 0, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_get) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Find ");
-    UCX_TEST_BEGIN
-    list = ucx_dlist_append(list, (void*)"the ");
-    list = ucx_dlist_append(list, (void*)"mid!");
-    
-    const char* mid = (const char*) (ucx_dlist_get(list, 1)->data);
-    
-    UCX_TEST_ASSERT(strncmp(mid, "the ", 4) == 0, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_contains) {
-    UcxDlist *l = ucx_dlist_append(NULL, (void*)"Contains ");
-    UCX_TEST_BEGIN
-    l = ucx_dlist_append(l, (void*)"a ");
-    l = ucx_dlist_append(l, (void*)"string!");
-    
-    UCX_TEST_ASSERT(ucx_dlist_contains(l,(void*)"a ",ucx_strcmp,NULL),"failed");
-    UCX_TEST_ASSERT(!ucx_dlist_contains(l,(void*)"a",ucx_strcmp,NULL),"failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(l);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_remove) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"Hello");
-    UCX_TEST_BEGIN
-    list = ucx_dlist_append(list, (void*)" fucking");
-    list = ucx_dlist_append(list, (void*)" World!");
-    
-    list = ucx_dlist_remove(list, ucx_dlist_get(list, 1));
-    
-    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
-            "failed");
-    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
-            "failed");
-    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
-    
-    UCX_TEST_END
-    ucx_dlist_free(list);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_clone) {
-   
-    char *hello = (char*)malloc(6);
-    char *world = (char*)malloc(8);
-    
-    memcpy(hello, "Hello", 6);
-    memcpy(world, " World!", 8);
-    
-    UcxDlist *list = ucx_dlist_append(NULL, hello);
-    list = ucx_dlist_append(list, world);
-    
-    UcxDlist *copy = ucx_dlist_clone(list, ucx_strcpy, NULL);
-    UCX_TEST_BEGIN
-
-    UCX_TEST_ASSERT(ucx_dlist_equals(list, copy, ucx_strcmp, NULL), "failed");
-    UCX_TEST_ASSERT(hello != copy->data, "first element is no copy");
-    UCX_TEST_ASSERT(world != copy->next->data, "second element is no copy");
-
-    UCX_TEST_END
-    free(copy->next->data);
-    free(copy->data);
-
-    free(world);
-    free(hello);
-    ucx_dlist_free(list);
-    ucx_dlist_free(copy);
-}
-
-UCX_TEST_IMPLEMENT(test_ucx_dlist_sort) {
-    UcxDlist *list = ucx_dlist_append(NULL, (void*)"this");
-    list = ucx_dlist_append(list, (void*)"is");
-    list = ucx_dlist_append(list, (void*)"a");
-    list = ucx_dlist_append(list, (void*)"test");
-    list = ucx_dlist_append(list, (void*)"for");
-    list = ucx_dlist_append(list, (void*)"partial");
-    list = ucx_dlist_append(list, (void*)"correctness");
-
-    UcxDlist *expected = ucx_dlist_append(NULL, (void*)"a");
-    expected = ucx_dlist_append(expected, (void*)"correctness");
-    expected = ucx_dlist_append(expected, (void*)"for");
-    expected = ucx_dlist_append(expected, (void*)"is");
-    expected = ucx_dlist_append(expected, (void*)"partial");
-    expected = ucx_dlist_append(expected, (void*)"test");
-    expected = ucx_dlist_append(expected, (void*)"this");
-
-    list = ucx_dlist_sort(list, ucx_strcmp, NULL);
-
-    UCX_TEST_BEGIN
-    UCX_TEST_ASSERT(
-            ucx_dlist_equals(list, expected, ucx_strcmp, NULL), "failed");
-    UcxDlist *l = list;
-    UCX_TEST_ASSERT(l->prev == NULL, "prev field of first entry is not null");
-    while (l->next != NULL) {
-        UCX_TEST_ASSERT(l->next->prev == l, "prev pointer corrupted");
-        l = l->next;
-    }
-    UCX_TEST_END
-
-    ucx_dlist_free(expected);
-    ucx_dlist_free(list);
-}
--- a/test/dlist_tests.h	Mon Jul 22 11:39:06 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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.
- */
-
-#ifndef DLIST_TESTS_H
-#define	DLIST_TESTS_H
-
-#include "main.h"
-
-#include "ucx/dlist.h"
-#include "ucx/test.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/*
- * Assumed to be correct:
- *   ucx_dlist_free
- */
-
-UCX_TEST_DECLARE(test_ucx_dlist_append);
-UCX_TEST_DECLARE(test_ucx_dlist_prepend);
-UCX_TEST_DECLARE(test_ucx_dlist_equals);
-UCX_TEST_DECLARE(test_ucx_dlist_concat);
-UCX_TEST_DECLARE(test_ucx_dlist_size);
-UCX_TEST_DECLARE(test_ucx_dlist_first);
-UCX_TEST_DECLARE(test_ucx_dlist_last);
-UCX_TEST_DECLARE(test_ucx_dlist_get);
-UCX_TEST_DECLARE(test_ucx_dlist_contains);
-UCX_TEST_DECLARE(test_ucx_dlist_remove);
-UCX_TEST_DECLARE(test_ucx_dlist_clone);
-UCX_TEST_DECLARE(test_ucx_dlist_sort);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* DLIST_TESTS_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/list_tests.c	Mon Jul 22 11:53:39 2013 +0200
@@ -0,0 +1,247 @@
+/*
+ * 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_tests.h"
+#include "ucx/utils.h"
+
+UCX_TEST_IMPLEMENT(test_ucx_list_append) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Hello");
+    UCX_TEST_BEGIN
+    
+    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
+            "failed");
+    
+    list = ucx_list_append(list, (void*)" World!");
+    
+    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
+            "failed");
+    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
+    UCX_TEST_END
+    
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_prepend) {
+    UcxList *list = ucx_list_prepend(NULL, (void*)" World!");
+    UCX_TEST_BEGIN
+
+    list = ucx_list_prepend(list, (void*)"Hello");
+    
+    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
+            "failed");
+    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
+            "failed");
+    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_equals) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Hello");
+    list = ucx_list_append(list, (void*)" World!");
+    UcxList *list2 = ucx_list_prepend(NULL, (void*)" World!");
+    list2 = ucx_list_prepend(list2, (void*)"Hello");
+    UcxList *list3 = ucx_list_prepend(NULL, (void*)" Welt!");
+    list3 = ucx_list_prepend(list3, (void*)"Hallo");
+    UCX_TEST_BEGIN
+    
+    UCX_TEST_ASSERT(ucx_list_equals(list, list2, ucx_strcmp, NULL), "failed");
+    UCX_TEST_ASSERT(!ucx_list_equals(list, list3, ucx_strcmp, NULL), "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list3);
+    ucx_list_free(list2);
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_concat) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Hello");
+    UcxList *list2 = ucx_list_prepend(NULL, (void*)" World!");
+    UCX_TEST_BEGIN
+    
+    list = ucx_list_concat(list, list2);
+    
+    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
+            "failed");
+    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
+            "failed");
+    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_size) {
+    UcxList *list = ucx_list_append(NULL, (void*)"This ");
+    UCX_TEST_BEGIN
+    list = ucx_list_append(list, (void*)"list ");
+    list = ucx_list_append(list, (void*)"has ");
+    list = ucx_list_append(list, (void*)"size ");
+    list = ucx_list_append(list, (void*)"5!");
+    
+    UCX_TEST_ASSERT(ucx_list_size(list) == 5, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_first) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Find ");
+    UCX_TEST_BEGIN
+    list = ucx_list_append(list, (void*)"the ");
+    list = ucx_list_append(list, (void*)"first!");
+    
+    const char* first = (const char*) (ucx_list_first(list)->data);
+    
+    UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_last) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Find ");
+    UCX_TEST_BEGIN
+    list = ucx_list_append(list, (void*)"the ");
+    list = ucx_list_append(list, (void*)"last!");
+    
+    const char* last = (const char*) (ucx_list_last(list)->data);
+    
+    UCX_TEST_ASSERT(strncmp(last, "last!", 5) == 0, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_get) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Find ");
+    UCX_TEST_BEGIN
+    list = ucx_list_append(list, (void*)"the ");
+    list = ucx_list_append(list, (void*)"mid!");
+    
+    const char* mid = (const char*) (ucx_list_get(list, 1)->data);
+    
+    UCX_TEST_ASSERT(strncmp(mid, "the ", 4) == 0, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_contains) {
+    UcxList *l = ucx_list_append(NULL, (void*)"Contains ");
+    UCX_TEST_BEGIN
+    l = ucx_list_append(l, (void*)"a ");
+    l = ucx_list_append(l, (void*)"string!");
+    
+    UCX_TEST_ASSERT(ucx_list_contains(l,(void*)"a ",ucx_strcmp,NULL),"failed");
+    UCX_TEST_ASSERT(!ucx_list_contains(l,(void*)"a",ucx_strcmp,NULL),"failed");
+    
+    UCX_TEST_END
+    ucx_list_free(l);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_remove) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Hello");
+    UCX_TEST_BEGIN
+    list = ucx_list_append(list, (void*)" fucking");
+    list = ucx_list_append(list, (void*)" World!");
+    
+    list = ucx_list_remove(list, ucx_list_get(list, 1));
+    
+    UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
+            "failed");
+    UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
+            "failed");
+    UCX_TEST_ASSERT(list->next->next == NULL, "failed");
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_clone) {
+   
+    char *hello = (char*)malloc(6);
+    char *world = (char*)malloc(8);
+    
+    memcpy(hello, "Hello", 6);
+    memcpy(world, " World!", 8);
+    
+    UcxList *list = ucx_list_append(NULL, hello);
+    list = ucx_list_append(list, world);
+    
+    UcxList *copy = ucx_list_clone(list, ucx_strcpy, NULL);
+    UCX_TEST_BEGIN
+
+    UCX_TEST_ASSERT(ucx_list_equals(list, copy, ucx_strcmp, NULL), "failed");
+    UCX_TEST_ASSERT(hello != copy->data, "first element is no copy");
+    UCX_TEST_ASSERT(world != copy->next->data, "second element is no copy");
+
+    UCX_TEST_END
+    free(copy->next->data);
+    free(copy->data);
+
+    free(world);
+    free(hello);
+    ucx_list_free(list);
+    ucx_list_free(copy);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_sort) {
+    UcxList *list = ucx_list_append(NULL, (void*)"this");
+    list = ucx_list_append(list, (void*)"is");
+    list = ucx_list_append(list, (void*)"a");
+    list = ucx_list_append(list, (void*)"test");
+    list = ucx_list_append(list, (void*)"for");
+    list = ucx_list_append(list, (void*)"partial");
+    list = ucx_list_append(list, (void*)"correctness");
+
+    UcxList *expected = ucx_list_append(NULL, (void*)"a");
+    expected = ucx_list_append(expected, (void*)"correctness");
+    expected = ucx_list_append(expected, (void*)"for");
+    expected = ucx_list_append(expected, (void*)"is");
+    expected = ucx_list_append(expected, (void*)"partial");
+    expected = ucx_list_append(expected, (void*)"test");
+    expected = ucx_list_append(expected, (void*)"this");
+
+    list = ucx_list_sort(list, ucx_strcmp, NULL);
+
+    UCX_TEST_BEGIN
+    UCX_TEST_ASSERT(
+            ucx_list_equals(list, expected, ucx_strcmp, NULL), "failed");
+    UcxList *l = list;
+    UCX_TEST_ASSERT(l->prev == NULL, "prev field of first entry is not null");
+    while (l->next != NULL) {
+        UCX_TEST_ASSERT(l->next->prev == l, "prev pointer corrupted");
+        l = l->next;
+    }
+    UCX_TEST_END
+
+    ucx_list_free(expected);
+    ucx_list_free(list);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/list_tests.h	Mon Jul 22 11:53:39 2013 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef LIST_TESTS_H
+#define	LIST_TESTS_H
+
+#include "main.h"
+
+#include "ucx/list.h"
+#include "ucx/test.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Assumed to be correct:
+ *   ucx_list_free
+ */
+
+UCX_TEST_DECLARE(test_ucx_list_append);
+UCX_TEST_DECLARE(test_ucx_list_prepend);
+UCX_TEST_DECLARE(test_ucx_list_equals);
+UCX_TEST_DECLARE(test_ucx_list_concat);
+UCX_TEST_DECLARE(test_ucx_list_size);
+UCX_TEST_DECLARE(test_ucx_list_first);
+UCX_TEST_DECLARE(test_ucx_list_last);
+UCX_TEST_DECLARE(test_ucx_list_get);
+UCX_TEST_DECLARE(test_ucx_list_contains);
+UCX_TEST_DECLARE(test_ucx_list_remove);
+UCX_TEST_DECLARE(test_ucx_list_clone);
+UCX_TEST_DECLARE(test_ucx_list_sort);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* LIST_TESTS_H */
+
--- a/test/main.c	Mon Jul 22 11:39:06 2013 +0200
+++ b/test/main.c	Mon Jul 22 11:53:39 2013 +0200
@@ -34,7 +34,7 @@
 #include "main.h"
 
 #include "logging_tests.h"
-#include "dlist_tests.h"
+#include "list_tests.h"
 #include "string_tests.h"
 #include "mpool_tests.h"
 #include "map_tests.h"
@@ -121,18 +121,18 @@
         ucx_test_register(suite, test_ucx_logger_log);
         
         /* UcxDlist Tests */
-        ucx_test_register(suite, test_ucx_dlist_append);
-        ucx_test_register(suite, test_ucx_dlist_prepend);
-        ucx_test_register(suite, test_ucx_dlist_equals);
-        ucx_test_register(suite, test_ucx_dlist_concat);
-        ucx_test_register(suite, test_ucx_dlist_size);
-        ucx_test_register(suite, test_ucx_dlist_first);
-        ucx_test_register(suite, test_ucx_dlist_last);
-        ucx_test_register(suite, test_ucx_dlist_get);
-        ucx_test_register(suite, test_ucx_dlist_contains);
-        ucx_test_register(suite, test_ucx_dlist_remove);
-        ucx_test_register(suite, test_ucx_dlist_clone);
-        ucx_test_register(suite, test_ucx_dlist_sort);
+        ucx_test_register(suite, test_ucx_list_append);
+        ucx_test_register(suite, test_ucx_list_prepend);
+        ucx_test_register(suite, test_ucx_list_equals);
+        ucx_test_register(suite, test_ucx_list_concat);
+        ucx_test_register(suite, test_ucx_list_size);
+        ucx_test_register(suite, test_ucx_list_first);
+        ucx_test_register(suite, test_ucx_list_last);
+        ucx_test_register(suite, test_ucx_list_get);
+        ucx_test_register(suite, test_ucx_list_contains);
+        ucx_test_register(suite, test_ucx_list_remove);
+        ucx_test_register(suite, test_ucx_list_clone);
+        ucx_test_register(suite, test_ucx_list_sort);
 
         /* UcxMemPool Tests */
         ucx_test_register(suite, test_ucx_mempool_new);
--- a/ucx/Makefile	Mon Jul 22 11:39:06 2013 +0200
+++ b/ucx/Makefile	Mon Jul 22 11:53:39 2013 +0200
@@ -30,7 +30,7 @@
 
 # list of source files
 SRC  = utils.c
-SRC += dlist.c
+SRC += list.c
 SRC += map.c
 SRC += properties.c
 SRC += mempool.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;
-}
--- a/ucx/dlist.h	Mon Jul 22 11:39:06 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +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.
- */
-
-#ifndef UCX_DLIST_H
-#define	UCX_DLIST_H
-
-#include "ucx.h"
-#include <stddef.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * Loop statement for UCX lists.
- * 
- * The first argument is a pointer to the list. In most cases this will be the
- * pointer to the first element of the list, but it may also be an arbitrary
- * element of the list. The iteration will then start with that element.
- * 
- * The second argument is the name of the iteration variable. The scope of
- * this variable is limited to the <code>UCX_FOREACH</code> statement.
- * 
- * @param list The first element of the list
- * @param elem The variable name of the element
- */
-#define UCX_FOREACH(list,elem) \
-        for (UcxDlist* elem = list ; elem != NULL ; elem = elem->next)
-
-typedef struct UcxDlist UcxDlist;
-struct UcxDlist {
-    void     *data;
-    UcxDlist *next;
-    UcxDlist *prev;
-};
-
-UcxDlist *ucx_dlist_clone(UcxDlist *l, copy_func fnc, void* data);
-int ucx_dlist_equals(const UcxDlist *l1, const UcxDlist *l2,
-        cmp_func fnc, void* data);
-
-void ucx_dlist_free(UcxDlist *l);
-UcxDlist *ucx_dlist_append(UcxDlist *l, void *data);
-UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data);
-UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2);
-UcxDlist *ucx_dlist_last(const UcxDlist *l);
-UcxDlist *ucx_dlist_get(const UcxDlist *l, int index);
-size_t ucx_dlist_size(const UcxDlist *l);
-int ucx_dlist_contains(UcxDlist *l, void *elem, cmp_func fnc, void *cmpdata);
-
-UcxDlist *ucx_dlist_sort(UcxDlist *l, cmp_func fnc, void *data);
-
-/* dlist specific functions */
-UcxDlist *ucx_dlist_first(const UcxDlist *l);
-UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_DLIST_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ucx/list.c	Mon Jul 22 11:53:39 2013 +0200
@@ -0,0 +1,269 @@
+/*
+ * 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) {
+    UcxList *ret = NULL;
+    while (l != NULL) {
+        if (fnc != NULL) {
+            ret = ucx_list_append(ret, fnc(l->data, data));
+        } else {
+            ret = ucx_list_append(ret, l->data);
+        }
+        l = l->next;
+    }
+    return ret;
+}
+
+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) {
+        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_list_free(UcxList *l) {
+    UcxList *e = l, *f;
+    while (e != NULL) {
+        f = e;
+        e = e->next;
+        free(f);
+    }
+}
+
+UcxList *ucx_list_append(UcxList *l, void *data)  {
+    UcxList *nl = (UcxList*) malloc(sizeof(UcxList));
+    if (nl == NULL) return NULL;
+    
+    nl->data = data;
+    nl->next = NULL;
+    if (l == NULL) {
+        nl->prev = NULL;
+        return nl;
+    } else {
+        UcxList *t = ucx_list_last(l);
+        t->next = nl;
+        nl->prev = t;
+        return l;
+    }
+}
+
+UcxList *ucx_list_prepend(UcxList *l, void *data) {
+    UcxList *nl = ucx_list_append(NULL, data);
+    if (nl == NULL) return NULL;
+    
+    if (l != NULL) {
+        nl->next = l;
+        l->prev = nl;
+    }
+    return nl;
+}
+
+UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) {
+    if (l1 == NULL) {
+        return l2;
+    } else {
+        UcxList *last = ucx_list_last(l1);
+        last->next = l2;
+        l2->prev = last;
+        return l1;
+    }
+}
+
+UcxList *ucx_list_last(const UcxList *l) {
+    if (l == NULL) return NULL;
+    
+    const UcxList *e = l;
+    while (e->next != NULL) {
+        e = e->next;
+    }
+    return (UcxList*)e;
+}
+
+UcxList *ucx_list_get(const UcxList *l, int index) {
+    if (l == NULL) return NULL;
+
+    const UcxList *e = l;
+    while (e->next != NULL && index > 0) {
+        e = e->next;
+        index--;
+    }
+    
+    return (UcxList*)(index == 0 ? e : NULL);
+}
+
+int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
+    UCX_FOREACH(e, l) {
+        if (!fnc(elem, e->data, cmpdata)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+size_t ucx_list_size(const UcxList *l) {
+    if (l == NULL) return 0;
+    
+    const UcxList *e = l;
+    size_t s = 1;
+    while (e->next != NULL) {
+        e = e->next;
+        s++;
+    }
+
+    return s;
+}
+
+UcxList *ucx_list_sort_merge(int length,
+        UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re,
+        cmp_func fnc, void* data) {
+
+    UcxList** sorted = (UcxList**) malloc(sizeof(UcxList*)*length);
+    UcxList *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;
+
+    UcxList *ret = sorted[0];
+    free(sorted);
+    return ret;
+}
+
+UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) {
+    if (l == NULL) {
+        return NULL;
+    }
+
+    UcxList *lc;
+    int ln = 1;
+
+    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;
+        ln++;
+    }
+    le = lc->next;
+
+    if (le == NULL) {
+        return l; // this list is already sorted :)
+    } else {
+        UcxList *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!
+        UcxList *remainder = re;
+        size_t remainder_length = ucx_list_size(remainder);
+        if (remainder != NULL) {
+            remainder = ucx_list_sort(remainder, fnc, data);
+        }
+
+        // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
+        UcxList *sorted = ucx_list_sort_merge(ln+rn,
+                ls, le, re,
+                fnc, data);
+
+        // merge sorted list with (also sorted) remainder
+        l = ucx_list_sort_merge(ln+rn+remainder_length,
+                sorted, remainder, NULL, fnc, data);
+
+        return l;
+    }
+}
+
+UcxList *ucx_list_first(const UcxList *l) {
+    if (l == NULL) return NULL;
+    
+    const UcxList *e = l;
+    while (e->prev != NULL) {
+        e = e->prev;
+    }
+    return (UcxList *)e;
+}
+
+UcxList *ucx_list_remove(UcxList *l, UcxList *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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ucx/list.h	Mon Jul 22 11:53:39 2013 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef UCX_LIST_H
+#define	UCX_LIST_H
+
+#include "ucx.h"
+#include <stddef.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/**
+ * Loop statement for UCX lists.
+ * 
+ * The first argument is a pointer to the list. In most cases this will be the
+ * pointer to the first element of the list, but it may also be an arbitrary
+ * element of the list. The iteration will then start with that element.
+ * 
+ * The second argument is the name of the iteration variable. The scope of
+ * this variable is limited to the <code>UCX_FOREACH</code> statement.
+ * 
+ * @param list The first element of the list
+ * @param elem The variable name of the element
+ */
+#define UCX_FOREACH(elem,list) \
+        for (UcxList* elem = list ; elem != NULL ; elem = elem->next)
+
+typedef struct UcxList UcxList;
+struct UcxList {
+    void    *data;
+    UcxList *next;
+    UcxList *prev;
+};
+
+UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void* data);
+int ucx_list_equals(const UcxList *l1, const UcxList *l2,
+        cmp_func fnc, void* data);
+
+void ucx_list_free(UcxList *l);
+UcxList *ucx_list_append(UcxList *l, void *data);
+UcxList *ucx_list_prepend(UcxList *l, void *data);
+UcxList *ucx_list_concat(UcxList *l1, UcxList *l2);
+UcxList *ucx_list_last(const UcxList *l);
+UcxList *ucx_list_get(const UcxList *l, int index);
+size_t ucx_list_size(const UcxList *l);
+int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata);
+
+UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data);
+
+UcxList *ucx_list_first(const UcxList *l);
+UcxList *ucx_list_remove(UcxList *l, UcxList *e);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* UCX_LIST_H */
+

mercurial