mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 13:26:58 +00:00
qapi-visit: Add visitor.type classification
We have three classes of QAPI visitors: input, output, and dealloc. Currently, all implementations of these visitors have one thing in common based on their visitor type: the implementation used for the visit_type_enum() callback. But since we plan to add more such common behavior, in relation to documenting and further refining the semantics, it makes more sense to have the visitor implementations advertise which class they belong to, so the common qapi-visit-core code can use that information in multiple places. A later patch will better document the types of visitors directly in visitor.h. For this patch, knowing the class of a visitor implementation lets us make input_type_enum() and output_type_enum() become static functions, by replacing the callback function Visitor.type_enum() with the simpler enum member Visitor.type. Share a common assertion in qapi-visit-core as part of the refactoring. Move comments in opts-visitor.c to match the refactored layout. Backports commit 983f52d4b3f86fb9dc9f8b142132feb5a8723016 from qemu
This commit is contained in:
parent
f50acc467f
commit
eef0932471
|
@ -15,6 +15,17 @@
|
|||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
|
||||
/*
|
||||
* There are three classes of visitors; setting the class determines
|
||||
* how QAPI enums are visited, as well as what additional restrictions
|
||||
* can be asserted.
|
||||
*/
|
||||
typedef enum VisitorType {
|
||||
VISITOR_INPUT,
|
||||
VISITOR_OUTPUT,
|
||||
VISITOR_DEALLOC,
|
||||
} VisitorType;
|
||||
|
||||
struct Visitor
|
||||
{
|
||||
/* Must be set */
|
||||
|
@ -30,12 +41,9 @@ struct Visitor
|
|||
GenericList *(*next_list)(Visitor *v, GenericList **list);
|
||||
void (*end_list)(Visitor *v);
|
||||
|
||||
void (*type_enum)(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp);
|
||||
/* May be NULL; only needed for input visitors. */
|
||||
void (*get_next_type)(Visitor *v, const char *name, QType *type,
|
||||
bool promote_int, Error **errp);
|
||||
/* Must be set. */
|
||||
void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
|
||||
Error **errp);
|
||||
/* Must be set. */
|
||||
|
@ -54,11 +62,9 @@ struct Visitor
|
|||
|
||||
/* May be NULL; most useful for input visitors. */
|
||||
void (*optional)(Visitor *v, const char *name, bool *present);
|
||||
|
||||
/* Must be set */
|
||||
VisitorType type;
|
||||
};
|
||||
|
||||
void input_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp);
|
||||
void output_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,19 @@ bool visit_optional(Visitor *v, const char *name, bool *present);
|
|||
*/
|
||||
void visit_get_next_type(Visitor *v, const char *name, QType *type,
|
||||
bool promote_int, Error **errp);
|
||||
/*
|
||||
* Visit an enum value.
|
||||
*
|
||||
* @strings expresses the mapping between C enum values and QAPI enum
|
||||
* names; it should be the ENUM_lookup array from visit-types.h.
|
||||
*
|
||||
* May call visit_type_str() under the hood, and the enum visit may
|
||||
* fail even if the corresponding string visit succeeded; this implies
|
||||
* that visit_type_str() must have no unwelcome side effects.
|
||||
*/
|
||||
void visit_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp);
|
||||
|
||||
void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
|
||||
void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
|
||||
Error **errp);
|
||||
|
|
|
@ -169,11 +169,6 @@ static void qapi_dealloc_type_size(Visitor *v, const char *name, uint64_t *obj,
|
|||
{
|
||||
}
|
||||
|
||||
static void qapi_dealloc_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char * const strings[], Error **errp)
|
||||
{
|
||||
}
|
||||
|
||||
Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
|
||||
{
|
||||
return &v->visitor;
|
||||
|
@ -190,6 +185,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
|||
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->visitor.type = VISITOR_DEALLOC;
|
||||
v->visitor.start_struct = qapi_dealloc_start_struct;
|
||||
v->visitor.end_struct = qapi_dealloc_end_struct;
|
||||
v->visitor.start_implicit_struct = qapi_dealloc_start_implicit_struct;
|
||||
|
@ -197,7 +193,6 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
|||
v->visitor.start_list = qapi_dealloc_start_list;
|
||||
v->visitor.next_list = qapi_dealloc_next_list;
|
||||
v->visitor.end_list = qapi_dealloc_end_list;
|
||||
v->visitor.type_enum = qapi_dealloc_type_enum;
|
||||
v->visitor.type_int64 = qapi_dealloc_type_int64;
|
||||
v->visitor.type_uint64 = qapi_dealloc_type_uint64;
|
||||
v->visitor.type_bool = qapi_dealloc_type_bool;
|
||||
|
|
|
@ -78,12 +78,6 @@ void visit_get_next_type(Visitor *v, const char *name, QType *type,
|
|||
}
|
||||
}
|
||||
|
||||
void visit_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
{
|
||||
v->type_enum(v, name, obj, strings, errp);
|
||||
}
|
||||
|
||||
void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
|
||||
{
|
||||
v->type_int64(v, name, obj, errp);
|
||||
|
@ -211,14 +205,13 @@ void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
|
|||
v->type_any(v, name, obj, errp);
|
||||
}
|
||||
|
||||
void output_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
static void output_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
{
|
||||
int i = 0;
|
||||
int value = *obj;
|
||||
char *enum_str;
|
||||
|
||||
assert(strings);
|
||||
while (strings[i++] != NULL);
|
||||
if (value < 0 || value >= i - 1) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
|
||||
|
@ -229,15 +222,13 @@ void output_type_enum(Visitor *v, const char *name, int *obj,
|
|||
visit_type_str(v, name, &enum_str, errp);
|
||||
}
|
||||
|
||||
void input_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
static void input_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
int64_t value = 0;
|
||||
char *enum_str;
|
||||
|
||||
assert(strings);
|
||||
|
||||
visit_type_str(v, name, &enum_str, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -260,3 +251,14 @@ void input_type_enum(Visitor *v, const char *name, int *obj,
|
|||
g_free(enum_str);
|
||||
*obj = (int)value;
|
||||
}
|
||||
|
||||
void visit_type_enum(Visitor *v, const char *name, int *obj,
|
||||
const char *const strings[], Error **errp)
|
||||
{
|
||||
assert(strings);
|
||||
if (v->type == VISITOR_INPUT) {
|
||||
input_type_enum(v, name, obj, strings, errp);
|
||||
} else if (v->type == VISITOR_OUTPUT) {
|
||||
output_type_enum(v, name, obj, strings, errp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,6 +350,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
|
|||
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->visitor.type = VISITOR_INPUT;
|
||||
v->visitor.start_struct = qmp_input_start_struct;
|
||||
v->visitor.end_struct = qmp_input_end_struct;
|
||||
v->visitor.start_implicit_struct = qmp_input_start_implicit_struct;
|
||||
|
@ -357,7 +358,6 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
|
|||
v->visitor.start_list = qmp_input_start_list;
|
||||
v->visitor.next_list = qmp_input_next_list;
|
||||
v->visitor.end_list = qmp_input_end_list;
|
||||
v->visitor.type_enum = input_type_enum;
|
||||
v->visitor.type_int64 = qmp_input_type_int64;
|
||||
v->visitor.type_uint64 = qmp_input_type_uint64;
|
||||
v->visitor.type_bool = qmp_input_type_bool;
|
||||
|
|
|
@ -234,12 +234,12 @@ QmpOutputVisitor *qmp_output_visitor_new(void)
|
|||
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->visitor.type = VISITOR_OUTPUT;
|
||||
v->visitor.start_struct = qmp_output_start_struct;
|
||||
v->visitor.end_struct = qmp_output_end_struct;
|
||||
v->visitor.start_list = qmp_output_start_list;
|
||||
v->visitor.next_list = qmp_output_next_list;
|
||||
v->visitor.end_list = qmp_output_end_list;
|
||||
v->visitor.type_enum = output_type_enum;
|
||||
v->visitor.type_int64 = qmp_output_type_int64;
|
||||
v->visitor.type_uint64 = qmp_output_type_uint64;
|
||||
v->visitor.type_bool = qmp_output_type_bool;
|
||||
|
|
|
@ -328,7 +328,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
|
|||
|
||||
v = g_malloc0(sizeof(*v));
|
||||
|
||||
v->visitor.type_enum = input_type_enum;
|
||||
v->visitor.type = VISITOR_INPUT;
|
||||
v->visitor.type_int64 = parse_type_int64;
|
||||
v->visitor.type_uint64 = parse_type_uint64;
|
||||
v->visitor.type_size = NULL;
|
||||
|
|
Loading…
Reference in a new issue