Added string_{trim,split,destroy,split_destroy}
This commit is contained in:
190
src/string.c
190
src/string.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user