remove dependency to ssize_t - fixes #552

Mon, 27 Jan 2025 20:27:39 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 27 Jan 2025 20:27:39 +0100
changeset 1162
e3bb67b72d33
parent 1161
747c4baed44f
child 1163
68ff0839bc6a

remove dependency to ssize_t - fixes #552

src/array_list.c file | annotate | diff | comparison | revisions
src/cx/common.h file | annotate | diff | comparison | revisions
src/cx/linked_list.h file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/cx/string.h file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
src/list.c file | annotate | diff | comparison | revisions
src/string.c file | annotate | diff | comparison | revisions
tests/test_list.c file | annotate | diff | comparison | revisions
tests/test_string.c file | annotate | diff | comparison | revisions
--- a/src/array_list.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/array_list.c	Mon Jan 27 20:27:39 2025 +0100
@@ -856,7 +856,7 @@
     }
 }
 
-static ssize_t cx_arl_find_remove(
+static size_t cx_arl_find_remove(
         struct cx_list_s *list,
         const void *elem,
         bool remove
@@ -865,14 +865,14 @@
     assert(list->collection.size < SIZE_MAX / 2);
     char *cur = ((const cx_array_list *) list)->data;
 
-    for (ssize_t i = 0; i < (ssize_t) list->collection.size; i++) {
+    for (size_t i = 0; i < list->collection.size; i++) {
         if (0 == list->collection.cmpfunc(elem, cur)) {
             if (remove) {
                 if (1 == cx_arl_remove(list, i, 1, NULL)) {
                     return i;
                 } else {
                     // should be unreachable
-                    return -1;  // LCOV_EXCL_LINE
+                    return list->collection.size;  // LCOV_EXCL_LINE
                 }
             } else {
                 return i;
@@ -881,7 +881,7 @@
         cur += list->collection.elem_size;
     }
 
-    return -1;
+    return list->collection.size;
 }
 
 static void cx_arl_sort(struct cx_list_s *list) {
--- a/src/cx/common.h	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/cx/common.h	Mon Jan 27 20:27:39 2025 +0100
@@ -120,22 +120,6 @@
 #endif
 
 // ---------------------------------------------------------------------------
-//       Missing Defines
-// ---------------------------------------------------------------------------
-
-#ifndef SSIZE_MAX // not defined in glibc since C23 and MSVC
-#if CX_WORDSIZE == 64
-/**
- * The maximum representable value in ssize_t.
- */
-#define SSIZE_MAX 0x7fffffffffffffffll
-#else
-#define SSIZE_MAX 0x7fffffffl
-#endif
-#endif
-
-
-// ---------------------------------------------------------------------------
 //       Attribute definitions
 // ---------------------------------------------------------------------------
 
@@ -365,10 +349,6 @@
 // ---------------------------------------------------------------------------
 
 #ifdef _MSC_VER
-// fix missing ssize_t definition
-#include <BaseTsd.h>
-typedef SSIZE_T ssize_t;
-
 // fix missing _Thread_local support
 #define _Thread_local __declspec(thread)
 #endif // _MSC_VER
--- a/src/cx/linked_list.h	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/cx/linked_list.h	Mon Jan 27 20:27:39 2025 +0100
@@ -111,44 +111,25 @@
 );
 
 /**
- * Finds the index of an element within a linked list.
+ * Finds the node containing an element within a linked list.
  *
  * @param start a pointer to the start node
  * @param loc_advance the location of the pointer to advance
  * @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 negative value if it could not be found
+ * @param found_index an optional pointer where the index of the found node
+ * (given that @p start has index 0) is stored
+ * @return the index of the element, if found - unspecified if not found
  */
-cx_attr_nonnull
-ssize_t cx_linked_list_find(
+cx_attr_nonnull_arg(1, 4, 5)
+void *cx_linked_list_find(
         const void *start,
         ptrdiff_t loc_advance,
         ptrdiff_t loc_data,
         cx_compare_func cmp_func,
-        const void *elem
-);
-
-/**
- * Finds the node containing an element within a linked list.
- *
- * @param result a pointer to the memory where the node pointer (or @c NULL if the element
- * could not be found) shall be stored to
- * @param start a pointer to the start node
- * @param loc_advance the location of the pointer to advance
- * @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 negative value if it could not be found
- */
-cx_attr_nonnull
-ssize_t cx_linked_list_find_node(
-        void **result,
-        const void *start,
-        ptrdiff_t loc_advance,
-        ptrdiff_t loc_data,
-        cx_compare_func cmp_func,
-        const void *elem
+        const void *elem,
+        size_t *found_index
 );
 
 /**
--- a/src/cx/list.h	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/cx/list.h	Mon Jan 27 20:27:39 2025 +0100
@@ -165,7 +165,7 @@
     /**
      * Member function for finding and optionally removing an element.
      */
-    ssize_t (*find_remove)(
+    size_t (*find_remove)(
             struct cx_list_s *list,
             const void *elem,
             bool remove
@@ -819,12 +819,12 @@
  *
  * @param list the list
  * @param elem the element to find
- * @return the index of the element or a negative
- * value when the element is not found
+ * @return the index of the element or the size of the list when the element is not found
+ * @see cxListIndexValid()
  */
 cx_attr_nonnull
 cx_attr_nodiscard
-static inline ssize_t cxListFind(
+static inline size_t cxListFind(
         const CxList *list,
         const void *elem
 ) {
@@ -832,17 +832,32 @@
 }
 
 /**
+ * Checks if the specified index is within bounds.
+ *
+ * @param list the list
+ * @param index the index
+ * @retval true if the index is within bounds
+ * @retval false if the index is out of bounds
+ */
+cx_attr_nonnull
+cx_attr_nodiscard
+static inline bool cxListIndexValid(const CxList *list, size_t index) {
+    return index < list->collection.size;
+}
+
+/**
  * Removes and returns the index of the first element that equals @p elem.
  *
  * Determining equality is performed by the list's comparator function.
  *
  * @param list the list
  * @param elem the element to find and remove
- * @return the index of the now removed element or a negative
- * value when the element is not found or could not be removed
+ * @return the index of the now removed element or the list size
+ * when the element is not found or could not be removed
+ * @see cxListIndexValid()
  */
 cx_attr_nonnull
-static inline ssize_t cxListFindRemove(
+static inline size_t cxListFindRemove(
         CxList *list,
         const void *elem
 ) {
--- a/src/cx/string.h	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/cx/string.h	Mon Jan 27 20:27:39 2025 +0100
@@ -1296,23 +1296,6 @@
  * @retval non-zero conversion was not possible
  */
 cx_attr_access_w(2) cx_attr_nonnull_arg(2)
-int cx_strtoz_lc_(cxstring str, ssize_t *output, int base, const char *groupsep);
-
-/**
- * Converts a string to a number.
- *
- * The function returns non-zero when conversion is not possible.
- * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
- * It sets errno to ERANGE when the target datatype is too small.
- *
- * @param str the string to convert
- * @param output a pointer to the integer variable where the result shall be stored
- * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
- * @retval zero success
- * @retval non-zero conversion was not possible
- */
-cx_attr_access_w(2) cx_attr_nonnull_arg(2)
 int cx_strtous_lc_(cxstring str, unsigned short *output, int base, const char *groupsep);
 
 /**
@@ -1449,7 +1432,7 @@
  * @retval non-zero conversion was not possible
  */
 cx_attr_access_w(2) cx_attr_nonnull_arg(2)
-int cx_strtouz_lc_(cxstring str, size_t *output, int base, const char *groupsep);
+int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep);
 
 /**
  * Converts a string to a single precision floating point number.
@@ -1627,22 +1610,6 @@
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
-#define cx_strtoz_lc(str, output, base, groupsep) cx_strtoz_lc_(cx_strcast(str), output, base, groupsep)
-
-/**
- * Converts a string to a number.
- *
- * The function returns non-zero when conversion is not possible.
- * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
- * It sets errno to ERANGE when the target datatype is too small.
- *
- * @param str the string to convert
- * @param output a pointer to the integer variable where the result shall be stored
- * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
- * @retval zero success
- * @retval non-zero conversion was not possible
- */
 #define cx_strtous_lc(str, output, base, groupsep) cx_strtous_lc_(cx_strcast(str), output, base, groupsep)
 
 /**
@@ -1771,7 +1738,7 @@
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
-#define cx_strtouz_lc(str, output, base, groupsep) cx_strtouz_lc_(cx_strcast(str), output, base, groupsep)
+#define cx_strtoz_lc(str, output, base, groupsep) cx_strtoz_lc_(cx_strcast(str), output, base, groupsep)
 
 /**
  * Converts a string to a number.
@@ -1781,7 +1748,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1799,7 +1766,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1817,7 +1784,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1835,7 +1802,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1853,7 +1820,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1871,7 +1838,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1889,7 +1856,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1907,7 +1874,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1925,7 +1892,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1943,7 +1910,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1961,7 +1928,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1979,7 +1946,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -1997,7 +1964,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -2015,7 +1982,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -2033,7 +2000,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -2051,7 +2018,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -2069,7 +2036,7 @@
  * It sets errno to ERANGE when the target datatype is too small.
  *
  * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
+ * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
@@ -2080,24 +2047,6 @@
 #define cx_strtou64(str, output, base) cx_strtou64_lc_(cx_strcast(str), output, base, ",")
 
 /**
- * Converts a string to a number.
- *
- * The function returns non-zero when conversion is not possible.
- * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
- * It sets errno to ERANGE when the target datatype is too small.
- *
- * The comma character is treated as group separator and ignored during parsing.
- * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtouz_lc()).
- *
- * @param str the string to convert
- * @param output a pointer to the integer variable where the result shall be stored
- * @param base 2, 8, 10, or 16
- * @retval zero success
- * @retval non-zero conversion was not possible
- */
-#define cx_strtouz(str, output, base) cx_strtouz_lc_(cx_strcast(str), output, base, ",")
-
-/**
  * Converts a string to a single precision floating point number.
  *
  * The function returns non-zero when conversion is not possible.
--- a/src/linked_list.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/linked_list.c	Mon Jan 27 20:27:39 2025 +0100
@@ -56,48 +56,33 @@
     return (void *) cur;
 }
 
-ssize_t cx_linked_list_find(
+void *cx_linked_list_find(
         const void *start,
         ptrdiff_t loc_advance,
         ptrdiff_t loc_data,
         cx_compare_func cmp_func,
-        const void *elem
+        const void *elem,
+        size_t *found_index
 ) {
-    void *dummy;
-    return cx_linked_list_find_node(
-            &dummy, start,
-            loc_advance, loc_data,
-            cmp_func, elem
-    );
-}
-
-ssize_t cx_linked_list_find_node(
-        void **result,
-        const void *start,
-        ptrdiff_t loc_advance,
-        ptrdiff_t loc_data,
-        cx_compare_func cmp_func,
-        const void *elem
-) {
-    assert(result != NULL);
     assert(start != NULL);
     assert(loc_advance >= 0);
     assert(loc_data >= 0);
     assert(cmp_func);
 
-    const void *node = start;
-    ssize_t index = 0;
+    void *node = (void*) start;
+    size_t index = 0;
     do {
         void *current = ll_data(node);
         if (cmp_func(current, elem) == 0) {
-            *result = (void *) node;
-            return index;
+            if (found_index != NULL) {
+                *found_index = index;
+            }
+            return node;
         }
         node = ll_advance(node);
         index++;
     } while (node != NULL);
-    *result = NULL;
-    return -1;
+    return NULL;
 }
 
 void *cx_linked_list_first(
@@ -930,35 +915,30 @@
     return node == NULL ? NULL : node->payload;
 }
 
-static ssize_t cx_ll_find_remove(
+static size_t cx_ll_find_remove(
         struct cx_list_s *list,
         const void *elem,
         bool remove
 ) {
+    size_t index;
+    cx_linked_list *ll = ((cx_linked_list *) list);
+    cx_linked_list_node *node = cx_linked_list_find(
+            ll->begin,
+            CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
+            list->collection.cmpfunc, elem,
+            &index
+    );
+    if (node == NULL) {
+        return list->collection.size;
+    }
     if (remove) {
-        cx_linked_list *ll = ((cx_linked_list *) list);
-        cx_linked_list_node *node;
-        ssize_t index = cx_linked_list_find_node(
-                (void **) &node,
-                ll->begin,
-                CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                list->collection.cmpfunc, elem
-        );
-        if (node != NULL) {
-            cx_invoke_destructor(list, node->payload);
-            cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
-                                  CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
-            list->collection.size--;
-            cxFree(list->collection.allocator, node);
-        }
-        return index;
-    } else {
-        return cx_linked_list_find(
-                ((cx_linked_list *) list)->begin,
-                CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
-                list->collection.cmpfunc, elem
-        );
+        cx_invoke_destructor(list, node->payload);
+        cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
+                              CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
+        list->collection.size--;
+        cxFree(list->collection.allocator, node);
     }
+    return index;
 }
 
 static void cx_ll_sort(struct cx_list_s *list) {
--- a/src/list.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/list.c	Mon Jan 27 20:27:39 2025 +0100
@@ -128,13 +128,13 @@
     return ptr == NULL ? NULL : *ptr;
 }
 
-static ssize_t cx_pl_find_remove(
+static size_t cx_pl_find_remove(
         struct cx_list_s *list,
         const void *elem,
         bool remove
 ) {
     cx_pl_hack_cmpfunc(list);
-    ssize_t ret = list->climpl->find_remove(list, &elem, remove);
+    size_t ret = list->climpl->find_remove(list, &elem, remove);
     cx_pl_unhack_cmpfunc(list);
     return ret;
 }
@@ -207,12 +207,12 @@
     return NULL;
 }
 
-static ssize_t cx_emptyl_find_remove(
+static size_t cx_emptyl_find_remove(
         cx_attr_unused struct cx_list_s *list,
         cx_attr_unused const void *elem,
         cx_attr_unused bool remove
 ) {
-    return -1;
+    return 0;
 }
 
 static bool cx_emptyl_iter_valid(cx_attr_unused const void *iter) {
--- a/src/string.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/src/string.c	Mon Jan 27 20:27:39 2025 +0100
@@ -688,7 +688,7 @@
     // Allocate result string
     cxmutstr result;
     {
-        ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length;
+        long long adjlen = (long long) replacement.length - (long long) pattern.length;
         size_t rcount = 0;
         curbuf = &ibuf;
         do {
@@ -899,16 +899,6 @@
     return cx_strtoll_lc(str, (long long*) output, base, groupsep);
 }
 
-int cx_strtoz_lc_(cxstring str, ssize_t *output, int base, const char *groupsep) {
-#if SSIZE_MAX == INT32_MAX
-    return cx_strtoi32_lc_(str, (int32_t*) output, base, groupsep);
-#elif SSIZE_MAX == INT64_MAX
-    return cx_strtoll_lc_(str, (long long*) output, base, groupsep);
-#else
-#error "unsupported ssize_t size"
-#endif
-}
-
 #define cx_strtoX_unsigned_impl(rtype, rmax) \
     uint64_t result; \
     if (cx_strtou64_lc(str, &result, base, groupsep)) { \
@@ -1029,7 +1019,7 @@
     return cx_strtoull_lc(str, (unsigned long long*) output, base, groupsep);
 }
 
-int cx_strtouz_lc_(cxstring str, size_t *output, int base, const char *groupsep) {
+int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep) {
 #if SIZE_MAX == UINT32_MAX
     return cx_strtou32_lc_(str, (uint32_t*) output, base, groupsep);
 #elif SIZE_MAX == UINT64_MAX
--- a/tests/test_list.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/tests/test_list.c	Mon Jan 27 20:27:39 2025 +0100
@@ -382,22 +382,31 @@
 }
 
 CX_TEST(test_linked_list_find) {
-    void *list = create_nodes_test_data(4);
+    node *list = create_nodes_test_data(4);
     assign_nodes_test_data(list, 2, 4, 6, 8);
     CX_TEST_DO {
+        size_t i = 10;
         int s;
         s = 2;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 0);
+        node *n = list;
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n);
+        CX_TEST_ASSERT(i == 0);
+        n = n->next;
         s = 4;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 1);
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n);
+        CX_TEST_ASSERT(i == 1);
+        n = n->next;
         s = 6;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 2);
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n);
+        CX_TEST_ASSERT(i == 2);
+        n = n->next;
         s = 8;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 3);
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n);
+        CX_TEST_ASSERT(i == 3);
         s = 10;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == NULL);
         s = -2;
-        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
+        CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == NULL);
     }
     destroy_nodes_test_data(list);
 }
@@ -967,8 +976,8 @@
 CX_TEST(test_empty_list_find) {
     int x = 42, y = 1337;
     CX_TEST_DO {
-        CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) < 0);
-        CX_TEST_ASSERT(cxListFind(cxEmptyList, &y) < 0);
+        CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) == 0);
+        CX_TEST_ASSERT(cxListFind(cxEmptyList, &y) == 0);
     }
 }
 
@@ -1536,10 +1545,10 @@
     const size_t testdata_len = 250;
     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
 
-    int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
+    unsigned exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
     int val = testdata[exp];
     // randomly picked number could occur earlier in list - find first position
-    for (int i = 0 ; i < exp ; i++) {
+    for (unsigned i = 0 ; i < exp ; i++) {
         if (testdata[i] == val) {
             exp = i;
             break;
@@ -1552,7 +1561,7 @@
     CX_TEST_ASSERT(cxListFind(list, &val) != exp);
 
     int notinlist = -1;
-    CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) < 0);
+    CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) == cxListSize(list));
     CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
 
     free(testdata);
@@ -1571,9 +1580,11 @@
     int *testdata = int_test_data_added_to_list(list, isptrlist, 128);
     CX_TEST_ASSERT(cxListSize(list) == len);
     for (size_t i = 0; i < len; i++) {
+        CX_TEST_ASSERT(cxListIndexValid(list, i));
         CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
     }
-    CX_TEST_ASSERT(cxListAt(list, cxListSize(list)) == NULL);
+    CX_TEST_ASSERT(!cxListIndexValid(list, len));
+    CX_TEST_ASSERT(cxListAt(list, len) == NULL);
     free(testdata);
 })
 
@@ -1620,10 +1631,10 @@
     int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
 
     for (size_t attempt = 0; attempt < 25; attempt++) {
-        int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
+        unsigned exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
         int val = testdata[exp];
         // randomly picked number could occur earlier in list - find first position
-        for (int i = 0 ; i < exp ; i++) {
+        for (unsigned i = 0 ; i < exp ; i++) {
             if (testdata[i] == val) {
                 exp = i;
                 break;
@@ -1633,7 +1644,7 @@
     }
 
     int notinlist = -1;
-    CX_TEST_ASSERT(cxListFind(list, &notinlist) < 0);
+    CX_TEST_ASSERT(cxListFind(list, &notinlist) == cxListSize(list));
 
     free(testdata);
 })
--- a/tests/test_string.c	Sun Jan 26 14:37:07 2025 +0100
+++ b/tests/test_string.c	Mon Jan 27 20:27:39 2025 +0100
@@ -985,8 +985,7 @@
     test_strtoint_impl(LL, num, base, i8, INT8_MIN, INT8_MAX); \
     test_strtoint_impl(LL, num, base, i16, INT16_MIN, INT16_MAX); \
     test_strtoint_impl(LL, num, base, i32, INT32_MIN, INT32_MAX); \
-    test_strtoint_impl(LL, num, base, i64, INT64_MIN, INT64_MAX); \
-    test_strtoint_impl(LL, num, base, z, -SSIZE_MAX-1, SSIZE_MAX)
+    test_strtoint_impl(LL, num, base, i64, INT64_MIN, INT64_MAX);
 
 #define test_strtoint_rollout_signed(num, base) \
     test_strtoint_rollout_signed_impl(num, base); \
@@ -1001,7 +1000,7 @@
     test_strtoint_impl(ULL, num, base, u16, 0, UINT16_MAX); \
     test_strtoint_impl(ULL, num, base, u32, 0, UINT32_MAX); \
     test_strtoint_impl(ULL, num, base, u64, 0, UINT64_MAX); \
-    test_strtoint_impl(ULL, num, base, uz, 0, SIZE_MAX)
+    test_strtoint_impl(ULL, num, base, z, 0, SIZE_MAX)
 
 CX_TEST(test_string_to_signed_integer) {
     short s;
@@ -1012,7 +1011,6 @@
     int16_t i16;
     int32_t i32;
     int64_t i64;
-    ssize_t z;
     CX_TEST_DO {
         // do some brute force tests with all ranges
         test_strtoint_rollout_signed(47, 10);
@@ -1100,7 +1098,7 @@
     uint16_t u16;
     uint32_t u32;
     uint64_t u64;
-    size_t uz;
+    size_t z;
     CX_TEST_DO {
         // do some brute force tests with all ranges
         test_strtoint_rollout(47, 10);

mercurial