@@ -95,7 +95,8 @@ struct Visitor
bool (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
/* Must be set */
- bool (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
+ bool (*type_str)(Visitor *v, const char *name, char **obj, bool consume,
+ Error **errp);
/* Must be set to visit numbers */
bool (*type_number)(Visitor *v, const char *name, double *obj,
@@ -654,6 +654,26 @@ bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
*/
bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
+/*
+ * Visit a string value but do not consume it.
+ *
+ * @name expresses the relationship of this string to its parent
+ * container; see the general description of @name above.
+ *
+ * @obj must be non-NULL. Input and clone visitors set *@obj to the
+ * value (always using "" rather than NULL for an empty string).
+ * Other visitors leave *@obj unchanged, and commonly treat NULL like
+ * "".
+ *
+ * This function must be called only with an input visitor.
+ *
+ * This is mostly identical with visit_type_str() but leaves the value intact.
+ * This is useful when the caller may interpret the value with a different
+ * type.
+ */
+bool visit_type_str_preserving(Visitor *v, const char *name, char **obj,
+ Error **errp);
+
/*
* Visit a number (i.e. double) value.
*
@@ -347,7 +347,8 @@ processed(OptsVisitor *ov, const char *name)
static bool
-opts_type_str(Visitor *v, const char *name, char **obj, Error **errp)
+opts_type_str(Visitor *v, const char *name, char **obj, bool consume,
+ Error **errp)
{
OptsVisitor *ov = to_ov(v);
const QemuOpt *opt;
@@ -363,7 +364,9 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp)
* valid enum value; this is harmless because tracking what gets
* consumed only matters to visit_end_struct() as the final error
* check if there were no other failures during the visit. */
- processed(ov, name);
+ if (consume) {
+ processed(ov, name);
+ }
return true;
}
@@ -108,7 +108,7 @@ static bool qapi_clone_type_bool(Visitor *v, const char *name, bool *obj,
}
static bool qapi_clone_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
QapiCloneVisitor *qcv = to_qcv(v);
@@ -62,9 +62,9 @@ static void qapi_dealloc_end_list(Visitor *v, void **obj)
}
static bool qapi_dealloc_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
- if (obj) {
+ if (obj && consume) {
g_free(*obj);
}
return true;
@@ -180,6 +180,7 @@ static bool forward_field_type_bool(Visitor *v, const char *name, bool *obj,
}
static bool forward_field_type_str(Visitor *v, const char *name, char **obj,
+ bool consume,
Error **errp)
{
ForwardFieldVisitor *ffv = to_ffv(v);
@@ -187,7 +188,8 @@ static bool forward_field_type_str(Visitor *v, const char *name, char **obj,
if (!forward_field_translate_name(ffv, &name, errp)) {
return false;
}
- return visit_type_str(ffv->target, name, obj, errp);
+ return (consume ? visit_type_str : visit_type_str_preserving)(
+ ffv->target, name, obj, errp);
}
static bool forward_field_type_size(Visitor *v, const char *name, uint64_t *obj,
@@ -336,7 +336,8 @@ bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
return v->type_bool(v, name, obj, errp);
}
-bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
+static bool visit_type_str_common(Visitor *v, const char *name, char **obj,
+ bool consume, Error **errp)
{
bool ok;
@@ -346,13 +347,25 @@ bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
assert(!(v->type & VISITOR_OUTPUT) || *obj);
*/
trace_visit_type_str(v, name, obj);
- ok = v->type_str(v, name, obj, errp);
+ ok = v->type_str(v, name, obj, consume, errp);
if (v->type & VISITOR_INPUT) {
assert(ok != !*obj);
}
return ok;
}
+bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
+{
+ return visit_type_str_common(v, name, obj, true, errp);
+}
+
+bool visit_type_str_preserving(Visitor *v, const char *name, char **obj,
+ Error **errp)
+{
+ assert(v->type & VISITOR_INPUT);
+ return visit_type_str_common(v, name, obj, false, errp);
+}
+
bool visit_type_number(Visitor *v, const char *name, double *obj,
Error **errp)
{
@@ -174,13 +174,13 @@ static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
}
static const char *qobject_input_get_keyval(QObjectInputVisitor *qiv,
- const char *name,
+ const char *name, bool consume,
Error **errp)
{
QObject *qobj;
QString *qstr;
- qobj = qobject_input_get_object(qiv, name, true, errp);
+ qobj = qobject_input_get_object(qiv, name, consume, errp);
if (!qobj) {
return NULL;
}
@@ -416,7 +416,7 @@ static bool qobject_input_type_int64_keyval(Visitor *v, const char *name,
int64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, true, errp);
if (!str) {
return false;
@@ -467,7 +467,7 @@ static bool qobject_input_type_uint64_keyval(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, true, errp);
if (!str) {
return false;
@@ -507,7 +507,7 @@ static bool qobject_input_type_bool_keyval(Visitor *v, const char *name,
bool *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, true, errp);
if (!str) {
return false;
@@ -522,10 +522,10 @@ static bool qobject_input_type_bool_keyval(Visitor *v, const char *name,
}
static bool qobject_input_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+ QObject *qobj = qobject_input_get_object(qiv, name, consume, errp);
QString *qstr;
*obj = NULL;
@@ -544,10 +544,11 @@ static bool qobject_input_type_str(Visitor *v, const char *name, char **obj,
}
static bool qobject_input_type_str_keyval(Visitor *v, const char *name,
- char **obj, Error **errp)
+ char **obj, bool consume,
+ Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, consume, errp);
*obj = g_strdup(str);
return !!str;
@@ -578,7 +579,7 @@ static bool qobject_input_type_number_keyval(Visitor *v, const char *name,
double *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, true, errp);
double val;
if (!str) {
@@ -635,7 +636,7 @@ static bool qobject_input_type_size_keyval(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
- const char *str = qobject_input_get_keyval(qiv, name, errp);
+ const char *str = qobject_input_get_keyval(qiv, name, true, errp);
if (!str) {
return false;
@@ -173,7 +173,7 @@ static bool qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
}
static bool qobject_output_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
QObjectOutputVisitor *qov = to_qov(v);
if (*obj) {
@@ -336,7 +336,7 @@ static bool parse_type_bool(Visitor *v, const char *name, bool *obj,
}
static bool parse_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
StringInputVisitor *siv = to_siv(v);
@@ -269,7 +269,7 @@ static bool print_type_bool(Visitor *v, const char *name, bool *obj,
}
static bool print_type_str(Visitor *v, const char *name, char **obj,
- Error **errp)
+ bool consume, Error **errp)
{
StringOutputVisitor *sov = to_sov(v);
char *out;
visit_type_str_preserving() is mostly indentical with visit_type_str() but leaves the value intact. This is useful when the caller may interpret the value with a different type. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> --- include/qapi/visitor-impl.h | 3 ++- include/qapi/visitor.h | 20 ++++++++++++++++++++ qapi/opts-visitor.c | 7 +++++-- qapi/qapi-clone-visitor.c | 2 +- qapi/qapi-dealloc-visitor.c | 4 ++-- qapi/qapi-forward-visitor.c | 4 +++- qapi/qapi-visit-core.c | 17 +++++++++++++++-- qapi/qobject-input-visitor.c | 23 ++++++++++++----------- qapi/qobject-output-visitor.c | 2 +- qapi/string-input-visitor.c | 2 +- qapi/string-output-visitor.c | 2 +- 11 files changed, 63 insertions(+), 23 deletions(-)