]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
vshStringToArray: Rewrite using 'g_strsplit'
authorPeter Krempa <pkrempa@redhat.com>
Wed, 11 Aug 2021 13:04:14 +0000 (15:04 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 18 Aug 2021 09:07:25 +0000 (11:07 +0200)
Use 'g_strsplit' to split the strings and then concatenate back when the
escape sequence (',,') is used.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
tools/vsh.c

index e67c0b35db0ab28a671f52bc1a1995127a69c32c..ea078c707bc5ccd7131b27dfd7a564a511ddf8ab 100644 (file)
@@ -122,48 +122,38 @@ int
 vshStringToArray(const char *str,
                  char ***array)
 {
-    g_autofree char *str_copied = g_strdup(str);
-    char *str_tok = NULL;
-    char *tmp;
-    unsigned int nstr_tokens = 0;
-    char **arr = NULL;
-    size_t len = strlen(str_copied);
-
-    /* tokenize the string from user and save its parts into an array */
-    nstr_tokens = 1;
-
-    /* count the delimiters, recognizing ,, as an escape for a
-     * literal comma */
-    str_tok = str_copied;
-    while ((str_tok = strchr(str_tok, ','))) {
-        if (str_tok[1] == ',')
-            str_tok++;
-        else
-            nstr_tokens++;
-        str_tok++;
-    }
+    g_auto(GStrv) tmp = NULL;
+    GStrv n;
+    size_t ntoks = 0;
+    bool concat = false;
+
+    tmp = g_strsplit(str, ",", 0);
+
+    *array = g_new0(char *, g_strv_length(tmp) + 1);
+    (*array)[ntoks++] = g_strdup(tmp[0]);
 
-    /* reserve the NULL element at the end */
-    arr = g_new0(char *, nstr_tokens + 1);
+    /* undo splitting of comma escape (',,') by concatenating back on empty strings */
+    for (n = tmp + 1; n[0]; n++) {
+        if (concat) {
+            g_autofree char *old = (*array)[ntoks - 1];
 
-    /* tokenize the input string, while treating ,, as a literal comma */
-    nstr_tokens = 0;
-    tmp = str_tok = str_copied;
-    while ((tmp = strchr(tmp, ','))) {
-        if (tmp[1] == ',') {
-            memmove(&tmp[1], &tmp[2], len - (tmp - str_copied) - 2 + 1);
-            len--;
-            tmp++;
+            (*array)[ntoks - 1] = g_strconcat(old, ",", n[0], NULL);
+            concat = false;
             continue;
         }
-        *tmp++ = '\0';
-        arr[nstr_tokens++] = g_strdup(str_tok);
-        str_tok = tmp;
+
+        if (strlen(n[0]) == 0) {
+            concat = true;
+        } else {
+            (*array)[ntoks++] = g_strdup(n[0]);
+        }
     }
-    arr[nstr_tokens++] = g_strdup(str_tok);
 
-    *array = arr;
-    return nstr_tokens;
+    /* corner case of ending with a single comma */
+    if (concat)
+        (*array)[ntoks++] = g_strdup("");
+
+    return ntoks;
 }
 
 virErrorPtr last_error;