From: Michael Tremer Date: Sat, 1 May 2021 13:31:57 +0000 (+0000) Subject: util: Refactor pakfire_split_string X-Git-Tag: 0.9.28~1285^2~164 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c81287d2a1dd946207c411c5ca63d77e2210e891;p=pakfire.git util: Refactor pakfire_split_string Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index 9956fc867..af5d09590 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -300,37 +300,59 @@ ERROR: return result; } -char** pakfire_split_string(const char* s, char delim) { - // Copy string to stack and count spaces - char buffer[strlen(s) + 2]; +static unsigned int pakfire_chrcnt(const char* s, char delim) { + size_t length = strlen(s); - size_t count = 1; - for (unsigned int i = 0; i < strlen(s) + 1; i++) { - buffer[i] = s[i]; + unsigned int count = 0; - if (s[i] == delim) { - buffer[i] = '\0'; + for (unsigned int i = 0; i < length; i++) + if (s[i] == delim) count++; - } + + return count; +} + +char** pakfire_split_string(const char* s, char delim) { + char** array = NULL; + + if (!s) { + errno = EINVAL; + return NULL; } - // Allocate an array of sufficient size - char** ret = malloc(sizeof(*ret) * (count + 1)); + // Count how often we need to split + unsigned int count = pakfire_chrcnt(s, delim) + 1; + + // Allocate array + array = calloc(count + 1, sizeof(*array)); + if (!array) + return NULL; + + // Copy string to stack + char* p = strdupa(s); + if (!p) + return NULL; - // Copy strings to heap one by one unsigned int i = 0; - char* p = buffer; while (*p) { - ret[i++] = strdup(p); + char* e = strchr(p, delim); - // Move pointer to the next string - p += strlen(p) + 1; - } + // Terminate the string + if (e) + *e = '\0'; - // Terminate array - ret[count] = NULL; + // Add string to the array + array[i++] = strdup(p); - return ret; + // End loop when we reached the end + if (!e) + break; + + // Or continue at the next line + p = e + 1; + } + + return array; } char* pakfire_string_join(char** list, const char* delim) { diff --git a/tests/libpakfire/util.c b/tests/libpakfire/util.c index e78b135a4..2f7f47cea 100644 --- a/tests/libpakfire/util.c +++ b/tests/libpakfire/util.c @@ -18,6 +18,7 @@ # # #############################################################################*/ +#include #include #include @@ -116,12 +117,48 @@ static int test_string_replace(const struct test* t) { return EXIT_SUCCESS; } +static int test_string_split(const struct test* t) { + char** result = pakfire_split_string(NULL, 'X'); + + // Must return on invalid input + ASSERT_ERRNO(!result, EINVAL); + + // Split a string + result = pakfire_split_string("ABCXABCXABC", 'X'); + ASSERT(result); + + ASSERT_STRING_EQUALS(result[0], "ABC"); + ASSERT_STRING_EQUALS(result[1], "ABC"); + ASSERT_STRING_EQUALS(result[2], "ABC"); + ASSERT_NULL(result[3]); + + // Split a string withtout the delimiter + result = pakfire_split_string("ABCABC", 'X'); + ASSERT(result); + + ASSERT_STRING_EQUALS(result[0], "ABCABC"); + ASSERT_NULL(result[1]); + + // String with only delimiters + result = pakfire_split_string("XXXX", 'X'); + ASSERT(result); + + ASSERT_STRING_EQUALS(result[0], ""); + ASSERT_STRING_EQUALS(result[1], ""); + ASSERT_STRING_EQUALS(result[2], ""); + ASSERT_STRING_EQUALS(result[3], ""); + ASSERT_NULL(result[4]); + + return EXIT_SUCCESS; +} + int main(int argc, char** argv) { testsuite_add_test(test_basename); testsuite_add_test(test_dirname); testsuite_add_test(test_string_startswith); testsuite_add_test(test_string_partition); testsuite_add_test(test_string_replace); + testsuite_add_test(test_string_split); return testsuite_run(); } diff --git a/tests/testsuite.h b/tests/testsuite.h index 0b025042e..412b7c910 100644 --- a/tests/testsuite.h +++ b/tests/testsuite.h @@ -21,6 +21,7 @@ #ifndef PAKFIRE_TESTSUITE_H #define PAKFIRE_TESTSUITE_H +#include #include #include #include