diff --git a/docs/string.md b/docs/string.md index e9b4b37..0e4bd39 100644 --- a/docs/string.md +++ b/docs/string.md @@ -5,20 +5,26 @@ C string helpers ## Functions ### find_substrings -Finds the indexes of all locations of the given needle in the haystack. The returned array of `size_t` is allocated by -this function and memory cleanup is managed by the user. `num_substrings` is a pointer to a pre-allocated `size_t` that will -be modified to contain the number of found substrings and subsequently the size of the returned array of `size_t`. -Returns `NULL` and prints to `stderr` if there is an error. +Finds the indicies of all locations of the given needle in the haystack. `substrings` is an array of `size_t` indicies that +the substring is found at. This function allocates the memory for `substrings` and memory cleanup is managed by the user. +`num_substrings` is a pointer to a pre-allocated `size_t` that will be modified to contain the number of found substrings +and subsequently the size of `substrings`. + +If no substrings are found, `substrings` will not be allocated and left set to `NULL`, `num_substrings` will be `0`, and +the function will return `0`. + +Returns 0 if the function is successful, returns a non-zero value and prints to `stderr` if there is an error. ```c -size_t *find_substrings(const char* haystack, const char* needle, size_t *num_substrings); +int find_substrings(const char* haystack, const char* needle, size_t *num_substrings, size_t **substrings); /* Usage */ const char* haystack = "One two three two"; const char* needle = "two"; -size_t subs_sz = 0; -size_t *subs = find_substrings(haystack, needle, &subs_sz); +size_t subs_sz = 0; +size_t *subs = NULL; +size_t *subs = find_substrings(haystack, needle, &subs_sz, &subs); // subs: [ 4, 14 ] // subs_sz: 2 diff --git a/include/lfstring.h b/include/lfstring.h index 1f413f7..9b65d98 100644 --- a/include/lfstring.h +++ b/include/lfstring.h @@ -3,7 +3,7 @@ #include -size_t *find_substrings(const char* haystack, const char* needle, size_t *num_substrings); +int find_substrings(const char* haystack, const char* needle, size_t *num_substrings, size_t **substrings); const char* substr(const char* str, size_t idx, size_t len); diff --git a/src/string.c b/src/string.c index d10a60c..f5b62ab 100644 --- a/src/string.c +++ b/src/string.c @@ -4,7 +4,12 @@ #include "lfstring.h" -size_t *find_substrings(const char* haystack, const char* needle, size_t *num_substrings) { +int find_substrings(const char* haystack, const char* needle, size_t *num_substrings, size_t **substrings) { + if (*substrings != NULL) { + fprintf(stderr, "substrings was not NULL in find_substring\n"); + return 1; + } + size_t sz_h = strlen(haystack); size_t sz_n = strlen(needle); @@ -15,20 +20,24 @@ size_t *find_substrings(const char* haystack, const char* needle, size_t *num_su } } - size_t *indicies = malloc(sizeof(size_t) * *num_substrings); - if (indicies == NULL) { + if (*num_substrings == 0) { + return 0; + } + + *substrings = malloc(sizeof(size_t) * *num_substrings); + if (*substrings == NULL) { fprintf(stderr, "Memory allocation failed in find_substrings\n"); - return NULL; + return -1; } size_t idx = 0; for (size_t i = 0; i <= sz_h - sz_n; ++i) { if (strncmp(haystack + i, needle, sz_n) == 0) { - indicies[idx++] = i; + (*substrings)[idx++] = i; } } - return indicies; + return 0; } const char* substr(const char* str, size_t idx, size_t len) { diff --git a/tests/tests.c b/tests/tests.c index ed37869..5424fba 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -262,7 +262,9 @@ void test_string() { }; size_t sub_sz = 0; - size_t *subs = find_substrings(haystack, needles[0], &sub_sz); + size_t *subs = NULL; + find_substrings(haystack, needles[0], &sub_sz, &subs); + assert(sub_sz == 3); assert(subs[0] == 5); assert(subs[1] == 13); @@ -273,11 +275,19 @@ void test_string() { free(s); free(subs); + subs = NULL; - subs = find_substrings(haystack, needles[1], &sub_sz); + find_substrings(haystack, needles[1], &sub_sz, &subs); assert(sub_sz == 2); assert(subs[0] == 9); + free(subs); + subs = NULL; + + find_substrings("test one two", "nope", &sub_sz, &subs); + free(subs); + subs = NULL; + printf("Passes all string tests\n"); }