[libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node

Peter Krempa posted 5 patches 6 years, 11 months ago
[libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Peter Krempa 6 years, 11 months ago
Quite a few parts modify the XPath context current node to shif 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>
---
 src/libvirt_private.syms |  1 +
 src/util/virxml.c        | 10 ++++++++++
 src/util/virxml.h        | 22 ++++++++++++++++++++++
 3 files changed, 33 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 038a744981..ee5d9957b0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3246,6 +3246,7 @@ virXMLValidatorFree;
 virXMLValidatorInit;
 virXMLValidatorValidate;
 virXPathBoolean;
+virXPathContextNodeRestore;
 virXPathInt;
 virXPathLong;
 virXPathLongHex;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 8eb201fddf..f55b9a362c 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1398,3 +1398,13 @@ virXMLFormatElement(virBufferPtr buf,
     virBufferFreeAndReset(childBuf);
     return ret;
 }
+
+
+void
+virXPathContextNodeRestore(virXPathContextNodeSavePtr save)
+{
+    if (!save->ctxt)
+        return;
+
+    save->ctxt->node = save->node;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 23a4da1b7e..1bd2c0e518 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -219,4 +219,26 @@ 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}
+
 #endif /* LIBVIRT_VIRXML_H */
-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Ján Tomko 6 years, 11 months ago
On Tue, Feb 26, 2019 at 06:08:11PM +0100, Peter Krempa wrote:
>Quite a few parts modify the XPath context current node to shif the

shift

>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>
>---
> src/libvirt_private.syms |  1 +
> src/util/virxml.c        | 10 ++++++++++
> src/util/virxml.h        | 22 ++++++++++++++++++++++
> 3 files changed, 33 insertions(+)
>

Reviewed-by: Ján Tomko <jtomko@redhat.com>

Jano
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Peter Krempa 6 years, 11 months ago
On Tue, Feb 26, 2019 at 18:08:11 +0100, Peter Krempa wrote:
> Quite a few parts modify the XPath context current node to shif 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>
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virxml.c        | 10 ++++++++++
>  src/util/virxml.h        | 22 ++++++++++++++++++++++
>  3 files changed, 33 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 038a744981..ee5d9957b0 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -3246,6 +3246,7 @@ virXMLValidatorFree;
>  virXMLValidatorInit;
>  virXMLValidatorValidate;
>  virXPathBoolean;
> +virXPathContextNodeRestore;
>  virXPathInt;
>  virXPathLong;
>  virXPathLongHex;
> diff --git a/src/util/virxml.c b/src/util/virxml.c
> index 8eb201fddf..f55b9a362c 100644
> --- a/src/util/virxml.c
> +++ b/src/util/virxml.c
> @@ -1398,3 +1398,13 @@ virXMLFormatElement(virBufferPtr buf,
>      virBufferFreeAndReset(childBuf);
>      return ret;
>  }
> +
> +
> +void
> +virXPathContextNodeRestore(virXPathContextNodeSavePtr save)
> +{
> +    if (!save->ctxt)
> +        return;
> +
> +    save->ctxt->node = save->node;
> +}
> diff --git a/src/util/virxml.h b/src/util/virxml.h
> index 23a4da1b7e..1bd2c0e518 100644
> --- a/src/util/virxml.h
> +++ b/src/util/virxml.h
> @@ -219,4 +219,26 @@ 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}

Oops, forgot to commit some local changes:

diff --git a/src/util/virxml.h b/src/util/virxml.h
index 1bd2c0e518..72b9d749d0 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -239,6 +239,7 @@ VIR_DEFINE_AUTOCLEAN_FUNC(virXPathContextNodeSave, virXPathContextNodeRestore);
  * 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}
+    VIR_AUTOCLEAN(virXPathContextNodeSave) ctxt##CtxtSave = {ctxt, ctxt->node}; \
+    ignore_value(&ctxt##CtxtSave)

 #endif /* LIBVIRT_VIRXML_H */


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Eric Blake 6 years, 11 months ago
On 2/26/19 11:08 AM, Peter Krempa wrote:
> Quite a few parts modify the XPath context current node to shif the

shift

> 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>
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virxml.c        | 10 ++++++++++
>  src/util/virxml.h        | 22 ++++++++++++++++++++++
>  3 files changed, 33 insertions(+)

Nice idea.


> +/**
> + * VIR_XPATH_NODE_AUTORESTORE:
> + * @ctxt: XML XPath context pointer
> + *
> + * This macro ensures that when the scope where it's used ends @ctxt's current

Reads better with s/ends/ends,/

> + * 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}

Worth using C99 syntax as in { .ctxt = (ctxt), .node = (ctxt)->node, } ?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Peter Krempa 6 years, 11 months ago
On Tue, Feb 26, 2019 at 11:29:33 -0600, Eric Blake wrote:
> On 2/26/19 11:08 AM, Peter Krempa wrote:
> > Quite a few parts modify the XPath context current node to shif the
> 
> shift
> 
> > 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>
> > ---
> >  src/libvirt_private.syms |  1 +
> >  src/util/virxml.c        | 10 ++++++++++
> >  src/util/virxml.h        | 22 ++++++++++++++++++++++
> >  3 files changed, 33 insertions(+)
> 
> Nice idea.
> 
> 
> > +/**
> > + * VIR_XPATH_NODE_AUTORESTORE:
> > + * @ctxt: XML XPath context pointer
> > + *
> > + * This macro ensures that when the scope where it's used ends @ctxt's current
> 
> Reads better with s/ends/ends,/
> 
> > + * 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}
> 
> Worth using C99 syntax as in { .ctxt = (ctxt), .node = (ctxt)->node, } ?

It would require renaming the argument of the macro as it would be
replaced otherwise. Interrestingly in most cases it would actually work
as in most cases the macro is used with 'ctxt'.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node
Posted by Eric Blake 6 years, 11 months ago
On 2/27/19 3:27 AM, Peter Krempa wrote:

>>> + * 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}
>>
>> Worth using C99 syntax as in { .ctxt = (ctxt), .node = (ctxt)->node, } ?
> 
> It would require renaming the argument of the macro as it would be
> replaced otherwise. Interrestingly in most cases it would actually work
> as in most cases the macro is used with 'ctxt'.

And hence why it's a good idea to use macro parameter names which can't
conflict with normal cods, such as:

#define VIR_XPATH_NODE_AUTORESTORE(_ctxt) \
    VIR_AUTOCLEAN(virXPathContextNodeSave) _ctxt##CtxtSave = { \
        .ctxt = (_ctxt), .node = (_ctxt)->node, }

But I'll leave it up to you to decide whether it makes sense to worry
about C99 initializers.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list