> Signed-off-by: Marc-André Lureau <[email protected]> > Signed-off-by: Markus Armbruster <[email protected]> > Message-ID: <[email protected]> > --- > include/qom/object.h | 74 ++++++++++++++++++++++++++++++++++++ > qom/object.c | 89 +++++++++++++++++++++++++++++++++++++++++--- > 2 files changed, 158 insertions(+), 5 deletions(-) > > diff --git a/include/qom/object.h b/include/qom/object.h > index 365d819d35a3..ce9375f37af9 100644 > --- a/include/qom/object.h > +++ b/include/qom/object.h > @@ -2006,6 +2006,80 @@ ObjectProperty > *object_class_property_add_enum(ObjectClass *klass, > int (*get)(Object *, Error **), > void (*set)(Object *, int, Error **)); > > +/** > + * struct QapiEnumProp: Descriptor for a property backed by a QAPI enum type > + * > + * Binds a QOM object property to a QAPI enum, providing automatic > + * string<->int conversion through QAPI visitors and optional > + * default-value initialization during object instance init. > + * > + * Use the QAPI_ENUM_PROP() macro to construct instances inline. > + * > + * @name: property name exposed on the QOM object > + * @description: human-readable description (shown in ``-device help``, etc.) > + * @default_value: initial enum value applied via @set during instance init, > + * or -1 (the QAPI_ENUM_PROP default) to skip initialization > + * @qapi_type: pointer to the generated QAPITypeInfo for the enum > + * (provides the string<->int lookup table) > + * @get: getter that returns the current enum value as int, or -1 on error > + * @set: setter that receives the enum value as int; %NULL for read-only > props > + */ > +typedef struct QapiEnumProp { > + const char *name; > + const char *description; > + const int default_value; > + const QAPITypeInfo *qapi_type; > + int (*get)(Object *, Error **); > + void (*set)(Object *, int, Error **); > +} QapiEnumProp; > + > +#define QAPI_ENUM_PROP(...) ({ \ > + static const QapiEnumProp _prop = { \ > + .default_value = -1, __VA_ARGS__ \ > + }; \ > + &_prop; }) > + > +/** > + * object_property_add_qapi_enum: > + * @obj: the object to add a property to > + * @prop: property descriptor > + * > + * Add an enum property with QAPI type association. > + * > + * Returns: The newly added property on success, or %NULL on failure. > + */ > +ObjectProperty * > +object_property_add_qapi_enum(Object *obj, const QapiEnumProp *prop); > + > +/** > + * object_class_property_add_qapi_enum: > + * @klass: the class object to add a property to > + * @prop: property descriptor > + * > + * Add an enum property with QAPI type association. > + * > + * Use the QAPI_ENUM_PROP() macro to construct the property descriptor > + * inline. If .default_value is not set, the property is not initialized > + * (default_value is -1). Otherwise, the setter is called with > + * default_value during object instance init. > + * > + * Example:: > + * > + * object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP( > + * .name = "policy", > + * .description = "Set the NUMA policy", > + * .default_value = HOST_MEM_POLICY_DEFAULT, > + * .qapi_type = &HostMemPolicy_type_info, > + * .get = my_get_policy, > + * .set = my_set_policy, > + * )); > + * > + * Returns: The newly added property on success, or %NULL on failure. > + */ > +ObjectProperty * > +object_class_property_add_qapi_enum(ObjectClass *klass, > + const QapiEnumProp *prop); > + > /** > * object_property_add_qapi: > * @obj: the object to add a property to > diff --git a/qom/object.c b/qom/object.c > index bebbfc43556d..c1aa2b96fcc2 100644 > --- a/qom/object.c > +++ b/qom/object.c > @@ -1219,7 +1219,7 @@ static void object_class_foreach_tramp(gpointer key, > gpointer value, > return; > } > > - if (data->implements_type && > + if (data->implements_type && > !object_class_dynamic_cast(k, data->implements_type)) { > return; > } > @@ -1786,7 +1786,6 @@ int object_property_get_enum(Object *obj, const char > *name, > char *str; > int ret; > ObjectProperty *prop = object_property_find_err(obj, name, errp); > - EnumProperty *enumprop; > > if (prop == NULL) { > return -1; > @@ -1799,14 +1798,17 @@ int object_property_get_enum(Object *obj, const char > *name, > return -1; > } > > - enumprop = prop->opaque; > - > str = object_property_get_str(obj, name, errp); > if (!str) { > return -1; > } > > - ret = qapi_enum_parse(enumprop->lookup, str, -1, errp); > + if (prop->qapi_type) { > + ret = qapi_enum_parse(prop->qapi_type->lookup, str, -1, errp); > + } else { > + EnumProperty *enumprop = prop->opaque; > + ret = qapi_enum_parse(enumprop->lookup, str, -1, errp); > + } > g_free(str); > > return ret; > @@ -2609,6 +2611,83 @@ object_class_property_add_enum(ObjectClass *klass, > const char *name, > prop); > } > > +static void get_qapi_enum(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + const QapiEnumProp *prop = opaque; > + int value; > + Error *err = NULL; > + > + value = prop->get(obj, &err);
It could assert (value != -1 || err) -- Marc-André Lureau <[email protected]>
