Fri, 18 Nov 2016 15:17:04 +0100
adds ucx_list_append_once() and ucx_list_prepend_once()
Makefile | 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/list.c | file | annotate | diff | comparison | revisions | |
ucx/list.h | file | annotate | diff | comparison | revisions | |
ucx/ucx.h | file | annotate | diff | comparison | revisions |
1.1 --- a/Makefile Thu Oct 13 16:25:21 2016 +0200 1.2 +++ b/Makefile Fri Nov 18 15:17:04 2016 +0100 1.3 @@ -49,10 +49,10 @@ 1.4 ucx-debug: FORCE 1.5 cd ucx; $(MAKE) CONF=$(CONF) debug 1.6 1.7 -test: ucx 1.8 +test: ucx FORCE 1.9 cd test; $(MAKE) CONF=$(CONF) 1.10 1.11 -test-debug: ucx-debug 1.12 +test-debug: ucx-debug FORCE 1.13 cd test; $(MAKE) CONF=$(CONF) debug 1.14 1.15 run: test
2.1 --- a/test/list_tests.c Thu Oct 13 16:25:21 2016 +0200 2.2 +++ b/test/list_tests.c Fri Nov 18 15:17:04 2016 +0100 2.3 @@ -68,6 +68,49 @@ 2.4 ucx_list_free(list); 2.5 } 2.6 2.7 +UCX_TEST(test_ucx_list_append_once) { 2.8 + UcxList *list, *first; 2.9 + list = first = ucx_list_append_once(NULL, (void*)"Hello", ucx_strcmp, NULL); 2.10 + UCX_TEST_BEGIN 2.11 + 2.12 + UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0, 2.13 + "failed"); 2.14 + 2.15 + list = ucx_list_append_once(list, (void*)"Hello", ucx_strcmp, NULL); 2.16 + list = ucx_list_append_once(list, (void*)" World!", ucx_strcmp, NULL); 2.17 + 2.18 + UCX_TEST_ASSERT(list == first, "does not return first element"); 2.19 + UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0, 2.20 + "'Hello' was not inserted _once_"); 2.21 + UCX_TEST_ASSERT(list->next->prev == list, "failed"); 2.22 + UCX_TEST_ASSERT(list->next->next == NULL, "right not terminated"); 2.23 + UCX_TEST_END 2.24 + 2.25 + ucx_list_free(list); 2.26 +} 2.27 + 2.28 +UCX_TEST(test_ucx_list_prepend_once) { 2.29 + UcxList *list, *last, *first; 2.30 + list = last = ucx_list_prepend_once(NULL, (void*)" World!", 2.31 + ucx_strcmp, NULL); 2.32 + UCX_TEST_BEGIN 2.33 + 2.34 + list = ucx_list_prepend_once(list, (void*)"Hello", ucx_strcmp, NULL); 2.35 + first = ucx_list_prepend_once(list, (void*)"Hello", ucx_strcmp, NULL); 2.36 + 2.37 + UCX_TEST_ASSERT(list == first, "'Hello' was not prepended _once_"); 2.38 + UCX_TEST_ASSERT(first == last->prev, "does not return first element"); 2.39 + UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0, 2.40 + "failed"); 2.41 + UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0, 2.42 + "failed"); 2.43 + UCX_TEST_ASSERT(list->next->next == NULL, "right not terminated"); 2.44 + UCX_TEST_ASSERT(list->prev == NULL, "left not terminated"); 2.45 + 2.46 + UCX_TEST_END 2.47 + ucx_list_free(list); 2.48 +} 2.49 + 2.50 UCX_TEST(test_ucx_list_equals) { 2.51 const char *hello = "Hello"; 2.52 const char *world = " World!";
3.1 --- a/test/list_tests.h Thu Oct 13 16:25:21 2016 +0200 3.2 +++ b/test/list_tests.h Fri Nov 18 15:17:04 2016 +0100 3.3 @@ -45,6 +45,8 @@ 3.4 3.5 UCX_TEST(test_ucx_list_append); 3.6 UCX_TEST(test_ucx_list_prepend); 3.7 +UCX_TEST(test_ucx_list_append_once); 3.8 +UCX_TEST(test_ucx_list_prepend_once); 3.9 UCX_TEST(test_ucx_list_equals); 3.10 UCX_TEST(test_ucx_list_concat); 3.11 UCX_TEST(test_ucx_list_size);
4.1 --- a/test/main.c Thu Oct 13 16:25:21 2016 +0200 4.2 +++ b/test/main.c Fri Nov 18 15:17:04 2016 +0100 4.3 @@ -137,6 +137,8 @@ 4.4 /* UcxList Tests */ 4.5 ucx_test_register(suite, test_ucx_list_append); 4.6 ucx_test_register(suite, test_ucx_list_prepend); 4.7 + ucx_test_register(suite, test_ucx_list_append_once); 4.8 + ucx_test_register(suite, test_ucx_list_prepend_once); 4.9 ucx_test_register(suite, test_ucx_list_equals); 4.10 ucx_test_register(suite, test_ucx_list_concat); 4.11 ucx_test_register(suite, test_ucx_list_size);
5.1 --- a/ucx/list.c Thu Oct 13 16:25:21 2016 +0200 5.2 +++ b/ucx/list.c Fri Nov 18 15:17:04 2016 +0100 5.3 @@ -106,6 +106,41 @@ 5.4 } 5.5 } 5.6 5.7 +UcxList *ucx_list_append_once(UcxList *l, void *data, 5.8 + cmp_func cmpfnc, void *cmpdata) { 5.9 + return ucx_list_append_once_a(ucx_default_allocator(), l, 5.10 + data, cmpfnc, cmpdata); 5.11 +} 5.12 + 5.13 +UcxList *ucx_list_append_once_a(UcxAllocator *alloc, UcxList *l, void *data, 5.14 + cmp_func cmpfnc, void *cmpdata) { 5.15 + 5.16 + UcxList *last = NULL; 5.17 + { 5.18 + UcxList *e = l; 5.19 + while (e) { 5.20 + if (cmpfnc(e->data, data, cmpdata) == 0) { 5.21 + return l; 5.22 + } 5.23 + last = e; 5.24 + e = e->next; 5.25 + } 5.26 + } 5.27 + 5.28 + UcxList *nl = ucx_list_append_a(alloc, NULL, data); 5.29 + if (!nl) { 5.30 + return NULL; 5.31 + } 5.32 + 5.33 + if (last == NULL) { 5.34 + return nl; 5.35 + } else { 5.36 + nl->prev = last; 5.37 + last->next = nl; 5.38 + return l; 5.39 + } 5.40 +} 5.41 + 5.42 UcxList *ucx_list_prepend(UcxList *l, void *data) { 5.43 return ucx_list_prepend_a(ucx_default_allocator(), l, data); 5.44 } 5.45 @@ -124,6 +159,40 @@ 5.46 return nl; 5.47 } 5.48 5.49 +UcxList *ucx_list_prepend_once(UcxList *l, void *data, 5.50 + cmp_func cmpfnc, void* cmpdata) { 5.51 + return ucx_list_prepend_once_a(ucx_default_allocator(), l, 5.52 + data, cmpfnc, cmpdata); 5.53 +} 5.54 + 5.55 +UcxList *ucx_list_prepend_once_a(UcxAllocator *alloc, UcxList *l, void *data, 5.56 + cmp_func cmpfnc, void *cmpdata) { 5.57 + 5.58 + if (l) { 5.59 + int found = 0; 5.60 + UcxList *first; 5.61 + { 5.62 + UcxList *e = l; 5.63 + while (e) { 5.64 + found |= (cmpfnc(e->data, data, cmpdata) == 0); 5.65 + first = e; 5.66 + e = e->prev; 5.67 + } 5.68 + } 5.69 + 5.70 + if (found) { 5.71 + return first; 5.72 + } else { 5.73 + UcxList *nl = ucx_list_append_a(alloc, NULL, data); 5.74 + nl->next = first; 5.75 + first->prev = nl; 5.76 + return nl; 5.77 + } 5.78 + } else { 5.79 + return ucx_list_append_a(alloc, NULL, data); 5.80 + } 5.81 +} 5.82 + 5.83 UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) { 5.84 if (l1) { 5.85 UcxList *last = ucx_list_last(l1);
6.1 --- a/ucx/list.h Thu Oct 13 16:25:21 2016 +0200 6.2 +++ b/ucx/list.h Fri Nov 18 15:17:04 2016 +0100 6.3 @@ -211,6 +211,41 @@ 6.4 UcxList *ucx_list_append_a(UcxAllocator *allocator, UcxList *list, void *data); 6.5 6.6 /** 6.7 + * Inserts an element at the end of the list, if it is not present in the list. 6.8 + * 6.9 + * 6.10 + * @param list the list where to append the data, or <code>NULL</code> to 6.11 + * create a new list 6.12 + * @param data the data to insert 6.13 + * @param cmpfnc the compare function 6.14 + * @param cmpdata additional data for the compare function 6.15 + * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to 6.16 + * the newly created list otherwise 6.17 + * @see ucx_list_append() 6.18 + */ 6.19 +UcxList *ucx_list_append_once(UcxList *list, void *data, 6.20 + cmp_func cmpfnc, void *cmpdata); 6.21 + 6.22 +/** 6.23 + * Inserts an element at the end of the list, if it is not present in the list, 6.24 + * using a UcxAllocator. 6.25 + * 6.26 + * See ucx_list_append() for details. 6.27 + * 6.28 + * @param allocator the allocator to use 6.29 + * @param list the list where to append the data, or <code>NULL</code> to 6.30 + * create a new list 6.31 + * @param data the data to insert 6.32 + * @param cmpfnc the compare function 6.33 + * @param cmpdata additional data for the compare function 6.34 + * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to 6.35 + * the newly created list otherwise 6.36 + * @see ucx_list_append_a() 6.37 + */ 6.38 +UcxList *ucx_list_append_once_a(UcxAllocator *allocator, 6.39 + UcxList *list, void *data, cmp_func cmpfnc, void *cmpdata); 6.40 + 6.41 +/** 6.42 * Inserts an element at the beginning of the list. 6.43 * 6.44 * You <i>should</i> overwrite the old list pointer by calling 6.45 @@ -241,6 +276,37 @@ 6.46 UcxList *ucx_list_prepend_a(UcxAllocator *allocator, UcxList *list, void *data); 6.47 6.48 /** 6.49 + * Inserts an element at the beginning of the list, if it is not present 6.50 + * in the list. 6.51 + * 6.52 + * @param list the list where to insert the data or <code>NULL</code> to create 6.53 + * a new list 6.54 + * @param data the data to insert 6.55 + * @param cmpfnc the compare function 6.56 + * @param cmpdata additional data for the compare function 6.57 + * @return a pointer to the new list head 6.58 + * @see ucx_list_prepend() 6.59 + */ 6.60 +UcxList *ucx_list_prepend_once(UcxList *list, void *data, 6.61 + cmp_func cmpfnc, void *cmpdata); 6.62 + 6.63 +/** 6.64 + * Inserts an element at the beginning of the list, if it is not present in 6.65 + * the list, using a UcxAllocator. 6.66 + * 6.67 + * @param allocator the allocator to use 6.68 + * @param list the list where to insert the data or <code>NULL</code> to create 6.69 + * a new list 6.70 + * @param data the data to insert 6.71 + * @param cmpfnc the compare function 6.72 + * @param cmpdata additional data for the compare function 6.73 + * @return a pointer to the new list head 6.74 + * @see ucx_list_prepend_a() 6.75 + */ 6.76 +UcxList *ucx_list_prepend_once_a(UcxAllocator *allocator, 6.77 + UcxList *list, void *data, cmp_func cmpfnc, void *cmpdata); 6.78 + 6.79 +/** 6.80 * Concatenates two lists. 6.81 * 6.82 * Either of the two arguments may be <code>NULL</code>.
7.1 --- a/ucx/ucx.h Thu Oct 13 16:25:21 2016 +0200 7.2 +++ b/ucx/ucx.h Fri Nov 18 15:17:04 2016 +0100 7.3 @@ -40,7 +40,7 @@ 7.4 #define UCX_VERSION_MAJOR 0 7.5 7.6 /** Minor UCX version as integer constant. */ 7.7 -#define UCX_VERSION_MINOR 10 7.8 +#define UCX_VERSION_MINOR 11 7.9 7.10 #include <stdlib.h> 7.11