diff mbox

[RFC,3/4] qdev: Make DeviceClass.props a linked list

Message ID 1415901921-14372-4-git-send-email-ehabkost@redhat.com
State New
Headers show

Commit Message

Eduardo Habkost Nov. 13, 2014, 6:05 p.m. UTC
This will allow the list to be easily extended by class_init functions,
instead of requiring a static array to be defined at build time.

It will also allow subclasses to easily inherit the properties from
parent classes, instead of requiring code to walk all parent classes to
find a property.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/core/qdev-properties.c | 14 ++++++--------
 hw/core/qdev.c            | 22 +++++++++++++++++-----
 include/hw/qdev-core.h    |  3 ++-
 qdev-monitor.c            | 13 ++++++-------
 qmp.c                     |  5 +++--
 5 files changed, 34 insertions(+), 23 deletions(-)
diff mbox

Patch

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2e47f70..d506793 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -822,16 +822,14 @@  PropertyInfo qdev_prop_arraylen = {
 
 /* --- public helpers --- */
 
-static Property *qdev_prop_walk(Property *props, const char *name)
+static Property *qdev_prop_walk(GList *props, const char *name)
 {
-    if (!props) {
-        return NULL;
-    }
-    while (props->name) {
-        if (strcmp(props->name, name) == 0) {
-            return props;
+    while (props) {
+        Property *prop = props->data;
+        if (strcmp(prop->name, name) == 0) {
+            return prop;
         }
-        props++;
+        props = props->next;
     }
     return NULL;
 }
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index ca4682c..b549ae6 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -920,13 +920,14 @@  void qdev_property_add_static(DeviceState *dev, Property *prop,
 void qdev_alias_all_properties(DeviceState *target, Object *source)
 {
     ObjectClass *class;
-    Property *prop;
+    GList *props;
 
     class = object_get_class(OBJECT(target));
     do {
         DeviceClass *dc = DEVICE_CLASS(class);
 
-        for (prop = dc->props; prop && prop->name; prop++) {
+        for (props = dc->props; props; props = props->next) {
+            Property *prop = props->data;
             object_property_add_alias(source, prop->name,
                                       OBJECT(target), prop->name,
                                       &error_abort);
@@ -1083,7 +1084,6 @@  static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
     ObjectClass *class;
-    Property *prop;
 
     if (qdev_hotplug) {
         dev->hotplugged = 1;
@@ -1103,7 +1103,9 @@  static void device_initfn(Object *obj)
 
     class = object_get_class(OBJECT(dev));
     do {
-        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+        GList *props;
+        for (props = DEVICE_CLASS(class)->props; props; props = props->next) {
+            Property *prop = props->data;
             qdev_property_add_legacy(dev, prop, &error_abort);
             qdev_property_add_static(dev, prop, &error_abort);
         }
@@ -1116,9 +1118,19 @@  static void device_initfn(Object *obj)
     QLIST_INIT(&dev->gpios);
 }
 
+void device_class_add_property(DeviceClass *dc, Property *prop)
+{
+    dc->props = g_list_append(dc->props, prop);
+}
+
 void device_class_add_properties(DeviceClass *dc, Property *props)
 {
-    dc->props = props;
+    if (!props) {
+        return;
+    }
+    for (; props->name; props++) {
+        device_class_add_property(dc, props);
+    }
 }
 
 static void device_post_init(Object *obj)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 30daa3e..4c5f920 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -101,7 +101,7 @@  typedef struct DeviceClass {
     DECLARE_BITMAP(categories, DEVICE_CATEGORY_MAX);
     const char *fw_name;
     const char *desc;
-    Property *props;
+    GList *props;
 
     /*
      * Shall we hide this device model from -device / device_add?
@@ -377,6 +377,7 @@  static inline bool qbus_is_hotpluggable(BusState *bus)
    return bus->hotplug_handler;
 }
 
+void device_class_add_property(DeviceClass *dc, Property *prop);
 void device_class_add_properties(DeviceClass *dc, Property *props);
 
 #endif
diff --git a/qdev-monitor.c b/qdev-monitor.c
index ebfa701..d151dfd 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -588,19 +588,18 @@  DeviceState *qdev_device_add(QemuOpts *opts)
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
-static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
+static void qdev_print_props(Monitor *mon, DeviceState *dev, GList *props,
                              int indent)
 {
-    if (!props)
-        return;
-    for (; props->name; props++) {
+    for (; props; props = props->next) {
+        Property *prop = props->data;
         Error *err = NULL;
         char *value;
-        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+        char *legacy_name = g_strdup_printf("legacy-%s", prop->name);
         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
         } else {
-            value = object_property_print(OBJECT(dev), props->name, true, &err);
+            value = object_property_print(OBJECT(dev), prop->name, true, &err);
         }
         g_free(legacy_name);
 
@@ -608,7 +607,7 @@  static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
             error_free(err);
             continue;
         }
-        qdev_printf("%s = %s\n", props->name,
+        qdev_printf("%s = %s\n", prop->name,
                     value && *value ? value : "<null>");
         g_free(value);
     }
diff --git a/qmp.c b/qmp.c
index 0b4f131..7d91a18 100644
--- a/qmp.c
+++ b/qmp.c
@@ -446,10 +446,11 @@  static DevicePropertyInfo *make_device_property_info(ObjectClass *klass,
                                                      const char *description)
 {
     DevicePropertyInfo *info;
-    Property *prop;
 
     do {
-        for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
+        GList *props;
+        for (props = DEVICE_CLASS(klass)->props; props; props = props->next) {
+            Property *prop = props->data;
             if (strcmp(name, prop->name) != 0) {
                 continue;
             }