Просмотр исходного кода

Added push_back_multiple, free, and remove to DArray. Added tests.

Aaro Saila 1 месяц назад
Родитель
Сommit
6ce34dfe91
4 измененных файлов с 198 добавлено и 26 удалено
  1. 66 25
      include/DArray.h
  2. 123 1
      tests/cmocka/DArray_tests.c
  3. 8 0
      tests/cmocka/main.c
  4. 1 0
      tests/cmocka/meson.build

+ 66 - 25
include/DArray.h

@@ -6,7 +6,7 @@
 #include <stdlib.h> // IWYU pragma: keep
 #include <stdlib.h> // IWYU pragma: keep
 #include <string.h>
 #include <string.h>
 
 
-#include "scufcont.h"
+#include "scufcont.h" // IWYU pragma: keep
 
 
 // #define SCUFCONT_BOUNDS_CHECK
 // #define SCUFCONT_BOUNDS_CHECK
 
 
@@ -18,21 +18,27 @@
 
 
 #define SCDARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, SCDArray_##type_name, SCDArray_##type_name##_##func_name)
 #define SCDARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, SCDArray_##type_name, SCDArray_##type_name##_##func_name)
 
 
-#define SCDARRAY_IMPL(type, type_name)                                \
-    SCDARRAY_EXPANDER(SCDARRAY_ALLOC, type, type_name, alloc)         \
-    SCDARRAY_EXPANDER(SCDARRAY_IS_NULL, type, type_name, is_null)     \
-    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK, type, type_name, push_back) \
-    SCDARRAY_EXPANDER(SCDARRAY_AT, type, type_name, at)
+#define SCDARRAY_IMPL(type, type_name)                                                  \
+    SCDARRAY_EXPANDER(SCDARRAY_ALLOC, type, type_name, alloc)                           \
+    SCDARRAY_EXPANDER(SCDARRAY_FREE, type, type_name, free)                             \
+    SCDARRAY_EXPANDER(SCDARRAY_IS_NULL, type, type_name, is_null)                       \
+    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK, type, type_name, push_back)                   \
+    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK_MULTIPLE, type, type_name, push_back_multiple) \
+    SCDARRAY_EXPANDER(SCDARRAY_AT, type, type_name, at)                                 \
+    SCDARRAY_EXPANDER(SCDARRAY_REMOVE, type, type_name, remove)
 
 
 #define SCDARRAY_HEADER(type, type_name) \
 #define SCDARRAY_HEADER(type, type_name) \
     SCDARRAY_STRUCT(type, type_name)     \
     SCDARRAY_STRUCT(type, type_name)     \
     SCDARRAY_SIGS(type, type_name)
     SCDARRAY_SIGS(type, type_name)
 
 
-#define SCDARRAY_SIGS(type, type_name)                                     \
-    SCDARRAY_EXPANDER(SCDARRAY_ALLOC_SIG, type, type_name, alloc);         \
-    SCDARRAY_EXPANDER(SCDARRAY_IS_NULL_SIG, type, type_name, is_null);     \
-    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK_SIG, type, type_name, push_back); \
-    SCDARRAY_EXPANDER(SCDARRAY_AT_SIG, type, type_name, at);
+#define SCDARRAY_SIGS(type, type_name)                                                       \
+    SCDARRAY_EXPANDER(SCDARRAY_ALLOC_SIG, type, type_name, alloc);                           \
+    SCDARRAY_EXPANDER(SCDARRAY_FREE_SIG, type, type_name, free);                             \
+    SCDARRAY_EXPANDER(SCDARRAY_IS_NULL_SIG, type, type_name, is_null);                       \
+    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK_SIG, type, type_name, push_back);                   \
+    SCDARRAY_EXPANDER(SCDARRAY_PUSH_BACK_MULTIPLE_SIG, type, type_name, push_back_multiple); \
+    SCDARRAY_EXPANDER(SCDARRAY_AT_SIG, type, type_name, at);                                 \
+    SCDARRAY_EXPANDER(SCDARRAY_REMOVE_SIG, type, type_name, remove);
 
 
 // SCDARRAY_ALLOC_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_alloc); \
 // SCDARRAY_ALLOC_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_alloc); \
 // SCDARRAY_PUSH_BACK_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_push_back);
 // SCDARRAY_PUSH_BACK_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_push_back);
@@ -59,6 +65,13 @@
         return SCUFCONT_SUCCESS;                      \
         return SCUFCONT_SUCCESS;                      \
     }
     }
 
 
+#define SCDARRAY_FREE_SIG(type, type_name, func_name) void func_name(type_name* darr)
+
+#define SCDARRAY_FREE(type, type_name, func_name)   \
+    SCDARRAY_FREE_SIG(type, type_name, func_name) { \
+        free(darr->data);                           \
+    }
+
 #define SCDARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr)
 #define SCDARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr)
 
 
 #define SCDARRAY_IS_NULL(type, type_name, func_name)   \
 #define SCDARRAY_IS_NULL(type, type_name, func_name)   \
@@ -68,22 +81,40 @@
 
 
 // SCDARRAY_ALLOC(int, SCDArray_int, SCDArray_int_alloc);
 // SCDARRAY_ALLOC(int, SCDArray_int, SCDArray_int_alloc);
 
 
-#define SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem)
-
-#define SCDARRAY_PUSH_BACK(type, type_name, func_name)                               \
-    SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) {                             \
-        if (darr->len + 1 > darr->capacity) {                                        \
-            darr->capacity *= 2;                                                     \
-            darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(type)); \
-            if (darr->data == NULL) {                                                \
-                return -1;                                                           \
-            }                                                                        \
-        }                                                                            \
-        memcpy(darr->data + darr->len, new_elem, sizeof(type));                      \
-        darr->len++;                                                                 \
-        return 1;                                                                    \
+#define SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) ScufContResult func_name(type_name* darr, const type* new_elem)
+
+#define SCDARRAY_PUSH_BACK(type, type_name, func_name)                                    \
+    SCDARRAY_PUSH_BACK_SIG(type, type_name, func_name) {                                  \
+        if (darr->len + 1 > darr->capacity) {                                             \
+            darr->capacity *= 2;                                                          \
+            darr->data = (type*) realloc(darr->data, darr->capacity * sizeof(*new_elem)); \
+            if (darr->data == NULL) {                                                     \
+                return SCUFCONT_OUT_OF_MEMORY;                                            \
+            }                                                                             \
+        }                                                                                 \
+        memcpy(darr->data + darr->len, new_elem, sizeof(*new_elem));                      \
+        darr->len++;                                                                      \
+        return SCUFCONT_SUCCESS;                                                          \
+    }
+
+#define SCDARRAY_PUSH_BACK_MULTIPLE_SIG(type, type_name, func_name) ScufContResult func_name(type_name* darr, const type* new_elems, const size_t new_elems_n)
+
+#define SCDARRAY_PUSH_BACK_MULTIPLE(type, type_name, func_name)                                      \
+    SCDARRAY_PUSH_BACK_MULTIPLE_SIG(type, type_name, func_name) {                                    \
+        if (darr->len + new_elems_n > darr->capacity) {                                              \
+            darr->data = (type*) realloc(darr->data, (darr->capacity + new_elems_n) * sizeof(type)); \
+            if (darr->data == NULL) {                                                                \
+                return SCUFCONT_OUT_OF_MEMORY;                                                       \
+            }                                                                                        \
+            darr->capacity += new_elems_n;                                                           \
+        }                                                                                            \
+        memcpy(darr->data + darr->len, new_elems, sizeof(type) * new_elems_n);                       \
+        darr->len += new_elems_n;                                                                    \
+        return SCUFCONT_SUCCESS;                                                                     \
     }
     }
 
 
+// SCDARRAY_PUSH_BACK_MULTIPLE(int, SCDArray_int, SCDArray_int_push_back_multiple)
+
 #define SCDARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
 #define SCDARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i)
 
 
 // SCDARRAY_PUSH_BACK(int, SCDArray_int, SCDArray_int_push_back);
 // SCDARRAY_PUSH_BACK(int, SCDArray_int, SCDArray_int_push_back);
@@ -111,4 +142,14 @@
 
 
 // SCDARRAY_AT(char*, SCDArray_charp, SCDArray_charp_at)
 // SCDARRAY_AT(char*, SCDArray_charp, SCDArray_charp_at)
 
 
+#define SCDARRAY_REMOVE_SIG(type, type_name, func_name) void func_name(type_name* darr, const size_t i)
+
+#define SCDARRAY_REMOVE(type, type_name, func_name)                                  \
+    SCDARRAY_REMOVE_SIG(type, type_name, func_name) {                                \
+        memmove(darr->data + i, darr->data + i + 1, (darr->len - i) * sizeof(type)); \
+        darr->len--;                                                                 \
+    }
+
+// SCDARRAY_REMOVE(char*, SCDArray_charp, SCDArray_charp_remove)
+
 #endif // SCUFCONT_DARRAY_H_
 #endif // SCUFCONT_DARRAY_H_

+ 123 - 1
tests/cmocka/DArray_tests.c

@@ -1,11 +1,12 @@
 #include <cmocka.h>
 #include <cmocka.h>
 
 
 #include "DArray.h"
 #include "DArray.h"
+#include "scufcont.h"
 
 
 SCDARRAY_HEADER(int, int)
 SCDARRAY_HEADER(int, int)
 SCDARRAY_IMPL(int, int)
 SCDARRAY_IMPL(int, int)
 
 
-void DArray_alloc_test(void** state) {
+void test_DArray_alloc(void** state) {
     (void) state;
     (void) state;
 
 
     SCDArray_int arr;
     SCDArray_int arr;
@@ -13,5 +14,126 @@ void DArray_alloc_test(void** state) {
     assert_non_null(arr.data);
     assert_non_null(arr.data);
     assert_uint_equal(arr.len, 0u);
     assert_uint_equal(arr.len, 0u);
     assert_uint_equal(arr.capacity, 1u);
     assert_uint_equal(arr.capacity, 1u);
+
+    SCDArray_int_free(&arr);
+}
+
+void test_DArray_push_back(void** state) {
+    (void) state;
+
+    SCDArray_int arr;
+    SCDArray_int_alloc(&arr);
+
+    assert_true(SCDArray_int_push_back(&arr, &(int){7}) == SCUFCONT_SUCCESS);
+    assert_true(arr.data[0] == 7);
+
+    assert_true(SCDArray_int_push_back(&arr, &(int){10}) == SCUFCONT_SUCCESS);
+    assert_true(arr.data[0] == 7);
+    assert_true(arr.data[1] == 10);
+
+    SCDArray_int_free(&arr);
+}
+
+void test_DArray_at(void** state) {
+    (void) state;
+
+    SCDArray_int arr;
+    SCDArray_int_alloc(&arr);
+
+    assert_true(SCDArray_int_push_back(&arr, &(int){7}) == SCUFCONT_SUCCESS);
+    assert_int_equal(*SCDArray_int_at(&arr, 0), 7);
+
+    assert_true(SCDArray_int_push_back(&arr, &(int){10}) == SCUFCONT_SUCCESS);
+    assert_int_equal(*SCDArray_int_at(&arr, 0), 7);
+    assert_int_equal(*SCDArray_int_at(&arr, 1), 10);
+
+    SCDArray_int_free(&arr);
+}
+
+void test_DArray_push_back_multiple(void** state) {
+    (void) state;
+
+    SCDArray_int arr;
+    SCDArray_int_alloc(&arr);
+
+    int nums[] = { 1, 2, 3, 4, 5 };
+    const size_t nums_len = sizeof(nums) / sizeof(nums[0]);
+    assert_true(SCDArray_int_push_back_multiple(&arr, nums, sizeof(nums) / sizeof(nums[0])) == SCUFCONT_SUCCESS);
+    for (size_t i = 0; i < arr.len; i++) {
+        assert_int_equal(*SCDArray_int_at(&arr, i), nums[i]);
+    }
+    int nums2[] = { 6, 7, 8 };
+    const size_t nums2_len = sizeof(nums2) / sizeof(nums2[0]);
+    assert_true(SCDArray_int_push_back_multiple(&arr, nums2, sizeof(nums2) / sizeof(nums2[0])) == SCUFCONT_SUCCESS);
+    for (size_t i = 0; i < nums_len; i++) {
+        assert_int_equal(*SCDArray_int_at(&arr, i), nums[i]);
+    }
+    for (size_t i = 0; i < nums2_len; i++) {
+        assert_int_equal(*SCDArray_int_at(&arr, i + nums_len), nums2[i]);
+    }
+
+    SCDArray_int_free(&arr);
+}
+
+void test_DArray_remove(void** state) {
+    (void) state;
+
+    SCDArray_int arr;
+    SCDArray_int_alloc(&arr);
+
+    int nums[] = { 1, 2, 3, 4, 5 };
+    SCDArray_int_push_back_multiple(&arr, nums, sizeof(nums) / sizeof(nums[0]));
+    for (size_t i = 0; i < arr.len; i++) {
+        assert_int_equal(*SCDArray_int_at(&arr, i), nums[i]);
+    }
+
+    // Remove last
+    {
+        const size_t old_len = arr.len;
+        SCDArray_int_remove(&arr, arr.len - 1);
+        assert_uint_equal(arr.len, old_len - 1);
+        int new_nums[] = { 1, 2, 3, 4 };
+        assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
+        for (size_t i = 0; i < arr.len; i++) {
+            assert_int_equal(*SCDArray_int_at(&arr, i), new_nums[i]);
+        }
+    }
+
+    // Remove from middle
+    {
+        const size_t old_len = arr.len;
+        SCDArray_int_remove(&arr, 1);
+        assert_uint_equal(arr.len, old_len - 1);
+        int new_nums[] = { 1, 3, 4 };
+        assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
+        for (size_t i = 0; i < arr.len; i++) {
+            assert_int_equal(*SCDArray_int_at(&arr, i), new_nums[i]);
+        }
+    }
+
+    // Remove first
+    {
+        const size_t old_len = arr.len;
+        SCDArray_int_remove(&arr, 0);
+        assert_uint_equal(arr.len, old_len - 1);
+        int new_nums[] = { 3, 4 };
+        assert_uint_equal(arr.len, sizeof(new_nums) / sizeof(new_nums[0]));
+        for (size_t i = 0; i < arr.len; i++) {
+            assert_int_equal(*SCDArray_int_at(&arr, i), new_nums[i]);
+        }
+    }
+
+    SCDArray_int_free(&arr);
 }
 }
 
 
+int DArray_tests_run(void) {
+    const struct CMUnitTest tests[] = {
+        cmocka_unit_test(test_DArray_alloc),
+        cmocka_unit_test(test_DArray_push_back),
+        cmocka_unit_test(test_DArray_at),
+        cmocka_unit_test(test_DArray_push_back_multiple),
+        cmocka_unit_test(test_DArray_remove),
+    };
+
+    return cmocka_run_group_tests_name("DArray", tests, NULL, NULL);
+}

+ 8 - 0
tests/cmocka/main.c

@@ -1,11 +1,19 @@
 #include <cmocka.h>
 #include <cmocka.h>
 
 
 int DString_tests_run(void);
 int DString_tests_run(void);
+int DArray_tests_run(void);
 
 
 int main(void) {
 int main(void) {
     int failed = 0;
     int failed = 0;
 
 
     failed = DString_tests_run();
     failed = DString_tests_run();
+    if (failed) {
+        return failed;
+    }
+    failed = DArray_tests_run();
+    if (failed) {
+        return failed;
+    }
 
 
     return failed;
     return failed;
 }
 }

+ 1 - 0
tests/cmocka/meson.build

@@ -1,5 +1,6 @@
   cmocka_tests = executable(
   cmocka_tests = executable(
     'cmocka_tests',
     'cmocka_tests',
+    'DArray_tests.c',
     'DString_tests.c',
     'DString_tests.c',
     'main.c',
     'main.c',
     include_directories: [
     include_directories: [