This patch introduces a parser for parsing lists of values as for example found in the XML here: 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 --- 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 @@ - - - - - - - - + + + + + + + + + + @@ -869,9 +871,14 @@ - - [a-zA-Z0-9_\.:]+ - + + + [a-zA-Z0-9_\.:]+ + + + \[[a-zA-Z0-9_\.:,&"' ]*\] + +