# HG changeset patch # User Mike Becker # Date 1765231751 -3600 # Node ID 03fbf1c99e73935c7c8ed1ac762b782b2fe5ac69 # Parent afdaa70034f809b2fd3cb9f7b43a1606607db955 add allocator support to cxPropertiesLoad() - resolves #776 diff -r afdaa70034f8 -r 03fbf1c99e73 docs/Writerside/topics/properties.h.md --- a/docs/Writerside/topics/properties.h.md Sun Dec 07 19:36:51 2025 +0100 +++ b/docs/Writerside/topics/properties.h.md Mon Dec 08 23:09:11 2025 +0100 @@ -66,9 +66,11 @@ char *buf, size_t capacity); CxPropertiesStatus cxPropertiesLoad(CxPropertiesConfig config, + const CxAllocator *allocator, AnyStr filename, CxMap *target); CxPropertiesStatus cxPropertiesLoadDefault( + const CxAllocator *allocator, AnyStr filename, CxMap *target); ``` @@ -115,6 +117,7 @@ which opens the file designated by the `filename` and loads all properties from that file into the specified `CxMap`. The convenience macro `cxPropertiesLoadDefault()` uses the default parser configuration for this. The target map must either store pointers of type `char*` or elements of type `cxmutstr`. +In either case, the specified `allocator` is used to allocate the memory for the value. > The stack buffers used by `cxPropertiesLoad()` can be changed when building UCX from sources > by setting the `CX_PROPERTIES_LOAD_FILL_SIZE` and `CX_PROPERTIES_LOAD_BUF_SIZE` macros diff -r afdaa70034f8 -r 03fbf1c99e73 src/cx/properties.h --- a/src/cx/properties.h Sun Dec 07 19:36:51 2025 +0100 +++ b/src/cx/properties.h Mon Dec 08 23:09:11 2025 +0100 @@ -340,13 +340,14 @@ * Internal function - use cxPropertiesLoad() instead. * * @param config the parser config + * @param allocator the allocator for the values * @param filename the file name * @param target the target map * @return status code */ -cx_attr_nonnull +cx_attr_nonnull_arg(4) CX_EXPORT CxPropertiesStatus cx_properties_load(CxPropertiesConfig config, - cxstring filename, CxMap *target); + const CxAllocator *allocator, cxstring filename, CxMap *target); /** * Loads properties from a file and inserts them into a map. @@ -357,6 +358,7 @@ * Any other configuration is not supported. * * @param config the parser config + * @param allocator the allocator for the values that will be stored in the map * @param filename (any string) the absolute or relative path to the file * @param target (@c CxMap*) the map where the properties shall be added * @retval CX_PROPERTIES_NO_ERROR (zero) at least one key/value pair was found @@ -369,7 +371,8 @@ * @retval CX_PROPERTIES_MAP_ERROR storing a key/value pair in the map failed * @see cxPropertiesLoadDefault() */ -#define cxPropertiesLoad(config, filename, target) cx_properties_load(config, cx_strcast(filename), target) +#define cxPropertiesLoad(config, allocator, filename, target) \ + cx_properties_load(config, allocator, cx_strcast(filename), target) /** * Loads properties from a file and inserts them into a map with a default config. @@ -379,6 +382,7 @@ * The map must either store pointers of type @c char*, or elements of type cxmutstr. * Any other configuration is not supported. * + * @param allocator the allocator for the values that will be stored in the map * @param filename (any string) the absolute or relative path to the file * @param target (@c CxMap*) the map where the properties shall be added * @retval CX_PROPERTIES_NO_ERROR (zero) at least one key/value pair was found @@ -391,7 +395,8 @@ * @retval CX_PROPERTIES_MAP_ERROR storing a key/value pair in the map failed * @see cxPropertiesLoad() */ -#define cxPropertiesLoadDefault(filename, target) cx_properties_load(cx_properties_config_default, cx_strcast(filename), target) +#define cxPropertiesLoadDefault(allocator, filename, target) \ + cx_properties_load(cx_properties_config_default, allocator, cx_strcast(filename), target) #ifdef __cplusplus diff -r afdaa70034f8 -r 03fbf1c99e73 src/properties.c --- a/src/properties.c Sun Dec 07 19:36:51 2025 +0100 +++ b/src/properties.c Mon Dec 08 23:09:11 2025 +0100 @@ -253,7 +253,7 @@ const unsigned cx_properties_load_buf_size = CX_PROPERTIES_LOAD_BUF_SIZE; CxPropertiesStatus cx_properties_load(CxPropertiesConfig config, - cxstring filename, CxMap *target) { + const CxAllocator *allocator, cxstring filename, CxMap *target) { // sanity check for the map const bool use_cstring = cxCollectionStoresPointers(target); if (!use_cstring && cxCollectionElementSize(target) != sizeof(cxmutstr)) { @@ -302,7 +302,7 @@ if (status != CX_PROPERTIES_NO_ERROR) { break; } else { - cxmutstr v = cx_strdup(value); + cxmutstr v = cx_strdup_a(allocator, value); if (v.ptr == NULL) { status = CX_PROPERTIES_MAP_ERROR; break; diff -r afdaa70034f8 -r 03fbf1c99e73 tests/test_properties.c --- a/tests/test_properties.c Sun Dec 07 19:36:51 2025 +0100 +++ b/tests/test_properties.c Mon Dec 08 23:09:11 2025 +0100 @@ -384,6 +384,8 @@ } CX_TEST(test_properties_load) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); char fname[16] = "ucxtestXXXXXX"; int tmpfd = mkstemp(fname); FILE *f = tmpfd < 0 ? NULL : fdopen(tmpfd, "w"); @@ -412,8 +414,8 @@ // we want to load the properties into a map of char* pointers CxMap *map = cxHashMapCreateSimple(CX_STORE_POINTERS); - cxDefineDestructor(map, cxFreeDefault); - CxPropertiesStatus status = cxPropertiesLoadDefault(fname, map); + cxDefineAdvancedDestructor(map, cxFree, &talloc); + CxPropertiesStatus status = cxPropertiesLoadDefault(&talloc.base, fname, map); CX_TEST_ASSERT(status == CX_PROPERTIES_NO_ERROR); CX_TEST_ASSERT(cxMapSize(map) == 5); @@ -440,8 +442,11 @@ free(long_key); free(long_value); + CX_TEST_ASSERT(cx_testing_allocator_used(&talloc)); cxMapFree(map); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); } + cx_testing_allocator_destroy(&talloc); if (f) fclose(f); remove(fname); }