diff --git a/include/DArray.h b/include/DArray.h new file mode 100644 index 0000000..45e68b5 --- /dev/null +++ b/include/DArray.h @@ -0,0 +1,114 @@ +#ifndef SCUFCONT_DARRAY_H_ +#define SCUFCONT_DARRAY_H_ + +#include +#include +#include // IWYU pragma: keep +#include + +#include "scufcont.h" + +// #define SCUFCONT_BOUNDS_CHECK + +#ifdef SCUFCONT_BOUNDS_CHECK + +#include + +#endif // SCUFCONT_BOUNDS_CHECK + +#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_HEADER(type, type_name) \ + SCDARRAY_STRUCT(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); + +// SCDARRAY_ALLOC_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_alloc); \ +// SCDARRAY_PUSH_BACK_SIG(type, SCDArray_##type_name, SCDArray_##type_name##_push_back); + +#define SCDARRAY_STRUCT(type, type_name) \ + typedef struct { \ + type* data; \ + size_t len; \ + size_t capacity; \ + } SCDArray_##type_name; + +// SCDARRAY_STRUCT(int); + +#define SCDARRAY_ALLOC_SIG(type, type_name, func_name) ScufContResult func_name(type_name* darr) + +#define SCDARRAY_ALLOC(type, type_name, func_name) \ + SCDARRAY_ALLOC_SIG(type, type_name, func_name) { \ + darr->data = (type*) calloc(1, sizeof(type)); \ + if (darr->data == NULL) { \ + return SCUFCONT_OUT_OF_MEMORY; \ + } \ + darr->len = 0; \ + darr->capacity = 1; \ + return SCUFCONT_SUCCESS; \ + } + +#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) \ + SCDARRAY_IS_NULL_SIG(type, type_name, func_name) { \ + return darr->data == NULL; \ + } + +// 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_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); + +#ifdef SCUFCONT_BOUNDS_CHECK + +#define SCDARRAY_AT(type, type_name, func_name) \ + SCDARRAY_AT_SIG(type, type_name, func_name) { \ + if (i < 0 || i > darr->len) { \ + fprintf(stderr, #func_name " out-of-bounds. i: %zu, len: %zu", i, darr->len); \ + exit(1); \ + } \ + \ + return darr->data + i; \ + } + +#else + +#define SCDARRAY_AT(type, type_name, func_name) \ + SCDARRAY_AT_SIG(type, type_name, func_name) { \ + return darr->data + i; \ + } + +#endif // SCUFCONT_BOUNDS_CHECK + +// SCDARRAY_AT(char*, SCDArray_charp, SCDArray_charp_at) + +#endif // SCUFCONT_DARRAY_H_ diff --git a/include/DString.h b/include/DString.h new file mode 100644 index 0000000..c17289f --- /dev/null +++ b/include/DString.h @@ -0,0 +1,51 @@ +#ifndef SCUFCONT_DSTRING_H_ +#define SCUFCONT_DSTRING_H_ + +#include +#include + +#include "scufcont.h" + +#define SCDSTRING_FMT(dstr) (int) (dstr).len, (dstr).data + +#define SCDString_is_null(dstr) ((dstr)->data == NULL) +#define SCDString_c_str(dstr) ((dstr)->data) + +typedef struct { + char* data; + size_t len; + size_t capacity; +} SCDString; + +ScufContResult SCDString_alloc(SCDString* dstr, const char* str, const size_t len); +ScufContResult SCDString_reserve(SCDString* dstr, const size_t new_capacity); +void SCDString_free(SCDString* dstr); +bool SCDString_equal(const SCDString* s1, const SCDString* s2); +bool SCDString_equal_c_str(const SCDString* s1, const char* s2); +bool SCDString_equal_next_chars_c_str( + const SCDString* dstr, + const char* str, + const size_t str_len, + const size_t s +); +ScufContResult SCDString_concat_c_str( + SCDString* dstr, + const char* str, + const size_t str_len +); +ScufContResult SCDString_alloc_concat_c_strs( + SCDString* dstr, + const char* s1, + const size_t s1_len, + const char* s2, + const size_t s2_len +); +ScufContResult SCDString_split( + const SCDString* dstr, + const char* delim, + SCDString** split_arr, + size_t* arr_len +); +void SCDString_split_arr_free(SCDString** arr, const size_t arr_len); + +#endif // SCUFCONT_DSTRING_H_ diff --git a/include/DynArray.h b/include/DynArray.h deleted file mode 100644 index 78cfdca..0000000 --- a/include/DynArray.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef DYN_ARRAY_H_ -#define DYN_ARRAY_H_ - -#include -#include - -// #define SCUFCONT_BOUNDS_CHECK - -#ifdef SCUFCONT_BOUNDS_CHECK - -#include -#include - -#endif // SCUFCONT_BOUNDS_CHECK - -#define DYN_ARRAY_EXPANDER(macro, type, type_name, func_name) macro(type, DynArray_##type_name, DynArray_##type_name##_##func_name); - -#define DYN_ARRAY_IMPL(type, type_name) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC, type, type_name, alloc) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL, type, type_name, is_null) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK, type, type_name, push_back) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_AT, type, type_name, at) - -#define DYN_ARRAY_HEADER(type, type_name) \ - DYN_ARRAY_STRUCT(type, type_name) \ - DYN_ARRAY_SIGS(type, type_name) - -#define DYN_ARRAY_SIGS(type, type_name) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_ALLOC_SIG, type, type_name, alloc) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_IS_NULL_SIG, type, type_name, is_null) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_PUSH_BACK_SIG, type, type_name, push_back) \ - DYN_ARRAY_EXPANDER(DYN_ARRAY_AT_SIG, type, type_name, at) - -// DYN_ARRAY_ALLOC_SIG(type, DynArray_##type_name, DynArray_##type_name##_alloc); \ -// DYN_ARRAY_PUSH_BACK_SIG(type, DynArray_##type_name, DynArray_##type_name##_push_back); - -#define DYN_ARRAY_STRUCT(type, type_name) \ - typedef struct { \ - type* data; \ - size_t len; \ - size_t capacity; \ - } DynArray_##type_name; - -// DYN_ARRAY_STRUCT(int); - -#define DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) bool func_name(type_name* darr) - -#define DYN_ARRAY_ALLOC(type, type_name, func_name) \ - DYN_ARRAY_ALLOC_SIG(type, type_name, func_name) { \ - darr->data = (type*) calloc(1, sizeof(type)); \ - if (darr->data == NULL) { \ - return false; \ - } \ - darr->len = 0; \ - darr->capacity = 1; \ - return true; \ - } - -#define DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) bool func_name(const type_name* darr) - -#define DYN_ARRAY_IS_NULL(type, type_name, func_name) \ - DYN_ARRAY_IS_NULL_SIG(type, type_name, func_name) { \ - return darr->data == NULL; \ - } - -// DYN_ARRAY_ALLOC(int, DynArray_int, DynArray_int_alloc); - -#define DYN_ARRAY_PUSH_BACK_SIG(type, type_name, func_name) int func_name(type_name* darr, const type* new_elem) - -#define DYN_ARRAY_PUSH_BACK(type, type_name, func_name) \ - DYN_ARRAY_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 DYN_ARRAY_AT_SIG(type, type_name, func_name) type* func_name(type_name* darr, const size_t i) - -// DYN_ARRAY_PUSH_BACK(int, DynArray_int, DynArray_int_push_back); - -#ifdef SCUFCONT_BOUNDS_CHECK - -#define DYN_ARRAY_AT(type, type_name, func_name) \ - DYN_ARRAY_AT_SIG(type, type_name, func_name) { \ - if (i < 0 || i > darr->len) { \ - fprintf(stderr, #func_name " out-of-bounds. i: %zu, len: %zu", i, darr->len); \ - exit(1); \ - } \ - \ - return darr->data + i; \ - } - -#else - -#define DYN_ARRAY_AT(type, type_name, func_name) \ - DYN_ARRAY_AT_SIG(type, type_name, func_name) { \ - return darr->data + i; \ - } - -#endif // SCUFCONT_BOUNDS_CHECK - -// DYN_ARRAY_AT(char*, DynArray_charp, DynArray_charp_at) - -#endif // DYN_ARRAY_H_ diff --git a/include/DynString.h b/include/DynString.h deleted file mode 100644 index 9cd95a8..0000000 --- a/include/DynString.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef DYN_STRING_H_ -#define DYN_STRING_H_ - -#include -#include - -#include "scufcont.h" - -#define DYN_STRING_FMT(dstr) (int) (dstr).len, (dstr).data - -#define DynString_is_null(dstr) ((dstr)->data == NULL) -#define DynString_c_str(dstr) ((dstr)->data) - -typedef struct { - char* data; - size_t len; - size_t capacity; -} DynString; - -ScufContResult DynString_alloc(DynString* dstr, const char* str, const size_t len); -ScufContResult DynString_reserve(DynString* dstr, const size_t new_capacity); -void DynString_free(DynString* dstr); -bool DynString_equal(const DynString* s1, const DynString* s2); -bool DynString_equal_c_str(const DynString* s1, const char* s2); -bool DynString_equal_next_chars_c_str( - const DynString* dstr, - const char* str, - const size_t str_len, - const size_t s -); -ScufContResult DynString_concat_c_str( - DynString* dstr, - const char* str, - const size_t str_len -); -ScufContResult DynString_alloc_concat_c_strs( - DynString* dstr, - const char* s1, - const size_t s1_len, - const char* s2, - const size_t s2_len -); -ScufContResult DynString_split( - const DynString* dstr, - const char* delim, - DynString** split_arr, - size_t* arr_len -); -void DynString_split_arr_free(DynString** arr, const size_t arr_len); - -#endif // DYN_STRING_H_ diff --git a/meson.build b/meson.build index 020fa65..3b4fdaa 100644 --- a/meson.build +++ b/meson.build @@ -20,7 +20,7 @@ scufcont_include = include_directories('include') scufcont_lib = library( 'scufcont', - 'src/DynString.c', + 'src/DString.c', 'src/scufcont.c', include_directories: [ 'include' diff --git a/src/DynString.c b/src/DString.c similarity index 72% rename from src/DynString.c rename to src/DString.c index d82ab8a..646da4b 100644 --- a/src/DynString.c +++ b/src/DString.c @@ -4,9 +4,9 @@ #include #include "scufcont.h" -#include "DynString.h" +#include "DString.h" -ScufContResult DynString_alloc(DynString* dstr, const char* str, const size_t len) { +ScufContResult SCDString_alloc(SCDString* dstr, const char* str, const size_t len) { dstr->data = (char*) malloc(sizeof(char) * (len + 1)); dstr->len = len; dstr->capacity = len + 1; @@ -19,7 +19,7 @@ ScufContResult DynString_alloc(DynString* dstr, const char* str, const size_t le return SCUFCONT_SUCCESS; } -ScufContResult DynString_reserve(DynString* dstr, const size_t new_capacity) { +ScufContResult SCDString_reserve(SCDString* dstr, const size_t new_capacity) { if (dstr->capacity < new_capacity) { errno = 0; dstr->data = (char*) realloc(dstr->data, sizeof(char) * new_capacity); @@ -32,7 +32,7 @@ ScufContResult DynString_reserve(DynString* dstr, const size_t new_capacity) { return SCUFCONT_SUCCESS; } -void DynString_free(DynString* dstr) { +void SCDString_free(SCDString* dstr) { if (dstr->data != NULL) { free(dstr->data); dstr->data = NULL; @@ -41,7 +41,7 @@ void DynString_free(DynString* dstr) { dstr->capacity = 0; } -bool DynString_equal(const DynString* s1, const DynString* s2) { +bool SCDString_equal(const SCDString* s1, const SCDString* s2) { if (s1->data == NULL || s2->data == NULL) { return false; } @@ -59,7 +59,7 @@ bool DynString_equal(const DynString* s1, const DynString* s2) { return true; } -bool DynString_equal_c_str(const DynString* s1, const char* s2) { +bool SCDString_equal_c_str(const SCDString* s1, const char* s2) { if (s1->data == NULL || s2 == NULL) { return false; } @@ -77,8 +77,8 @@ bool DynString_equal_c_str(const DynString* s1, const char* s2) { return true; } -bool DynString_equal_next_chars_c_str( - const DynString* dstr, +bool SCDString_equal_next_chars_c_str( + const SCDString* dstr, const char* str, const size_t str_len, size_t s @@ -97,14 +97,14 @@ bool DynString_equal_next_chars_c_str( return true; } -ScufContResult DynString_concat_c_str( - DynString* dstr, +ScufContResult SCDString_concat_c_str( + SCDString* dstr, const char* str, const size_t str_len ) { const size_t new_len = dstr->len + str_len; if (new_len > dstr->capacity) { - ScufContResult res = DynString_reserve(dstr, new_len + 1); + ScufContResult res = SCDString_reserve(dstr, new_len + 1); if (res != SCUFCONT_SUCCESS) { return res; } @@ -117,60 +117,60 @@ ScufContResult DynString_concat_c_str( return SCUFCONT_SUCCESS; } -ScufContResult DynString_alloc_concat_c_strs( - DynString* dstr, +ScufContResult SCDString_alloc_concat_c_strs( + SCDString* dstr, const char* s1, const size_t s1_len, const char* s2, const size_t s2_len ) { - ScufContResult res = DynString_alloc(dstr, s1, s1_len); + ScufContResult res = SCDString_alloc(dstr, s1, s1_len); if (res != SCUFCONT_SUCCESS) { return res; } - res = DynString_concat_c_str(dstr, s2, s2_len); + res = SCDString_concat_c_str(dstr, s2, s2_len); if (res != SCUFCONT_SUCCESS) { return res; } return SCUFCONT_SUCCESS; } -ScufContResult DynString_split( - const DynString* dstr, +ScufContResult SCDString_split( + const SCDString* dstr, const char* delim, - DynString** split_arr, + SCDString** split_arr, size_t* arr_len ) { ScufContResult ret = SCUFCONT_SUCCESS; *arr_len = 0; - DynString elem; - ScufContResult res = DynString_alloc(&elem, "", 0); + SCDString elem; + ScufContResult res = SCDString_alloc(&elem, "", 0); if (res != SCUFCONT_SUCCESS) { return res; } const size_t delim_len = strlen(delim); for (size_t i = 0; i < dstr->len; i++) { - if (DynString_equal_next_chars_c_str(dstr, delim, delim_len, i)) { + if (SCDString_equal_next_chars_c_str(dstr, delim, delim_len, i)) { *arr_len += 1; - *split_arr = realloc(*split_arr, sizeof(DynString) * (*arr_len)); + *split_arr = realloc(*split_arr, sizeof(SCDString) * (*arr_len)); if (split_arr == NULL) { ret = SCUFCONT_OUT_OF_MEMORY; break; } (*split_arr)[(*arr_len) - 1] = elem; - res = DynString_alloc(&elem, "", 0); + res = SCDString_alloc(&elem, "", 0); if (res != SCUFCONT_SUCCESS) { ret = res; break; } i += delim_len - 1; } else { - DynString_concat_c_str(&elem, dstr->data + i, 1); + SCDString_concat_c_str(&elem, dstr->data + i, 1); } } if (ret == SCUFCONT_SUCCESS) { - *split_arr = realloc(*split_arr, sizeof(DynString) * (*arr_len + 1)); + *split_arr = realloc(*split_arr, sizeof(SCDString) * (*arr_len + 1)); if (split_arr != NULL) { (*split_arr)[*arr_len] = elem; *arr_len += 1; @@ -180,18 +180,18 @@ ScufContResult DynString_split( } for (size_t i = 0; i < *arr_len; i++) { - DynString_free((*split_arr) + i); + SCDString_free((*split_arr) + i); } free(*split_arr); *split_arr = NULL; - DynString_free(&elem); + SCDString_free(&elem); return ret; } -void DynString_split_arr_free(DynString** arr, const size_t arr_len) { +void SCDString_split_arr_free(SCDString** arr, const size_t arr_len) { for (size_t i = 0; i < arr_len; i++) { - DynString_free((*arr) + i); + SCDString_free((*arr) + i); } free(*arr); *arr = NULL; diff --git a/tests/cmocka/DArray_tests.c b/tests/cmocka/DArray_tests.c new file mode 100644 index 0000000..c741a9c --- /dev/null +++ b/tests/cmocka/DArray_tests.c @@ -0,0 +1,17 @@ +#include + +#include "DArray.h" + +SCDARRAY_HEADER(int, int) +SCDARRAY_IMPL(int, int) + +void DArray_alloc_test(void** state) { + (void) state; + + SCDArray_int arr; + assert_true(SCDArray_int_alloc(&arr) == SCUFCONT_SUCCESS); + assert_non_null(arr.data); + assert_uint_equal(arr.len, 0u); + assert_uint_equal(arr.capacity, 1u); +} + diff --git a/tests/cmocka/DString_tests.c b/tests/cmocka/DString_tests.c new file mode 100644 index 0000000..6724110 --- /dev/null +++ b/tests/cmocka/DString_tests.c @@ -0,0 +1,166 @@ +#include +#include + +#include + +#include "scufcont.h" +#include "DString.h" + +void test_SCDString_alloc(void** state) { + (void) state; + + const char* c_str = "Hello"; + const size_t c_str_len = strlen(c_str); + SCDString dstr; + assert_true(SCDString_alloc(&dstr, c_str, c_str_len) == SCUFCONT_SUCCESS); + + assert_memory_equal(dstr.data, c_str, c_str_len + 1); + assert_true(dstr.len == c_str_len); + assert_true(dstr.capacity == c_str_len + 1); + + free(dstr.data); +} + +void test_SCDString_free(void** state) { + (void) state; + + SCDString dstr; + assert_true(SCDString_alloc(&dstr, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + + SCDString_free(&dstr); + + assert_null(dstr.data); + assert_true(dstr.len == 0); + assert_true(dstr.capacity == 0); +} + +void test_SCDString_equal(void** state) { + (void) state; + + SCDString s1; + assert_true(SCDString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + SCDString s2; + assert_true(SCDString_alloc(&s2, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + assert_true(SCDString_equal(&s1, &s2)); + SCDString_free(&s1); + SCDString_free(&s2); + + assert_true(SCDString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + assert_true(SCDString_alloc(&s2, "Hell0", strlen("Hell0")) == SCUFCONT_SUCCESS); + assert_false(SCDString_equal(&s1, &s2)); + SCDString_free(&s1); + SCDString_free(&s2); + + assert_true(SCDString_alloc(&s1, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); + assert_true(SCDString_alloc(&s2, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + assert_false(SCDString_equal(&s1, &s2)); + SCDString_free(&s1); + SCDString_free(&s2); +} + +void test_SCDString_equal_c_str(void** state) { + (void) state; + + SCDString s1; + assert_true(SCDString_alloc(&s1,"Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + char* s2 = "Hello"; + assert_true(SCDString_equal_c_str(&s1, s2)); + SCDString_free(&s1); + + assert_true(SCDString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + s2 = "Hell0"; + assert_false(SCDString_equal_c_str(&s1, s2)); + SCDString_free(&s1); + + assert_true(SCDString_alloc(&s1, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); + s2 = "Hello"; + assert_false(SCDString_equal_c_str(&s1, s2)); + SCDString_free(&s1); +} + +void test_SCDString_equal_next_chars_c_str(void** state) { + (void) state; + + SCDString dstr; + assert_true(SCDString_alloc(&dstr, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); + char* str = "ll"; + size_t str_len = strlen(str); + assert_true(SCDString_equal_next_chars_c_str(&dstr, str, str_len, 2)); + assert_false(SCDString_equal_next_chars_c_str(&dstr, str, str_len, 1)); + SCDString_free(&dstr); +} + +void test_SCDString_concat_c_str(void** state) { + (void) state; + + const char* dstr_c_str = "Hello"; + const char* c_str = " World"; + const size_t combined_length = strlen(dstr_c_str) + strlen(c_str); + + SCDString dstr; + assert_true(SCDString_alloc(&dstr, dstr_c_str, strlen("Hello")) == SCUFCONT_SUCCESS); + SCDString_concat_c_str(&dstr, c_str, strlen(c_str)); + + assert_memory_equal(dstr.data, (void*) "Hello World\0", strlen("Hello World") + 1); + assert_true(dstr.len == combined_length); + assert_true(dstr.capacity == combined_length + 1); + + SCDString_free(&dstr); +} + +void test_SCDString_c_str(void** state) { + (void) state; + + const char* c_str = "Hello"; + SCDString dstr; + assert_true(SCDString_alloc(&dstr, c_str, strlen(c_str)) == SCUFCONT_SUCCESS); + + assert_string_equal(c_str, SCDString_c_str(&dstr)); + + SCDString_concat_c_str(&dstr, " World", strlen(" World")); + + assert_string_equal("Hello World", SCDString_c_str(&dstr)); +} + +void test_SCDString_split(void** state) { + (void) state; + + SCDString dstr; + assert_true(SCDString_alloc(&dstr, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); + size_t arr_len = 0; + SCDString* arr = NULL; + ScufContResult res = SCDString_split(&dstr, " ", &arr, &arr_len); + assert_true(res == SCUFCONT_SUCCESS); + assert_true(arr_len == 2); + assert_string_equal(SCDString_c_str(arr), "Hello"); + assert_string_equal(SCDString_c_str(arr + 1), "World"); + SCDString_free(&dstr); + SCDString_split_arr_free(&arr, arr_len); + assert_true(arr == NULL); + + assert_true(SCDString_alloc(&dstr, " Hello World", strlen(" Hello World")) == SCUFCONT_SUCCESS); + arr_len = 0; + res = SCDString_split(&dstr, " ", &arr, &arr_len); + assert_true(arr_len == 3); + assert_string_equal(SCDString_c_str(arr), ""); + assert_string_equal(SCDString_c_str(arr + 1), "Hello"); + assert_string_equal(SCDString_c_str(arr + 2), "World"); + SCDString_free(&dstr); + SCDString_split_arr_free(&arr, arr_len); + assert_true(arr == NULL); +} + +int DString_tests_run(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_SCDString_alloc), + cmocka_unit_test(test_SCDString_free), + cmocka_unit_test(test_SCDString_equal), + cmocka_unit_test(test_SCDString_equal_c_str), + cmocka_unit_test(test_SCDString_equal_next_chars_c_str), + cmocka_unit_test(test_SCDString_concat_c_str), + cmocka_unit_test(test_SCDString_c_str), + cmocka_unit_test(test_SCDString_split), + }; + + return cmocka_run_group_tests_name("DString", tests, NULL, NULL); +} diff --git a/tests/cmocka/main.c b/tests/cmocka/main.c index d9c0d8e..1029b4b 100644 --- a/tests/cmocka/main.c +++ b/tests/cmocka/main.c @@ -1,167 +1,12 @@ -#include -#include - #include -#include "scufcont.h" -#include "DynString.h" - -void test_DynString_alloc(void** state) { - (void) state; - - const char* c_str = "Hello"; - const size_t c_str_len = strlen(c_str); - DynString dstr; - assert_true(DynString_alloc(&dstr, c_str, c_str_len) == SCUFCONT_SUCCESS); - - assert_memory_equal(dstr.data, c_str, c_str_len + 1); - assert_true(dstr.len == c_str_len); - assert_true(dstr.capacity == c_str_len + 1); - - free(dstr.data); -} - -void test_DynString_free(void** state) { - (void) state; - - DynString dstr; - assert_true(DynString_alloc(&dstr, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - - DynString_free(&dstr); - - assert_null(dstr.data); - assert_true(dstr.len == 0); - assert_true(dstr.capacity == 0); -} - -void test_DynString_equal(void** state) { - (void) state; - - DynString s1; - assert_true(DynString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - DynString s2; - assert_true(DynString_alloc(&s2, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - assert_true(DynString_equal(&s1, &s2)); - DynString_free(&s1); - DynString_free(&s2); - - assert_true(DynString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - assert_true(DynString_alloc(&s2, "Hell0", strlen("Hell0")) == SCUFCONT_SUCCESS); - assert_false(DynString_equal(&s1, &s2)); - DynString_free(&s1); - DynString_free(&s2); - - assert_true(DynString_alloc(&s1, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); - assert_true(DynString_alloc(&s2, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - assert_false(DynString_equal(&s1, &s2)); - DynString_free(&s1); - DynString_free(&s2); -} - -void test_DynString_equal_c_str(void** state) { - (void) state; - - DynString s1; - assert_true(DynString_alloc(&s1,"Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - char* s2 = "Hello"; - assert_true(DynString_equal_c_str(&s1, s2)); - DynString_free(&s1); - - assert_true(DynString_alloc(&s1, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - s2 = "Hell0"; - assert_false(DynString_equal_c_str(&s1, s2)); - DynString_free(&s1); - - assert_true(DynString_alloc(&s1, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); - s2 = "Hello"; - assert_false(DynString_equal_c_str(&s1, s2)); - DynString_free(&s1); -} - -void test_DynString_equal_next_chars_c_str(void** state) { - (void) state; - - DynString dstr; - assert_true(DynString_alloc(&dstr, "Hello", strlen("Hello")) == SCUFCONT_SUCCESS); - char* str = "ll"; - size_t str_len = strlen(str); - assert_true(DynString_equal_next_chars_c_str(&dstr, str, str_len, 2)); - assert_false(DynString_equal_next_chars_c_str(&dstr, str, str_len, 1)); - DynString_free(&dstr); -} - -void test_DynString_concat_c_str(void** state) { - (void) state; - - const char* dstr_c_str = "Hello"; - const char* c_str = " World"; - const size_t combined_length = strlen(dstr_c_str) + strlen(c_str); - - DynString dstr; - assert_true(DynString_alloc(&dstr, dstr_c_str, strlen("Hello")) == SCUFCONT_SUCCESS); - DynString_concat_c_str(&dstr, c_str, strlen(c_str)); - - assert_memory_equal(dstr.data, (void*) "Hello World\0", strlen("Hello World") + 1); - assert_true(dstr.len == combined_length); - assert_true(dstr.capacity == combined_length + 1); - - DynString_free(&dstr); -} - -void test_DynString_c_str(void** state) { - (void) state; - - const char* c_str = "Hello"; - DynString dstr; - assert_true(DynString_alloc(&dstr, c_str, strlen(c_str)) == SCUFCONT_SUCCESS); - - assert_string_equal(c_str, DynString_c_str(&dstr)); - - DynString_concat_c_str(&dstr, " World", strlen(" World")); - - assert_string_equal("Hello World", DynString_c_str(&dstr)); -} - -void test_DynString_split(void** state) { - (void) state; - - DynString dstr; - assert_true(DynString_alloc(&dstr, "Hello World", strlen("Hello World")) == SCUFCONT_SUCCESS); - size_t arr_len = 0; - DynString* arr = NULL; - ScufContResult res = DynString_split(&dstr, " ", &arr, &arr_len); - assert_true(res == SCUFCONT_SUCCESS); - assert_true(arr_len == 2); - assert_string_equal(DynString_c_str(arr), "Hello"); - assert_string_equal(DynString_c_str(arr + 1), "World"); - DynString_free(&dstr); - DynString_split_arr_free(&arr, arr_len); - assert_true(arr == NULL); - - assert_true(DynString_alloc(&dstr, " Hello World", strlen(" Hello World")) == SCUFCONT_SUCCESS); - arr_len = 0; - res = DynString_split(&dstr, " ", &arr, &arr_len); - assert_true(arr_len == 3); - assert_string_equal(DynString_c_str(arr), ""); - assert_string_equal(DynString_c_str(arr + 1), "Hello"); - assert_string_equal(DynString_c_str(arr + 2), "World"); - DynString_free(&dstr); - DynString_split_arr_free(&arr, arr_len); - assert_true(arr == NULL); -} +int DString_tests_run(void); int main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_DynString_alloc), - cmocka_unit_test(test_DynString_free), - cmocka_unit_test(test_DynString_equal), - cmocka_unit_test(test_DynString_equal_c_str), - cmocka_unit_test(test_DynString_equal_next_chars_c_str), - cmocka_unit_test(test_DynString_concat_c_str), - cmocka_unit_test(test_DynString_c_str), - cmocka_unit_test(test_DynString_split), - }; + int failed = 0; - return cmocka_run_group_tests(tests, NULL, NULL); + failed = DString_tests_run(); + + return failed; } diff --git a/tests/cmocka/meson.build b/tests/cmocka/meson.build index 1498781..892c279 100644 --- a/tests/cmocka/meson.build +++ b/tests/cmocka/meson.build @@ -1,5 +1,6 @@ cmocka_tests = executable( 'cmocka_tests', + 'DString_tests.c', 'main.c', include_directories: [ scufcont_include