aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/monitor/monitor.h1
-rw-r--r--include/qapi/qmp/dispatch.h22
-rw-r--r--include/qapi/qmp/qerror.h9
-rw-r--r--include/qapi/qobject-input-visitor.h40
-rw-r--r--include/qapi/qobject-output-visitor.h35
-rw-r--r--include/qapi/visitor-impl.h7
-rw-r--r--include/qapi/visitor.h19
-rw-r--r--include/qemu/module.h2
8 files changed, 100 insertions, 35 deletions
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index e64b944d7c..d2b3aafdb4 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -16,6 +16,7 @@ extern Monitor *cur_mon;
bool monitor_cur_is_qmp(void);
+void monitor_init_qmp_commands(void);
void monitor_init(Chardev *chr, int flags);
void monitor_cleanup(void);
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 57651ea955..20578dcd48 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -34,18 +34,24 @@ typedef struct QmpCommand
bool enabled;
} QmpCommand;
-void qmp_register_command(const char *name, QmpCommandFunc *fn,
- QmpCommandOptions options);
-void qmp_unregister_command(const char *name);
-QmpCommand *qmp_find_command(const char *name);
-QObject *qmp_dispatch(QObject *request);
-void qmp_disable_command(const char *name);
-void qmp_enable_command(const char *name);
+typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
+
+void qmp_register_command(QmpCommandList *cmds, const char *name,
+ QmpCommandFunc *fn, QmpCommandOptions options);
+void qmp_unregister_command(QmpCommandList *cmds, const char *name);
+QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name);
+QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request);
+void qmp_disable_command(QmpCommandList *cmds, const char *name);
+void qmp_enable_command(QmpCommandList *cmds, const char *name);
+
bool qmp_command_is_enabled(const QmpCommand *cmd);
const char *qmp_command_name(const QmpCommand *cmd);
bool qmp_has_success_response(const QmpCommand *cmd);
QObject *qmp_build_error_object(Error *err);
+
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
-void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
+
+void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn,
+ void *opaque);
#endif
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6586c9fa62..c82360f429 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -82,15 +82,6 @@
#define QERR_QGA_COMMAND_FAILED \
"Guest agent command failed, error was '%s'"
-#define QERR_QMP_BAD_INPUT_OBJECT \
- "Expected '%s' in QMP input"
-
-#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
- "QMP input object member '%s' expects '%s'"
-
-#define QERR_QMP_EXTRA_MEMBER \
- "QMP input object member '%s' is unexpected"
-
#define QERR_SET_PASSWD_FAILED \
"Could not set password"
diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h
index cde328da9f..0b7633a38f 100644
--- a/include/qapi/qobject-input-visitor.h
+++ b/include/qapi/qobject-input-visitor.h
@@ -1,6 +1,7 @@
/*
* Input Visitor
*
+ * Copyright (C) 2017 Red Hat, Inc.
* Copyright IBM, Corp. 2011
*
* Authors:
@@ -20,11 +21,42 @@
typedef struct QObjectInputVisitor QObjectInputVisitor;
/*
- * Return a new input visitor that converts a QObject to a QAPI object.
+ * Create a QObject input visitor for @obj
*
- * Set @strict to reject a parse that doesn't consume all keys of a
- * dictionary; otherwise excess input is ignored.
+ * A QObject input visitor visit builds a QAPI object from a QObject.
+ * This simultaneously walks the QAPI object being built and the
+ * QObject. The latter walk starts at @obj.
+ *
+ * visit_type_FOO() creates an instance of QAPI type FOO. The visited
+ * QObject must match FOO. QDict matches struct/union types, QList
+ * matches list types, QString matches type 'str' and enumeration
+ * types, QInt matches integer types, QFloat matches type 'number',
+ * QBool matches type 'bool'. Type 'any' is matched by QObject. A
+ * QAPI alternate type is matched when one of its member types is.
+ *
+ * visit_start_struct() ... visit_end_struct() visits a QDict and
+ * creates a QAPI struct/union. Visits in between visit the
+ * dictionary members. visit_optional() is true when the QDict has
+ * this member. visit_check_struct() fails if unvisited members
+ * remain.
+ *
+ * visit_start_list() ... visit_end_list() visits a QList and creates
+ * a QAPI list. Visits in between visit list members, one after the
+ * other. visit_next_list() returns NULL when all QList members have
+ * been visited. visit_check_list() fails if unvisited members
+ * remain.
+ *
+ * visit_start_alternate() ... visit_end_alternate() visits a QObject
+ * and creates a QAPI alternate. The visit in between visits the same
+ * QObject and initializes the alternate member that is in use.
+ *
+ * Error messages refer to parts of @obj in JavaScript/Python syntax.
+ * For example, 'a.b[2]' refers to the second member of the QList
+ * member 'b' of the QDict member 'a' of QDict @obj.
+ *
+ * The caller is responsible for freeing the visitor with
+ * visit_free().
*/
-Visitor *qobject_input_visitor_new(QObject *obj, bool strict);
+Visitor *qobject_input_visitor_new(QObject *obj);
#endif
diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h
index 8241877bd7..9b990c318e 100644
--- a/include/qapi/qobject-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -19,11 +19,38 @@
typedef struct QObjectOutputVisitor QObjectOutputVisitor;
-/*
- * Create a new QObject output visitor.
+/**
+ * Create a QObject output visitor for @obj
+ *
+ * A QObject output visitor visit builds a QObject from QAPI Object.
+ * This simultaneously walks the QAPI object and the QObject being
+ * built. The latter walk starts at @obj.
+ *
+ * visit_type_FOO() creates a QObject for QAPI type FOO. It creates a
+ * QDict for struct/union types, a QList for list types, QString for
+ * type 'str' and enumeration types, QInt for integer types, QFloat
+ * for type 'number', QBool for type 'bool'. For type 'any', it
+ * increments the QObject's reference count. For QAPI alternate
+ * types, it creates the QObject for the member that is in use.
+ *
+ * visit_start_struct() ... visit_end_struct() visits a QAPI
+ * struct/union and creates a QDict. Visits in between visit the
+ * members. visit_optional() is true when the struct/union has this
+ * member. visit_check_struct() does nothing.
+ *
+ * visit_start_list() ... visit_end_list() visits a QAPI list and
+ * creates a QList. Visits in between visit list members, one after
+ * the other. visit_next_list() returns NULL when all QAPI list
+ * members have been visited. visit_check_list() does nothing.
+ *
+ * visit_start_alternate() ... visit_end_alternate() visits a QAPI
+ * alternate. The visit in between creates the QObject for the
+ * alternate member that is in use.
+ *
+ * Errors are not expected to happen.
*
- * If everything else succeeds, pass @result to visit_complete() to
- * collect the result of the visit.
+ * The caller is responsible for freeing the visitor with
+ * visit_free().
*/
Visitor *qobject_output_visitor_new(QObject **result);
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 8bd47ee4bb..e87709db5c 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -61,6 +61,9 @@ struct Visitor
/* Must be set */
GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
+ /* Optional; intended for input visitors */
+ void (*check_list)(Visitor *v, Error **errp);
+
/* Must be set */
void (*end_list)(Visitor *v, void **list);
@@ -102,8 +105,8 @@ struct Visitor
/* Must be set to visit explicit null values. */
void (*type_null)(Visitor *v, const char *name, Error **errp);
- /* Must be set for input visitors, optional otherwise. The core
- * takes care of the return type in the public interface. */
+ /* Must be set for input visitors to visit structs, optional otherwise.
+ The core takes care of the return type in the public interface. */
void (*optional)(Visitor *v, const char *name, bool *present);
/* Must be set */
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 9bb6cba237..1a1b62012b 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -66,12 +66,6 @@
* object, @name is the key associated with the value; and when
* visiting a member of a list, @name is NULL.
*
- * FIXME: Clients must pass NULL for @name when visiting a member of a
- * list, but this leads to poor error messages; it might be nicer to
- * require a non-NULL name such as "key.0" for '{ "key": [ "value" ]
- * }' if an error is encountered on "value" (or to have the visitor
- * core auto-generate the nicer name).
- *
* The visit_type_FOO() functions expect a non-null @obj argument;
* they allocate *@obj during input visits, leave it unchanged on
* output visits, and recursively free any resources during a dealloc
@@ -376,6 +370,19 @@ void visit_start_list(Visitor *v, const char *name, GenericList **list,
GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
/*
+ * Prepare for completing a list visit.
+ *
+ * @errp obeys typical error usage, and reports failures such as
+ * unvisited list tail remaining in the input stream.
+ *
+ * Should be called prior to visit_end_list() if all other
+ * intermediate visit steps were successful, to allow the visitor one
+ * last chance to report errors. May be skipped on a cleanup path,
+ * where there is no need to check for further errors.
+ */
+void visit_check_list(Visitor *v, Error **errp);
+
+/*
* Complete a list visit started earlier.
*
* @list must match what was passed to the paired visit_start_list().
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 877cca7d7b..56dd218205 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -42,7 +42,6 @@ static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
typedef enum {
MODULE_INIT_BLOCK,
MODULE_INIT_OPTS,
- MODULE_INIT_QAPI,
MODULE_INIT_QOM,
MODULE_INIT_TRACE,
MODULE_INIT_MAX
@@ -50,7 +49,6 @@ typedef enum {
#define block_init(function) module_init(function, MODULE_INIT_BLOCK)
#define opts_init(function) module_init(function, MODULE_INIT_OPTS)
-#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
#define type_init(function) module_init(function, MODULE_INIT_QOM)
#define trace_init(function) module_init(function, MODULE_INIT_TRACE)