[libvirt] [PATCH 09/50] list: Add helper to convert strings separated by ', ' to array

Osier Yang jyang at redhat.com
Thu Jul 19 16:40:40 UTC 2012


tools/virsh.c: New helper function vshStringToArray, use the helper
in cmdUndefine.
---
 tools/virsh.c |  107 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 66 insertions(+), 41 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 40f3be3..9c3b565 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3014,6 +3014,51 @@ static const vshCmdOptDef opts_undefine[] = {
     {NULL, 0, 0, NULL}
 };
 
+/*
+ * Convert the strings separated by ',' into array. The caller
+ * must free the returned array after use.
+ *
+ * Returns the length of the filled array on success, or -1
+ * on error.
+ */
+static int
+vshStringToArray(char *str,
+                 char ***array)
+{
+    char *str_tok = NULL;
+    unsigned int nstr_tokens = 0;
+    char **arr = NULL;
+
+    /* tokenize the string from user and save it's parts into an array */
+    if (str) {
+        nstr_tokens = 1;
+
+        /* count the delimiters */
+        str_tok = str;
+        while (*str_tok) {
+            if (*str_tok == ',')
+                nstr_tokens++;
+            str_tok++;
+        }
+
+        if (VIR_ALLOC_N(arr, nstr_tokens) < 0) {
+            virReportOOMError();
+            return -1;
+        }
+
+        /* tokenize the input string */
+        nstr_tokens = 0;
+        str_tok = str;
+        do {
+            arr[nstr_tokens] = strsep(&str_tok, ",");
+            nstr_tokens++;
+        } while (str_tok);
+    }
+
+    *array = arr;
+    return nstr_tokens;
+}
+
 static bool
 cmdUndefine(vshControl *ctl, const vshCmd *cmd)
 {
@@ -3039,21 +3084,21 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
     int running;
     /* list of volumes to remove along with this domain */
     const char *volumes_arg = NULL;
-    char *volumes = NULL;
-    char **volume_tokens = NULL;
-    char *volume_tok = NULL;
-    int nvolume_tokens = 0;
+    char *volumes_str = NULL;
+    char **volumes = NULL;
+    char *volume = NULL;
+    int volumes_len = 0;
     char *def = NULL;
     char *source = NULL;
     char *target = NULL;
     int vol_i;
-    int tok_i;
     xmlDocPtr doc = NULL;
     xmlXPathContextPtr ctxt = NULL;
     xmlNodePtr *vol_nodes = NULL;
     int nvolumes = 0;
     virStorageVolPtr vol = NULL;
     bool vol_del_failed = false;
+    int i;
 
     if (managed_save) {
         flags |= VIR_DOMAIN_UNDEFINE_MANAGED_SAVE;
@@ -3072,7 +3117,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
 
     /* check if a string that should contain list of volumes to remove is present */
     if (vshCommandOptString(cmd, "storage", &volumes_arg) > 0) {
-        volumes = vshStrdup(ctl, volumes_arg);
+        volumes_str = vshStrdup(ctl, volumes_arg);
 
         if (remove_all_storage) {
             vshError(ctl, _("Specified both --storage and --remove-all-storage"));
@@ -3212,27 +3257,8 @@ out:
     if (remove_storage || remove_all_storage) {
         ret = false;
 
-        /* tokenize the string from user and save it's parts into an array */
-        if (volumes) {
-            /* count the delimiters */
-            volume_tok = volumes;
-            nvolume_tokens = 1; /* we need at least one member */
-            while (*volume_tok) {
-                if (*volume_tok == ',')
-                    nvolume_tokens++;
-                volume_tok++;
-            }
-
-            volume_tokens = vshCalloc(ctl, nvolume_tokens,  sizeof(char *));
-
-            /* tokenize the input string */
-            nvolume_tokens = 0;
-            volume_tok = volumes;
-            do {
-                volume_tokens[nvolume_tokens] = strsep(&volume_tok, ",");
-                nvolume_tokens++;
-            } while (volume_tok);
-        }
+        if ((volumes_len = vshStringToArray(volumes_str, &volumes)) < 0)
+            goto cleanup;
 
         doc = virXMLParseStringCtxt(def, _("(domain_definition)"), &ctxt);
         if (!doc)
@@ -3268,17 +3294,17 @@ out:
 
             /* lookup if volume was selected by user */
             if (volumes) {
-                volume_tok = NULL;
-                for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) {
-                    if (volume_tokens[tok_i] &&
-                        (STREQ_NULLABLE(volume_tokens[tok_i], target) ||
-                         STREQ_NULLABLE(volume_tokens[tok_i], source))) {
-                        volume_tok = volume_tokens[tok_i];
-                        volume_tokens[tok_i] = NULL;
+                volume = NULL;
+                for (i = 0; i < volumes_len; i++) {
+                    if (volumes[i] &&
+                        (STREQ_NULLABLE(volumes[i], target) ||
+                         STREQ_NULLABLE(volumes[i], source))) {
+                        volume = volumes[i];
+                        volumes[i] = NULL;
                         break;
                     }
                 }
-                if (!volume_tok)
+                if (!volume)
                     continue;
             }
 
@@ -3311,16 +3337,16 @@ out:
                          target, source);
                 vol_del_failed = true;
             }
-            vshPrint(ctl, _("Volume '%s' removed.\n"), volume_tok?volume_tok:source);
+            vshPrint(ctl, _("Volume '%s' removed.\n"), volume ? volume :source);
         }
 
         /* print volumes specified by user that were not found in domain definition */
         if (volumes) {
-            for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) {
-                if (volume_tokens[tok_i])
+            for (i = 0; i < volumes_len; i++) {
+                if (volumes[i])
                     vshPrint(ctl, _("Volume '%s' was not found in domain's "
                                     "definition.\n"),
-                             volume_tokens[tok_i]);
+                             volumes[i]);
             }
         }
 
@@ -3331,8 +3357,8 @@ out:
 cleanup:
     VIR_FREE(source);
     VIR_FREE(target);
+    VIR_FREE(volumes_str);
     VIR_FREE(volumes);
-    VIR_FREE(volume_tokens);
     VIR_FREE(def);
     VIR_FREE(vol_nodes);
     if (vol)
@@ -3343,7 +3369,6 @@ cleanup:
     return ret;
 }
 
-
 /*
  * "start" command
  */
-- 
1.7.7.3




More information about the libvir-list mailing list