diff --git a/src/string.c b/src/string.c index 17dfb52..1c22c54 100644 --- a/src/string.c +++ b/src/string.c @@ -685,7 +685,7 @@ string_result_t string_to_upper(const string_t *str) { } *dst = '\0'; result = string_new(buf); -free(buf); + free(buf); SET_MSG(result, "String successfully converted to uppercase"); @@ -749,3 +749,193 @@ string_result_t string_reverse(const string_t *str) { return result; } + +/** + * string_trim + * @str: a non-null string + * + * Trims whitespace from @str + * + * Returns a string_result_t containing the trimmed string + */ +string_result_t string_trim(const string_t *str) { + string_result_t result = {0}; + + if (str == NULL) { + result.status = STRING_ERR_INVALID; + SET_MSG(result, "Invalid string"); + + return result; + } + + const char *start = str->data; + while (*start && is_space((unsigned char)*start)) { + start++; + } + + if (*start == '\0') { + return string_new(""); + } + + const char *end = str->data + str->byte_size - 1; + while (end > start && is_space((unsigned char)*end)) { + end--; + } + + const size_t len = (end - start) + 1; + char *trimmed = malloc(len + 1); + if (trimmed == NULL) { + result.status = STRING_ERR_ALLOCATE; + SET_MSG(result, "Cannot allocate memory"); + + return result; + } + + memcpy(trimmed, start, len); + trimmed[len] = '\0'; + result = string_new(trimmed); + free(trimmed); + + result.status = STRING_OK; + SET_MSG(result, "String successfully trimmed"); + + return result; +} + +/** + * string_split + * @str: a non-null string + * @delim: delimiter string + * + * Splits @str by @delim + * + * Returns a string_result_t containing an array of String pointers + */ +string_result_t string_split(const string_t *str, const char *delim) { + string_result_t result = {0}; + string_result_t tmp_res = {0}; + + if (str == NULL || delim == NULL || delim[0] == '\0') { + result.status = STRING_ERR_INVALID; + SET_MSG(result, "Invalid strings"); + + return result; + } + + const char *ptr = str->data; + const size_t delim_len = strlen(delim); + size_t count = 1; + + while ((ptr = strstr(ptr, delim))) { + count++; + ptr += delim_len; + } + + string_t **string_array = malloc(count * sizeof(string_t *)); + if (string_array == NULL) { + result.status = STRING_ERR_ALLOCATE; + SET_MSG(result, "Cannot allocate memory"); + + return result; + } + + const char *start = str->data; + size_t idx = 0; + + while ((ptr = strstr(start, delim))) { + const size_t part_len = ptr - start; + char *tmp = malloc(part_len + 1); + if (tmp == NULL) { + result.status = STRING_ERR_ALLOCATE; + SET_MSG(result, "Cannot allocate memory"); + + goto cleanup; + } + + memcpy(tmp, start, part_len); + tmp[part_len] = '\0'; + + tmp_res = string_new(tmp); + free(tmp); + if (tmp_res.status != STRING_OK) { result = tmp_res; goto cleanup; } + + string_array[idx++] = tmp_res.value.string; + start = ptr + delim_len; + } + + tmp_res = string_new(start); + if (tmp_res.status != STRING_OK) { result = tmp_res; goto cleanup; } + + string_array[idx] = tmp_res.value.string; + + result.status = STRING_OK; + result.value.split.strings = string_array; + result.value.split.count = count; + SET_MSG(result, "String successfully split"); + + return result; + +cleanup: + for (size_t j = 0; j < idx; j++) { string_destroy(string_array[j]); } + free(string_array); + + return result; +} + +/** + * string_destroy + * @str: a non-null string + * + * Destroys @str + * + * Returns a string_result_t data type + */ +string_result_t string_destroy(string_t *str) { + string_result_t result = {0}; + + if (str == NULL) { + result.status = STRING_ERR_INVALID; + SET_MSG(result, "Invalid string"); + + return result; + } + + free(str->data); + free(str); + + result.status = STRING_OK; + SET_MSG(result, "String successfully deleted"); + + return result; +} + +/** + * string_split_destory + * @split: an array of pointers of String + * @count: the number of elements + * + * Destroys the @split array of Strings + * + * Returns a string_result_t data type + */ +string_result_t string_split_destroy(string_t **split, size_t count) { + string_result_t result = {0}; + + if (split == NULL) { + result.status = STRING_ERR_INVALID; + SET_MSG(result, "Invalid string"); + + return result; + } + + for (size_t idx = 0; idx < count; idx++) { + string_destroy(split[idx]); + } + + free(split); + + result.status = STRING_OK; + SET_MSG(result, "Array of strings successfully deleted"); + + return result; +}