in libs/utils/src/celix_convert_utils.c [141:219]
static celix_status_t celix_utils_convertStringToArrayList(const char* val,
celix_array_list_t* listIn,
const celix_array_list_t* defaultValue,
celix_status_t (*addEntry)(celix_array_list_t*,
const char*),
celix_array_list_t** listOut) {
assert(listOut != NULL);
*listOut = NULL;
celix_autoptr(celix_array_list_t) list = listIn;
if (!val && defaultValue) {
*listOut = celix_arrayList_copy(defaultValue);
return *listOut ? CELIX_ILLEGAL_ARGUMENT : CELIX_ENOMEM;
} else if (!list) {
return ENOMEM;
} else if (!val) {
return CELIX_ILLEGAL_ARGUMENT;
}
if (celix_utils_isStringNullOrEmpty(val)) {
*listOut = celix_steal_ptr(list);
return CELIX_SUCCESS; // empty string -> empty list
}
char* buf = NULL;
size_t bufSize = 0;
FILE* entryStream = NULL;
celix_status_t status = CELIX_SUCCESS;
size_t max = strlen(val);
entryStream = open_memstream(&buf, &bufSize);
if (!entryStream) {
return CELIX_ENOMEM;
}
for (size_t i = 0; i <= max && status == CELIX_SUCCESS; ++i) {
if (val[i] == ESCAPE_CHAR) {
// escape character, next char must be escapeChar or separatorChar
if (i + 1 < max && (val[i + 1] == ESCAPE_CHAR || val[i + 1] == SEPARATOR_CHAR)) {
// write escaped char
i += 1;
int rc = fputc(val[i], entryStream);
if (rc == EOF) {
status = CELIX_ENOMEM;
}
} else {
// invalid escape (ending with escapeChar or followed by an invalid char)
status = CELIX_ILLEGAL_ARGUMENT;
}
} else if (val[i] == SEPARATOR_CHAR || val[i] == '\0') {
//end of entry
int rc = fputc('\0', entryStream);
if (rc == EOF) {
status = CELIX_ENOMEM;
continue;
}
fflush(entryStream);
status = addEntry(list, buf);
rewind(entryStream);
} else {
//normal char
int rc = fputc(val[i], entryStream);
if (rc == EOF) {
status = CELIX_ENOMEM;
}
}
}
fclose(entryStream);
free(buf);
if (status == CELIX_SUCCESS) {
*listOut = celix_steal_ptr(list);
} else if (status == CELIX_ILLEGAL_ARGUMENT) {
if (defaultValue) {
*listOut = celix_arrayList_copy(defaultValue);
return *listOut ? status : CELIX_ENOMEM;
}
return status;
}
return status;
}