Mon, 22 Jul 2013 13:45:49 +0200
changed signature of sstrncat + some documentation for UcxList + new features for UcxList
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 | |
test/string_tests.c | file | annotate | diff | comparison | revisions | |
ucx/list.c | file | annotate | diff | comparison | revisions | |
ucx/list.h | file | annotate | diff | comparison | revisions | |
ucx/string.c | file | annotate | diff | comparison | revisions | |
ucx/string.h | file | annotate | diff | comparison | revisions |
1.1 --- a/test/list_tests.c Mon Jul 22 11:53:39 2013 +0200 1.2 +++ b/test/list_tests.c Mon Jul 22 13:45:49 2013 +0200 1.3 @@ -99,12 +99,13 @@ 1.4 1.5 UCX_TEST_IMPLEMENT(test_ucx_list_size) { 1.6 UcxList *list = ucx_list_append(NULL, (void*)"This "); 1.7 - UCX_TEST_BEGIN 1.8 list = ucx_list_append(list, (void*)"list "); 1.9 list = ucx_list_append(list, (void*)"has "); 1.10 list = ucx_list_append(list, (void*)"size "); 1.11 list = ucx_list_append(list, (void*)"5!"); 1.12 1.13 + UCX_TEST_BEGIN 1.14 + 1.15 UCX_TEST_ASSERT(ucx_list_size(list) == 5, "failed"); 1.16 1.17 UCX_TEST_END 1.18 @@ -113,10 +114,11 @@ 1.19 1.20 UCX_TEST_IMPLEMENT(test_ucx_list_first) { 1.21 UcxList *list = ucx_list_append(NULL, (void*)"Find "); 1.22 - UCX_TEST_BEGIN 1.23 list = ucx_list_append(list, (void*)"the "); 1.24 list = ucx_list_append(list, (void*)"first!"); 1.25 1.26 + UCX_TEST_BEGIN 1.27 + 1.28 const char* first = (const char*) (ucx_list_first(list)->data); 1.29 1.30 UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed"); 1.31 @@ -127,10 +129,11 @@ 1.32 1.33 UCX_TEST_IMPLEMENT(test_ucx_list_last) { 1.34 UcxList *list = ucx_list_append(NULL, (void*)"Find "); 1.35 - UCX_TEST_BEGIN 1.36 list = ucx_list_append(list, (void*)"the "); 1.37 list = ucx_list_append(list, (void*)"last!"); 1.38 1.39 + UCX_TEST_BEGIN 1.40 + 1.41 const char* last = (const char*) (ucx_list_last(list)->data); 1.42 1.43 UCX_TEST_ASSERT(strncmp(last, "last!", 5) == 0, "failed"); 1.44 @@ -141,10 +144,11 @@ 1.45 1.46 UCX_TEST_IMPLEMENT(test_ucx_list_get) { 1.47 UcxList *list = ucx_list_append(NULL, (void*)"Find "); 1.48 - UCX_TEST_BEGIN 1.49 list = ucx_list_append(list, (void*)"the "); 1.50 list = ucx_list_append(list, (void*)"mid!"); 1.51 1.52 + UCX_TEST_BEGIN 1.53 + 1.54 const char* mid = (const char*) (ucx_list_get(list, 1)->data); 1.55 1.56 UCX_TEST_ASSERT(strncmp(mid, "the ", 4) == 0, "failed"); 1.57 @@ -153,14 +157,53 @@ 1.58 ucx_list_free(list); 1.59 } 1.60 1.61 +UCX_TEST_IMPLEMENT(test_ucx_list_indexof) { 1.62 + UcxList *list = ucx_list_append(NULL, (void*)"Find "); 1.63 + list = ucx_list_append(list, (void*)"the "); 1.64 + list = ucx_list_append(list, (void*)"mid!"); 1.65 + 1.66 + UCX_TEST_BEGIN 1.67 + 1.68 + UCX_TEST_ASSERT(ucx_list_indexof(list, list) == 0, "failed"); 1.69 + UCX_TEST_ASSERT(ucx_list_indexof(list, list->next) == 1, "failed"); 1.70 + UCX_TEST_ASSERT(ucx_list_indexof(list, ucx_list_get(list, 2)) == 2, 1.71 + "failed"); 1.72 + 1.73 + UcxList *otherlist = ucx_list_append(NULL, (void*) "foobar"); 1.74 + UCX_TEST_ASSERT(ucx_list_indexof(list, otherlist) == -1, "failed"); 1.75 + ucx_list_free(otherlist); 1.76 + 1.77 + UCX_TEST_END 1.78 + ucx_list_free(list); 1.79 +} 1.80 + 1.81 +UCX_TEST_IMPLEMENT(test_ucx_list_find) { 1.82 + UcxList *l = ucx_list_append(NULL, (void*)"find "); 1.83 + l = ucx_list_append(l, (void*)"some "); 1.84 + l = ucx_list_append(l, (void*)"string!"); 1.85 + 1.86 + UCX_TEST_BEGIN 1.87 + 1.88 + UCX_TEST_ASSERT(ucx_list_find(l,(void*)"some ",ucx_strcmp,NULL) == 1, 1.89 + "doesn't find string"); 1.90 + UCX_TEST_ASSERT(ucx_list_find(l,(void*)"a",ucx_strcmp,NULL) == -1, 1.91 + "finds non-existing string"); 1.92 + 1.93 + UCX_TEST_END 1.94 + ucx_list_free(l); 1.95 +} 1.96 + 1.97 UCX_TEST_IMPLEMENT(test_ucx_list_contains) { 1.98 UcxList *l = ucx_list_append(NULL, (void*)"Contains "); 1.99 - UCX_TEST_BEGIN 1.100 l = ucx_list_append(l, (void*)"a "); 1.101 l = ucx_list_append(l, (void*)"string!"); 1.102 1.103 - UCX_TEST_ASSERT(ucx_list_contains(l,(void*)"a ",ucx_strcmp,NULL),"failed"); 1.104 - UCX_TEST_ASSERT(!ucx_list_contains(l,(void*)"a",ucx_strcmp,NULL),"failed"); 1.105 + UCX_TEST_BEGIN 1.106 + 1.107 + UCX_TEST_ASSERT(ucx_list_contains(l,(void*)"a ",ucx_strcmp,NULL), 1.108 + "false negative"); 1.109 + UCX_TEST_ASSERT(!ucx_list_contains(l,(void*)"a",ucx_strcmp,NULL), 1.110 + "false positive"); 1.111 1.112 UCX_TEST_END 1.113 ucx_list_free(l); 1.114 @@ -168,10 +211,11 @@ 1.115 1.116 UCX_TEST_IMPLEMENT(test_ucx_list_remove) { 1.117 UcxList *list = ucx_list_append(NULL, (void*)"Hello"); 1.118 - UCX_TEST_BEGIN 1.119 list = ucx_list_append(list, (void*)" fucking"); 1.120 list = ucx_list_append(list, (void*)" World!"); 1.121 1.122 + UCX_TEST_BEGIN 1.123 + 1.124 list = ucx_list_remove(list, ucx_list_get(list, 1)); 1.125 1.126 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
2.1 --- a/test/list_tests.h Mon Jul 22 11:53:39 2013 +0200 2.2 +++ b/test/list_tests.h Mon Jul 22 13:45:49 2013 +0200 2.3 @@ -51,6 +51,8 @@ 2.4 UCX_TEST_DECLARE(test_ucx_list_first); 2.5 UCX_TEST_DECLARE(test_ucx_list_last); 2.6 UCX_TEST_DECLARE(test_ucx_list_get); 2.7 +UCX_TEST_DECLARE(test_ucx_list_indexof); 2.8 +UCX_TEST_DECLARE(test_ucx_list_find); 2.9 UCX_TEST_DECLARE(test_ucx_list_contains); 2.10 UCX_TEST_DECLARE(test_ucx_list_remove); 2.11 UCX_TEST_DECLARE(test_ucx_list_clone);
3.1 --- a/test/main.c Mon Jul 22 11:53:39 2013 +0200 3.2 +++ b/test/main.c Mon Jul 22 13:45:49 2013 +0200 3.3 @@ -120,7 +120,7 @@ 3.4 /* UcxLogger Tests */ 3.5 ucx_test_register(suite, test_ucx_logger_log); 3.6 3.7 - /* UcxDlist Tests */ 3.8 + /* UcxList Tests */ 3.9 ucx_test_register(suite, test_ucx_list_append); 3.10 ucx_test_register(suite, test_ucx_list_prepend); 3.11 ucx_test_register(suite, test_ucx_list_equals); 3.12 @@ -129,6 +129,8 @@ 3.13 ucx_test_register(suite, test_ucx_list_first); 3.14 ucx_test_register(suite, test_ucx_list_last); 3.15 ucx_test_register(suite, test_ucx_list_get); 3.16 + ucx_test_register(suite, test_ucx_list_indexof); 3.17 + ucx_test_register(suite, test_ucx_list_find); 3.18 ucx_test_register(suite, test_ucx_list_contains); 3.19 ucx_test_register(suite, test_ucx_list_remove); 3.20 ucx_test_register(suite, test_ucx_list_clone);
4.1 --- a/test/string_tests.c Mon Jul 22 11:53:39 2013 +0200 4.2 +++ b/test/string_tests.c Mon Jul 22 13:45:49 2013 +0200 4.3 @@ -49,7 +49,7 @@ 4.4 sstr_t cat; 4.5 cat.ptr = (char*) malloc(16); 4.6 cat.length = 16; 4.7 - cat = sstrncat(3, cat, s1, s2, s3); 4.8 + cat = sstrncat(cat, 3, s1, s2, s3); 4.9 4.10 UCX_TEST_BEGIN 4.11
5.1 --- a/ucx/list.c Mon Jul 22 11:53:39 2013 +0200 5.2 +++ b/ucx/list.c Mon Jul 22 13:45:49 2013 +0200 5.3 @@ -116,6 +116,18 @@ 5.4 return (UcxList*)e; 5.5 } 5.6 5.7 +ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem) { 5.8 + ssize_t index = 0; 5.9 + while (list) { 5.10 + if (list == elem) { 5.11 + return index; 5.12 + } 5.13 + list = list->next; 5.14 + index++; 5.15 + } 5.16 + return -1; 5.17 +} 5.18 + 5.19 UcxList *ucx_list_get(const UcxList *l, int index) { 5.20 if (l == NULL) return NULL; 5.21 5.22 @@ -128,13 +140,19 @@ 5.23 return (UcxList*)(index == 0 ? e : NULL); 5.24 } 5.25 5.26 +ssize_t ucx_list_find(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) { 5.27 + ssize_t index = 0; 5.28 + UCX_FOREACH(e, l) { 5.29 + if (fnc(elem, e->data, cmpdata) == 0) { 5.30 + return index; 5.31 + } 5.32 + index++; 5.33 + } 5.34 + return -1; 5.35 +} 5.36 + 5.37 int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) { 5.38 - UCX_FOREACH(e, l) { 5.39 - if (!fnc(elem, e->data, cmpdata)) { 5.40 - return 1; 5.41 - } 5.42 - } 5.43 - return 0; 5.44 + return ucx_list_find(l, elem, fnc, cmpdata) > -1; 5.45 } 5.46 5.47 size_t ucx_list_size(const UcxList *l) {
6.1 --- a/ucx/list.h Mon Jul 22 11:53:39 2013 +0200 6.2 +++ b/ucx/list.h Mon Jul 22 13:45:49 2013 +0200 6.3 @@ -25,6 +25,13 @@ 6.4 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6.5 * POSSIBILITY OF SUCH DAMAGE. 6.6 */ 6.7 +/** 6.8 + * Double linked list implementation. 6.9 + * 6.10 + * @file list.h 6.11 + * @author Mike Becker 6.12 + * @author Olaf Wintermann 6.13 + */ 6.14 6.15 #ifndef UCX_LIST_H 6.16 #define UCX_LIST_H 6.17 @@ -52,30 +59,77 @@ 6.18 #define UCX_FOREACH(elem,list) \ 6.19 for (UcxList* elem = list ; elem != NULL ; elem = elem->next) 6.20 6.21 +/** 6.22 + * UCX list type 6.23 + * @see UcxList 6.24 + */ 6.25 typedef struct UcxList UcxList; 6.26 struct UcxList { 6.27 + /** 6.28 + * List element payload. 6.29 + */ 6.30 void *data; 6.31 + /** 6.32 + * Pointer to the next list element or <code>NULL</code>, if this is the 6.33 + * last element. 6.34 + */ 6.35 UcxList *next; 6.36 + /** 6.37 + * Pointer to the previous list element or <code>NULL</code>, if this is 6.38 + * the first element. 6.39 + */ 6.40 UcxList *prev; 6.41 }; 6.42 6.43 UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void* data); 6.44 -int ucx_list_equals(const UcxList *l1, const UcxList *l2, 6.45 - cmp_func fnc, void* data); 6.46 6.47 -void ucx_list_free(UcxList *l); 6.48 -UcxList *ucx_list_append(UcxList *l, void *data); 6.49 -UcxList *ucx_list_prepend(UcxList *l, void *data); 6.50 -UcxList *ucx_list_concat(UcxList *l1, UcxList *l2); 6.51 -UcxList *ucx_list_last(const UcxList *l); 6.52 -UcxList *ucx_list_get(const UcxList *l, int index); 6.53 -size_t ucx_list_size(const UcxList *l); 6.54 -int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata); 6.55 +/** 6.56 + * Compares two UCX lists element-wise by using a compare function. 6.57 + * 6.58 + * Each element of the two specified lists are compared by using the specified 6.59 + * compare function and the additional data. The type and content of this 6.60 + * additional data depends on the cmp_func() used. 6.61 + * 6.62 + * If the list pointers denote elements within a list, the lists are compared 6.63 + * starting with the denoted elements. Thus any previous elements are not taken 6.64 + * into account. This might be useful to check, if certain list tails match 6.65 + * each other. 6.66 + * 6.67 + * @param list1 the first list 6.68 + * @param list2 the second list 6.69 + * @param cmpfnc the compare function 6.70 + * @param data additional data for the compare function 6.71 + * @return 1, if and only if the two lists equal element-wise, 0 otherwise 6.72 + */ 6.73 +int ucx_list_equals(const UcxList *list1, const UcxList *list2, 6.74 + cmp_func cmpfnc, void* data); 6.75 6.76 -UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data); 6.77 +/** 6.78 + * Destroys the entire list. 6.79 + * 6.80 + * The members of the list are not automatically freed, so ensure they are 6.81 + * otherwise referenced or a memory leak will occur. 6.82 + * 6.83 + * <b>Caution:</b> the argument <b>MUST</b> denote an entire list (i.e. a call 6.84 + * to ucx_list_first() on the argument must return the argument itself) 6.85 + * 6.86 + * @param list The list to free. 6.87 + */ 6.88 +void ucx_list_free(UcxList *list); 6.89 +UcxList *ucx_list_append(UcxList *list, void *data); 6.90 +UcxList *ucx_list_prepend(UcxList *list, void *data); 6.91 +UcxList *ucx_list_concat(UcxList *list1, UcxList *list2); 6.92 +UcxList *ucx_list_last(const UcxList *list); 6.93 +UcxList *ucx_list_get(const UcxList *list, int index); 6.94 +ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem); 6.95 +size_t ucx_list_size(const UcxList *list); 6.96 +ssize_t ucx_list_find(UcxList *list, void *elem, cmp_func fnc, void *cmpdata); 6.97 +int ucx_list_contains(UcxList *list, void *elem, cmp_func fnc, void *cmpdata); 6.98 6.99 -UcxList *ucx_list_first(const UcxList *l); 6.100 -UcxList *ucx_list_remove(UcxList *l, UcxList *e); 6.101 +UcxList *ucx_list_sort(UcxList *list, cmp_func cmpfnc, void *data); 6.102 + 6.103 +UcxList *ucx_list_first(const UcxList *list); 6.104 +UcxList *ucx_list_remove(UcxList *list, UcxList *element); 6.105 6.106 #ifdef __cplusplus 6.107 }
7.1 --- a/ucx/string.c Mon Jul 22 11:53:39 2013 +0200 7.2 +++ b/ucx/string.c Mon Jul 22 13:45:49 2013 +0200 7.3 @@ -61,7 +61,7 @@ 7.4 return size; 7.5 } 7.6 7.7 -sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...) { 7.8 +sstr_t sstrncat(sstr_t s, size_t n, sstr_t c1, ...) { 7.9 va_list ap; 7.10 va_start(ap, c1); 7.11 s.ptr[0] = 0;
8.1 --- a/ucx/string.h Mon Jul 22 11:53:39 2013 +0200 8.2 +++ b/ucx/string.h Mon Jul 22 13:45:49 2013 +0200 8.3 @@ -142,14 +142,14 @@ 8.4 * <code>mystring.ptr[mystring.length]='\0'</code> after calling this 8.5 * function</li> 8.6 * </ul> 8.7 - * 8.8 + * 8.9 + * @param dest new sstr_t with capacity information and allocated memory 8.10 * @param count the total number of strings to concatenate 8.11 - * @param dest new sstr_t with capacity information and allocated memory 8.12 * @param src the first string 8.13 * @param ... all other strings 8.14 * @return the argument for <code>dest</code> is returned 8.15 */ 8.16 -sstr_t sstrncat(size_t count, sstr_t dest, sstr_t src, ...); 8.17 +sstr_t sstrncat(sstr_t dest, size_t count, sstr_t src, ...); 8.18 8.19 8.20 /**