Jelajahi Sumber

Added a return value to SCDArray_copyer_func.

Aaro Saila 3 hari lalu
induk
melakukan
bbd9b46aba
3 mengubah file dengan 70 tambahan dan 23 penghapusan
  1. 48 7
      include/scufcont/DArray.h
  2. 6 5
      include/scufcont/scufcont.h
  3. 16 11
      tests/cmocka/DArray_tests.c

+ 48 - 7
include/scufcont/DArray.h

@@ -63,8 +63,15 @@
 
 #define SCDARRAY_COPYER_FUNC_TYPE_NAME(type_name) SCDArray_##type_name##_copyer_func
 
+/**
+  @typedef SCDArray_copyer_func
+
+  @return 0 on success, user defined non-zero value for errors. SCDArray functions that call
+          this function return SCUFCONT_USER_ERR when this function encounters an error and
+          returns the user-defined error value as an out parameter.
+*/
 #define SCDARRAY_COPYER(type, type_name) \
-    typedef void (*SCDARRAY_COPYER_FUNC_TYPE_NAME(type_name))(type * dst, type * src)
+    typedef int (*SCDARRAY_COPYER_FUNC_TYPE_NAME(type_name))(type * dst, type * src)
 
 // SCDARRAY_DESTROYER(char *, charp);
 
@@ -107,7 +114,12 @@
 
 // SCDARRAY_ALLOC(char *, charp, SCDArray_charp_alloc)
 
-#define SCDARRAY_ALLOC_COPY_SIG(type, type_name, func_name) ScufContResult func_name(SCDArray_##type_name *const dst, const SCDArray_##type_name *const src)
+#define SCDARRAY_ALLOC_COPY_SIG(type, type_name, func_name) \
+    ScufContResult func_name(                               \
+        SCDArray_##type_name *const dst,                    \
+        const SCDArray_##type_name *const src,              \
+        int *const copyer_err                               \
+    )
 
 /**
   @fn SCDArray_alloc_copy
@@ -130,7 +142,13 @@
             for (size_t i = 0; i < src->len; i++) {                 \
                 type *dst_elem = SCDArray_##type_name##_at(dst, i); \
                 type *src_elem = SCDArray_##type_name##_at(src, i); \
-                dst->elem_copy(dst_elem, src_elem);                 \
+                const int err = dst->elem_copy(dst_elem, src_elem); \
+                if (err != 0) {                                     \
+                    if (copyer_err != NULL) {                       \
+                        *copyer_err = err;                          \
+                    }                                               \
+                    return SCUFCONT_USER_ERR;                       \
+                }                                                   \
             }                                                       \
         }                                                           \
         return SCUFCONT_SUCCESS;                                    \
@@ -158,7 +176,12 @@
         return darr->data == NULL;                     \
     }
 
-#define SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) ScufContResult func_name(SCDArray_##type_name *const darr, type *new_elem)
+#define SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) \
+    ScufContResult func_name(                              \
+        SCDArray_##type_name *const darr,                  \
+        type *new_elem,                                    \
+        int *const copyer_err                              \
+    )
 
 /**
   @fn SCDArray_push_back
@@ -179,12 +202,24 @@
         darr->len++;                                                                       \
         if (darr->elem_copy != NULL) {                                                     \
             type *dst = SCDArray_##type_name##_at(darr, darr->len - 1);                    \
-            darr->elem_copy(dst, new_elem);                                                \
+            const int err = darr->elem_copy(dst, new_elem);                                \
+            if (err != 0) {                                                                \
+                if (copyer_err != NULL) {                                                  \
+                    *copyer_err = err;                                                     \
+                }                                                                          \
+                return SCUFCONT_USER_ERR;                                                  \
+            }                                                                              \
         }                                                                                  \
         return SCUFCONT_SUCCESS;                                                           \
     }
 
-#define SCDARRAY_PUSH_BACK_MULTIPLE_SIG(type, type_name, func_name) ScufContResult func_name(SCDArray_##type_name *const darr, type *new_elems, const size_t new_elems_n)
+#define SCDARRAY_PUSH_BACK_MULTIPLE_SIG(type, type_name, func_name) \
+    ScufContResult func_name(                                       \
+        SCDArray_##type_name *const darr,                           \
+        type *new_elems,                                            \
+        const size_t new_elems_n,                                   \
+        int *const copyer_err                                       \
+    )
 
 /**
   @fn SCDArray_push_back_multiple
@@ -206,7 +241,13 @@
             for (size_t i = 0; i < new_elems_n; i++) {                                                \
                 type *dst = SCDArray_##type_name##_at(darr, darr->len + i);                           \
                 type *src = new_elems + i;                                                            \
-                darr->elem_copy(dst, src);                                                            \
+                const int err = darr->elem_copy(dst, src);                                            \
+                if (err != 0) {                                                                       \
+                    if (copyer_err != NULL) {                                                         \
+                        *copyer_err = err;                                                            \
+                    }                                                                                 \
+                    return SCUFCONT_USER_ERR;                                                         \
+                }                                                                                     \
             }                                                                                         \
         }                                                                                             \
         darr->len += new_elems_n;                                                                     \

+ 6 - 5
include/scufcont/scufcont.h

@@ -1,10 +1,11 @@
 #ifndef SCUFCONT_H_
 #define SCUFCONT_H_
 
-#define SCUFCONT_RESULT_X(X) \
-    X(SCUFCONT_SUCCESS) \
+#define SCUFCONT_RESULT_X(X)  \
+    X(SCUFCONT_SUCCESS)       \
     X(SCUFCONT_OUT_OF_MEMORY) \
-    X(SCUFCONT_OUT_OF_BOUNDS)
+    X(SCUFCONT_OUT_OF_BOUNDS) \
+    X(SCUFCONT_USER_ERR)
 
 #define X(val) val,
 
@@ -14,8 +15,8 @@ typedef enum {
 
 #undef X
 
-extern const char* SCUFCONT_VERSION;
+extern const char *SCUFCONT_VERSION;
 
-const char* ScufContResult_to_str(const ScufContResult res);
+const char *ScufContResult_to_str(const ScufContResult res);
 
 #endif // SCUFCONT_H_

+ 16 - 11
tests/cmocka/DArray_tests.c

@@ -18,11 +18,16 @@ void darray_charp_destroyer(char **elem) {
     }
 }
 
-void darray_charp_copyer(char **dst, char **src) {
+int darray_charp_copyer(char **dst, char **src) {
     if (dst != NULL && src != NULL && *src != NULL) {
         *dst = (char *) malloc(sizeof(char) * (strlen(*src) + 1));
+        if (dst == NULL) {
+            return SCUFCONT_OUT_OF_MEMORY;
+        }
         strncpy(*dst, *src, strlen(*src) + 1);
     }
+
+    return 0;
 }
 
 void test_DArray_alloc(void **state) {
@@ -51,11 +56,11 @@ void test_DArray_alloc_copy(void **state) {
         char buf[100];
         snprintf(buf, 100, "%d", n);
         char *bufptr = buf;
-        assert_true(SCDArray_charp_push_back(&arr, &bufptr) == SCUFCONT_SUCCESS);
+        assert_true(SCDArray_charp_push_back(&arr, &bufptr, NULL) == SCUFCONT_SUCCESS);
     }
 
     SCDArray_charp copied;
-    assert_true(SCDArray_charp_alloc_copy(&copied, &arr) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_alloc_copy(&copied, &arr, NULL) == SCUFCONT_SUCCESS);
     assert_non_null(copied.data);
     assert_uint_equal(copied.capacity, arr.capacity);
     assert_uint_equal(copied.len, arr.len);
@@ -108,10 +113,10 @@ void test_DArray_push_back(void **state) {
 
     char *str2 = "World";
 
-    assert_true(SCDArray_charp_push_back(&arr, &(char *) { str1 }) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back(&arr, &(char *) { str1 }, NULL) == SCUFCONT_SUCCESS);
     assert_string_equal(*SCDArray_charp_at(&arr, 0), str1);
 
-    assert_true(SCDArray_charp_push_back(&arr, &(char *) { str2 }) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back(&arr, &(char *) { str2 }, NULL) == SCUFCONT_SUCCESS);
     assert_string_equal(*SCDArray_charp_at(&arr, 0), str1);
     assert_string_equal(*SCDArray_charp_at(&arr, 1), str2);
 
@@ -128,10 +133,10 @@ void test_DArray_at(void **state) {
     SCDArray_charp arr;
     SCDARRAY_CHARP_ALLOC(&arr);
 
-    assert_true(SCDArray_charp_push_back(&arr, &(char *) { "Hello" }) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back(&arr, &(char *) { "Hello" }, NULL) == SCUFCONT_SUCCESS);
     assert_string_equal(*SCDArray_charp_at(&arr, 0), "Hello");
 
-    assert_true(SCDArray_charp_push_back(&arr, &(char *) { "World" }) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back(&arr, &(char *) { "World" }, NULL) == SCUFCONT_SUCCESS);
     assert_string_equal(*SCDArray_charp_at(&arr, 0), "Hello");
     assert_string_equal(*SCDArray_charp_at(&arr, 1), "World");
 
@@ -146,7 +151,7 @@ void test_DArray_push_back_multiple(void **state) {
 
     char *nums[] = { "1", "2", "3", "4", "5" };
     const size_t nums_len = sizeof(nums) / sizeof(nums[0]);
-    assert_true(SCDArray_charp_push_back_multiple(&arr, nums, nums_len) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back_multiple(&arr, nums, nums_len, NULL) == SCUFCONT_SUCCESS);
     for (size_t i = 0; i < arr.len; i++) {
         assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
     }
@@ -155,7 +160,7 @@ void test_DArray_push_back_multiple(void **state) {
     nums2[0] = "6";
     nums2[1] = "7";
     nums2[2] = "8";
-    assert_true(SCDArray_charp_push_back_multiple(&arr, nums2, nums2_len) == SCUFCONT_SUCCESS);
+    assert_true(SCDArray_charp_push_back_multiple(&arr, nums2, nums2_len, NULL) == SCUFCONT_SUCCESS);
     for (size_t i = 0; i < nums_len; i++) {
         assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
     }
@@ -191,7 +196,7 @@ void test_DArray_remove(void **state) {
     nums[4] = (char *) malloc(2);
     strncpy(nums[4], "5", 2);
     const size_t nums_len = 5;
-    SCDArray_charp_push_back_multiple(&arr, nums, nums_len);
+    SCDArray_charp_push_back_multiple(&arr, nums, nums_len, NULL);
     for (size_t i = 0; i < arr.len; i++) {
         assert_string_equal(*SCDArray_charp_at(&arr, i), nums[i]);
     }
@@ -256,7 +261,7 @@ void test_DArray_clear(void **state) {
     const size_t words_len = sizeof(words) / sizeof(words[0]);
 
     for (size_t i = 0; i < words_len; i++) {
-        SCDArray_charp_push_back(&arr, words + i);
+        SCDArray_charp_push_back(&arr, words + i, NULL);
     }
 
     assert_uint_equal(arr.len, words_len);