1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-22 14:50:27 +03:00

util: xml: Return GPtrArray from virXMLNodeGetSubelement

Rework the helper to use a GPtrArray structure to simplify callers.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2023-02-13 15:53:23 +01:00
parent 765edaf171
commit 08a7fc834c
5 changed files with 58 additions and 61 deletions

View File

@ -16386,23 +16386,23 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
xmlNodePtr node)
{
g_autofree virDomainFeatureKVM *kvm = g_new0(virDomainFeatureKVM, 1);
g_autofree xmlNodePtr *feats = NULL;
size_t nfeats = virXMLNodeGetSubelementList(node, NULL, &feats);
g_autoptr(GPtrArray) feats = virXMLNodeGetSubelementList(node, NULL);
size_t i;
for (i = 0; i < nfeats; i++) {
for (i = 0; i < feats->len; i++) {
xmlNodePtr feat = g_ptr_array_index(feats, i);
int feature;
virTristateSwitch value;
feature = virDomainKVMTypeFromString((const char *)feats[i]->name);
feature = virDomainKVMTypeFromString((const char *)feat->name);
if (feature < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported KVM feature: %1$s"),
feats[i]->name);
feat->name);
return -1;
}
if (virXMLPropTristateSwitch(feats[i], "state", VIR_XML_PROP_REQUIRED,
if (virXMLPropTristateSwitch(feat, "state", VIR_XML_PROP_REQUIRED,
&value) < 0)
return -1;
@ -16412,7 +16412,7 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
if (feature == VIR_DOMAIN_KVM_DIRTY_RING &&
value == VIR_TRISTATE_SWITCH_ON) {
if (virXMLPropUInt(feats[i], "size", 0, VIR_XML_PROP_REQUIRED,
if (virXMLPropUInt(feat, "size", 0, VIR_XML_PROP_REQUIRED,
&kvm->dirty_ring_size) < 0) {
return -1;
}
@ -16439,25 +16439,25 @@ static int
virDomainFeaturesXENDefParse(virDomainDef *def,
xmlNodePtr node)
{
g_autofree xmlNodePtr *feats = NULL;
size_t nfeats = virXMLNodeGetSubelementList(node, NULL, &feats);
g_autoptr(GPtrArray) feats = virXMLNodeGetSubelementList(node, NULL);
size_t i;
def->features[VIR_DOMAIN_FEATURE_XEN] = VIR_TRISTATE_SWITCH_ON;
for (i = 0; i < nfeats; i++) {
for (i = 0; i < feats->len; i++) {
xmlNodePtr feat = g_ptr_array_index(feats, i);
int feature;
virTristateSwitch value;
feature = virDomainXenTypeFromString((const char *)feats[i]->name);
feature = virDomainXenTypeFromString((const char *)feat->name);
if (feature < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported Xen feature: %1$s"),
feats[i]->name);
feat->name);
return -1;
}
if (virXMLPropTristateSwitch(feats[i], "state",
if (virXMLPropTristateSwitch(feat, "state",
VIR_XML_PROP_REQUIRED, &value) < 0)
return -1;
@ -16471,7 +16471,7 @@ virDomainFeaturesXENDefParse(virDomainDef *def,
if (value != VIR_TRISTATE_SWITCH_ON)
break;
if (virXMLPropEnum(feats[i], "mode",
if (virXMLPropEnum(feat, "mode",
virDomainXenPassthroughModeTypeFromString,
VIR_XML_PROP_NONZERO,
&def->xen_passthrough_mode) < 0)
@ -16491,8 +16491,7 @@ static int
virDomainFeaturesCapabilitiesDefParse(virDomainDef *def,
xmlNodePtr node)
{
g_autofree xmlNodePtr *caps = NULL;
size_t ncaps = virXMLNodeGetSubelementList(node, NULL, &caps);
g_autoptr(GPtrArray) caps = virXMLNodeGetSubelementList(node, NULL);
virDomainCapabilitiesPolicy policy;
size_t i;
@ -16504,17 +16503,18 @@ virDomainFeaturesCapabilitiesDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_CAPABILITIES] = policy;
for (i = 0; i < ncaps; i++) {
for (i = 0; i < caps->len; i++) {
xmlNodePtr cap = g_ptr_array_index(caps, i);
virTristateSwitch state;
int val = virDomainProcessCapsFeatureTypeFromString((const char *)caps[i]->name);
int val = virDomainProcessCapsFeatureTypeFromString((const char *)cap->name);
if (val < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unexpected capability feature '%1$s'"), caps[i]->name);
_("unexpected capability feature '%1$s'"), cap->name);
return -1;
}
if (virXMLPropTristateSwitch(caps[i], "state", VIR_XML_PROP_NONE, &state) < 0)
if (virXMLPropTristateSwitch(cap, "state", VIR_XML_PROP_NONE, &state) < 0)
return -1;
if (state == VIR_TRISTATE_SWITCH_ABSENT)

View File

@ -601,26 +601,28 @@ virNetworkDHCPDefParseXML(const char *networkName,
xmlNodePtr node,
virNetworkIPDef *def)
{
g_autofree xmlNodePtr *rangeNodes = NULL;
size_t nrangeNodes = virXMLNodeGetSubelementList(node, "range", &rangeNodes);
g_autofree xmlNodePtr *hostNodes = NULL;
size_t nhostNodes = virXMLNodeGetSubelementList(node, "host", &hostNodes);
g_autoptr(GPtrArray) rangeNodes = virXMLNodeGetSubelementList(node, "range");
g_autoptr(GPtrArray) hostNodes = virXMLNodeGetSubelementList(node, "host");
xmlNodePtr bootp = virXMLNodeGetSubelement(node, "bootp");
size_t i;
for (i = 0; i < nrangeNodes; i++) {
for (i = 0; i < rangeNodes->len; i++) {
virNetworkDHCPRangeDef range = { 0 };
if (virNetworkDHCPRangeDefParseXML(networkName, def, rangeNodes[i], &range) < 0)
if (virNetworkDHCPRangeDefParseXML(networkName, def,
g_ptr_array_index(rangeNodes, i),
&range) < 0)
return -1;
VIR_APPEND_ELEMENT(def->ranges, def->nranges, range);
}
for (i = 0; i < nhostNodes; i++) {
for (i = 0; i < hostNodes->len; i++) {
virNetworkDHCPHostDef host = { 0 };
if (virNetworkDHCPHostDefParseXML(networkName, def, hostNodes[i],
if (virNetworkDHCPHostDefParseXML(networkName, def,
g_ptr_array_index(hostNodes, i),
&host, false) < 0)
return -1;
@ -650,17 +652,16 @@ virNetworkDNSHostDefParseXML(const char *networkName,
virNetworkDNSHostDef *def,
bool partialOkay)
{
g_autofree xmlNodePtr *hostnameNodes = NULL;
size_t nhostnameNodes = virXMLNodeGetSubelementList(node, "hostname", &hostnameNodes);
g_autoptr(GPtrArray) hostnameNodes = virXMLNodeGetSubelementList(node, "hostname");
size_t i;
g_auto(GStrv) hostnames = NULL;
g_autofree char *ip = virXMLPropString(node, "ip");
if (nhostnameNodes > 0) {
hostnames = g_new0(char *, nhostnameNodes + 1);
if (hostnameNodes->len > 0) {
hostnames = g_new0(char *, hostnameNodes->len + 1);
for (i = 0; i < nhostnameNodes; i++) {
if (!(hostnames[i] = virXMLNodeContentString(hostnameNodes[i])))
for (i = 0; i < hostnameNodes->len; i++) {
if (!(hostnames[i] = virXMLNodeContentString(g_ptr_array_index(hostnameNodes, i))))
return -1;
if (*hostnames[i] == '\0') {
@ -694,7 +695,7 @@ virNetworkDNSHostDefParseXML(const char *networkName,
return -1;
}
if (nhostnameNodes == 0) {
if (hostnameNodes->len == 0) {
virReportError(VIR_ERR_XML_DETAIL,
_("Missing ip and hostname in network '%1$s' DNS HOST record"),
networkName);
@ -703,7 +704,7 @@ virNetworkDNSHostDefParseXML(const char *networkName,
}
def->names = g_steal_pointer(&hostnames);
def->nnames = nhostnameNodes;
def->nnames = hostnameNodes->len;
return 0;
}

View File

@ -2362,8 +2362,7 @@ static virNWFilterRuleDef *
virNWFilterRuleParse(xmlNodePtr node)
{
g_autofree char *statematch = NULL;
g_autofree xmlNodePtr *attrNodes = NULL;
size_t nattrNodes = 0;
g_autoptr(GPtrArray) attrNodes = NULL;
g_autoptr(virNWFilterRuleDef) ret = NULL;
ret = g_new0(virNWFilterRuleDef, 1);
@ -2389,17 +2388,18 @@ virNWFilterRuleParse(xmlNodePtr node)
(STREQ(statematch, "0") || STRCASEEQ(statematch, "false")))
ret->flags |= RULE_FLAG_NO_STATEMATCH;
nattrNodes = virXMLNodeGetSubelementList(node, NULL, &attrNodes);
attrNodes = virXMLNodeGetSubelementList(node, NULL);
if (nattrNodes > 0) {
if (attrNodes->len > 0) {
size_t i;
size_t attr = 0;
/* First we look up the type of the first valid element. The rest of
* the parsing then only considers elements with same name. */
for (i = 0; i < nattrNodes; i++) {
for (i = 0; i < attrNodes->len; i++) {
for (attr = 0; virAttr[attr].id; attr++) {
if (virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id)) {
if (virXMLNodeNameEqual(g_ptr_array_index(attrNodes, i),
virAttr[attr].id)) {
ret->prtclType = virAttr[attr].prtclType;
break;
}
@ -2411,15 +2411,17 @@ virNWFilterRuleParse(xmlNodePtr node)
}
/* parse the correct subelements now */
for (i = 0; i < nattrNodes; i++) {
for (i = 0; i < attrNodes->len; i++) {
xmlNodePtr attrNode = g_ptr_array_index(attrNodes, i);
/* no valid elements */
if (!virAttr[attr].id)
break;
if (!virXMLNodeNameEqual(attrNodes[i], virAttr[attr].id))
if (!virXMLNodeNameEqual(attrNode, virAttr[attr].id))
continue;
if (virNWFilterRuleDetailsParse(attrNodes[i], ret, virAttr[attr].att) < 0)
if (virNWFilterRuleDetailsParse(attrNode, ret, virAttr[attr].att) < 0)
return NULL;
}

View File

@ -904,33 +904,28 @@ virXMLNodeGetSubelement(xmlNodePtr node,
* virXMLNodeGetSubelementList:
* @node: node to get subelement of
* @name: name of subelement to fetch (NULL to fetch all sub-elements)
* @list: If non-NULL, filled with a list of pointers to the nodes. Caller is
* responsible for freeing the list but not the members.
*
* Find and return a sub-elements node of @node named @name in a list.
* Returns the number of subelements with @name
* Find and return a sub-elements node of @node named @name in a GPtrArray
* populated with the xmlNodePtr objects. Caller is responsible for freeing the
* array but not the contained xmlNode objects.
*/
size_t
GPtrArray *
virXMLNodeGetSubelementList(xmlNodePtr node,
const char *name,
xmlNodePtr **list)
const char *name)
{
GPtrArray *ret = g_ptr_array_new();
xmlNodePtr n;
size_t nelems = 0;
for (n = node->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE) {
if (name && !virXMLNodeNameEqual(n, name))
continue;
if (list)
VIR_APPEND_ELEMENT_COPY(*list, nelems, n);
else
nelems++;
g_ptr_array_add(ret, n);
}
}
return nelems;
return ret;
}

View File

@ -77,10 +77,9 @@ xmlNodePtr
virXMLNodeGetSubelement(xmlNodePtr node,
const char *name);
size_t
GPtrArray *
virXMLNodeGetSubelementList(xmlNodePtr node,
const char *name,
xmlNodePtr **list);
const char *name);
xmlNodePtr
virXPathNode(const char *xpath,