qom: Add recursive version of object_child_for_each
Useful for iterating through an entire QOM subtree. Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Message-id: 1441383782-24378-2-git-send-email-peter.maydell@linaro.org
This commit is contained in:
parent
d5523a1365
commit
d714b8de77
@ -1493,6 +1493,21 @@ void object_property_set_description(Object *obj, const char *name,
|
||||
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* object_child_foreach_recursive:
|
||||
* @obj: the object whose children will be navigated
|
||||
* @fn: the iterator function to be called
|
||||
* @opaque: an opaque value that will be passed to the iterator
|
||||
*
|
||||
* Call @fn passing each child of @obj and @opaque to it, until @fn returns
|
||||
* non-zero. Calls recursively, all child nodes of @obj will also be passed
|
||||
* all the way down to the leaf nodes of the tree. Depth first ordering.
|
||||
*
|
||||
* Returns: The last value returned by @fn, or 0 if there is no child.
|
||||
*/
|
||||
int object_child_foreach_recursive(Object *obj,
|
||||
int (*fn)(Object *child, void *opaque),
|
||||
void *opaque);
|
||||
/**
|
||||
* container_get:
|
||||
* @root: root of the #path, e.g., object_get_root()
|
||||
|
25
qom/object.c
25
qom/object.c
@ -775,23 +775,42 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
|
||||
enumerating_types = false;
|
||||
}
|
||||
|
||||
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
|
||||
void *opaque)
|
||||
static int do_object_child_foreach(Object *obj,
|
||||
int (*fn)(Object *child, void *opaque),
|
||||
void *opaque, bool recurse)
|
||||
{
|
||||
ObjectProperty *prop, *next;
|
||||
int ret = 0;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(prop, &obj->properties, node, next) {
|
||||
if (object_property_is_child(prop)) {
|
||||
ret = fn(prop->opaque, opaque);
|
||||
Object *child = prop->opaque;
|
||||
|
||||
ret = fn(child, opaque);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
if (recurse) {
|
||||
do_object_child_foreach(child, fn, opaque, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
|
||||
void *opaque)
|
||||
{
|
||||
return do_object_child_foreach(obj, fn, opaque, false);
|
||||
}
|
||||
|
||||
int object_child_foreach_recursive(Object *obj,
|
||||
int (*fn)(Object *child, void *opaque),
|
||||
void *opaque)
|
||||
{
|
||||
return do_object_child_foreach(obj, fn, opaque, true);
|
||||
}
|
||||
|
||||
static void object_class_get_list_tramp(ObjectClass *klass, void *opaque)
|
||||
{
|
||||
GSList **list = opaque;
|
||||
|
Loading…
Reference in New Issue
Block a user