update ucx

Sun, 07 May 2023 11:53:10 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 May 2023 11:53:10 +0200
changeset 748
49a284f61e8c
parent 747
efbd59642577
child 749
bbadf84cfc2d

update ucx

ucx/array_list.c file | annotate | diff | comparison | revisions
ucx/cx/hash_map.h file | annotate | diff | comparison | revisions
ucx/cx/iterator.h file | annotate | diff | comparison | revisions
ucx/cx/linked_list.h file | annotate | diff | comparison | revisions
ucx/cx/list.h file | annotate | diff | comparison | revisions
ucx/cx/string.h file | annotate | diff | comparison | revisions
ucx/linked_list.c file | annotate | diff | comparison | revisions
ucx/list.c file | annotate | diff | comparison | revisions
ucx/string.c file | annotate | diff | comparison | revisions
--- a/ucx/array_list.c	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/array_list.c	Sun May 07 11:53:10 2023 +0200
@@ -345,21 +345,22 @@
     }
 }
 
-static size_t cx_arl_find(
+static ssize_t cx_arl_find(
         struct cx_list_s const *list,
         void const *elem
 ) {
     assert(list->cmpfunc != NULL);
+    assert(list->size < SIZE_MAX / 2);
     char *cur = ((cx_array_list const *) list)->data;
 
-    for (size_t i = 0; i < list->size; i++) {
+    for (ssize_t i = 0; i < (ssize_t) list->size; i++) {
         if (0 == list->cmpfunc(elem, cur)) {
             return i;
         }
         cur += list->item_size;
     }
 
-    return list->size;
+    return -1;
 }
 
 static void cx_arl_sort(struct cx_list_s *list) {
--- a/ucx/cx/hash_map.h	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/cx/hash_map.h	Sun May 07 11:53:10 2023 +0200
@@ -90,6 +90,22 @@
 );
 
 /**
+ * Creates a new hash map with a default number of buckets.
+ *
+ * If \p item_size is CX_STORE_POINTERS, the created map will be created as if
+ * cxMapStorePointers() was called immediately after creation.
+ *
+ * @note Iterators provided by this hash map implementation provide the remove operation.
+ * The index value of an iterator is the incremented when the iterator advanced without removal.
+ * In other words, when the iterator is finished, \c index==size .
+ *
+ * @param itemsize the size of one element
+ * @return a pointer to the new hash map
+ */
+#define cxHashMapCreateSimple(itemsize) \
+    cxHashMapCreate(cxDefaultAllocator, itemsize, 0)
+
+/**
  * Increases the number of buckets, if necessary.
  *
  * The load threshold is \c 0.75*buckets. If the element count exceeds the load
--- a/ucx/cx/iterator.h	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/cx/iterator.h	Sun May 07 11:53:10 2023 +0200
@@ -74,7 +74,7 @@
     bool (*flag_removal)(void *);
 
     /**
-     * Indicates whether this iterator is muting.
+     * Indicates whether this iterator may remove elements.
      */
     bool mutating;
 
--- a/ucx/cx/linked_list.h	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/cx/linked_list.h	Sun May 07 11:53:10 2023 +0200
@@ -118,9 +118,9 @@
  * @param loc_data the location of the \c data pointer within your node struct
  * @param cmp_func a compare function to compare \p elem against the node data
  * @param elem a pointer to the element to find
- * @return the index of the element or a past-one index if the element could not be found
+ * @return the index of the element or a negative value if it could not be found
  */
-size_t cx_linked_list_find(
+ssize_t cx_linked_list_find(
         void const *start,
         ptrdiff_t loc_advance,
         ptrdiff_t loc_data,
--- a/ucx/cx/list.h	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/cx/list.h	Sun May 07 11:53:10 2023 +0200
@@ -136,7 +136,7 @@
     /**
      * Member function for finding an element.
      */
-    size_t (*find)(
+    ssize_t (*find)(
             struct cx_list_s const *list,
             void const *elem
     );
@@ -569,10 +569,11 @@
  *
  * @param list the list
  * @param elem the element to find
- * @return the index of the element or \c (size+1) if the element is not found
+ * @return the index of the element or a negative
+ * value when the element is not found
  */
 __attribute__((__nonnull__))
-static inline size_t cxListFind(
+static inline ssize_t cxListFind(
         CxList const *list,
         void const *elem
 ) {
--- a/ucx/cx/string.h	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/cx/string.h	Sun May 07 11:53:10 2023 +0200
@@ -296,28 +296,50 @@
 );
 
 /**
- * Concatenates two or more strings.
+ * Concatenates strings.
  *
  * The resulting string will be allocated by the specified allocator.
-  * So developers \em must pass the return value to cx_strfree() eventually.
-  *
-  * \note It is guaranteed that there is only one allocation.
-  * It is also guaranteed that the returned string is zero-terminated.
+ * So developers \em must pass the return value to cx_strfree_a() eventually.
+ *
+ * If \p str already contains a string, the memory will be reallocated and
+ * the other strings are appended. Otherwise, new memory is allocated.
+ *
+ * \note It is guaranteed that there is only one allocation.
+ * It is also guaranteed that the returned string is zero-terminated.
  *
  * @param alloc the allocator to use
- * @param count   the total number of strings to concatenate
- * @param ...     all strings
+ * @param str   the string the other strings shall be concatenated to
+ * @param count the number of the other following strings to concatenate
+ * @param ...   all other strings
  * @return the concatenated string
  */
 __attribute__((__warn_unused_result__, __nonnull__))
-cxmutstr cx_strcat_a(
+cxmutstr cx_strcat_ma(
         CxAllocator const *alloc,
+        cxmutstr str,
         size_t count,
         ...
 );
 
 /**
- * Concatenates two or more strings.
+ * Concatenates strings and returns a new string.
+ *
+ * The resulting string will be allocated by the specified allocator.
+ * So developers \em must pass the return value to cx_strfree_a() eventually.
+ *
+ * \note It is guaranteed that there is only one allocation.
+ * It is also guaranteed that the returned string is zero-terminated.
+ *
+ * @param alloc the allocator to use
+ * @param count the number of the other following strings to concatenate
+ * @param ...   all other strings
+ * @return the concatenated string
+ */
+#define cx_strcat_a(alloc, count, ...) \
+cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
+
+/**
+ * Concatenates strings and returns a new string.
  *
  * The resulting string will be allocated by standard \c malloc().
  * So developers \em must pass the return value to cx_strfree() eventually.
@@ -325,12 +347,32 @@
  * \note It is guaranteed that there is only one allocation.
  * It is also guaranteed that the returned string is zero-terminated.
  *
- * @param count   the total number of strings to concatenate
- * @param ...     all strings
+ * @param count   the number of the other following strings to concatenate
+ * @param ...     all other strings
  * @return the concatenated string
  */
 #define cx_strcat(count, ...) \
-cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__)
+cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
+
+/**
+ * Concatenates strings.
+ *
+ * The resulting string will be allocated by standard \c malloc().
+ * So developers \em must pass the return value to cx_strfree() eventually.
+ *
+ * If \p str already contains a string, the memory will be reallocated and
+ * the other strings are appended. Otherwise, new memory is allocated.
+ *
+ * \note It is guaranteed that there is only one allocation.
+ * It is also guaranteed that the returned string is zero-terminated.
+ *
+ * @param str     the string the other strings shall be concatenated to
+ * @param count   the number of the other following strings to concatenate
+ * @param ...     all other strings
+ * @return the concatenated string
+ */
+#define cx_strcat_m(str, count, ...) \
+cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__)
 
 /**
  * Returns a substring starting at the specified location.
@@ -732,6 +774,35 @@
  */
 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
 
+
+/**
+ * Creates a duplicate of the specified string.
+ *
+ * The new string will contain a copy allocated by \p allocator.
+ *
+ * \note The returned string is guaranteed to be zero-terminated.
+ *
+ * @param allocator the allocator to use
+ * @param string the string to duplicate
+ * @return a duplicate of the string
+ * @see cx_strdup_m()
+ */
+#define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
+
+/**
+ * Creates a duplicate of the specified string.
+ *
+ * The new string will contain a copy allocated by standard
+ * \c malloc(). So developers \em must pass the return value to cx_strfree().
+ *
+ * \note The returned string is guaranteed to be zero-terminated.
+ *
+ * @param string the string to duplicate
+ * @return a duplicate of the string
+ * @see cx_strdup_ma()
+ */
+#define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
+
 /**
  * Omits leading and trailing spaces.
  *
--- a/ucx/linked_list.c	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/linked_list.c	Sun May 07 11:53:10 2023 +0200
@@ -56,7 +56,7 @@
     return (void *) cur;
 }
 
-size_t cx_linked_list_find(
+ssize_t cx_linked_list_find(
         void const *start,
         ptrdiff_t loc_advance,
         ptrdiff_t loc_data,
@@ -69,7 +69,7 @@
     assert(cmp_func);
 
     void const *node = start;
-    size_t index = 0;
+    ssize_t index = 0;
     do {
         void *current = ll_data(node);
         if (cmp_func(current, elem) == 0) {
@@ -78,7 +78,7 @@
         node = ll_advance(node);
         index++;
     } while (node != NULL);
-    return index;
+    return -1;
 }
 
 void *cx_linked_list_first(
@@ -355,6 +355,9 @@
     // set start node
     ls = *begin;
 
+    // early exit when this list is empty
+    if (ls == NULL) return;
+
     // check how many elements are already sorted
     lc = ls;
     size_t ln = 1;
@@ -729,7 +732,7 @@
     return node == NULL ? NULL : node->payload;
 }
 
-static size_t cx_ll_find(
+static ssize_t cx_ll_find(
         struct cx_list_s const *list,
         void const *elem
 ) {
--- a/ucx/list.c	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/list.c	Sun May 07 11:53:10 2023 +0200
@@ -115,12 +115,12 @@
     return ptr == NULL ? NULL : *ptr;
 }
 
-static size_t cx_pl_find(
+static ssize_t cx_pl_find(
         struct cx_list_s const *list,
         void const *elem
 ) {
     cx_pl_hack_cmpfunc(list);
-    size_t ret = list->climpl->find(list, &elem);
+    ssize_t ret = list->climpl->find(list, &elem);
     cx_pl_unhack_cmpfunc(list);
     return ret;
 }
--- a/ucx/string.c	Fri Apr 21 21:25:32 2023 +0200
+++ b/ucx/string.c	Sun May 07 11:53:10 2023 +0200
@@ -98,11 +98,14 @@
     return size;
 }
 
-cxmutstr cx_strcat_a(
+cxmutstr cx_strcat_ma(
         CxAllocator const *alloc,
+        cxmutstr str,
         size_t count,
         ...
 ) {
+    if (count == 0) return str;
+
     cxstring *strings = calloc(count, sizeof(cxstring));
     if (!strings) abort();
 
@@ -110,34 +113,38 @@
     va_start(ap, count);
 
     // get all args and overall length
-    size_t slen = 0;
+    size_t slen = str.length;
     cx_for_n(i, count) {
         cxstring s = va_arg (ap, cxstring);
         strings[i] = s;
         slen += s.length;
     }
+    va_end(ap);
 
-    // create new string
-    cxmutstr result;
-    result.ptr = cxMalloc(alloc, slen + 1);
-    result.length = slen;
-    if (result.ptr == NULL) abort();
+    // reallocate or create new string
+    if (str.ptr == NULL) {
+        str.ptr = cxMalloc(alloc, slen + 1);
+    } else {
+        str.ptr = cxRealloc(alloc, str.ptr, slen + 1);
+    }
+    if (str.ptr == NULL) abort();
 
     // concatenate strings
-    size_t pos = 0;
+    size_t pos = str.length;
+    str.length = slen;
     cx_for_n(i, count) {
         cxstring s = strings[i];
-        memcpy(result.ptr + pos, s.ptr, s.length);
+        memcpy(str.ptr + pos, s.ptr, s.length);
         pos += s.length;
     }
 
     // terminate string
-    result.ptr[result.length] = '\0';
+    str.ptr[str.length] = '\0';
 
     // free temporary array
     free(strings);
 
-    return result;
+    return str;
 }
 
 cxstring cx_strsubs(

mercurial