util: XML: Introduce automatic reset of XPath's current node

Quite a few parts modify the XPath context current node to shift the
scope and allow easier queries. This also means that the node needs
to be restored afterwards.

Introduce a macro based on 'VIR_AUTOCLEAN' which adds a local structure
on the stack remembering the original node along with a function which
will make sure that the node is reset when the local structure leaves
scope.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2019-02-26 17:34:57 +01:00
parent 786f47414d
commit 23ab209272
3 changed files with 35 additions and 0 deletions

View File

@ -3247,6 +3247,7 @@ virXMLValidatorFree;
virXMLValidatorInit;
virXMLValidatorValidate;
virXPathBoolean;
virXPathContextNodeRestore;
virXPathInt;
virXPathLong;
virXPathLongHex;

View File

@ -1398,3 +1398,13 @@ virXMLFormatElement(virBufferPtr buf,
virBufferFreeAndReset(childBuf);
return ret;
}
void
virXPathContextNodeRestore(virXPathContextNodeSavePtr save)
{
if (!save->ctxt)
return;
save->ctxt->node = save->node;
}

View File

@ -219,4 +219,28 @@ virXMLFormatElement(virBufferPtr buf,
virBufferPtr attrBuf,
virBufferPtr childBuf);
struct _virXPathContextNodeSave {
xmlXPathContextPtr ctxt;
xmlNodePtr node;
};
typedef struct _virXPathContextNodeSave virXPathContextNodeSave;
typedef virXPathContextNodeSave *virXPathContextNodeSavePtr;
void
virXPathContextNodeRestore(virXPathContextNodeSavePtr save);
VIR_DEFINE_AUTOCLEAN_FUNC(virXPathContextNodeSave, virXPathContextNodeRestore);
/**
* VIR_XPATH_NODE_AUTORESTORE:
* @ctxt: XML XPath context pointer
*
* This macro ensures that when the scope where it's used ends, @ctxt's current
* node pointer is reset to the original value when this macro was used.
*/
# define VIR_XPATH_NODE_AUTORESTORE(_ctxt) \
VIR_AUTOCLEAN(virXPathContextNodeSave) _ctxt ## CtxtSave = { .ctxt = _ctxt,\
.node = _ctxt->node}; \
ignore_value(&_ctxt ## CtxtSave)
#endif /* LIBVIRT_VIRXML_H */