changed signature of sstrncat + some documentation for UcxList + new features for UcxList

Mon, 22 Jul 2013 13:45:49 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 22 Jul 2013 13:45:49 +0200
changeset 123
7fb0f74517c5
parent 122
540d99722f1f
child 124
8b44653541ef

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
--- a/test/list_tests.c	Mon Jul 22 11:53:39 2013 +0200
+++ b/test/list_tests.c	Mon Jul 22 13:45:49 2013 +0200
@@ -99,12 +99,13 @@
 
 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_BEGIN
+    
     UCX_TEST_ASSERT(ucx_list_size(list) == 5, "failed");
     
     UCX_TEST_END
@@ -113,10 +114,11 @@
 
 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!");
     
+    UCX_TEST_BEGIN
+    
     const char* first = (const char*) (ucx_list_first(list)->data);
     
     UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed");
@@ -127,10 +129,11 @@
 
 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!");
     
+    UCX_TEST_BEGIN
+    
     const char* last = (const char*) (ucx_list_last(list)->data);
     
     UCX_TEST_ASSERT(strncmp(last, "last!", 5) == 0, "failed");
@@ -141,10 +144,11 @@
 
 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!");
     
+    UCX_TEST_BEGIN
+    
     const char* mid = (const char*) (ucx_list_get(list, 1)->data);
     
     UCX_TEST_ASSERT(strncmp(mid, "the ", 4) == 0, "failed");
@@ -153,14 +157,53 @@
     ucx_list_free(list);
 }
 
+UCX_TEST_IMPLEMENT(test_ucx_list_indexof) {
+    UcxList *list = ucx_list_append(NULL, (void*)"Find ");
+    list = ucx_list_append(list, (void*)"the ");
+    list = ucx_list_append(list, (void*)"mid!");
+    
+    UCX_TEST_BEGIN
+    
+    UCX_TEST_ASSERT(ucx_list_indexof(list, list) == 0, "failed");
+    UCX_TEST_ASSERT(ucx_list_indexof(list, list->next) == 1, "failed");
+    UCX_TEST_ASSERT(ucx_list_indexof(list, ucx_list_get(list, 2)) == 2,
+        "failed");
+    
+    UcxList *otherlist = ucx_list_append(NULL, (void*) "foobar");
+    UCX_TEST_ASSERT(ucx_list_indexof(list, otherlist) == -1, "failed");
+    ucx_list_free(otherlist);
+    
+    UCX_TEST_END
+    ucx_list_free(list);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_list_find) {
+    UcxList *l = ucx_list_append(NULL, (void*)"find ");
+    l = ucx_list_append(l, (void*)"some ");
+    l = ucx_list_append(l, (void*)"string!");
+    
+    UCX_TEST_BEGIN
+    
+    UCX_TEST_ASSERT(ucx_list_find(l,(void*)"some ",ucx_strcmp,NULL) == 1,
+        "doesn't find string");
+    UCX_TEST_ASSERT(ucx_list_find(l,(void*)"a",ucx_strcmp,NULL) == -1,
+        "finds non-existing string");
+    
+    UCX_TEST_END
+    ucx_list_free(l);
+}
+
 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_BEGIN
+    
+    UCX_TEST_ASSERT(ucx_list_contains(l,(void*)"a ",ucx_strcmp,NULL),
+        "false negative");
+    UCX_TEST_ASSERT(!ucx_list_contains(l,(void*)"a",ucx_strcmp,NULL),
+        "false positive");
     
     UCX_TEST_END
     ucx_list_free(l);
@@ -168,10 +211,11 @@
 
 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!");
     
+    UCX_TEST_BEGIN
+    
     list = ucx_list_remove(list, ucx_list_get(list, 1));
     
     UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
--- a/test/list_tests.h	Mon Jul 22 11:53:39 2013 +0200
+++ b/test/list_tests.h	Mon Jul 22 13:45:49 2013 +0200
@@ -51,6 +51,8 @@
 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_indexof);
+UCX_TEST_DECLARE(test_ucx_list_find);
 UCX_TEST_DECLARE(test_ucx_list_contains);
 UCX_TEST_DECLARE(test_ucx_list_remove);
 UCX_TEST_DECLARE(test_ucx_list_clone);
--- a/test/main.c	Mon Jul 22 11:53:39 2013 +0200
+++ b/test/main.c	Mon Jul 22 13:45:49 2013 +0200
@@ -120,7 +120,7 @@
         /* UcxLogger Tests */
         ucx_test_register(suite, test_ucx_logger_log);
         
-        /* UcxDlist Tests */
+        /* UcxList Tests */
         ucx_test_register(suite, test_ucx_list_append);
         ucx_test_register(suite, test_ucx_list_prepend);
         ucx_test_register(suite, test_ucx_list_equals);
@@ -129,6 +129,8 @@
         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_indexof);
+        ucx_test_register(suite, test_ucx_list_find);
         ucx_test_register(suite, test_ucx_list_contains);
         ucx_test_register(suite, test_ucx_list_remove);
         ucx_test_register(suite, test_ucx_list_clone);
--- a/test/string_tests.c	Mon Jul 22 11:53:39 2013 +0200
+++ b/test/string_tests.c	Mon Jul 22 13:45:49 2013 +0200
@@ -49,7 +49,7 @@
     sstr_t cat;
     cat.ptr = (char*) malloc(16);
     cat.length = 16;
-    cat = sstrncat(3, cat, s1, s2, s3);
+    cat = sstrncat(cat, 3, s1, s2, s3);
     
     UCX_TEST_BEGIN
     
--- a/ucx/list.c	Mon Jul 22 11:53:39 2013 +0200
+++ b/ucx/list.c	Mon Jul 22 13:45:49 2013 +0200
@@ -116,6 +116,18 @@
     return (UcxList*)e;
 }
 
+ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem) {
+    ssize_t index = 0;
+    while (list) {
+        if (list == elem) {
+            return index;
+        }
+        list = list->next;
+        index++;
+    }
+    return -1;
+}
+
 UcxList *ucx_list_get(const UcxList *l, int index) {
     if (l == NULL) return NULL;
 
@@ -128,13 +140,19 @@
     return (UcxList*)(index == 0 ? e : NULL);
 }
 
-int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
+ssize_t ucx_list_find(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
+    ssize_t index = 0;
     UCX_FOREACH(e, l) {
-        if (!fnc(elem, e->data, cmpdata)) {
-            return 1;
+        if (fnc(elem, e->data, cmpdata) == 0) {
+            return index;
         }
+        index++;
     }
-    return 0;
+    return -1;
+}
+
+int ucx_list_contains(UcxList *l, void *elem, cmp_func fnc, void *cmpdata) {
+    return ucx_list_find(l, elem, fnc, cmpdata) > -1;
 }
 
 size_t ucx_list_size(const UcxList *l) {
--- a/ucx/list.h	Mon Jul 22 11:53:39 2013 +0200
+++ b/ucx/list.h	Mon Jul 22 13:45:49 2013 +0200
@@ -25,6 +25,13 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/**
+ * Double linked list implementation.
+ * 
+ * @file   list.h
+ * @author Mike Becker
+ * @author Olaf Wintermann
+ */
 
 #ifndef UCX_LIST_H
 #define	UCX_LIST_H
@@ -52,30 +59,77 @@
 #define UCX_FOREACH(elem,list) \
         for (UcxList* elem = list ; elem != NULL ; elem = elem->next)
 
+/**
+ * UCX list type
+ * @see UcxList
+ */
 typedef struct UcxList UcxList;
 struct UcxList {
+    /**
+     * List element payload.
+     */
     void    *data;
+    /**
+     * Pointer to the next list element or <code>NULL</code>, if this is the
+     * last element.
+     */
     UcxList *next;
+    /**
+     * Pointer to the previous list element or <code>NULL</code>, if this is
+     * the first element.
+     */
     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);
+
+/**
+ * Compares two UCX lists element-wise by using a compare function.
+ * 
+ * Each element of the two specified lists are compared by using the specified
+ * compare function and the additional data. The type and content of this
+ * additional data depends on the cmp_func() used.
+ * 
+ * If the list pointers denote elements within a list, the lists are compared
+ * starting with the denoted elements. Thus any previous elements are not taken
+ * into account. This might be useful to check, if certain list tails match
+ * each other.
+ * 
+ * @param list1 the first list
+ * @param list2 the second list
+ * @param cmpfnc the compare function
+ * @param data additional data for the compare function
+ * @return 1, if and only if the two lists equal element-wise, 0 otherwise
+ */
+int ucx_list_equals(const UcxList *list1, const UcxList *list2,
+        cmp_func cmpfnc, 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);
+/**
+ * Destroys the entire list.
+ * 
+ * The members of the list are not automatically freed, so ensure they are
+ * otherwise referenced or a memory leak will occur.
+ * 
+ * <b>Caution:</b> the argument <b>MUST</b> denote an entire list (i.e. a call
+ * to ucx_list_first() on the argument must return the argument itself)
+ * 
+ * @param list The list to free.
+ */
+void ucx_list_free(UcxList *list);
+UcxList *ucx_list_append(UcxList *list, void *data);
+UcxList *ucx_list_prepend(UcxList *list, void *data);
+UcxList *ucx_list_concat(UcxList *list1, UcxList *list2);
+UcxList *ucx_list_last(const UcxList *list);
+UcxList *ucx_list_get(const UcxList *list, int index);
+ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem);
+size_t ucx_list_size(const UcxList *list);
+ssize_t ucx_list_find(UcxList *list, void *elem, cmp_func fnc, void *cmpdata);
+int ucx_list_contains(UcxList *list, void *elem, cmp_func fnc, void *cmpdata);
 
-UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data);
+UcxList *ucx_list_sort(UcxList *list, cmp_func cmpfnc, void *data);
 
-UcxList *ucx_list_first(const UcxList *l);
-UcxList *ucx_list_remove(UcxList *l, UcxList *e);
+UcxList *ucx_list_first(const UcxList *list);
+UcxList *ucx_list_remove(UcxList *list, UcxList *element);
 
 #ifdef	__cplusplus
 }
--- a/ucx/string.c	Mon Jul 22 11:53:39 2013 +0200
+++ b/ucx/string.c	Mon Jul 22 13:45:49 2013 +0200
@@ -61,7 +61,7 @@
     return size;
 }
 
-sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...) {
+sstr_t sstrncat(sstr_t s, size_t n, sstr_t c1, ...) {
     va_list ap;
     va_start(ap, c1);
     s.ptr[0] = 0;
--- a/ucx/string.h	Mon Jul 22 11:53:39 2013 +0200
+++ b/ucx/string.h	Mon Jul 22 13:45:49 2013 +0200
@@ -142,14 +142,14 @@
  *       <code>mystring.ptr[mystring.length]='\0'</code> after calling this
  *       function</li>
  * </ul>
-  *
+ *
+ * @param dest    new sstr_t with capacity information and allocated memory
  * @param count   the total number of strings to concatenate
- * @param dest    new sstr_t with capacity information and allocated memory
  * @param src     the first string
  * @param ...     all other strings
  * @return the argument for <code>dest</code> is returned
  */
-sstr_t sstrncat(size_t count, sstr_t dest, sstr_t src, ...);
+sstr_t sstrncat(sstr_t dest, size_t count, sstr_t src, ...);
 
 
 /**

mercurial