[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH V1 3/4] Parse lists of values



This patch introduces a parser for parsing lists of values as for example
found in the XML here:

        <parameter name='TEST' value='[10.1.2.3,10.2.3.4, 10.1.1.1]'/>

The list of values is then stored in the newly introduced data type
virNWFilterVarValue.

Adapt the XML schema to be able to handle lists.

Signed-off-by: Stefan Berger <stefanb linux vnet ibm com>

---
 docs/schemas/nwfilter.rng  |   29 ++++++----
 src/conf/nwfilter_params.c |  123 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 138 insertions(+), 14 deletions(-)

Index: libvirt-acl/src/conf/nwfilter_params.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_params.c
+++ libvirt-acl/src/conf/nwfilter_params.c
@@ -616,9 +618,124 @@ isValidVarValue(const char *value)
 }
 
 static virNWFilterVarValuePtr
-virNWFilterParseVarValue(const char *val)
+virNWFilterVarValueParseAsArray(const char *val, bool verbose)
+{
+    unsigned int i, j, k, l;
+    size_t bytes_to_copy;
+    virNWFilterVarValuePtr res;
+    char stopchar;
+    char *item;
+
+    i = 0;
+
+    while (val[i] && c_isspace(val[i]))
+         i++;
+
+    /* arrays start with '[' and end with ']' */
+    if (val[i] == '[') {
+        j = strlen(val) -  1;
+        while (j > i && val[j] && c_isspace(val[j]))
+            j--;
+        if (val[j] != ']') {
+            if (verbose)
+                virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("Invalid array syntax"));
+            return NULL;
+        }
+        i++;
+        j--;
+    } else {
+        if (verbose)
+            virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                                   _("Array does not start with '['"));
+        return NULL;
+    }
+
+    if (VIR_ALLOC(res) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    res->valType = NWFILTER_VALUE_TYPE_ARRAY;
+
+    while (i <= j) {
+        while (c_isspace(val[i]))
+           i++;
+        if (val[i] == '"' || val[i] == '\'') {
+           stopchar = val[i];
+           i++;
+        } else {
+           stopchar = ',';
+        }
+        /* i points to first letter in item */
+        k = i;
+        while (k <= j && val[k] != stopchar)
+            k++;
+        /* k point to the stopchar or end of value */
+        if (k > j) {
+            /* if end of value was reached test for proper stopchar */
+            if ((stopchar == '\'' || stopchar == '"') &&
+                val[k] != stopchar) {
+                virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("Illegal list syntax"));
+                goto err_exit;
+            }
+        }
+        /* l points to the next char to parse for the next item */
+        l = k + 1;
+
+        if (stopchar == ',') {
+            k--;
+            /* skip trailing whitespace */
+            while (k > i && c_isspace(val[k]))
+                k--;
+        } else
+            k--;
+
+        bytes_to_copy = (k >= i) ? ( k - i + 1) : 0;
+
+        item = strndup(&val[i], bytes_to_copy);
+
+        if (!item) {
+            virReportOOMError();
+            goto err_exit;
+        }
+
+        if (virNWFilterVarValueAddValue(res, item, false) == false) {
+            goto err_exit;
+        }
+
+        i = l;
+        if (stopchar != ',') {
+            /* search for comma */
+            while (i < j && c_isspace(val[i]))
+                i++;
+            if (i <= j && val[i] != ',') {
+                virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("Malformed list"));
+                goto err_exit;
+            }
+            i++;
+        }
+    }
+
+    return res;
+
+err_exit:
+    virNWFilterVarValueFree(res);
+    return NULL;
+}
+
+static virNWFilterVarValuePtr
+virNWFilterVarValueParse(const char *val)
 {
-    // FIXME: only handling simple values for now, no arrays
+    virNWFilterVarValuePtr res;
+
+    res = virNWFilterVarValueParseAsArray(val, false);
+    if (res)
+        return res;
+
+
     return virNWFilterVarValueCreateSimple(val, true);
 }
 
@@ -645,7 +762,7 @@ virNWFilterParseParamAttributes(xmlNodeP
                 if (nam != NULL && val != NULL) {
                     if (!isValidVarName(nam))
                         goto skip_entry;
-                    value = virNWFilterParseVarValue(val);
+                    value = virNWFilterVarValueParse(val);
                     if (!value)
                         goto skip_entry;
                     if (virNWFilterHashTablePut(table, nam, value, 1)) {
Index: libvirt-acl/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/nwfilter.rng
+++ libvirt-acl/docs/schemas/nwfilter.rng
@@ -313,14 +313,16 @@
       <data type="NCName"/>
     </attribute>
     <optional>
-      <element name="parameter">
-        <attribute name="name">
-          <ref name="filter-param-name"/>
-        </attribute>
-        <attribute name="value">
-          <ref name="filter-param-value"/>
-        </attribute>
-      </element>
+      <zeroOrMore>
+        <element name="parameter">
+          <attribute name="name">
+            <ref name="filter-param-name"/>
+          </attribute>
+          <attribute name="value">
+            <ref name="filter-param-value"/>
+          </attribute>
+        </element>
+      </zeroOrMore>
     </optional>
   </define>
 
@@ -869,9 +871,14 @@
   </define>
 
   <define name="filter-param-value">
-    <data type="string">
-      <param name="pattern">[a-zA-Z0-9_\.:]+</param>
-    </data>
+    <choice>
+      <data type="string">
+        <param name="pattern">[a-zA-Z0-9_\.:]+</param>
+      </data>
+      <data type="string">
+        <param name="pattern">\[[a-zA-Z0-9_\.:,&amp;&quot;&apos; ]*\]</param>
+      </data>
+    </choice>
   </define>
 
   <define name='action-type'>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]