vshParseSnapshotDiskspec(vshControl *ctl, virBufferPtr buf, const char *str)
{
int ret = -1;
- char *name = NULL;
- char *snapshot = NULL;
- char *driver = NULL;
- char *file = NULL;
- char *spec = vshStrdup(ctl, str);
- char *tmp = spec;
- size_t len = strlen(str);
-
- if (*str == ',')
+ const char *name = NULL;
+ const char *snapshot = NULL;
+ const char *driver = NULL;
+ const char *file = NULL;
+ char **array = NULL;
+ int narray;
+ int i;
+
+ narray = vshStringToArray(str, &array);
+ if (narray <= 0)
goto cleanup;
- name = tmp;
- while ((tmp = strchr(tmp, ','))) {
- if (tmp[1] == ',') {
- /* Recognize ,, as an escape for a literal comma */
- memmove(&tmp[1], &tmp[2], len - (tmp - spec) - 2 + 1);
- len--;
- tmp++;
- continue;
- }
- /* Terminate previous string, look for next recognized one */
- *tmp++ = '\0';
- if (!snapshot && STRPREFIX(tmp, "snapshot="))
- snapshot = tmp + strlen("snapshot=");
- else if (!driver && STRPREFIX(tmp, "driver="))
- driver = tmp + strlen("driver=");
- else if (!file && STRPREFIX(tmp, "file="))
- file = tmp + strlen("file=");
+
+ name = array[0];
+ for (i = 1; i < narray; i++) {
+ if (!snapshot && STRPREFIX(array[i], "snapshot="))
+ snapshot = array[i] + strlen("snapshot=");
+ else if (!driver && STRPREFIX(array[i], "driver="))
+ driver = array[i] + strlen("driver=");
+ else if (!file && STRPREFIX(array[i], "file="))
+ file = array[i] + strlen("file=");
else
goto cleanup;
}
cleanup:
if (ret < 0)
vshError(ctl, _("unable to parse diskspec: %s"), str);
- VIR_FREE(spec);
+ if (array) {
+ VIR_FREE(*array);
+ VIR_FREE(array);
+ }
return ret;
}
/*
* Convert the strings separated by ',' into array. The caller
- * must free the returned array after use.
+ * must free the first array element and the returned array after
+ * use (all other array elements belong to the memory allocated
+ * for the first array element).
*
* Returns the length of the filled array on success, or -1
* on error.
{
char *str_copied = vshStrdup(NULL, 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 it's parts into an array */
- if (str_copied) {
- nstr_tokens = 1;
+ /* tokenize the string from user and save its parts into an array */
+ nstr_tokens = 1;
- /* count the delimiters */
- str_tok = str_copied;
- while (*str_tok) {
- if (*str_tok == ',')
- nstr_tokens++;
+ /* 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++;
+ }
- if (VIR_ALLOC_N(arr, nstr_tokens) < 0) {
- virReportOOMError();
- VIR_FREE(str_copied);
- return -1;
- }
+ if (VIR_ALLOC_N(arr, nstr_tokens) < 0) {
+ virReportOOMError();
+ VIR_FREE(str_copied);
+ return -1;
+ }
- /* tokenize the input string */
- nstr_tokens = 0;
- str_tok = str_copied;
- do {
- arr[nstr_tokens] = strsep(&str_tok, ",");
- nstr_tokens++;
- } while (str_tok);
+ /* 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++;
+ continue;
+ }
+ *tmp++ = '\0';
+ arr[nstr_tokens++] = str_tok;
+ str_tok = tmp;
}
+ arr[nstr_tokens++] = str_tok;
*array = arr;
return nstr_tokens;