From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eric Blake <eblake@redhat.com>, Alexander Graf <agraf@suse.de>,
Richard Henderson <rth@twiddle.net>,
Paolo Bonzini <pbonzini@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Igor Mammedov <imammedo@redhat.com>,
Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH 2/4] string-input-visitor: Support alternate types
Date: Tue, 2 May 2017 17:31:13 -0300 [thread overview]
Message-ID: <20170502203115.22233-3-ehabkost@redhat.com> (raw)
In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com>
When parsing alternates from a string, there are some limitations in
what we can do, but it is a valid use case in some situations. We can
support booleans, integer types, and enums.
This will be used to support 'feature=force' in -cpu options, while
keeping 'feature=on|off|true|false' represented as boolean values.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
qapi/string-input-visitor.c | 71 ++++++++++++++++++++++----
tests/test-string-input-visitor.c | 89 +++++++++++++++++++++++++++++++++
tests/qapi-schema/qapi-schema-test.json | 8 +++
3 files changed, 158 insertions(+), 10 deletions(-)
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index c089491c24..bf8f58748b 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -19,6 +19,7 @@
#include "qemu/option.h"
#include "qemu/queue.h"
#include "qemu/range.h"
+#include "qemu/bitops.h"
struct StringInputVisitor
@@ -278,21 +279,34 @@ static void parse_type_size(Visitor *v, const char *name, uint64_t *obj,
*obj = val;
}
+static int try_parse_bool(const char *s, bool *result)
+{
+ if (!strcasecmp(s, "on") ||
+ !strcasecmp(s, "yes") ||
+ !strcasecmp(s, "true")) {
+ if (result) {
+ *result = true;
+ }
+ return 0;
+ }
+ if (!strcasecmp(s, "off") ||
+ !strcasecmp(s, "no") ||
+ !strcasecmp(s, "false")) {
+ if (result) {
+ *result = false;
+ }
+ return 0;
+ }
+
+ return -1;
+}
+
static void parse_type_bool(Visitor *v, const char *name, bool *obj,
Error **errp)
{
StringInputVisitor *siv = to_siv(v);
- 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;
+ if (try_parse_bool(siv->string, obj) == 0) {
return;
}
@@ -326,6 +340,42 @@ static void parse_type_number(Visitor *v, const char *name, double *obj,
*obj = val;
}
+/* Support for alternates on string-input-visitor is limited, because
+ * the input string doesn't have any type information.
+ *
+ * Supported alternate member types:
+ * 1) enums
+ * 2) integer types
+ * 3) booleans (but only if the there's no enum variant
+ * containing "on", "off", "true", or "false" as members)
+ *
+ * UNSUPPORTED alternate member types:
+ * 1) strings
+ * 2) complex types
+ */
+static void start_alternate(Visitor *v, const char *name,
+ GenericAlternate **obj, size_t size,
+ unsigned long supported_qtypes, Error **errp)
+{
+ StringInputVisitor *siv = to_siv(v);
+ QType t = QTYPE_QSTRING;
+
+ if (supported_qtypes & BIT(QTYPE_QBOOL)) {
+ if (try_parse_bool(siv->string, NULL) == 0) {
+ t = QTYPE_QBOOL;
+ }
+ }
+
+ if (supported_qtypes & BIT(QTYPE_QINT)) {
+ if (parse_str(siv, name, NULL) == 0) {
+ t = QTYPE_QINT;
+ }
+ }
+
+ *obj = g_malloc0(size);
+ (*obj)->type = t;
+}
+
static void string_input_free(Visitor *v)
{
StringInputVisitor *siv = to_siv(v);
@@ -353,6 +403,7 @@ Visitor *string_input_visitor_new(const char *str)
v->visitor.next_list = next_list;
v->visitor.check_list = check_list;
v->visitor.end_list = end_list;
+ v->visitor.start_alternate = start_alternate;
v->visitor.free = string_input_free;
v->string = str;
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 79313a7f7a..1e867d62c9 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -290,6 +290,91 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
}
}
+static void test_visitor_in_alt_bool_enum(TestInputVisitorData *data,
+ const void *unused)
+{
+ Error *err = NULL;
+ Visitor *v;
+ AltBoolEnum *be = NULL;
+
+ v = visitor_input_test_init(data, "true");
+ visit_type_AltBoolEnum(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QBOOL);
+ g_assert(be->u.b);
+ qapi_free_AltBoolEnum(be);
+
+ v = visitor_input_test_init(data, "off");
+ visit_type_AltBoolEnum(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QBOOL);
+ g_assert(!be->u.b);
+ qapi_free_AltBoolEnum(be);
+
+ v = visitor_input_test_init(data, "value2");
+ visit_type_AltBoolEnum(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QSTRING);
+ g_assert_cmpint(be->u.e, ==, ENUM_ONE_VALUE2);
+ qapi_free_AltBoolEnum(be);
+
+ v = visitor_input_test_init(data, "value100");
+ visit_type_AltBoolEnum(v, NULL, &be, &err);
+ error_free_or_abort(&err);
+ qapi_free_AltBoolEnum(be);
+
+ v = visitor_input_test_init(data, "10");
+ visit_type_AltBoolEnum(v, NULL, &be, &err);
+ error_free_or_abort(&err);
+ qapi_free_AltBoolEnum(be);
+}
+
+static void test_visitor_in_alt_enum_int(TestInputVisitorData *data,
+ const void *unused)
+{
+ Error *err = NULL;
+ Visitor *v;
+ AltOnOffInt *be = NULL;
+
+ v = visitor_input_test_init(data, "on");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QSTRING);
+ g_assert_cmpint(be->u.o, ==, TEST_ON_OFF_AUTO_ON);
+ qapi_free_AltOnOffInt(be);
+
+ v = visitor_input_test_init(data, "off");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QSTRING);
+ g_assert_cmpint(be->u.o, ==, TEST_ON_OFF_AUTO_OFF);
+ qapi_free_AltOnOffInt(be);
+
+ v = visitor_input_test_init(data, "auto");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QSTRING);
+ g_assert_cmpint(be->u.o, ==, TEST_ON_OFF_AUTO_AUTO);
+ qapi_free_AltOnOffInt(be);
+
+ v = visitor_input_test_init(data, "-12345");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ g_assert(!err);
+ g_assert_cmpint(be->type, ==, QTYPE_QINT);
+ g_assert_cmpint(be->u.i, ==, -12345);
+ qapi_free_AltOnOffInt(be);
+
+ v = visitor_input_test_init(data, "true");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ error_free_or_abort(&err);
+ qapi_free_AltOnOffInt(be);
+
+ v = visitor_input_test_init(data, "value2");
+ visit_type_AltOnOffInt(v, NULL, &be, &err);
+ error_free_or_abort(&err);
+ qapi_free_AltOnOffInt(be);
+}
+
/* Try to crash the visitors */
static void test_visitor_in_fuzz(TestInputVisitorData *data,
const void *unused)
@@ -366,6 +451,10 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_string);
input_visitor_test_add("/string-visitor/input/enum",
&in_visitor_data, test_visitor_in_enum);
+ input_visitor_test_add("/string-visitor/input/alternate/bool_enum",
+ &in_visitor_data, test_visitor_in_alt_bool_enum);
+ input_visitor_test_add("/string-visitor/input/alternate/enum_int",
+ &in_visitor_data, test_visitor_in_alt_enum_int);
input_visitor_test_add("/string-visitor/input/fuzz",
&in_visitor_data, test_visitor_in_fuzz);
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 842ea3c5e3..231c8952e8 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -106,6 +106,14 @@
{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
+
+# for testing string-input-visitor handling of alternates:
+{ 'enum': 'TestOnOffAuto',
+ 'data': [ 'on', 'off', 'auto' ] }
+
+{ 'alternate': 'AltBoolEnum', 'data': { 'b': 'bool', 'e': 'EnumOne' } }
+{ 'alternate': 'AltOnOffInt', 'data': { 'o': 'TestOnOffAuto', 'i': 'int' } }
+
# for testing native lists
{ 'union': 'UserDefNativeListUnion',
'data': { 'integer': ['int'],
--
2.11.0.259.g40922b1
next prev parent reply other threads:[~2017-05-02 20:31 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-02 20:31 [Qemu-devel] [PATCH 0/4] x86: Support "-cpu feature=force" Eduardo Habkost
2017-05-02 20:31 ` [Qemu-devel] [PATCH 1/4] visitor: Add 'supported_qtypes' parameter to visit_start_alternate() Eduardo Habkost
2017-05-02 21:29 ` Eric Blake
2017-05-02 22:35 ` Eduardo Habkost
2017-05-03 15:41 ` Markus Armbruster
2017-05-02 20:31 ` Eduardo Habkost [this message]
2017-05-02 21:37 ` [Qemu-devel] [PATCH 2/4] string-input-visitor: Support alternate types Eric Blake
2017-05-02 22:51 ` Eduardo Habkost
2017-05-03 16:07 ` Markus Armbruster
2017-05-03 18:30 ` Eduardo Habkost
2017-05-04 8:06 ` Markus Armbruster
2017-05-04 13:23 ` Eric Blake
2017-05-04 13:42 ` Markus Armbruster
2017-05-04 14:10 ` Eduardo Habkost
2017-05-04 19:42 ` Eduardo Habkost
2017-05-04 20:03 ` Eric Blake
2017-05-04 20:18 ` Eduardo Habkost
2017-05-05 6:26 ` Markus Armbruster
2017-05-02 20:31 ` [Qemu-devel] [PATCH 3/4] tests: Add [+-]feature and feature=on|off test cases Eduardo Habkost
2017-05-02 20:31 ` [Qemu-devel] [PATCH 4/4] x86: Support feature=force on the command-line Eduardo Habkost
2017-05-02 20:43 ` [Qemu-devel] [PATCH] fixup! tests: Add [+-]feature and feature=on|off test cases Eduardo Habkost
2017-05-02 21:42 ` [Qemu-devel] [PATCH 4/4] x86: Support feature=force on the command-line Eric Blake
2017-05-02 22:51 ` Eduardo Habkost
2017-05-04 9:49 ` Igor Mammedov
2017-05-05 17:21 ` Eduardo Habkost
2017-05-04 10:16 ` Kashyap Chamarthy
2017-05-05 17:59 ` Eduardo Habkost
2017-05-08 10:56 ` Kashyap Chamarthy
2017-05-02 20:46 ` [Qemu-devel] [PATCH 0/4] x86: Support "-cpu feature=force" no-reply
2017-05-02 21:01 ` Eduardo Habkost
2017-05-02 20:47 ` no-reply
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=20170502203115.22233-3-ehabkost@redhat.com \
--to=ehabkost@redhat.com \
--cc=agraf@suse.de \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=imammedo@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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).