diff mbox

[v3,6/8] qom: object_class_property_iter_init() function

Message ID 1477499426-9550-7-git-send-email-ehabkost@redhat.com
State New
Headers show

Commit Message

Eduardo Habkost Oct. 26, 2016, 4:30 p.m. UTC
The new function will allow us to iterate over class properties
using the same logic we use for object properties. Unit test
included.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/object.h       | 14 ++++++++++++++
 qom/object.c               | 11 +++++++++--
 tests/check-qom-proplist.c | 28 ++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)

Comments

Igor Mammedov Oct. 27, 2016, 3:34 p.m. UTC | #1
On Wed, 26 Oct 2016 14:30:24 -0200
Eduardo Habkost <ehabkost@redhat.com> wrote:

> The new function will allow us to iterate over class properties
> using the same logic we use for object properties. Unit test
> included.
with current master this patch doesn't apply:

Applying: qom: object_class_property_iter_init() function
Context reduced to (2/2) to apply fragment at 1010
Context reduced to (2/2) to apply fragment at 1019
error: patch failed: qom/object.c:1017
error: qom/object.c: patch does not apply
error: patch failed: tests/check-qom-proplist.c:524
error: tests/check-qom-proplist.c: patch does not apply
Patch failed at 0001 qom: object_class_property_iter_init() function

> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  include/qom/object.h       | 14 ++++++++++++++
>  qom/object.c               | 11 +++++++++--
>  tests/check-qom-proplist.c | 28 ++++++++++++++++++++++++++++
>  3 files changed, 51 insertions(+), 2 deletions(-)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 5ecc2d1..6e3646e 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -995,6 +995,20 @@ void object_property_iter_init(ObjectPropertyIterator *iter,
>                                 Object *obj);
>  
>  /**
> + * object_class_property_iter_init:
> + * @klass: the class
> + *
> + * Initializes an iterator for traversing all properties
> + * registered against an object class and all parent classes.
> + *
> + * It is forbidden to modify the property list while iterating,
> + * whether removing or adding properties.
> + */
> +void object_class_property_iter_init(ObjectPropertyIterator *iter,
> +                                     ObjectClass *klass);
> +
> +
> +/**
>   * object_property_iter_next:
>   * @iter: the iterator instance
>   *
> diff --git a/qom/object.c b/qom/object.c
> index 7a05e35..3ae9cc7 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1010,6 +1010,14 @@ void object_property_iter_init(ObjectPropertyIterator *iter,
>      iter->nextclass = object_get_class(obj);
>  }
>  
> +
> +void object_class_property_iter_init(ObjectPropertyIterator *iter,
> +                                     ObjectClass *klass)
> +{
> +    g_hash_table_iter_init(&iter->iter, klass->properties);
> +    iter->nextclass = object_class_get_parent(klass);
> +}
> +
>  ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
>  {
>      gpointer key, val;
> @@ -1017,8 +1025,7 @@ ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
>          if (!iter->nextclass) {
>              return NULL;
>          }
> -        g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
> -        iter->nextclass = object_class_get_parent(iter->nextclass);
> +        object_class_property_iter_init(iter, iter->nextclass);
>      }
>      return val;
>  }
> diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
> index a92acc9..769549c 100644
> --- a/tests/check-qom-proplist.c
> +++ b/tests/check-qom-proplist.c
> @@ -496,6 +496,33 @@ static void test_dummy_iterator(void)
>  }
>  
>  
> +static void test_dummy_class_iterator(void)
> +{
> +    ObjectClass *klass = object_class_by_name(TYPE_DUMMY);
> +    ObjectProperty *prop;
> +    ObjectPropertyIterator iter;
> +    bool seensv = false, seenav = false, seentype;
> +
> +    object_class_property_iter_init(&iter, klass);
> +    while ((prop = object_property_iter_next(&iter))) {
> +        if (g_str_equal(prop->name, "sv")) {
> +            seensv = true;
> +        } else if (g_str_equal(prop->name, "av")) {
> +            seenav = true;
> +        } else if (g_str_equal(prop->name, "type")) {
> +            /* This prop comes from the base Object class */
> +            seentype = true;
> +        } else {
> +            g_printerr("Found prop '%s'\n", prop->name);
> +            g_assert_not_reached();
> +        }
> +    }
> +    g_assert(seenav);
> +    g_assert(seensv);
> +    g_assert(seentype);
> +}
> +
> +
>  static void test_dummy_delchild(void)
>  {
>      Object *parent = object_get_objects_root();
> @@ -524,6 +551,7 @@ int main(int argc, char **argv)
>      g_test_add_func("/qom/proplist/badenum", test_dummy_badenum);
>      g_test_add_func("/qom/proplist/getenum", test_dummy_getenum);
>      g_test_add_func("/qom/proplist/iterator", test_dummy_iterator);
> +    g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator);
>      g_test_add_func("/qom/proplist/delchild", test_dummy_delchild);
>  
>      return g_test_run();
Eduardo Habkost Oct. 27, 2016, 4:49 p.m. UTC | #2
On Thu, Oct 27, 2016 at 05:34:45PM +0200, Igor Mammedov wrote:
> On Wed, 26 Oct 2016 14:30:24 -0200
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > The new function will allow us to iterate over class properties
> > using the same logic we use for object properties. Unit test
> > included.
> with current master this patch doesn't apply:
> 
> Applying: qom: object_class_property_iter_init() function
> Context reduced to (2/2) to apply fragment at 1010
> Context reduced to (2/2) to apply fragment at 1019
> error: patch failed: qom/object.c:1017
> error: qom/object.c: patch does not apply
> error: patch failed: tests/check-qom-proplist.c:524
> error: tests/check-qom-proplist.c: patch does not apply
> Patch failed at 0001 qom: object_class_property_iter_init() function

It works here:

  $ git rev-parse HEAD
  5929d7e8a0e1f43333bc3528b50397ae8dd0fd6b
  $ grep -i 'message-id:' /tmp/apv3 
  Message-Id: <1477499426-9550-2-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-3-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-4-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-5-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-6-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-7-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-8-git-send-email-ehabkost@redhat.com>
  Message-Id: <1477499426-9550-9-git-send-email-ehabkost@redhat.com>
  $ git am /tmp/apv3
  Applying: tests: check-qom-proplist: Remove duplicate "bv" property
  Applying: tests: check-qom-proplist: Use &error_abort to catch errors
  Applying: qdev: device_class_set_props() function
  Applying: qdev: Extract property-default code to qdev_property_set_to_default()
  Applying: qdev: Register static properties as class properties
  Applying: qom: object_class_property_iter_init() function
  Applying: qmp: Support abstract classes on device-list-properties
  Applying: qdev: Warning about using object_class_property_add() in new code
  $
diff mbox

Patch

diff --git a/include/qom/object.h b/include/qom/object.h
index 5ecc2d1..6e3646e 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -995,6 +995,20 @@  void object_property_iter_init(ObjectPropertyIterator *iter,
                                Object *obj);
 
 /**
+ * object_class_property_iter_init:
+ * @klass: the class
+ *
+ * Initializes an iterator for traversing all properties
+ * registered against an object class and all parent classes.
+ *
+ * It is forbidden to modify the property list while iterating,
+ * whether removing or adding properties.
+ */
+void object_class_property_iter_init(ObjectPropertyIterator *iter,
+                                     ObjectClass *klass);
+
+
+/**
  * object_property_iter_next:
  * @iter: the iterator instance
  *
diff --git a/qom/object.c b/qom/object.c
index 7a05e35..3ae9cc7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1010,6 +1010,14 @@  void object_property_iter_init(ObjectPropertyIterator *iter,
     iter->nextclass = object_get_class(obj);
 }
 
+
+void object_class_property_iter_init(ObjectPropertyIterator *iter,
+                                     ObjectClass *klass)
+{
+    g_hash_table_iter_init(&iter->iter, klass->properties);
+    iter->nextclass = object_class_get_parent(klass);
+}
+
 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
 {
     gpointer key, val;
@@ -1017,8 +1025,7 @@  ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
         if (!iter->nextclass) {
             return NULL;
         }
-        g_hash_table_iter_init(&iter->iter, iter->nextclass->properties);
-        iter->nextclass = object_class_get_parent(iter->nextclass);
+        object_class_property_iter_init(iter, iter->nextclass);
     }
     return val;
 }
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index a92acc9..769549c 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -496,6 +496,33 @@  static void test_dummy_iterator(void)
 }
 
 
+static void test_dummy_class_iterator(void)
+{
+    ObjectClass *klass = object_class_by_name(TYPE_DUMMY);
+    ObjectProperty *prop;
+    ObjectPropertyIterator iter;
+    bool seensv = false, seenav = false, seentype;
+
+    object_class_property_iter_init(&iter, klass);
+    while ((prop = object_property_iter_next(&iter))) {
+        if (g_str_equal(prop->name, "sv")) {
+            seensv = true;
+        } else if (g_str_equal(prop->name, "av")) {
+            seenav = true;
+        } else if (g_str_equal(prop->name, "type")) {
+            /* This prop comes from the base Object class */
+            seentype = true;
+        } else {
+            g_printerr("Found prop '%s'\n", prop->name);
+            g_assert_not_reached();
+        }
+    }
+    g_assert(seenav);
+    g_assert(seensv);
+    g_assert(seentype);
+}
+
+
 static void test_dummy_delchild(void)
 {
     Object *parent = object_get_objects_root();
@@ -524,6 +551,7 @@  int main(int argc, char **argv)
     g_test_add_func("/qom/proplist/badenum", test_dummy_badenum);
     g_test_add_func("/qom/proplist/getenum", test_dummy_getenum);
     g_test_add_func("/qom/proplist/iterator", test_dummy_iterator);
+    g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator);
     g_test_add_func("/qom/proplist/delchild", test_dummy_delchild);
 
     return g_test_run();