#include "qapi/visitor.h"
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
+#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-builtin-visit.h"
#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qjson.h"
#include "trace.h"
/* TODO: replace QObject with a simpler visitor to avoid a dependency
{
if (!type->parent_type && type->parent) {
type->parent_type = type_get_by_name(type->parent);
- g_assert(type->parent_type != NULL);
+ if (!type->parent_type) {
+ fprintf(stderr, "Type '%s' is missing its parent '%s'\n",
+ type->name, type->parent);
+ abort();
+ }
}
return type->parent_type;
new_iface->concrete_class = ti->class;
new_iface->interface_type = interface_type;
- ti->class->interfaces = g_slist_append(ti->class->interfaces,
- iface_impl->class);
+ ti->class->interfaces = g_slist_append(ti->class->interfaces, new_iface);
}
static void object_property_free(gpointer data)
{
ObjectProperty *prop = data;
+ if (prop->defval) {
+ qobject_unref(prop->defval);
+ prop->defval = NULL;
+ }
g_free(prop->name);
g_free(prop->type);
g_free(prop->description);
int i;
g_assert(parent->class_size <= ti->class_size);
+ g_assert(parent->instance_size <= ti->instance_size);
memcpy(ti->class, parent->class, parent->class_size);
ti->class->interfaces = NULL;
- ti->class->properties = g_hash_table_new_full(
- g_str_hash, g_str_equal, g_free, object_property_free);
for (e = parent->class->interfaces; e; e = e->next) {
InterfaceClass *iface = e->data;
for (i = 0; i < ti->num_interfaces; i++) {
TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
+ if (!t) {
+ error_report("missing interface '%s' for object '%s'",
+ ti->interfaces[i].typename, parent->name);
+ abort();
+ }
for (e = ti->class->interfaces; e; e = e->next) {
TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
type_initialize_interface(ti, t, t);
}
- } else {
- ti->class->properties = g_hash_table_new_full(
- g_str_hash, g_str_equal, g_free, object_property_free);
}
+ ti->class->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ object_property_free);
+
ti->class->type = ti;
while (parent) {
}
}
-void object_apply_global_props(Object *obj, const GPtrArray *props, Error **errp)
+bool object_apply_global_props(Object *obj, const GPtrArray *props,
+ Error **errp)
{
int i;
if (!props) {
- return;
+ return true;
}
for (i = 0; i < props->len; i++) {
continue;
}
p->used = true;
- object_property_parse(obj, p->value, p->property, &err);
- if (err != NULL) {
+ if (!object_property_parse(obj, p->property, p->value, &err)) {
error_prepend(&err, "can't apply global %s.%s=%s: ",
p->driver, p->property, p->value);
/*
*/
if (errp) {
error_propagate(errp, err);
- return;
+ return false;
} else {
warn_report_err(err);
}
}
}
+
+ return true;
}
/*
* Global property defaults
* Slot 0: accelerator's global property defaults
* Slot 1: machine's global property defaults
+ * Slot 2: global properties from legacy command line option
* Each is a GPtrArray of of GlobalProperty.
* Applied in order, later entries override earlier ones.
*/
-static GPtrArray *object_compat_props[2];
+static GPtrArray *object_compat_props[3];
+
+/*
+ * Retrieve @GPtrArray for global property defined with options
+ * other than "-global". These are generally used for syntactic
+ * sugar and legacy command line options.
+ */
+void object_register_sugar_prop(const char *driver, const char *prop, const char *value)
+{
+ GlobalProperty *g;
+ if (!object_compat_props[2]) {
+ object_compat_props[2] = g_ptr_array_new();
+ }
+ g = g_new0(GlobalProperty, 1);
+ g->driver = g_strdup(driver);
+ g->property = g_strdup(prop);
+ g->value = g_strdup(value);
+ g_ptr_array_add(object_compat_props[2], g);
+}
/*
* Set machine's global property defaults to @compat_props.
for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) {
object_apply_global_props(obj, object_compat_props[i],
- &error_abort);
+ i == 2 ? &error_fatal : &error_abort);
}
}
-static void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
+static void object_class_property_init_all(Object *obj)
{
- Object *obj = data;
+ ObjectPropertyIterator iter;
+ ObjectProperty *prop;
+
+ object_class_property_iter_init(&iter, object_get_class(obj));
+ while ((prop = object_property_iter_next(&iter))) {
+ if (prop->init) {
+ prop->init(obj, prop);
+ }
+ }
+}
+static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
+{
type_initialize(type);
g_assert(type->instance_size >= sizeof(Object));
memset(obj, 0, type->instance_size);
obj->class = type->class;
object_ref(obj);
+ object_class_property_init_all(obj);
obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, object_property_free);
object_init_with_type(obj, type);
object_initialize_with_type(data, size, type);
}
-void object_initialize_child(Object *parentobj, const char *propname,
- void *childobj, size_t size, const char *type,
- Error **errp, ...)
+bool object_initialize_child_with_props(Object *parentobj,
+ const char *propname,
+ void *childobj, size_t size,
+ const char *type,
+ Error **errp, ...)
{
va_list vargs;
+ bool ok;
va_start(vargs, errp);
- object_initialize_childv(parentobj, propname, childobj, size, type, errp,
- vargs);
+ ok = object_initialize_child_with_propsv(parentobj, propname,
+ childobj, size, type, errp,
+ vargs);
va_end(vargs);
+ return ok;
}
-void object_initialize_childv(Object *parentobj, const char *propname,
- void *childobj, size_t size, const char *type,
- Error **errp, va_list vargs)
+bool object_initialize_child_with_propsv(Object *parentobj,
+ const char *propname,
+ void *childobj, size_t size,
+ const char *type,
+ Error **errp, va_list vargs)
{
Error *local_err = NULL;
+ bool ok = false;
Object *obj;
UserCreatable *uc;
object_initialize(childobj, size, type);
obj = OBJECT(childobj);
- object_set_propv(obj, &local_err, vargs);
- if (local_err) {
+ if (!object_set_propv(obj, errp, vargs)) {
goto out;
}
- object_property_add_child(parentobj, propname, obj, &local_err);
- if (local_err) {
- goto out;
- }
+ object_property_add_child(parentobj, propname, obj);
uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
if (uc) {
- user_creatable_complete(uc, &local_err);
- if (local_err) {
+ if (!user_creatable_complete(uc, &local_err)) {
object_unparent(obj);
goto out;
}
}
+ ok = true;
+
+out:
/*
- * Since object_property_add_child added a reference to the child object,
- * we can drop the reference added by object_initialize(), so the child
- * property will own the only reference to the object.
+ * We want @obj's reference to be 1 on success, 0 on failure.
+ * On success, it's 2: one taken by object_initialize(), and one
+ * by object_property_add_child().
+ * On failure in object_initialize() or earlier, it's 1.
+ * On failure afterwards, it's also 1: object_unparent() releases
+ * the reference taken by object_property_add_child().
*/
object_unref(obj);
-out:
- if (local_err) {
- error_propagate(errp, local_err);
- object_unref(obj);
- }
+ error_propagate(errp, local_err);
+ return ok;
+}
+
+void object_initialize_child_internal(Object *parent,
+ const char *propname,
+ void *child, size_t size,
+ const char *type)
+{
+ object_initialize_child_with_props(parent, propname, child, size, type,
+ &error_abort, NULL);
}
static inline bool object_property_is_child(ObjectProperty *prop)
static void object_property_del_all(Object *obj)
{
+ g_autoptr(GHashTable) done = g_hash_table_new(NULL, NULL);
ObjectProperty *prop;
- GHashTableIter iter;
- gpointer key, value;
+ ObjectPropertyIterator iter;
bool released;
do {
released = false;
- g_hash_table_iter_init(&iter, obj->properties);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- prop = value;
- if (prop->release) {
- prop->release(obj, prop->name, prop->opaque);
- prop->release = NULL;
- released = true;
- break;
+ object_property_iter_init(&iter, obj);
+ while ((prop = object_property_iter_next(&iter)) != NULL) {
+ if (g_hash_table_add(done, prop)) {
+ if (prop->release) {
+ prop->release(obj, prop->name, prop->opaque);
+ released = true;
+ break;
+ }
}
- g_hash_table_iter_remove(&iter);
}
} while (released);
g_hash_table_unref(obj->properties);
}
-static void object_property_del_child(Object *obj, Object *child, Error **errp)
+static void object_property_del_child(Object *obj, Object *child)
{
ObjectProperty *prop;
GHashTableIter iter;
void object_unparent(Object *obj)
{
if (obj->parent) {
- object_property_del_child(obj->parent, obj, NULL);
+ object_property_del_child(obj->parent, obj);
}
}
return obj;
}
+Object *object_new_with_class(ObjectClass *klass)
+{
+ return object_new_with_type(klass->type);
+}
+
Object *object_new(const char *typename)
{
TypeImpl *ti = type_get_by_name(typename);
}
obj = object_new_with_type(klass->type);
- if (object_set_propv(obj, &local_err, vargs) < 0) {
+ if (!object_set_propv(obj, errp, vargs)) {
goto error;
}
if (id != NULL) {
- object_property_add_child(parent, id, obj, &local_err);
- if (local_err) {
- goto error;
- }
+ object_property_add_child(parent, id, obj);
}
uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
if (uc) {
- user_creatable_complete(uc, &local_err);
- if (local_err) {
+ if (!user_creatable_complete(uc, &local_err)) {
if (id != NULL) {
object_unparent(obj);
}
}
}
- object_unref(OBJECT(obj));
+ object_unref(obj);
return obj;
error:
}
-int object_set_props(Object *obj,
+bool object_set_props(Object *obj,
Error **errp,
...)
{
va_list vargs;
- int ret;
+ bool ret;
va_start(vargs, errp);
ret = object_set_propv(obj, errp, vargs);
}
-int object_set_propv(Object *obj,
+bool object_set_propv(Object *obj,
Error **errp,
va_list vargs)
{
const char *propname;
- Error *local_err = NULL;
propname = va_arg(vargs, char *);
while (propname != NULL) {
const char *value = va_arg(vargs, char *);
g_assert(value != NULL);
- object_property_parse(obj, value, propname, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return -1;
+ if (!object_property_parse(obj, propname, value, errp)) {
+ return false;
}
propname = va_arg(vargs, char *);
}
- return 0;
+ return true;
}
return type->class;
}
+ObjectClass *module_object_class_by_name(const char *typename)
+{
+ ObjectClass *oc;
+
+ oc = object_class_by_name(typename);
+#ifdef CONFIG_MODULES
+ if (!oc) {
+ module_load_qom_one(typename);
+ oc = object_class_by_name(typename);
+ }
+#endif
+ return oc;
+}
+
ObjectClass *object_class_get_parent(ObjectClass *class)
{
TypeImpl *type = type_get_parent(class->type);
break;
}
if (recurse) {
- do_object_child_foreach(child, fn, opaque, true);
+ ret = do_object_child_foreach(child, fn, opaque, true);
+ if (ret != 0) {
+ break;
+ }
}
}
}
object_class_cmp);
}
-void object_ref(Object *obj)
+Object *object_ref(Object *obj)
{
if (!obj) {
- return;
+ return NULL;
}
atomic_inc(&obj->ref);
+ return obj;
}
void object_unref(Object *obj)
}
}
-ObjectProperty *
-object_property_add(Object *obj, const char *name, const char *type,
- ObjectPropertyAccessor *get,
- ObjectPropertyAccessor *set,
- ObjectPropertyRelease *release,
- void *opaque, Error **errp)
+static ObjectProperty *
+object_property_try_add(Object *obj, const char *name, const char *type,
+ ObjectPropertyAccessor *get,
+ ObjectPropertyAccessor *set,
+ ObjectPropertyRelease *release,
+ void *opaque, Error **errp)
{
ObjectProperty *prop;
size_t name_len = strlen(name);
for (i = 0; ; ++i) {
char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
- ret = object_property_add(obj, full_name, type, get, set,
- release, opaque, NULL);
+ ret = object_property_try_add(obj, full_name, type, get, set,
+ release, opaque, NULL);
g_free(full_name);
if (ret) {
break;
}
if (object_property_find(obj, name, NULL) != NULL) {
- error_setg(errp, "attempt to add duplicate property '%s'"
- " to object (type '%s')", name,
- object_get_typename(obj));
+ error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
+ name, object_get_typename(obj));
return NULL;
}
return prop;
}
+ObjectProperty *
+object_property_add(Object *obj, const char *name, const char *type,
+ ObjectPropertyAccessor *get,
+ ObjectPropertyAccessor *set,
+ ObjectPropertyRelease *release,
+ void *opaque)
+{
+ return object_property_try_add(obj, name, type, get, set, release,
+ opaque, &error_abort);
+}
+
ObjectProperty *
object_class_property_add(ObjectClass *klass,
const char *name,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque,
- Error **errp)
+ void *opaque)
{
ObjectProperty *prop;
- if (object_class_property_find(klass, name, NULL) != NULL) {
- error_setg(errp, "attempt to add duplicate property '%s'"
- " to object (type '%s')", name,
- object_class_get_name(klass));
- return NULL;
- }
+ assert(!object_class_property_find(klass, name, NULL));
prop = g_malloc0(sizeof(*prop));
prop->release = release;
prop->opaque = opaque;
- g_hash_table_insert(klass->properties, g_strdup(name), prop);
+ g_hash_table_insert(klass->properties, prop->name, prop);
return prop;
}
return prop;
}
-void object_property_del(Object *obj, const char *name, Error **errp)
+void object_property_del(Object *obj, const char *name)
{
ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
- if (!prop) {
- error_setg(errp, "Property '.%s' not found", name);
- return;
- }
-
if (prop->release) {
prop->release(obj, name, prop->opaque);
}
g_hash_table_remove(obj->properties, name);
}
-void object_property_get(Object *obj, Visitor *v, const char *name,
+bool object_property_get(Object *obj, const char *name, Visitor *v,
Error **errp)
{
+ Error *err = NULL;
ObjectProperty *prop = object_property_find(obj, name, errp);
+
if (prop == NULL) {
- return;
+ return false;
}
if (!prop->get) {
error_setg(errp, QERR_PERMISSION_DENIED);
- } else {
- prop->get(obj, v, name, prop->opaque, errp);
+ return false;
}
+ prop->get(obj, v, name, prop->opaque, &err);
+ error_propagate(errp, err);
+ return !err;
}
-void object_property_set(Object *obj, Visitor *v, const char *name,
+bool object_property_set(Object *obj, const char *name, Visitor *v,
Error **errp)
{
+ Error *err = NULL;
ObjectProperty *prop = object_property_find(obj, name, errp);
+
if (prop == NULL) {
- return;
+ return false;
}
if (!prop->set) {
error_setg(errp, QERR_PERMISSION_DENIED);
- } else {
- prop->set(obj, v, name, prop->opaque, errp);
+ return false;
}
+ prop->set(obj, v, name, prop->opaque, &err);
+ error_propagate(errp, err);
+ return !err;
}
-void object_property_set_str(Object *obj, const char *value,
- const char *name, Error **errp)
+bool object_property_set_str(Object *obj, const char *name,
+ const char *value, Error **errp)
{
QString *qstr = qstring_from_str(value);
- object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
+ bool ok = object_property_set_qobject(obj, name, QOBJECT(qstr), errp);
qobject_unref(qstr);
+ return ok;
}
char *object_property_get_str(Object *obj, const char *name,
return retval;
}
-void object_property_set_link(Object *obj, Object *value,
- const char *name, Error **errp)
+bool object_property_set_link(Object *obj, const char *name,
+ Object *value, Error **errp)
{
+ g_autofree char *path = NULL;
+
if (value) {
- gchar *path = object_get_canonical_path(value);
- object_property_set_str(obj, path, name, errp);
- g_free(path);
- } else {
- object_property_set_str(obj, "", name, errp);
+ path = object_get_canonical_path(value);
}
+ return object_property_set_str(obj, name, path ?: "", errp);
}
Object *object_property_get_link(Object *obj, const char *name,
return target;
}
-void object_property_set_bool(Object *obj, bool value,
- const char *name, Error **errp)
+bool object_property_set_bool(Object *obj, const char *name,
+ bool value, Error **errp)
{
QBool *qbool = qbool_from_bool(value);
- object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
+ bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp);
qobject_unref(qbool);
+ return ok;
}
bool object_property_get_bool(Object *obj, const char *name,
return retval;
}
-void object_property_set_int(Object *obj, int64_t value,
- const char *name, Error **errp)
+bool object_property_set_int(Object *obj, const char *name,
+ int64_t value, Error **errp)
{
QNum *qnum = qnum_from_int(value);
- object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
+ bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
qobject_unref(qnum);
+ return ok;
}
int64_t object_property_get_int(Object *obj, const char *name,
return retval;
}
-void object_property_set_uint(Object *obj, uint64_t value,
- const char *name, Error **errp)
+static void object_property_init_defval(Object *obj, ObjectProperty *prop)
+{
+ Visitor *v = qobject_input_visitor_new(prop->defval);
+
+ assert(prop->set != NULL);
+ prop->set(obj, v, prop->name, prop->opaque, &error_abort);
+
+ visit_free(v);
+}
+
+static void object_property_set_default(ObjectProperty *prop, QObject *defval)
+{
+ assert(!prop->defval);
+ assert(!prop->init);
+
+ prop->defval = defval;
+ prop->init = object_property_init_defval;
+}
+
+void object_property_set_default_bool(ObjectProperty *prop, bool value)
+{
+ object_property_set_default(prop, QOBJECT(qbool_from_bool(value)));
+}
+
+void object_property_set_default_str(ObjectProperty *prop, const char *value)
+{
+ object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
+}
+
+void object_property_set_default_int(ObjectProperty *prop, int64_t value)
+{
+ object_property_set_default(prop, QOBJECT(qnum_from_int(value)));
+}
+
+void object_property_set_default_uint(ObjectProperty *prop, uint64_t value)
+{
+ object_property_set_default(prop, QOBJECT(qnum_from_uint(value)));
+}
+
+bool object_property_set_uint(Object *obj, const char *name,
+ uint64_t value, Error **errp)
{
QNum *qnum = qnum_from_uint(value);
+ bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp);
- object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
qobject_unref(qnum);
+ return ok;
}
uint64_t object_property_get_uint(Object *obj, const char *name,
int object_property_get_enum(Object *obj, const char *name,
const char *typename, Error **errp)
{
- Error *err = NULL;
- Visitor *v;
char *str;
int ret;
ObjectProperty *prop = object_property_find(obj, name, errp);
enumprop = prop->opaque;
- v = string_output_visitor_new(false, &str);
- object_property_get(obj, v, name, &err);
- if (err) {
- error_propagate(errp, err);
- visit_free(v);
+ str = object_property_get_str(obj, name, errp);
+ if (!str) {
return 0;
}
- visit_complete(v, &str);
- visit_free(v);
- v = string_input_visitor_new(str);
- visit_type_enum(v, name, &ret, enumprop->lookup, errp);
+ ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
g_free(str);
- visit_free(v);
return ret;
}
-void object_property_get_uint16List(Object *obj, const char *name,
- uint16List **list, Error **errp)
-{
- Error *err = NULL;
- Visitor *v;
- char *str;
-
- v = string_output_visitor_new(false, &str);
- object_property_get(obj, v, name, &err);
- if (err) {
- error_propagate(errp, err);
- goto out;
- }
- visit_complete(v, &str);
- visit_free(v);
- v = string_input_visitor_new(str);
- visit_type_uint16List(v, NULL, list, errp);
-
- g_free(str);
-out:
- visit_free(v);
-}
-
-void object_property_parse(Object *obj, const char *string,
- const char *name, Error **errp)
+bool object_property_parse(Object *obj, const char *name,
+ const char *string, Error **errp)
{
Visitor *v = string_input_visitor_new(string);
- object_property_set(obj, v, name, errp);
+ bool ok = object_property_set(obj, name, v, errp);
+
visit_free(v);
+ return ok;
}
char *object_property_print(Object *obj, const char *name, bool human,
Error *local_err = NULL;
v = string_output_visitor_new(human, &string);
- object_property_get(obj, v, name, &local_err);
- if (local_err) {
+ if (!object_property_get(obj, name, v, &local_err)) {
error_propagate(errp, local_err);
goto out;
}
Error **errp)
{
Object *child = opaque;
- gchar *path;
+ char *path;
path = object_get_canonical_path(child);
visit_type_str(v, name, &path, errp);
g_free(path);
}
-static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part)
+static Object *object_resolve_child_property(Object *parent, void *opaque,
+ const char *part)
{
return opaque;
}
object_unref(child);
}
-void object_property_add_child(Object *obj, const char *name,
- Object *child, Error **errp)
+ObjectProperty *
+object_property_add_child(Object *obj, const char *name,
+ Object *child)
{
- Error *local_err = NULL;
- gchar *type;
+ g_autofree char *type = NULL;
ObjectProperty *op;
- if (child->parent != NULL) {
- error_setg(errp, "child object is already parented");
- return;
- }
+ assert(!child->parent);
- type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
+ type = g_strdup_printf("child<%s>", object_get_typename(child));
op = object_property_add(obj, name, type, object_get_child_property, NULL,
- object_finalize_child_property, child, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
- }
-
+ object_finalize_child_property, child);
op->resolve = object_resolve_child_property;
object_ref(child);
child->parent = obj;
-
-out:
- g_free(type);
+ return op;
}
void object_property_allow_set_link(const Object *obj, const char *name,
}
typedef struct {
- Object **child;
+ union {
+ Object **targetp;
+ Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer */
+ ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */
+ };
void (*check)(const Object *, const char *, Object *, Error **);
ObjectPropertyLinkFlags flags;
} LinkProperty;
+static Object **
+object_link_get_targetp(Object *obj, LinkProperty *lprop)
+{
+ if (lprop->flags & OBJ_PROP_LINK_DIRECT) {
+ return &lprop->target;
+ } else if (lprop->flags & OBJ_PROP_LINK_CLASS) {
+ return (void *)obj + lprop->offset;
+ } else {
+ return lprop->targetp;
+ }
+}
+
static void object_get_link_property(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
LinkProperty *lprop = opaque;
- Object **child = lprop->child;
- gchar *path;
+ Object **targetp = object_link_get_targetp(obj, lprop);
+ char *path;
- if (*child) {
- path = object_get_canonical_path(*child);
+ if (*targetp) {
+ path = object_get_canonical_path(*targetp);
visit_type_str(v, name, &path, errp);
g_free(path);
} else {
- path = (gchar *)"";
+ path = (char *)"";
visit_type_str(v, name, &path, errp);
}
}
const char *path, Error **errp)
{
const char *type;
- gchar *target_type;
+ char *target_type;
bool ambiguous = false;
Object *target;
{
Error *local_err = NULL;
LinkProperty *prop = opaque;
- Object **child = prop->child;
- Object *old_target = *child;
- Object *new_target = NULL;
+ Object **targetp = object_link_get_targetp(obj, prop);
+ Object *old_target = *targetp;
+ Object *new_target;
char *path = NULL;
- visit_type_str(v, name, &path, &local_err);
+ if (!visit_type_str(v, name, &path, errp)) {
+ return;
+ }
- if (!local_err && strcmp(path, "") != 0) {
- new_target = object_resolve_link(obj, name, path, &local_err);
+ if (*path) {
+ new_target = object_resolve_link(obj, name, path, errp);
+ if (!new_target) {
+ g_free(path);
+ return;
+ }
+ } else {
+ new_target = NULL;
}
g_free(path);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
prop->check(obj, name, new_target, &local_err);
if (local_err) {
return;
}
- *child = new_target;
- if (prop->flags == OBJ_PROP_LINK_STRONG) {
+ *targetp = new_target;
+ if (prop->flags & OBJ_PROP_LINK_STRONG) {
object_ref(new_target);
object_unref(old_target);
}
}
-static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part)
+static Object *object_resolve_link_property(Object *parent, void *opaque,
+ const char *part)
{
LinkProperty *lprop = opaque;
- return *lprop->child;
+ return *object_link_get_targetp(parent, lprop);
}
static void object_release_link_property(Object *obj, const char *name,
void *opaque)
{
LinkProperty *prop = opaque;
+ Object **targetp = object_link_get_targetp(obj, prop);
- if ((prop->flags & OBJ_PROP_LINK_STRONG) && *prop->child) {
- object_unref(*prop->child);
+ if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) {
+ object_unref(*targetp);
+ }
+ if (!(prop->flags & OBJ_PROP_LINK_CLASS)) {
+ g_free(prop);
}
- g_free(prop);
}
-void object_property_add_link(Object *obj, const char *name,
- const char *type, Object **child,
- void (*check)(const Object *, const char *,
- Object *, Error **),
- ObjectPropertyLinkFlags flags,
- Error **errp)
+static ObjectProperty *
+object_add_link_prop(Object *obj, const char *name,
+ const char *type, void *ptr,
+ void (*check)(const Object *, const char *,
+ Object *, Error **),
+ ObjectPropertyLinkFlags flags)
{
- Error *local_err = NULL;
LinkProperty *prop = g_malloc(sizeof(*prop));
- gchar *full_type;
+ g_autofree char *full_type = NULL;
ObjectProperty *op;
- prop->child = child;
+ if (flags & OBJ_PROP_LINK_DIRECT) {
+ prop->target = ptr;
+ } else {
+ prop->targetp = ptr;
+ }
prop->check = check;
prop->flags = flags;
object_get_link_property,
check ? object_set_link_property : NULL,
object_release_link_property,
- prop,
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- goto out;
- }
+ prop);
+ op->resolve = object_resolve_link_property;
+ return op;
+}
+
+ObjectProperty *
+object_property_add_link(Object *obj, const char *name,
+ const char *type, Object **targetp,
+ void (*check)(const Object *, const char *,
+ Object *, Error **),
+ ObjectPropertyLinkFlags flags)
+{
+ return object_add_link_prop(obj, name, type, targetp, check, flags);
+}
+
+ObjectProperty *
+object_class_property_add_link(ObjectClass *oc,
+ const char *name,
+ const char *type, ptrdiff_t offset,
+ void (*check)(const Object *obj, const char *name,
+ Object *val, Error **errp),
+ ObjectPropertyLinkFlags flags)
+{
+ LinkProperty *prop = g_new0(LinkProperty, 1);
+ char *full_type;
+ ObjectProperty *op;
+
+ prop->offset = offset;
+ prop->check = check;
+ prop->flags = flags | OBJ_PROP_LINK_CLASS;
+
+ full_type = g_strdup_printf("link<%s>", type);
+
+ op = object_class_property_add(oc, name, full_type,
+ object_get_link_property,
+ check ? object_set_link_property : NULL,
+ object_release_link_property,
+ prop);
op->resolve = object_resolve_link_property;
-out:
g_free(full_type);
+ return op;
}
-void object_property_add_const_link(Object *obj, const char *name,
- Object *target, Error **errp)
+ObjectProperty *
+object_property_add_const_link(Object *obj, const char *name,
+ Object *target)
{
- char *link_type;
- ObjectProperty *op;
-
- link_type = g_strdup_printf("link<%s>", object_get_typename(target));
- op = object_property_add(obj, name, link_type,
- object_get_child_property, NULL,
- NULL, target, errp);
- if (op != NULL) {
- op->resolve = object_resolve_child_property;
- }
- g_free(link_type);
+ return object_add_link_prop(obj, name,
+ object_get_typename(target), target,
+ NULL, OBJ_PROP_LINK_DIRECT);
}
-gchar *object_get_canonical_path_component(Object *obj)
+char *object_get_canonical_path_component(const Object *obj)
{
ObjectProperty *prop = NULL;
GHashTableIter iter;
return NULL;
}
-gchar *object_get_canonical_path(Object *obj)
+char *object_get_canonical_path(const Object *obj)
{
Object *root = object_get_root();
char *newpath, *path = NULL;
return path;
}
-Object *object_resolve_path_component(Object *parent, const gchar *part)
+Object *object_resolve_path_component(Object *parent, const char *part)
{
ObjectProperty *prop = object_property_find(parent, part, NULL);
if (prop == NULL) {
}
static Object *object_resolve_abs_path(Object *parent,
- gchar **parts,
- const char *typename,
- int index)
+ char **parts,
+ const char *typename)
{
Object *child;
- if (parts[index] == NULL) {
+ if (*parts == NULL) {
return object_dynamic_cast(parent, typename);
}
- if (strcmp(parts[index], "") == 0) {
- return object_resolve_abs_path(parent, parts, typename, index + 1);
+ if (strcmp(*parts, "") == 0) {
+ return object_resolve_abs_path(parent, parts + 1, typename);
}
- child = object_resolve_path_component(parent, parts[index]);
+ child = object_resolve_path_component(parent, *parts);
if (!child) {
return NULL;
}
- return object_resolve_abs_path(child, parts, typename, index + 1);
+ return object_resolve_abs_path(child, parts + 1, typename);
}
static Object *object_resolve_partial_path(Object *parent,
- gchar **parts,
- const char *typename,
- bool *ambiguous)
+ char **parts,
+ const char *typename,
+ bool *ambiguous)
{
Object *obj;
GHashTableIter iter;
ObjectProperty *prop;
- obj = object_resolve_abs_path(parent, parts, typename, 0);
+ obj = object_resolve_abs_path(parent, parts, typename);
g_hash_table_iter_init(&iter, parent->properties);
while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) {
bool *ambiguousp)
{
Object *obj;
- gchar **parts;
+ char **parts;
parts = g_strsplit(path, "/", 0);
assert(parts);
*ambiguousp = ambiguous;
}
} else {
- obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
+ obj = object_resolve_abs_path(object_get_root(), parts + 1, typename);
}
g_strfreev(parts);
{
StringProperty *prop = opaque;
char *value;
- Error *local_err = NULL;
- visit_type_str(v, name, &value, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+ if (!visit_type_str(v, name, &value, errp)) {
return;
}
g_free(prop);
}
-void object_property_add_str(Object *obj, const char *name,
- char *(*get)(Object *, Error **),
- void (*set)(Object *, const char *, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_str(Object *obj, const char *name,
+ char *(*get)(Object *, Error **),
+ void (*set)(Object *, const char *, Error **))
{
- Error *local_err = NULL;
StringProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_property_add(obj, name, "string",
- get ? property_get_str : NULL,
- set ? property_set_str : NULL,
- property_release_str,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "string",
+ get ? property_get_str : NULL,
+ set ? property_set_str : NULL,
+ property_release_str,
+ prop);
}
-void object_class_property_add_str(ObjectClass *klass, const char *name,
+ObjectProperty *
+object_class_property_add_str(ObjectClass *klass, const char *name,
char *(*get)(Object *, Error **),
void (*set)(Object *, const char *,
- Error **),
- Error **errp)
+ Error **))
{
- Error *local_err = NULL;
StringProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_class_property_add(klass, name, "string",
- get ? property_get_str : NULL,
- set ? property_set_str : NULL,
- property_release_str,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_class_property_add(klass, name, "string",
+ get ? property_get_str : NULL,
+ set ? property_set_str : NULL,
+ NULL,
+ prop);
}
typedef struct BoolProperty
{
BoolProperty *prop = opaque;
bool value;
- Error *local_err = NULL;
- visit_type_bool(v, name, &value, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+ if (!visit_type_bool(v, name, &value, errp)) {
return;
}
g_free(prop);
}
-void object_property_add_bool(Object *obj, const char *name,
- bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_bool(Object *obj, const char *name,
+ bool (*get)(Object *, Error **),
+ void (*set)(Object *, bool, Error **))
{
- Error *local_err = NULL;
BoolProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_property_add(obj, name, "bool",
- get ? property_get_bool : NULL,
- set ? property_set_bool : NULL,
- property_release_bool,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "bool",
+ get ? property_get_bool : NULL,
+ set ? property_set_bool : NULL,
+ property_release_bool,
+ prop);
}
-void object_class_property_add_bool(ObjectClass *klass, const char *name,
+ObjectProperty *
+object_class_property_add_bool(ObjectClass *klass, const char *name,
bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **),
- Error **errp)
+ void (*set)(Object *, bool, Error **))
{
- Error *local_err = NULL;
BoolProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
prop->set = set;
- object_class_property_add(klass, name, "bool",
- get ? property_get_bool : NULL,
- set ? property_set_bool : NULL,
- property_release_bool,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_class_property_add(klass, name, "bool",
+ get ? property_get_bool : NULL,
+ set ? property_set_bool : NULL,
+ NULL,
+ prop);
}
static void property_get_enum(Object *obj, Visitor *v, const char *name,
{
EnumProperty *prop = opaque;
int value;
- Error *err = NULL;
- visit_type_enum(v, name, &value, prop->lookup, &err);
- if (err) {
- error_propagate(errp, err);
+ if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
return;
}
prop->set(obj, value, errp);
g_free(prop);
}
-void object_property_add_enum(Object *obj, const char *name,
- const char *typename,
- const QEnumLookup *lookup,
- int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_enum(Object *obj, const char *name,
+ const char *typename,
+ const QEnumLookup *lookup,
+ int (*get)(Object *, Error **),
+ void (*set)(Object *, int, Error **))
{
- Error *local_err = NULL;
EnumProperty *prop = g_malloc(sizeof(*prop));
prop->lookup = lookup;
prop->get = get;
prop->set = set;
- object_property_add(obj, name, typename,
- get ? property_get_enum : NULL,
- set ? property_set_enum : NULL,
- property_release_enum,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, typename,
+ get ? property_get_enum : NULL,
+ set ? property_set_enum : NULL,
+ property_release_enum,
+ prop);
}
-void object_class_property_add_enum(ObjectClass *klass, const char *name,
+ObjectProperty *
+object_class_property_add_enum(ObjectClass *klass, const char *name,
const char *typename,
const QEnumLookup *lookup,
int (*get)(Object *, Error **),
- void (*set)(Object *, int, Error **),
- Error **errp)
+ void (*set)(Object *, int, Error **))
{
- Error *local_err = NULL;
EnumProperty *prop = g_malloc(sizeof(*prop));
prop->lookup = lookup;
prop->get = get;
prop->set = set;
- object_class_property_add(klass, name, typename,
- get ? property_get_enum : NULL,
- set ? property_set_enum : NULL,
- property_release_enum,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_class_property_add(klass, name, typename,
+ get ? property_get_enum : NULL,
+ set ? property_set_enum : NULL,
+ NULL,
+ prop);
}
typedef struct TMProperty {
goto out;
}
- visit_start_struct(v, name, NULL, 0, &err);
- if (err) {
+ if (!visit_start_struct(v, name, NULL, 0, &err)) {
goto out;
}
- visit_type_int32(v, "tm_year", &value.tm_year, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_year", &value.tm_year, &err)) {
goto out_end;
}
- visit_type_int32(v, "tm_mon", &value.tm_mon, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_mon", &value.tm_mon, &err)) {
goto out_end;
}
- visit_type_int32(v, "tm_mday", &value.tm_mday, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_mday", &value.tm_mday, &err)) {
goto out_end;
}
- visit_type_int32(v, "tm_hour", &value.tm_hour, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_hour", &value.tm_hour, &err)) {
goto out_end;
}
- visit_type_int32(v, "tm_min", &value.tm_min, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_min", &value.tm_min, &err)) {
goto out_end;
}
- visit_type_int32(v, "tm_sec", &value.tm_sec, &err);
- if (err) {
+ if (!visit_type_int32(v, "tm_sec", &value.tm_sec, &err)) {
goto out_end;
}
visit_check_struct(v, &err);
g_free(prop);
}
-void object_property_add_tm(Object *obj, const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp)
+ObjectProperty *
+object_property_add_tm(Object *obj, const char *name,
+ void (*get)(Object *, struct tm *, Error **))
{
- Error *local_err = NULL;
TMProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
- object_property_add(obj, name, "struct tm",
- get ? property_get_tm : NULL, NULL,
- property_release_tm,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_property_add(obj, name, "struct tm",
+ get ? property_get_tm : NULL, NULL,
+ property_release_tm,
+ prop);
}
-void object_class_property_add_tm(ObjectClass *klass, const char *name,
- void (*get)(Object *, struct tm *, Error **),
- Error **errp)
+ObjectProperty *
+object_class_property_add_tm(ObjectClass *klass, const char *name,
+ void (*get)(Object *, struct tm *, Error **))
{
- Error *local_err = NULL;
TMProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
- object_class_property_add(klass, name, "struct tm",
- get ? property_get_tm : NULL, NULL,
- property_release_tm,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- }
+ return object_class_property_add(klass, name, "struct tm",
+ get ? property_get_tm : NULL,
+ NULL, NULL, prop);
}
-static char *qdev_get_type(Object *obj, Error **errp)
+static char *object_get_type(Object *obj, Error **errp)
{
return g_strdup(object_get_typename(obj));
}
visit_type_uint8(v, name, &value, errp);
}
+static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint8_t *field = opaque;
+ uint8_t value;
+
+ if (!visit_type_uint8(v, name, &value, errp)) {
+ return;
+ }
+
+ *field = value;
+}
+
static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint16(v, name, &value, errp);
}
+static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint16_t *field = opaque;
+ uint16_t value;
+
+ if (!visit_type_uint16(v, name, &value, errp)) {
+ return;
+ }
+
+ *field = value;
+}
+
static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint32(v, name, &value, errp);
}
+static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint32_t *field = opaque;
+ uint32_t value;
+
+ if (!visit_type_uint32(v, name, &value, errp)) {
+ return;
+ }
+
+ *field = value;
+}
+
static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint64(v, name, &value, errp);
}
-void object_property_add_uint8_ptr(Object *obj, const char *name,
- const uint8_t *v, Error **errp)
+static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
{
- object_property_add(obj, name, "uint8", property_get_uint8_ptr,
- NULL, NULL, (void *)v, errp);
+ uint64_t *field = opaque;
+ uint64_t value;
+
+ if (!visit_type_uint64(v, name, &value, errp)) {
+ return;
+ }
+
+ *field = value;
}
-void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
- const uint8_t *v, Error **errp)
+ObjectProperty *
+object_property_add_uint8_ptr(Object *obj, const char *name,
+ const uint8_t *v,
+ ObjectPropertyFlags flags)
{
- object_class_property_add(klass, name, "uint8", property_get_uint8_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint8_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint8_ptr;
+ }
+
+ return object_property_add(obj, name, "uint8",
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint16_ptr(Object *obj, const char *name,
- const uint16_t *v, Error **errp)
+ObjectProperty *
+object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
+ const uint8_t *v,
+ ObjectPropertyFlags flags)
{
- object_property_add(obj, name, "uint16", property_get_uint16_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint8_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint8_ptr;
+ }
+
+ return object_class_property_add(klass, name, "uint8",
+ getter, setter, NULL, (void *)v);
}
-void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
- const uint16_t *v, Error **errp)
+ObjectProperty *
+object_property_add_uint16_ptr(Object *obj, const char *name,
+ const uint16_t *v,
+ ObjectPropertyFlags flags)
{
- object_class_property_add(klass, name, "uint16", property_get_uint16_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint16_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint16_ptr;
+ }
+
+ return object_property_add(obj, name, "uint16",
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint32_ptr(Object *obj, const char *name,
- const uint32_t *v, Error **errp)
+ObjectProperty *
+object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
+ const uint16_t *v,
+ ObjectPropertyFlags flags)
{
- object_property_add(obj, name, "uint32", property_get_uint32_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint16_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint16_ptr;
+ }
+
+ return object_class_property_add(klass, name, "uint16",
+ getter, setter, NULL, (void *)v);
}
-void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
- const uint32_t *v, Error **errp)
+ObjectProperty *
+object_property_add_uint32_ptr(Object *obj, const char *name,
+ const uint32_t *v,
+ ObjectPropertyFlags flags)
{
- object_class_property_add(klass, name, "uint32", property_get_uint32_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint32_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint32_ptr;
+ }
+
+ return object_property_add(obj, name, "uint32",
+ getter, setter, NULL, (void *)v);
}
-void object_property_add_uint64_ptr(Object *obj, const char *name,
- const uint64_t *v, Error **errp)
+ObjectProperty *
+object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
+ const uint32_t *v,
+ ObjectPropertyFlags flags)
{
- object_property_add(obj, name, "uint64", property_get_uint64_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint32_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint32_ptr;
+ }
+
+ return object_class_property_add(klass, name, "uint32",
+ getter, setter, NULL, (void *)v);
}
-void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
- const uint64_t *v, Error **errp)
+ObjectProperty *
+object_property_add_uint64_ptr(Object *obj, const char *name,
+ const uint64_t *v,
+ ObjectPropertyFlags flags)
{
- object_class_property_add(klass, name, "uint64", property_get_uint64_ptr,
- NULL, NULL, (void *)v, errp);
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint64_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint64_ptr;
+ }
+
+ return object_property_add(obj, name, "uint64",
+ getter, setter, NULL, (void *)v);
+}
+
+ObjectProperty *
+object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
+ const uint64_t *v,
+ ObjectPropertyFlags flags)
+{
+ ObjectPropertyAccessor *getter = NULL;
+ ObjectPropertyAccessor *setter = NULL;
+
+ if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) {
+ getter = property_get_uint64_ptr;
+ }
+
+ if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) {
+ setter = property_set_uint64_ptr;
+ }
+
+ return object_class_property_add(klass, name, "uint64",
+ getter, setter, NULL, (void *)v);
}
typedef struct {
{
AliasProperty *prop = opaque;
- object_property_get(prop->target_obj, v, prop->target_name, errp);
+ object_property_get(prop->target_obj, prop->target_name, v, errp);
}
static void property_set_alias(Object *obj, Visitor *v, const char *name,
{
AliasProperty *prop = opaque;
- object_property_set(prop->target_obj, v, prop->target_name, errp);
+ object_property_set(prop->target_obj, prop->target_name, v, errp);
}
static Object *property_resolve_alias(Object *obj, void *opaque,
- const gchar *part)
+ const char *part)
{
AliasProperty *prop = opaque;
g_free(prop);
}
-void object_property_add_alias(Object *obj, const char *name,
- Object *target_obj, const char *target_name,
- Error **errp)
+ObjectProperty *
+object_property_add_alias(Object *obj, const char *name,
+ Object *target_obj, const char *target_name)
{
AliasProperty *prop;
ObjectProperty *op;
ObjectProperty *target_prop;
- gchar *prop_type;
- Error *local_err = NULL;
+ g_autofree char *prop_type = NULL;
- target_prop = object_property_find(target_obj, target_name, errp);
- if (!target_prop) {
- return;
- }
+ target_prop = object_property_find(target_obj, target_name,
+ &error_abort);
if (object_property_is_child(target_prop)) {
prop_type = g_strdup_printf("link%s",
property_get_alias,
property_set_alias,
property_release_alias,
- prop, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- g_free(prop);
- goto out;
- }
+ prop);
op->resolve = property_resolve_alias;
+ if (target_prop->defval) {
+ op->defval = qobject_ref(target_prop->defval);
+ }
object_property_set_description(obj, op->name,
- target_prop->description,
- &error_abort);
-
-out:
- g_free(prop_type);
+ target_prop->description);
+ return op;
}
void object_property_set_description(Object *obj, const char *name,
- const char *description, Error **errp)
+ const char *description)
{
ObjectProperty *op;
- op = object_property_find(obj, name, errp);
- if (!op) {
- return;
- }
-
+ op = object_property_find(obj, name, &error_abort);
g_free(op->description);
op->description = g_strdup(description);
}
void object_class_property_set_description(ObjectClass *klass,
const char *name,
- const char *description,
- Error **errp)
+ const char *description)
{
ObjectProperty *op;
op = g_hash_table_lookup(klass->properties, name);
- if (!op) {
- error_setg(errp, "Property '.%s' not found", name);
- return;
- }
-
g_free(op->description);
op->description = g_strdup(description);
}
static void object_class_init(ObjectClass *klass, void *data)
{
- object_class_property_add_str(klass, "type", qdev_get_type,
- NULL, &error_abort);
+ object_class_property_add_str(klass, "type", object_get_type,
+ NULL);
}
static void register_types(void)