adds ucx_list_append_once() and ucx_list_prepend_once()

Fri, 18 Nov 2016 15:17:04 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 18 Nov 2016 15:17:04 +0100
changeset 228
9f385abc72fb
parent 227
740fbd7bab71
child 229
9db71925eaa8

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  

mercurial