]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Introduce virBitmapParseUnlimited
authorJán Tomko <jtomko@redhat.com>
Fri, 17 Jun 2016 13:12:02 +0000 (15:12 +0200)
committerJán Tomko <jtomko@redhat.com>
Mon, 20 Jun 2016 10:09:52 +0000 (12:09 +0200)
For parsing a bitmap of an unknown size.

src/libvirt_private.syms
src/util/virbitmap.c
src/util/virbitmap.h
tests/virbitmaptest.c

index 0106afe8a2f625813d7547b237578c9c2b7bbc19..501c23e67f9b9913a261a9bedb511acad4d3e73b 100644 (file)
@@ -1208,6 +1208,7 @@ virBitmapNextSetBit;
 virBitmapOverlaps;
 virBitmapParse;
 virBitmapParseSeparator;
+virBitmapParseUnlimited;
 virBitmapSetAll;
 virBitmapSetBit;
 virBitmapSetBitExpand;
index 3381a3d348eea7ad416e74429f6e472efb3cec60..32767631334495eec40812f7614c486056ca861d 100644 (file)
@@ -542,6 +542,118 @@ virBitmapParse(const char *str,
     return virBitmapParseSeparator(str, '\0', bitmap, bitmapSize);
 }
 
+/**
+ * virBitmapParseUnlimited:
+ * @str: points to a string representing a human-readable bitmap
+ * @bitmap: a bitmap created from @str
+ *
+ * This function is the counterpart of virBitmapFormat. This function creates
+ * a bitmap, in which bits are set according to the content of @str.
+ *
+ * The bitmap is expanded to accomodate all the bits.
+ *
+ * @str is a comma separated string of fields N, which means a number of bit
+ * to set, and ^N, which means to unset the bit, and N-M for ranges of bits
+ * to set.
+ *
+ * Returns 0 on success, or -1 in case of error.
+ */
+int
+virBitmapParseUnlimited(const char *str,
+                        virBitmapPtr *bitmap)
+{
+    bool neg = false;
+    const char *cur = str;
+    char *tmp;
+    size_t i;
+    int start, last;
+
+    if (!(*bitmap = virBitmapNewEmpty()))
+        return -1;
+
+    if (!str)
+        goto error;
+
+    virSkipSpaces(&cur);
+
+    if (*cur == '\0')
+        goto error;
+
+    while (*cur != 0) {
+        /*
+         * 3 constructs are allowed:
+         *     - N   : a single CPU number
+         *     - N-M : a range of CPU numbers with N < M
+         *     - ^N  : remove a single CPU number from the current set
+         */
+        if (*cur == '^') {
+            cur++;
+            neg = true;
+        }
+
+        if (!c_isdigit(*cur))
+            goto error;
+
+        if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
+            goto error;
+        if (start < 0)
+            goto error;
+
+        cur = tmp;
+
+        virSkipSpaces(&cur);
+
+        if (*cur == ',' || *cur == 0) {
+            if (neg) {
+                if (virBitmapClearBitExpand(*bitmap, start) < 0)
+                    goto error;
+            } else {
+                if (virBitmapSetBitExpand(*bitmap, start) < 0)
+                    goto error;
+            }
+        } else if (*cur == '-') {
+            if (neg)
+                goto error;
+
+            cur++;
+            virSkipSpaces(&cur);
+
+            if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
+                goto error;
+            if (last < start)
+                goto error;
+
+            cur = tmp;
+
+            for (i = start; i <= last; i++) {
+                if (virBitmapSetBitExpand(*bitmap, i) < 0)
+                    goto error;
+            }
+
+            virSkipSpaces(&cur);
+        }
+
+        if (*cur == ',') {
+            cur++;
+            virSkipSpaces(&cur);
+            neg = false;
+        } else if (*cur == 0) {
+            break;
+        } else {
+            goto error;
+        }
+    }
+
+    return 0;
+
+ error:
+    virReportError(VIR_ERR_INVALID_ARG,
+                   _("Failed to parse bitmap '%s'"), str);
+    virBitmapFree(*bitmap);
+    *bitmap = NULL;
+    return -1;
+}
+
 /**
  * virBitmapNewCopy:
  * @src: the source bitmap.
index 3356e1e7778462fb4bd66609782e47edbe6e33ff..5984b80ea17253957aeee2bfe6cc92da3d97cf86 100644 (file)
@@ -94,6 +94,10 @@ virBitmapParseSeparator(const char *str,
                         char terminator,
                         virBitmapPtr *bitmap,
                         size_t bitmapSize);
+int
+virBitmapParseUnlimited(const char *str,
+                        virBitmapPtr *bitmap)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 virBitmapPtr virBitmapNewCopy(virBitmapPtr src) ATTRIBUTE_NONNULL(1);
 
index 89c41d00c7c3d53f13077d1f5e1e21f367ba0c13..009fa0dad363374dafd525472a5b0d0bfe067a18 100644 (file)
@@ -632,12 +632,19 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
 
     TEST_MAP(151, "100");
 
+    virBitmapFree(map);
+    if (virBitmapParseUnlimited("34,1023", &map) < 0)
+        goto cleanup;
+
+    TEST_MAP(1024, "34,1023");
+
     ret = 0;
 
  cleanup:
     virBitmapFree(map);
     return ret;
 }
+
 #undef TEST_MAP