From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: armbru@redhat.com, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH v12 01/18] qapi-visit: Add visitor.type classification
Date: Mon, 29 Feb 2016 22:14:15 -0700 [thread overview]
Message-ID: <1456809272-14184-2-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1456809272-14184-1-git-send-email-eblake@redhat.com>
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.
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 field Visitor.type. Share a common assertion
in qapi-visit-core as part of the refactoring.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
v12: new patch
---
include/qapi/visitor-impl.h | 21 ++++++++++++---------
qapi/qapi-visit-core.c | 28 +++++++++++++++-------------
qapi/opts-visitor.c | 12 ++----------
qapi/qapi-dealloc-visitor.c | 7 +------
qapi/qmp-input-visitor.c | 2 +-
qapi/qmp-output-visitor.c | 2 +-
qapi/string-input-visitor.c | 2 +-
qapi/string-output-visitor.c | 2 +-
8 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 2bd8f29..228a2a6 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -14,6 +14,15 @@
#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 */
@@ -36,10 +45,6 @@ struct Visitor
void (*end_alternate)(Visitor *v);
/* Must be set. */
- void (*type_enum)(Visitor *v, const char *name, int *obj,
- const char *const strings[], Error **errp);
-
- /* Must be set. */
void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
Error **errp);
/* Must be set. */
@@ -58,11 +63,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
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 856606b..a08d073 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -71,12 +71,6 @@ bool visit_optional(Visitor *v, const char *name, bool *present)
return *present;
}
-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);
@@ -207,14 +201,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");
@@ -225,15 +218,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);
@@ -256,3 +247,14 @@ void input_type_enum(Visitor *v, const char *name, int *obj,
g_free(enum_str);
*obj = 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);
+ }
+}
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 73e4ace..f9a2346 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -506,6 +506,8 @@ opts_visitor_new(const QemuOpts *opts)
ov = g_malloc0(sizeof *ov);
+ ov->visitor.type = VISITOR_INPUT;
+
ov->visitor.start_struct = &opts_start_struct;
ov->visitor.end_struct = &opts_end_struct;
@@ -513,16 +515,6 @@ opts_visitor_new(const QemuOpts *opts)
ov->visitor.next_list = &opts_next_list;
ov->visitor.end_list = &opts_end_list;
- /* input_type_enum() covers both "normal" enums and union discriminators.
- * The union discriminator field is always generated as "type"; it should
- * match the "type" QemuOpt child of any QemuOpts.
- *
- * input_type_enum() will remove the looked-up key from the
- * "unprocessed_opts" hash even if the lookup fails, because the removal is
- * done earlier in opts_type_str(). This should be harmless.
- */
- ov->visitor.type_enum = &input_type_enum;
-
ov->visitor.type_int64 = &opts_type_int64;
ov->visitor.type_uint64 = &opts_type_uint64;
ov->visitor.type_size = &opts_type_size;
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 6922179..c19a459 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -163,11 +163,6 @@ static void qapi_dealloc_type_anything(Visitor *v, const char *name,
}
}
-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;
@@ -184,6 +179,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_alternate = qapi_dealloc_start_alternate;
@@ -191,7 +187,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;
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index e659832..03dcb65 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -338,13 +338,13 @@ 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_list = qmp_input_start_list;
v->visitor.next_list = qmp_input_next_list;
v->visitor.end_list = qmp_input_end_list;
v->visitor.start_alternate = qmp_input_start_alternate;
- 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;
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index d44c676..1f2a7ba 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -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;
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 59eb5dc..d591e67 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -347,7 +347,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 = parse_type_size;
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index c2e5c5b..0d44d7e 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -351,7 +351,7 @@ StringOutputVisitor *string_output_visitor_new(bool human)
v->string = g_string_new(NULL);
v->human = human;
- v->visitor.type_enum = output_type_enum;
+ v->visitor.type = VISITOR_OUTPUT;
v->visitor.type_int64 = print_type_int64;
v->visitor.type_uint64 = print_type_uint64;
v->visitor.type_size = print_type_size;
--
2.5.0
next prev parent reply other threads:[~2016-03-01 5:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-01 5:14 [Qemu-devel] [PATCH v12 00/18] qapi visitor cleanups (post-introspection cleanups subset E) Eric Blake
2016-03-01 5:14 ` Eric Blake [this message]
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 02/18] qapi: Guarantee NULL obj on input visitor callback error Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 03/18] qmp: Drop dead command->type Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 04/18] qmp-input: Clean up stack handling Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 05/18] qmp-input: Don't consume input when checking has_member Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 06/18] qmp-input: Refactor when list is advanced Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 07/18] qapi: Document visitor interfaces, add assertions Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 08/18] tests: Add check-qnull Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 09/18] qapi: Add visit_type_null() visitor Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 10/18] qmp: Support explicit null during visits Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 11/18] spapr_drc: Expose 'null' in qom-get when there is no fdt Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 12/18] qmp: Tighten output visitor rules Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 13/18] qapi: Split visit_end_struct() into pieces Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 14/18] qapi-commands: Wrap argument visit in visit_start_struct Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 15/18] qom: Wrap prop " Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 16/18] qmp-input: Require struct push to visit members of top dict Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 17/18] qapi: Simplify semantics of visit_next_list() Eric Blake
2016-03-01 5:14 ` [Qemu-devel] [PATCH v12 18/18] qapi: Change visit_type_FOO() to no longer return partial objects Eric Blake
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1456809272-14184-2-git-send-email-eblake@redhat.com \
--to=eblake@redhat.com \
--cc=armbru@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).