]> git.ipfire.org Git - pakfire.git/commitdiff
util: Refactor pakfire_split_string
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 1 May 2021 13:31:57 +0000 (13:31 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 1 May 2021 13:31:57 +0000 (13:31 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/util.c
tests/libpakfire/util.c
tests/testsuite.h

index 9956fc867a1b31cae70cd260061654848a0453bc..af5d09590ab4839223254b4e6b4146a1931e00d3 100644 (file)
@@ -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) {
index e78b135a4eb2c46ad703d608a2eae7e5d73eec13..2f7f47ceac531f962a642848cba2dfc627d2b089 100644 (file)
@@ -18,6 +18,7 @@
 #                                                                             #
 #############################################################################*/
 
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -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();
 }
index 0b025042ea1963583002d3445a1877d488dd021b..412b7c910e7d97cdc6d37db87a4a9c42ec62bbcf 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef PAKFIRE_TESTSUITE_H
 #define PAKFIRE_TESTSUITE_H
 
+#include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>