On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
Signed-off-by: Paolo Bonzini<pbonz...@redhat.com>

Reviewed-by: Anthony Liguori <aligu...@us.ibm.com>

Regards,

Anthony Liguori

---
  include/qemu/object.h |   25 +++++++++++++++++++++++--
  qom/object.c          |   26 ++++++++++++++++++--------
  2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index f36aff6..4ec7942 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -773,14 +773,35 @@ gchar *object_get_canonical_path(Object *obj);
   * specifying objects easy.  At each level of the composition tree, the 
partial
   * path is matched as an absolute path.  The first match is not returned.  At
   * least two matches are searched for.  A successful result is only returned 
if
- * only one match is founded.  If more than one match is found, a flag is
- * return to indicate that the match was ambiguous.
+ * only one match is found.  If more than one match is found, a flag is
+ * returned to indicate that the match was ambiguous.
   *
   * Returns: The matched object or NULL on path lookup failure.
   */
  Object *object_resolve_path(const char *path, bool *ambiguous);

  /**
+ * object_resolve_path_type:
+ * @path: the path to resolve
+ * @typename: the type to look for.
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * This is similar to object_resolve_path.  However, when looking for a
+ * partial path only matches that implement the given type are considered.
+ * This restricts the search and avoids spuriously flagging matches as
+ * ambiguous.
+ *
+ * For both partial and absolute paths, the return value goes through
+ * a dynamic cast to @typename.  This is important if either the link,
+ * or the typename itself are of interface types.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_type(const char *path, const char *typename,
+                                 bool *ambiguous);
+
+/**
   * object_property_add_child:
   * @obj: the object to add a property to
   * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index 314fc7a..ea4a1f5 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -947,17 +947,18 @@ gchar *object_get_canonical_path(Object *obj)

  static Object *object_resolve_abs_path(Object *parent,
                                            gchar **parts,
+                                          const char *typename,
                                            int index)
  {
      ObjectProperty *prop;
      Object *child;

      if (parts[index] == NULL) {
-        return parent;
+        return object_dynamic_cast(parent, typename);
      }

      if (strcmp(parts[index], "") == 0) {
-        return object_resolve_abs_path(parent, parts, index + 1);
+        return object_resolve_abs_path(parent, parts, typename, index + 1);
      }

      prop = object_property_find(parent, parts[index]);
@@ -979,17 +980,18 @@ static Object *object_resolve_abs_path(Object *parent,
          return NULL;
      }

-    return object_resolve_abs_path(child, parts, index + 1);
+    return object_resolve_abs_path(child, parts, typename, index + 1);
  }

  static Object *object_resolve_partial_path(Object *parent,
                                                gchar **parts,
+                                              const char *typename,
                                                bool *ambiguous)
  {
      Object *obj;
      ObjectProperty *prop;

-    obj = object_resolve_abs_path(parent, parts, 0);
+    obj = object_resolve_abs_path(parent, parts, typename, 0);

      QTAILQ_FOREACH(prop,&parent->properties, node) {
          Object *found;
@@ -998,7 +1000,8 @@ static Object *object_resolve_partial_path(Object *parent,
              continue;
          }

-        found = object_resolve_partial_path(prop->opaque, parts, ambiguous);
+        found = object_resolve_partial_path(prop->opaque, parts,
+                                            typename, ambiguous);
          if (found) {
              if (obj) {
                  if (ambiguous) {
@@ -1017,7 +1020,8 @@ static Object *object_resolve_partial_path(Object *parent,
      return obj;
  }

-Object *object_resolve_path(const char *path, bool *ambiguous)
+Object *object_resolve_path_type(const char *path, const char *typename,
+                                 bool *ambiguous)
  {
      bool partial_path = true;
      Object *obj;
@@ -1037,9 +1041,10 @@ Object *object_resolve_path(const char *path, bool 
*ambiguous)
          if (ambiguous) {
              *ambiguous = false;
          }
-        obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
+        obj = object_resolve_partial_path(object_get_root(), parts,
+                                          typename, ambiguous);
      } else {
-        obj = object_resolve_abs_path(object_get_root(), parts, 1);
+        obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
      }

      g_strfreev(parts);
@@ -1047,6 +1052,11 @@ Object *object_resolve_path(const char *path, bool 
*ambiguous)
      return obj;
  }

+Object *object_resolve_path(const char *path, bool *ambiguous)
+{
+    return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
+}
+
  typedef struct StringProperty
  {
      char *(*get)(Object *, Error **);


Reply via email to