Tue, 18 Nov 2025 17:36:41 +0100
add missing test coverage for cx_array_reserve()
| src/array_list.c | file | annotate | diff | comparison | revisions | |
| tests/test_list.c | file | annotate | diff | comparison | revisions |
--- a/src/array_list.c Mon Nov 17 22:28:04 2025 +0100 +++ b/src/array_list.c Tue Nov 18 17:36:41 2025 +0100 @@ -42,10 +42,11 @@ cx_attr_unused CxArrayReallocator *alloc ) { size_t n; + // LCOV_EXCL_START if (cx_szmul(new_capacity, elem_size, &n)) { errno = EOVERFLOW; return NULL; - } + } // LCOV_EXCL_STOP return cxReallocDefault(array, n); } @@ -66,10 +67,11 @@ ) { // check for overflow size_t n; + // LCOV_EXCL_START if (cx_szmul(new_capacity, elem_size, &n)) { errno = EOVERFLOW; return NULL; - } + } // LCOV_EXCL_STOP // retrieve the pointer to the actual allocator const CxAllocator *al = alloc->allocator; @@ -108,13 +110,11 @@ * * @param current_capacity the current capacity of the array * @param needed_capacity the required capacity of the array - * @param maximum_capacity the maximum capacity (given by the data type) * @return the new capacity */ static size_t cx_array_grow_capacity( size_t current_capacity, - size_t needed_capacity, - size_t maximum_capacity + size_t needed_capacity ) { if (current_capacity >= needed_capacity) { return current_capacity; @@ -125,12 +125,7 @@ else if (cap < 1024) alignment = 64; else if (cap < 8192) alignment = 512; else alignment = 1024; - - if (cap - 1 > maximum_capacity - alignment) { - return maximum_capacity; - } else { - return cap - (cap % alignment) + alignment; - } + return cap - (cap % alignment) + alignment; } int cx_array_reserve( @@ -288,7 +283,7 @@ const size_t newsize = oldsize < minsize ? minsize : oldsize; // reallocate if necessary - const size_t newcap = cx_array_grow_capacity(oldcap, newsize, max_size); + const size_t newcap = cx_array_grow_capacity(oldcap, newsize); if (newcap > oldcap) { // check if we need to repair the src pointer uintptr_t targetaddr = (uintptr_t) *target; @@ -381,8 +376,7 @@ const size_t old_size = *size; const size_t old_capacity = *capacity; // the necessary capacity is the worst case assumption, including duplicates - const size_t needed_capacity = cx_array_grow_capacity(old_capacity, - old_size + elem_count, SIZE_MAX); + const size_t needed_capacity = cx_array_grow_capacity(old_capacity, old_size + elem_count); // if we need more than we have, try a reallocation if (needed_capacity > old_capacity) { @@ -792,8 +786,7 @@ // guarantee enough capacity if (arl->capacity < list->collection.size + n) { - const size_t new_capacity = cx_array_grow_capacity(arl->capacity, - list->collection.size + n, SIZE_MAX); + const size_t new_capacity = cx_array_grow_capacity(arl->capacity,list->collection.size + n); if (cxReallocateArray( list->collection.allocator, &arl->data, new_capacity,
--- a/tests/test_list.c Mon Nov 17 22:28:04 2025 +0100 +++ b/tests/test_list.c Tue Nov 18 17:36:41 2025 +0100 @@ -144,20 +144,112 @@ } CX_TEST(test_array_reserve) { + { + // default size + CX_ARRAY_DECLARE(int, arr); + cx_array_initialize(arr, 16); + int result; + CX_TEST_DO { + result = cx_array_reserve( + (void **) &(arr), + &(arr_size), + &(arr_capacity), + 0, // default width + sizeof(int), + 30, + cx_array_default_reallocator + ); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(arr_size == 0); + CX_TEST_ASSERT(arr_capacity == 30); + } + cxFreeDefault(arr); + } + { + // 16-bit size + CX_ARRAY_DECLARE_SIZED(char, arr, uint16_t); + cx_array_initialize(arr, 16); + arr_size = 5; + int result; + CX_TEST_DO { + errno = 0; + result = cx_array_simple_reserve(arr, 3); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(errno == 0); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 16); + + result = cx_array_simple_reserve(arr, 20); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(errno == 0); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 25); + + result = cx_array_simple_reserve(arr, 2000); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(errno == 0); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 2005); + + // this does not fit into an array with a 16-bit size + result = cx_array_simple_reserve(arr, 70000); + CX_TEST_ASSERT(result == 1); + CX_TEST_ASSERT(errno == EOVERFLOW); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 2005); + } + cxFreeDefault(arr); + } + { + // 8-bit size + CX_ARRAY_DECLARE_SIZED(char, arr, uint8_t); + cx_array_initialize(arr, 16); + arr_size = 5; + int result; + CX_TEST_DO { + errno = 0; + result = cx_array_simple_reserve(arr, 3); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(errno == 0); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 16); + + result = cx_array_simple_reserve(arr, 20); + CX_TEST_ASSERT(result == 0); + CX_TEST_ASSERT(errno == 0); + CX_TEST_ASSERT(arr_size == 5); + CX_TEST_ASSERT(arr_capacity == 25); + + // this does not fit into an array with an 8-bit size + arr_size = 10; + result = cx_array_simple_reserve(arr, 250); + CX_TEST_ASSERT(result == 1); + CX_TEST_ASSERT(errno == EOVERFLOW); + CX_TEST_ASSERT(arr_size == 10); + CX_TEST_ASSERT(arr_capacity == 25); + } + cxFreeDefault(arr); + } +} + +CX_TEST(test_array_reserve_unsupported_width) { CX_ARRAY_DECLARE_SIZED(int, arr, uint16_t); cx_array_initialize(arr, 16); - arr_size = 5; int result; CX_TEST_DO { - result = cx_array_simple_reserve(arr, 3); - CX_TEST_ASSERT(result == 0); - CX_TEST_ASSERT(arr_size == 5); + result = cx_array_reserve( + (void **) &(arr), + &(arr_size), + &(arr_capacity), + 12, // unsupported width + sizeof(int), + 30, + cx_array_default_reallocator + ); + CX_TEST_ASSERT(result != 0); + CX_TEST_ASSERT(errno == EINVAL); + CX_TEST_ASSERT(arr_size == 0); CX_TEST_ASSERT(arr_capacity == 16); - - result = cx_array_simple_reserve(arr, 20); - CX_TEST_ASSERT(result == 0); - CX_TEST_ASSERT(arr_size == 5); - CX_TEST_ASSERT(arr_capacity == 25); } cxFreeDefault(arr); } @@ -3196,6 +3288,7 @@ cx_test_register(suite, test_array_add8); cx_test_register(suite, test_array_copy_unsupported_width); cx_test_register(suite, test_array_reserve); + cx_test_register(suite, test_array_reserve_unsupported_width); cx_test_register(suite, test_array_insert_sorted); cx_test_register(suite, test_array_insert_unique); cx_test_register(suite, test_array_binary_search);