[libvirt PATCH v6 0/8] Refactor XML parsing boilerplate code

This series lays the groundwork for replacing some recurring boilerplate code in src/conf/ regarding the extraction of XML attribute values. For an on / off attribute, the boilerplate code looks roughly like this, g_autofree char *str = NULL; if (str = virXMLPropString(node, "x")) { int val; if ((val = virTristateBoolTypeFromString(str)) <= 0) { virReportError(...) return -1; } def->x = val; } with some variations regarding how `str` is free'd in case of later re-use, the exact error message for invalid values, whether or not `VIR_TRISTATE_(SWITCH|BOOL)_ABSENT` is explicitly checked for (`val < 0` vs. `val <= 0`), whether an intermediate variable is used or the value is assigned directly, and in some cases the conditions in the two if-blocks are merged. After the refactoring, the above code block looks like this: if (virXMLPropTristateBool(node, "x", VIR_XML_PROP_OPTIONAL, &def->x) < 0) return -1; Similar functions are introduced for integer valued attributes, unsigned integer valued attributes and enum valued attributes. Patches #6, #7, and #8 demonstrate the application of these function and stand representative of more patches that I did not sent along yet as to not drown the mailing list in spam. These patches remove a total of ~ 1000 lines of code and fix some places, where e.g. `<foo bar="default"/>` would incorrectly be accepted as virXMLTristateBool. As an added benefit, this refactoring makes the error messages for invalid values in these XML attributes much more consistent: $ git diff master | grep "^-.*_(\"" | wc -l 239 $ git diff master | grep "^+.*_(\"" | wc -l 21 V1: https://listman.redhat.com/archives/libvir-list/2021-March/msg00853.html V2: https://listman.redhat.com/archives/libvir-list/2021-March/msg00994.html V3: https://listman.redhat.com/archives/libvir-list/2021-March/msg01066.html V4: https://listman.redhat.com/archives/libvir-list/2021-April/msg00209.html V5: https://listman.redhat.com/archives/libvir-list/2021-April/msg00232.html Changes since V5: * Applied changes requested in https://listman.redhat.com/archives/libvir-list/2021-April/msg00658.html Cheers, Tim Tim Wiederhake (8): virxml: Add virXMLPropTristateBool virxml: Add virXMLPropTristateSwitch virxml: Add virXMLPropInt virxml: Add virXMLPropUInt virxml: Add virXMLPropEnum virNetworkForwardNatDefParseXML: Use virXMLProp* virDomainIOThreadIDDefParseXML: Use virXMLProp* virCPUDefParseXML: Use virXMLProp* src/conf/cpu_conf.c | 14 +-- src/conf/domain_conf.c | 14 +-- src/conf/network_conf.c | 16 +-- src/libvirt_private.syms | 5 + src/util/virxml.c | 249 +++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 42 +++++++ 6 files changed, 305 insertions(+), 35 deletions(-) -- 2.26.2

Convenience function to return the value of a yes / no XML attribute. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virxml.c | 44 ++++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 12 +++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a727537c76..331cbb57d5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3550,6 +3550,7 @@ virXMLParseHelper; virXMLPickShellSafeComment; virXMLPropString; virXMLPropStringLimit; +virXMLPropTristateBool; virXMLSaveFile; virXMLValidateAgainstSchema; virXMLValidatorFree; diff --git a/src/util/virxml.c b/src/util/virxml.c index 117f50f2bf..6b197e0fff 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -558,6 +558,50 @@ virXMLNodeContentString(xmlNodePtr node) } +/** + * virXMLPropTristateBool: + * @node: XML dom node pointer + * @name: Name of the property (attribute) to get + * @flags: Bitwise or of virXMLPropFlags + * @result: The returned value + * + * Convenience function to return value of a yes / no attribute. + * + * Returns 1 in case of success in which case @result is set, + * or 0 if the attribute is not present, + * or -1 and reports an error on failure. + */ +int +virXMLPropTristateBool(xmlNodePtr node, + const char* name, + virXMLPropFlags flags, + virTristateBool *result) +{ + g_autofree char *tmp = NULL; + int val; + + if (!(tmp = virXMLPropString(node, name))) { + if (!(flags & VIR_XML_PROP_REQUIRED)) + return 0; + + virReportError(VIR_ERR_XML_ERROR, + _("Missing required attribute '%s' in element '%s'"), + name, node->name); + return -1; + } + + if ((val = virTristateBoolTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': '%s'. Expected 'yes' or 'no'"), + name, node->name, tmp); + return -1; + } + + *result = val; + return 1; +} + + /** * virXPathBoolean: * @xpath: the XPath string to evaluate diff --git a/src/util/virxml.h b/src/util/virxml.h index de171dce12..bd246153f5 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -28,10 +28,16 @@ #include <libxml/relaxng.h> #include "virbuffer.h" +#include "virenum.h" xmlXPathContextPtr virXMLXPathContextNew(xmlDocPtr xml) G_GNUC_WARN_UNUSED_RESULT; +typedef enum { + VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */ + VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */ +} virXMLPropFlags; + int virXPathBoolean(const char *xpath, xmlXPathContextPtr ctxt); char * virXPathString(const char *xpath, @@ -78,6 +84,12 @@ char * virXMLPropStringLimit(xmlNodePtr node, size_t maxlen); char * virXMLNodeContentString(xmlNodePtr node); +int virXMLPropTristateBool(xmlNodePtr node, + const char *name, + virXMLPropFlags flags, + virTristateBool *result) + ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); + /* Internal function; prefer the macros below. */ xmlDocPtr virXMLParseHelper(int domcode, const char *filename, -- 2.26.2

Convenience function to return the value of an on / off XML attribute. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virxml.c | 44 ++++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 6 ++++++ 3 files changed, 51 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 331cbb57d5..ba70e8b4ca 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3551,6 +3551,7 @@ virXMLPickShellSafeComment; virXMLPropString; virXMLPropStringLimit; virXMLPropTristateBool; +virXMLPropTristateSwitch; virXMLSaveFile; virXMLValidateAgainstSchema; virXMLValidatorFree; diff --git a/src/util/virxml.c b/src/util/virxml.c index 6b197e0fff..1b1c3878e6 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -602,6 +602,50 @@ virXMLPropTristateBool(xmlNodePtr node, } +/** + * virXMLPropTristateSwitch: + * @node: XML dom node pointer + * @name: Name of the property (attribute) to get + * @flags: Bitwise or of virXMLPropFlags + * @result: The returned value + * + * Convenience function to return value of an on / off attribute. + * + * Returns 1 in case of success in which case @result is set, + * or 0 if the attribute is not present, + * or -1 and reports an error on failure. + */ +int +virXMLPropTristateSwitch(xmlNodePtr node, + const char* name, + virXMLPropFlags flags, + virTristateSwitch *result) +{ + g_autofree char *tmp = NULL; + int val; + + if (!(tmp = virXMLPropString(node, name))) { + if (!(flags & VIR_XML_PROP_REQUIRED)) + return 0; + + virReportError(VIR_ERR_XML_ERROR, + _("Missing required attribute '%s' in element '%s'"), + name, node->name); + return -1; + } + + if ((val = virTristateSwitchTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': '%s'. Expected 'on' or 'off'"), + name, node->name, tmp); + return -1; + } + + *result = val; + return 1; +} + + /** * virXPathBoolean: * @xpath: the XPath string to evaluate diff --git a/src/util/virxml.h b/src/util/virxml.h index bd246153f5..4c9497ba17 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -90,6 +90,12 @@ int virXMLPropTristateBool(xmlNodePtr node, virTristateBool *result) ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); +int virXMLPropTristateSwitch(xmlNodePtr node, + const char *name, + virXMLPropFlags flags, + virTristateSwitch *result) + ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); + /* Internal function; prefer the macros below. */ xmlDocPtr virXMLParseHelper(int domcode, const char *filename, -- 2.26.2

Convenience function to return the value of an integer XML attribute. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virxml.c | 53 ++++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 8 ++++++ 3 files changed, 62 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ba70e8b4ca..11e7b0c741 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3548,6 +3548,7 @@ virXMLNodeSanitizeNamespaces; virXMLNodeToString; virXMLParseHelper; virXMLPickShellSafeComment; +virXMLPropInt; virXMLPropString; virXMLPropStringLimit; virXMLPropTristateBool; diff --git a/src/util/virxml.c b/src/util/virxml.c index 1b1c3878e6..6da4a2b1f6 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -646,6 +646,59 @@ virXMLPropTristateSwitch(xmlNodePtr node, } +/** + * virXMLPropInt: + * @node: XML dom node pointer + * @name: Name of the property (attribute) to get + * @base: Number base, see strtol + * @flags: Bitwise or of virXMLPropFlags + * @result: The returned value + * + * Convenience function to return value of an integer attribute. + * + * Returns 1 in case of success in which case @result is set, + * or 0 if the attribute is not present, + * or -1 and reports an error on failure. + */ +int +virXMLPropInt(xmlNodePtr node, + const char *name, + int base, + virXMLPropFlags flags, + int *result) +{ + g_autofree char *tmp = NULL; + int val; + + if (!(tmp = virXMLPropString(node, name))) { + if (!(flags & VIR_XML_PROP_REQUIRED)) + return 0; + + virReportError(VIR_ERR_XML_ERROR, + _("Missing required attribute '%s' in element '%s'"), + name, node->name); + return -1; + } + + if (virStrToLong_i(tmp, NULL, base, &val) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': '%s'. Expected integer value"), + name, node->name, tmp); + return -1; + } + + if ((flags & VIR_XML_PROP_NONZERO) && (val == 0)) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': Zero is not permitted"), + name, node->name); + return -1; + } + + *result = val; + return 1; +} + + /** * virXPathBoolean: * @xpath: the XPath string to evaluate diff --git a/src/util/virxml.h b/src/util/virxml.h index 4c9497ba17..10c2404f5f 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -36,6 +36,7 @@ xmlXPathContextPtr virXMLXPathContextNew(xmlDocPtr xml) typedef enum { VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */ VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */ + VIR_XML_PROP_NONZERO = 1 << 1, /* Attribute may not be zero */ } virXMLPropFlags; int virXPathBoolean(const char *xpath, @@ -96,6 +97,13 @@ int virXMLPropTristateSwitch(xmlNodePtr node, virTristateSwitch *result) ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); +int virXMLPropInt(xmlNodePtr node, + const char *name, + int base, + virXMLPropFlags flags, + int *result) + ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); + /* Internal function; prefer the macros below. */ xmlDocPtr virXMLParseHelper(int domcode, const char *filename, -- 2.26.2

Convenience function to return the value of an unsigned integer XML attribute. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virxml.c | 60 ++++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 8 ++++++ 3 files changed, 69 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 11e7b0c741..9c94edb523 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3553,6 +3553,7 @@ virXMLPropString; virXMLPropStringLimit; virXMLPropTristateBool; virXMLPropTristateSwitch; +virXMLPropUInt; virXMLSaveFile; virXMLValidateAgainstSchema; virXMLValidatorFree; diff --git a/src/util/virxml.c b/src/util/virxml.c index 6da4a2b1f6..662a700262 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -699,6 +699,66 @@ virXMLPropInt(xmlNodePtr node, } +/** + * virXMLPropUInt: + * @node: XML dom node pointer + * @name: Name of the property (attribute) to get + * @base: Number base, see strtol + * @flags: Bitwise or of virXMLPropFlags + * @result: The returned value + * + * Convenience function to return value of an unsigned integer attribute. + * + * Returns 1 in case of success in which case @result is set, + * or 0 if the attribute is not present, + * or -1 and reports an error on failure. + */ +int +virXMLPropUInt(xmlNodePtr node, + const char* name, + int base, + virXMLPropFlags flags, + unsigned int *result) +{ + g_autofree char *tmp = NULL; + int ret; + unsigned int val; + + if (!(tmp = virXMLPropString(node, name))) { + if (!(flags & VIR_XML_PROP_REQUIRED)) + return 0; + + virReportError(VIR_ERR_XML_ERROR, + _("Missing required attribute '%s' in element '%s'"), + name, node->name); + return -1; + } + + if (flags & VIR_XML_PROP_WRAPNEGATIVE) { + ret = virStrToLong_ui(tmp, NULL, base, &val); + } else { + ret = virStrToLong_uip(tmp, NULL, base, &val); + } + + if (ret < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': '%s'. Expected integer value"), + name, node->name, tmp); + return -1; + } + + if ((flags & VIR_XML_PROP_NONZERO) && (val == 0)) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': Zero is not permitted"), + name, node->name); + return -1; + } + + *result = val; + return 1; +} + + /** * virXPathBoolean: * @xpath: the XPath string to evaluate diff --git a/src/util/virxml.h b/src/util/virxml.h index 10c2404f5f..aed4715123 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -37,6 +37,7 @@ typedef enum { VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */ VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */ VIR_XML_PROP_NONZERO = 1 << 1, /* Attribute may not be zero */ + VIR_XML_PROP_WRAPNEGATIVE = 1 << 2, /* Wrap around negative values */ } virXMLPropFlags; int virXPathBoolean(const char *xpath, @@ -104,6 +105,13 @@ int virXMLPropInt(xmlNodePtr node, int *result) ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +int virXMLPropUInt(xmlNodePtr node, + const char* name, + int base, + virXMLPropFlags flags, + unsigned int *result) + ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); + /* Internal function; prefer the macros below. */ xmlDocPtr virXMLParseHelper(int domcode, const char *filename, -- 2.26.2

Convenience function to return the value of an enum XML attribute. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virxml.c | 48 ++++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 8 +++++++ 3 files changed, 57 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9c94edb523..0fcbf546a6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3548,6 +3548,7 @@ virXMLNodeSanitizeNamespaces; virXMLNodeToString; virXMLParseHelper; virXMLPickShellSafeComment; +virXMLPropEnum; virXMLPropInt; virXMLPropString; virXMLPropStringLimit; diff --git a/src/util/virxml.c b/src/util/virxml.c index 662a700262..94948ca021 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -759,6 +759,54 @@ virXMLPropUInt(xmlNodePtr node, } +/** + * virXMLPropEnum: + * @node: XML dom node pointer + * @name: Name of the property (attribute) to get + * @strToInt: Conversion function to turn enum name to value. Expected to + * return negative value on failure. + * @flags: Bitwise or of virXMLPropFlags + * @result: The returned value + * + * Convenience function to return value of an enum attribute. + * + * Returns 1 in case of success in which case @result is set, + * or 0 if the attribute is not present, + * or -1 and reports an error on failure. + */ +int +virXMLPropEnum(xmlNodePtr node, + const char* name, + int (*strToInt)(const char*), + virXMLPropFlags flags, + unsigned int *result) +{ + g_autofree char *tmp = NULL; + int ret; + + if (!(tmp = virXMLPropString(node, name))) { + if (!(flags & VIR_XML_PROP_REQUIRED)) + return 0; + + virReportError(VIR_ERR_XML_ERROR, + _("Missing required attribute '%s' in element '%s'"), + name, node->name); + return -1; + } + + ret = strToInt(tmp); + if (ret < 0 || + ((flags & VIR_XML_PROP_NONZERO) && (ret == 0))) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid value for attribute '%s' in element '%s': '%s'."), + name, node->name, NULLSTR(tmp)); + return -1; + } + + *result = ret; + return 0; +} + /** * virXPathBoolean: * @xpath: the XPath string to evaluate diff --git a/src/util/virxml.h b/src/util/virxml.h index aed4715123..d362cfb794 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -112,6 +112,14 @@ int virXMLPropUInt(xmlNodePtr node, unsigned int *result) ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +int virXMLPropEnum(xmlNodePtr node, + const char* name, + int (*strToInt)(const char*), + virXMLPropFlags flags, + unsigned int *result) + ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) + ATTRIBUTE_NONNULL(4); + /* Internal function; prefer the macros below. */ xmlDocPtr virXMLParseHelper(int domcode, const char *filename, -- 2.26.2

Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/network_conf.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f0f5ef6f42..17835ac8d3 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1321,7 +1321,6 @@ virNetworkForwardNatDefParseXML(const char *networkName, g_autofree xmlNodePtr *natPortNodes = NULL; g_autofree char *addrStart = NULL; g_autofree char *addrEnd = NULL; - g_autofree char *ipv6 = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt) ctxt->node = node; @@ -1333,18 +1332,9 @@ virNetworkForwardNatDefParseXML(const char *networkName, return -1; } - ipv6 = virXMLPropString(node, "ipv6"); - if (ipv6) { - int natIPv6; - if ((natIPv6 = virTristateBoolTypeFromString(ipv6)) <= 0) { - virReportError(VIR_ERR_XML_ERROR, - _("Invalid ipv6 setting '%s' " - "in network '%s' NAT"), - ipv6, networkName); - return -1; - } - def->natIPv6 = natIPv6; - } + if (virXMLPropTristateBool(node, "ipv6", VIR_XML_PROP_OPTIONAL, + &def->natIPv6) < 0) + return -1; /* addresses for SNAT */ nNatAddrs = virXPathNodeSet("./address", ctxt, &natAddrNodes); -- 2.26.2

Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a0fb7731d9..858ef5db9d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18229,21 +18229,13 @@ static virDomainIOThreadIDDef * virDomainIOThreadIDDefParseXML(xmlNodePtr node) { virDomainIOThreadIDDef *iothrid; - g_autofree char *tmp = NULL; iothrid = g_new0(virDomainIOThreadIDDef, 1); - if (!(tmp = virXMLPropString(node, "id"))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing 'id' attribute in <iothread> element")); - goto error; - } - if (virStrToLong_uip(tmp, NULL, 10, &iothrid->iothread_id) < 0 || - iothrid->iothread_id == 0) { - virReportError(VIR_ERR_XML_ERROR, - _("invalid iothread 'id' value '%s'"), tmp); + if (virXMLPropUInt(node, "id", 10, + VIR_XML_PROP_REQUIRED | VIR_XML_PROP_NONZERO, + &iothrid->iothread_id) < 0) goto error; - } return iothrid; -- 2.26.2

Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/cpu_conf.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index c095ab0e89..c7bea8ae00 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -423,7 +423,6 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, if (def->type == VIR_CPU_TYPE_GUEST) { g_autofree char *match = virXMLPropString(ctxt->node, "match"); - g_autofree char *check = NULL; if (match) { def->match = virCPUMatchTypeFromString(match); @@ -435,16 +434,9 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, } } - if ((check = virXMLPropString(ctxt->node, "check"))) { - int value = virCPUCheckTypeFromString(check); - if (value < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Invalid check attribute for CPU " - "specification")); - return -1; - } - def->check = value; - } + if (virXMLPropEnum(ctxt->node, "check", virCPUCheckTypeFromString, + VIR_XML_PROP_OPTIONAL, &def->check) < 0) + return -1; } if (def->type == VIR_CPU_TYPE_HOST) { -- 2.26.2

On Fri, Apr 16, 2021 at 11:41:44 +0200, Tim Wiederhake wrote: [...]
Tim Wiederhake (8): virxml: Add virXMLPropTristateBool virxml: Add virXMLPropTristateSwitch virxml: Add virXMLPropInt virxml: Add virXMLPropUInt virxml: Add virXMLPropEnum
I've rebased these on top of the virxml.h formatting fix and pushed them now. Additionally I've converted few types to appropriate enum values to see how compilers will like that in respect to virXMLPropEnum: https://listman.redhat.com/archives/libvir-list/2021-April/msg00679.html
virNetworkForwardNatDefParseXML: Use virXMLProp* virDomainIOThreadIDDefParseXML: Use virXMLProp* virCPUDefParseXML: Use virXMLProp*
src/conf/cpu_conf.c | 14 +-- src/conf/domain_conf.c | 14 +-- src/conf/network_conf.c | 16 +-- src/libvirt_private.syms | 5 + src/util/virxml.c | 249 +++++++++++++++++++++++++++++++++++++++ src/util/virxml.h | 42 +++++++ 6 files changed, 305 insertions(+), 35 deletions(-)
-- 2.26.2
participants (2)
-
Peter Krempa
-
Tim Wiederhake