aboutsummaryrefslogtreecommitdiff
path: root/qapi
diff options
context:
space:
mode:
Diffstat (limited to 'qapi')
-rw-r--r--qapi/opts-visitor.c12
-rw-r--r--qapi/qapi-visit-core.c8
-rw-r--r--qapi/qmp-dispatch.c29
-rw-r--r--qapi/qmp-registry.c37
-rw-r--r--qapi/qobject-input-visitor.c209
-rw-r--r--qapi/string-input-visitor.c97
-rw-r--r--qapi/trace-events1
7 files changed, 240 insertions, 153 deletions
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index a0a7c0e734..026d25b767 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -273,6 +273,16 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
static void
+opts_check_list(Visitor *v, Error **errp)
+{
+ /*
+ * FIXME should set error when unvisited elements remain. Mostly
+ * harmless, as the generated visits always visit all elements.
+ */
+}
+
+
+static void
opts_end_list(Visitor *v, void **obj)
{
OptsVisitor *ov = to_ov(v);
@@ -528,6 +538,7 @@ opts_visitor_new(const QemuOpts *opts)
{
OptsVisitor *ov;
+ assert(opts);
ov = g_malloc0(sizeof *ov);
ov->visitor.type = VISITOR_INPUT;
@@ -538,6 +549,7 @@ opts_visitor_new(const QemuOpts *opts)
ov->visitor.start_list = &opts_start_list;
ov->visitor.next_list = &opts_next_list;
+ ov->visitor.check_list = &opts_check_list;
ov->visitor.end_list = &opts_end_list;
ov->visitor.type_int64 = &opts_type_int64;
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index e6e93f02e6..43a09d147d 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -90,6 +90,14 @@ GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
return v->next_list(v, tail, size);
}
+void visit_check_list(Visitor *v, Error **errp)
+{
+ trace_visit_check_list(v);
+ if (v->check_list) {
+ v->check_list(v, errp);
+ }
+}
+
void visit_end_list(Visitor *v, void **obj)
{
trace_visit_end_list(v, obj);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 48bec2072b..dc502129d8 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -30,8 +30,7 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
dict = qobject_to_qdict(request);
if (!dict) {
- error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT,
- "request is not a dictionary");
+ error_setg(errp, "Expected '%s' in QMP input", "object");
return NULL;
}
@@ -42,26 +41,34 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
if (!strcmp(arg_name, "execute")) {
if (qobject_type(arg_obj) != QTYPE_QSTRING) {
- error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
- "string");
+ error_setg(errp, "QMP input object member '%s' expects '%s'",
+ "execute", "string");
return NULL;
}
has_exec_key = true;
- } else if (strcmp(arg_name, "arguments")) {
- error_setg(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
+ } else if (!strcmp(arg_name, "arguments")) {
+ if (qobject_type(arg_obj) != QTYPE_QDICT) {
+ error_setg(errp, "QMP input object member '%s' expects '%s'",
+ "arguments", "object");
+ return NULL;
+ }
+ } else {
+ error_setg(errp, "QMP input object member '%s' is unexpected",
+ arg_name);
return NULL;
}
}
if (!has_exec_key) {
- error_setg(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
+ error_setg(errp, "Expected '%s' in QMP input", "execute");
return NULL;
}
return dict;
}
-static QObject *do_qmp_dispatch(QObject *request, Error **errp)
+static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
+ Error **errp)
{
Error *local_err = NULL;
const char *command;
@@ -75,7 +82,7 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
}
command = qdict_get_str(dict, "execute");
- cmd = qmp_find_command(command);
+ cmd = qmp_find_command(cmds, command);
if (cmd == NULL) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has not been found", command);
@@ -115,13 +122,13 @@ QObject *qmp_build_error_object(Error *err)
error_get_pretty(err));
}
-QObject *qmp_dispatch(QObject *request)
+QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request)
{
Error *err = NULL;
QObject *ret;
QDict *rsp;
- ret = do_qmp_dispatch(request, &err);
+ ret = do_qmp_dispatch(cmds, request, &err);
rsp = qdict_new();
if (err) {
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index e8053686f3..5af484cd9a 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -15,11 +15,8 @@
#include "qemu/osdep.h"
#include "qapi/qmp/dispatch.h"
-static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
- QTAILQ_HEAD_INITIALIZER(qmp_commands);
-
-void qmp_register_command(const char *name, QmpCommandFunc *fn,
- QmpCommandOptions options)
+void qmp_register_command(QmpCommandList *cmds, const char *name,
+ QmpCommandFunc *fn, QmpCommandOptions options)
{
QmpCommand *cmd = g_malloc0(sizeof(*cmd));
@@ -27,22 +24,22 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn,
cmd->fn = fn;
cmd->enabled = true;
cmd->options = options;
- QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
+ QTAILQ_INSERT_TAIL(cmds, cmd, node);
}
-void qmp_unregister_command(const char *name)
+void qmp_unregister_command(QmpCommandList *cmds, const char *name)
{
- QmpCommand *cmd = qmp_find_command(name);
+ QmpCommand *cmd = qmp_find_command(cmds, name);
- QTAILQ_REMOVE(&qmp_commands, cmd, node);
+ QTAILQ_REMOVE(cmds, cmd, node);
g_free(cmd);
}
-QmpCommand *qmp_find_command(const char *name)
+QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name)
{
QmpCommand *cmd;
- QTAILQ_FOREACH(cmd, &qmp_commands, node) {
+ QTAILQ_FOREACH(cmd, cmds, node) {
if (strcmp(cmd->name, name) == 0) {
return cmd;
}
@@ -50,11 +47,12 @@ QmpCommand *qmp_find_command(const char *name)
return NULL;
}
-static void qmp_toggle_command(const char *name, bool enabled)
+static void qmp_toggle_command(QmpCommandList *cmds, const char *name,
+ bool enabled)
{
QmpCommand *cmd;
- QTAILQ_FOREACH(cmd, &qmp_commands, node) {
+ QTAILQ_FOREACH(cmd, cmds, node) {
if (strcmp(cmd->name, name) == 0) {
cmd->enabled = enabled;
return;
@@ -62,14 +60,14 @@ static void qmp_toggle_command(const char *name, bool enabled)
}
}
-void qmp_disable_command(const char *name)
+void qmp_disable_command(QmpCommandList *cmds, const char *name)
{
- qmp_toggle_command(name, false);
+ qmp_toggle_command(cmds, name, false);
}
-void qmp_enable_command(const char *name)
+void qmp_enable_command(QmpCommandList *cmds, const char *name)
{
- qmp_toggle_command(name, true);
+ qmp_toggle_command(cmds, name, true);
}
bool qmp_command_is_enabled(const QmpCommand *cmd)
@@ -87,11 +85,12 @@ bool qmp_has_success_response(const QmpCommand *cmd)
return !(cmd->options & QCO_NO_SUCCESS_RESP);
}
-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)
{
QmpCommand *cmd;
- QTAILQ_FOREACH(cmd, &qmp_commands, node) {
+ QTAILQ_FOREACH(cmd, cmds, node) {
fn(cmd, opaque);
}
}
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 0063327b3b..d192727e0b 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -21,21 +21,19 @@
#include "qapi/qmp/types.h"
#include "qapi/qmp/qerror.h"
-#define QIV_STACK_SIZE 1024
-
-typedef struct StackObject
-{
- QObject *obj; /* Object being visited */
+typedef struct StackObject {
+ const char *name; /* Name of @obj in its parent, if any */
+ QObject *obj; /* QDict or QList being visited */
void *qapi; /* sanity check that caller uses same pointer */
- GHashTable *h; /* If obj is dict: unvisited keys */
- const QListEntry *entry; /* If obj is list: unvisited tail */
+ GHashTable *h; /* If @obj is QDict: unvisited keys */
+ const QListEntry *entry; /* If @obj is QList: unvisited tail */
+ unsigned index; /* If @obj is QList: list index of @entry */
- QSLIST_ENTRY(StackObject) node;
+ QSLIST_ENTRY(StackObject) node; /* parent */
} StackObject;
-struct QObjectInputVisitor
-{
+struct QObjectInputVisitor {
Visitor visitor;
/* Root of visit at visitor creation. */
@@ -45,8 +43,7 @@ struct QObjectInputVisitor
* QDict or QList). */
QSLIST_HEAD(, StackObject) stack;
- /* True to reject parse in visit_end_struct() if unvisited keys remain. */
- bool strict;
+ GString *errname; /* Accumulator for full_name() */
};
static QObjectInputVisitor *to_qiv(Visitor *v)
@@ -54,9 +51,51 @@ static QObjectInputVisitor *to_qiv(Visitor *v)
return container_of(v, QObjectInputVisitor, visitor);
}
-static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
- const char *name,
- bool consume, Error **errp)
+static const char *full_name_nth(QObjectInputVisitor *qiv, const char *name,
+ int n)
+{
+ StackObject *so;
+ char buf[32];
+
+ if (qiv->errname) {
+ g_string_truncate(qiv->errname, 0);
+ } else {
+ qiv->errname = g_string_new("");
+ }
+
+ QSLIST_FOREACH(so , &qiv->stack, node) {
+ if (n) {
+ n--;
+ } else if (qobject_type(so->obj) == QTYPE_QDICT) {
+ g_string_prepend(qiv->errname, name ?: "<anonymous>");
+ g_string_prepend_c(qiv->errname, '.');
+ } else {
+ snprintf(buf, sizeof(buf), "[%u]", so->index);
+ g_string_prepend(qiv->errname, buf);
+ }
+ name = so->name;
+ }
+ assert(!n);
+
+ if (name) {
+ g_string_prepend(qiv->errname, name);
+ } else if (qiv->errname->str[0] == '.') {
+ g_string_erase(qiv->errname, 0, 1);
+ } else if (!qiv->errname->str[0]) {
+ return "<anonymous>";
+ }
+
+ return qiv->errname->str;
+}
+
+static const char *full_name(QObjectInputVisitor *qiv, const char *name)
+{
+ return full_name_nth(qiv, name, 0);
+}
+
+static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv,
+ const char *name,
+ bool consume)
{
StackObject *tos;
QObject *qobj;
@@ -80,22 +119,37 @@ static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
bool removed = g_hash_table_remove(tos->h, name);
assert(removed);
}
- if (!ret) {
- error_setg(errp, QERR_MISSING_PARAMETER, name);
- }
} else {
assert(qobject_type(qobj) == QTYPE_QLIST);
assert(!name);
- ret = qlist_entry_obj(tos->entry);
- assert(ret);
+ if (tos->entry) {
+ ret = qlist_entry_obj(tos->entry);
+ if (consume) {
+ tos->entry = qlist_next(tos->entry);
+ }
+ } else {
+ ret = NULL;
+ }
if (consume) {
- tos->entry = qlist_next(tos->entry);
+ tos->index++;
}
}
return ret;
}
+static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
+ const char *name,
+ bool consume, Error **errp)
+{
+ QObject *obj = qobject_input_try_get_object(qiv, name, consume);
+
+ if (!obj) {
+ error_setg(errp, QERR_MISSING_PARAMETER, full_name(qiv, name));
+ }
+ return obj;
+}
+
static void qdict_add_key(const char *key, QObject *obj, void *opaque)
{
GHashTable *h = opaque;
@@ -103,22 +157,25 @@ static void qdict_add_key(const char *key, QObject *obj, void *opaque)
}
static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv,
- QObject *obj, void *qapi,
- Error **errp)
+ const char *name,
+ QObject *obj, void *qapi)
{
GHashTable *h;
StackObject *tos = g_new0(StackObject, 1);
assert(obj);
+ tos->name = name;
tos->obj = obj;
tos->qapi = qapi;
- if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
+ if (qobject_type(obj) == QTYPE_QDICT) {
h = g_hash_table_new(g_str_hash, g_str_equal);
qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
tos->h = h;
- } else if (qobject_type(obj) == QTYPE_QLIST) {
+ } else {
+ assert(qobject_type(obj) == QTYPE_QLIST);
tos->entry = qlist_first(qobject_to_qlist(obj));
+ tos->index = -1;
}
QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
@@ -130,19 +187,15 @@ static void qobject_input_check_struct(Visitor *v, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
StackObject *tos = QSLIST_FIRST(&qiv->stack);
+ GHashTableIter iter;
+ const char *key;
assert(tos && !tos->entry);
- if (qiv->strict) {
- GHashTable *const top_ht = tos->h;
- if (top_ht) {
- GHashTableIter iter;
- const char *key;
-
- g_hash_table_iter_init(&iter, top_ht);
- if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
- error_setg(errp, QERR_QMP_EXTRA_MEMBER, key);
- }
- }
+
+ g_hash_table_iter_init(&iter, tos->h);
+ if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
+ error_setg(errp, "Parameter '%s' is unexpected",
+ full_name(qiv, key));
}
}
@@ -170,7 +223,6 @@ static void qobject_input_start_struct(Visitor *v, const char *name, void **obj,
{
QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
- Error *err = NULL;
if (obj) {
*obj = NULL;
@@ -179,16 +231,12 @@ static void qobject_input_start_struct(Visitor *v, const char *name, void **obj,
return;
}
if (qobject_type(qobj) != QTYPE_QDICT) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "QDict");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "object");
return;
}
- qobject_input_push(qiv, qobj, obj, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ qobject_input_push(qiv, name, qobj, obj);
if (obj) {
*obj = g_malloc0(size);
@@ -204,25 +252,21 @@ static void qobject_input_start_list(Visitor *v, const char *name,
QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
const QListEntry *entry;
+ if (list) {
+ *list = NULL;
+ }
if (!qobj) {
return;
}
if (qobject_type(qobj) != QTYPE_QLIST) {
- if (list) {
- *list = NULL;
- }
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "list");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "array");
return;
}
- entry = qobject_input_push(qiv, qobj, list, errp);
- if (list) {
- if (entry) {
- *list = g_malloc0(size);
- } else {
- *list = NULL;
- }
+ entry = qobject_input_push(qiv, name, qobj, list);
+ if (entry && list) {
+ *list = g_malloc0(size);
}
}
@@ -230,15 +274,30 @@ static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
size_t size)
{
QObjectInputVisitor *qiv = to_qiv(v);
- StackObject *so = QSLIST_FIRST(&qiv->stack);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+
+ assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
- if (!so->entry) {
+ if (!tos->entry) {
return NULL;
}
tail->next = g_malloc0(size);
return tail->next;
}
+static void qobject_input_check_list(Visitor *v, Error **errp)
+{
+ QObjectInputVisitor *qiv = to_qiv(v);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+
+ assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
+
+ if (tos->entry) {
+ error_setg(errp, "Only %u list elements expected in %s",
+ tos->index + 1, full_name_nth(qiv, NULL, 1));
+ }
+}
+
static void qobject_input_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
@@ -270,8 +329,8 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
}
qint = qobject_to_qint(qobj);
if (!qint) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "integer");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "integer");
return;
}
@@ -291,8 +350,8 @@ static void qobject_input_type_uint64(Visitor *v, const char *name,
}
qint = qobject_to_qint(qobj);
if (!qint) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "integer");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "integer");
return;
}
@@ -311,8 +370,8 @@ static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
}
qbool = qobject_to_qbool(qobj);
if (!qbool) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "boolean");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "boolean");
return;
}
@@ -332,8 +391,8 @@ static void qobject_input_type_str(Visitor *v, const char *name, char **obj,
}
qstr = qobject_to_qstring(qobj);
if (!qstr) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "string");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "string");
return;
}
@@ -363,8 +422,8 @@ static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
return;
}
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "number");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "number");
}
static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
@@ -392,15 +451,15 @@ static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
}
if (qobject_type(qobj) != QTYPE_QNULL) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "null");
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+ full_name(qiv, name), "null");
}
}
static void qobject_input_optional(Visitor *v, const char *name, bool *present)
{
QObjectInputVisitor *qiv = to_qiv(v);
- QObject *qobj = qobject_input_get_object(qiv, name, false, NULL);
+ QObject *qobj = qobject_input_try_get_object(qiv, name, false);
if (!qobj) {
*present = false;
@@ -413,6 +472,7 @@ static void qobject_input_optional(Visitor *v, const char *name, bool *present)
static void qobject_input_free(Visitor *v)
{
QObjectInputVisitor *qiv = to_qiv(v);
+
while (!QSLIST_EMPTY(&qiv->stack)) {
StackObject *tos = QSLIST_FIRST(&qiv->stack);
@@ -421,10 +481,13 @@ static void qobject_input_free(Visitor *v)
}
qobject_decref(qiv->root);
+ if (qiv->errname) {
+ g_string_free(qiv->errname, TRUE);
+ }
g_free(qiv);
}
-Visitor *qobject_input_visitor_new(QObject *obj, bool strict)
+Visitor *qobject_input_visitor_new(QObject *obj)
{
QObjectInputVisitor *v;
@@ -437,6 +500,7 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool strict)
v->visitor.end_struct = qobject_input_pop;
v->visitor.start_list = qobject_input_start_list;
v->visitor.next_list = qobject_input_next_list;
+ v->visitor.check_list = qobject_input_check_list;
v->visitor.end_list = qobject_input_pop;
v->visitor.start_alternate = qobject_input_start_alternate;
v->visitor.type_int64 = qobject_input_type_int64;
@@ -448,7 +512,6 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool strict)
v->visitor.type_null = qobject_input_type_null;
v->visitor.optional = qobject_input_optional;
v->visitor.free = qobject_input_free;
- v->strict = strict;
v->root = obj;
qobject_incref(obj);
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8dfa561252..806b01ae3a 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -170,6 +170,35 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
return tail->next;
}
+static void check_list(Visitor *v, Error **errp)
+{
+ const StringInputVisitor *siv = to_siv(v);
+ Range *r;
+ GList *cur_range;
+
+ if (!siv->ranges || !siv->cur_range) {
+ return;
+ }
+
+ r = siv->cur_range->data;
+ if (!r) {
+ return;
+ }
+
+ if (!range_contains(r, siv->cur)) {
+ cur_range = g_list_next(siv->cur_range);
+ if (!cur_range) {
+ return;
+ }
+ r = cur_range->data;
+ if (!r) {
+ return;
+ }
+ }
+
+ error_setg(errp, "Range contains too many values");
+}
+
static void end_list(Visitor *v, void **obj)
{
StringInputVisitor *siv = to_siv(v);
@@ -182,12 +211,6 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
{
StringInputVisitor *siv = to_siv(v);
- if (!siv->string) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "integer");
- return;
- }
-
if (parse_str(siv, name, errp) < 0) {
return;
}
@@ -242,13 +265,7 @@ static void parse_type_size(Visitor *v, const char *name, uint64_t *obj,
Error *err = NULL;
uint64_t val;
- if (siv->string) {
- parse_option_size(name, siv->string, &val, &err);
- } else {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "size");
- return;
- }
+ parse_option_size(name, siv->string, &val, &err);
if (err) {
error_propagate(errp, err);
return;
@@ -262,19 +279,17 @@ static void parse_type_bool(Visitor *v, const char *name, bool *obj,
{
StringInputVisitor *siv = to_siv(v);
- if (siv->string) {
- if (!strcasecmp(siv->string, "on") ||
- !strcasecmp(siv->string, "yes") ||
- !strcasecmp(siv->string, "true")) {
- *obj = true;
- return;
- }
- if (!strcasecmp(siv->string, "off") ||
- !strcasecmp(siv->string, "no") ||
- !strcasecmp(siv->string, "false")) {
- *obj = false;
- return;
- }
+ if (!strcasecmp(siv->string, "on") ||
+ !strcasecmp(siv->string, "yes") ||
+ !strcasecmp(siv->string, "true")) {
+ *obj = true;
+ return;
+ }
+ if (!strcasecmp(siv->string, "off") ||
+ !strcasecmp(siv->string, "no") ||
+ !strcasecmp(siv->string, "false")) {
+ *obj = false;
+ return;
}
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
@@ -285,13 +300,8 @@ static void parse_type_str(Visitor *v, const char *name, char **obj,
Error **errp)
{
StringInputVisitor *siv = to_siv(v);
- if (siv->string) {
- *obj = g_strdup(siv->string);
- } else {
- *obj = NULL;
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
- "string");
- }
+
+ *obj = g_strdup(siv->string);
}
static void parse_type_number(Visitor *v, const char *name, double *obj,
@@ -302,10 +312,8 @@ static void parse_type_number(Visitor *v, const char *name, double *obj,
double val;
errno = 0;
- if (siv->string) {
- val = strtod(siv->string, &endp);
- }
- if (!siv->string || errno || endp == siv->string || *endp) {
+ val = strtod(siv->string, &endp);
+ if (errno || endp == siv->string || *endp) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"number");
return;
@@ -314,18 +322,6 @@ static void parse_type_number(Visitor *v, const char *name, double *obj,
*obj = val;
}
-static void parse_optional(Visitor *v, const char *name, bool *present)
-{
- StringInputVisitor *siv = to_siv(v);
-
- if (!siv->string) {
- *present = false;
- return;
- }
-
- *present = true;
-}
-
static void string_input_free(Visitor *v)
{
StringInputVisitor *siv = to_siv(v);
@@ -339,6 +335,7 @@ Visitor *string_input_visitor_new(const char *str)
{
StringInputVisitor *v;
+ assert(str);
v = g_malloc0(sizeof(*v));
v->visitor.type = VISITOR_INPUT;
@@ -350,8 +347,8 @@ Visitor *string_input_visitor_new(const char *str)
v->visitor.type_number = parse_type_number;
v->visitor.start_list = start_list;
v->visitor.next_list = next_list;
+ v->visitor.check_list = check_list;
v->visitor.end_list = end_list;
- v->visitor.optional = parse_optional;
v->visitor.free = string_input_free;
v->string = str;
diff --git a/qapi/trace-events b/qapi/trace-events
index 9cbb61b2bd..339cacf0ad 100644
--- a/qapi/trace-events
+++ b/qapi/trace-events
@@ -8,6 +8,7 @@ visit_end_struct(void *v, void *obj) "v=%p obj=%p"
visit_start_list(void *v, const char *name, void *obj, size_t size) "v=%p name=%s obj=%p size=%zu"
visit_next_list(void *v, void *tail, size_t size) "v=%p tail=%p size=%zu"
+visit_check_list(void *v) "v=%p"
visit_end_list(void *v, void *obj) "v=%p obj=%p"
visit_start_alternate(void *v, const char *name, void *obj, size_t size, bool promote_int) "v=%p name=%s obj=%p size=%zu promote_int=%d"