From: "Michael S. Tsirkin" <mst@redhat.com>
To: Hu Tao <hutao@cn.fujitsu.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
qemu-devel@nongnu.org, Igor Mammedov <imammedo@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3.2 27/31] qapi: make string input visitor parse int list
Date: Sun, 8 Jun 2014 13:11:03 +0300 [thread overview]
Message-ID: <20140608101103.GF21677@redhat.com> (raw)
In-Reply-To: <cd5ad5f646f665b0d62a2693de1dfdc2dd071a16.1400049817.git.hutao@cn.fujitsu.com>
On Wed, May 14, 2014 at 05:43:31PM +0800, Hu Tao wrote:
> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Conflicts with
commit e2cd0f4fb42b1fae65ad22e8efde9804446e6254
qapi: Replace start_optional()/end_optional() by optional()
needs a rebase.
> ---
> qapi/string-input-visitor.c | 181 ++++++++++++++++++++++++++++++++++++--
> tests/test-string-input-visitor.c | 39 ++++++++
> 2 files changed, 212 insertions(+), 8 deletions(-)
>
> diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
> index 793548a..0f6add7 100644
> --- a/qapi/string-input-visitor.c
> +++ b/qapi/string-input-visitor.c
> @@ -15,31 +15,182 @@
> #include "qapi/visitor-impl.h"
> #include "qapi/qmp/qerror.h"
> #include "qemu/option.h"
> +#include "qemu/queue.h"
> +#include "qemu/range.h"
> +
>
> struct StringInputVisitor
> {
> Visitor visitor;
> +
> + bool head;
> +
> + SignedRangeList *ranges;
> + SignedRange *cur_range;
> + int64_t cur;
> +
> const char *string;
> };
>
> +static void parse_str(StringInputVisitor *siv, Error **errp)
> +{
> + char *str = (char *) siv->string;
> + long long start, end;
> + SignedRange *r, *next;
> + char *endptr;
> +
> + if (siv->ranges) {
> + return;
> + }
> +
> + siv->ranges = g_malloc0(sizeof(*siv->ranges));
> + QTAILQ_INIT(siv->ranges);
> + errno = 0;
> + do {
> + start = strtoll(str, &endptr, 0);
> + if (errno == 0 && endptr > str && INT64_MIN <= start &&
> + start <= INT64_MAX) {
> + if (*endptr == '\0') {
> + if (!range_list_add(siv->ranges, start, 1)) {
> + goto error;
> + }
> + str = NULL;
> + } else if (*endptr == '-') {
> + str = endptr + 1;
> + end = strtoll(str, &endptr, 0);
> + if (errno == 0 && endptr > str &&
> + INT64_MIN <= end && end <= INT64_MAX && start <= end &&
> + (start > INT64_MAX - 65536 ||
> + end < start + 65536)) {
> + if (*endptr == '\0') {
> + if (!range_list_add(siv->ranges, start,
> + end - start + 1)) {
> + goto error;
> + }
> + str = NULL;
> + } else if (*endptr == ',') {
> + str = endptr + 1;
> + if (!range_list_add(siv->ranges, start,
> + end - start + 1)) {
> + goto error;
> + }
> + } else {
> + goto error;
> + }
> + } else {
> + goto error;
> + }
> + } else if (*endptr == ',') {
> + str = endptr + 1;
> + if (!range_list_add(siv->ranges, start, 1)) {
> + goto error;
> + }
> + } else {
> + goto error;
> + }
> + } else {
> + goto error;
> + }
> + } while (str);
> +
> + return;
> +error:
> + if (siv->ranges) {
> + QTAILQ_FOREACH_SAFE(r, siv->ranges, entry, next) {
> + QTAILQ_REMOVE(siv->ranges, r, entry);
> + g_free(r);
> + }
> + g_free(siv->ranges);
> + siv->ranges = NULL;
> + }
> +}
> +
> +static void
> +start_list(Visitor *v, const char *name, Error **errp)
> +{
> + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> +
> + parse_str(siv, errp);
> +
> + if (siv->ranges) {
> + siv->cur_range = QTAILQ_FIRST(siv->ranges);
> + if (siv->cur_range) {
> + siv->cur = siv->cur_range->start;
> + }
> + }
> +}
> +
> +static GenericList *
> +next_list(Visitor *v, GenericList **list, Error **errp)
> +{
> + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> + GenericList **link;
> +
> + if (!siv->ranges || !siv->cur_range) {
> + return NULL;
> + }
> +
> + if (siv->cur < siv->cur_range->start ||
> + siv->cur >= (siv->cur_range->start + siv->cur_range->length)) {
> + siv->cur_range = QTAILQ_NEXT(siv->cur_range, entry);
> + if (siv->cur_range) {
> + siv->cur = siv->cur_range->start;
> + } else {
> + return NULL;
> + }
> + }
> +
> + if (siv->head) {
> + link = list;
> + siv->head = false;
> + } else {
> + link = &(*list)->next;
> + }
> +
> + *link = g_malloc0(sizeof **link);
> + return *link;
> +}
> +
> +static void
> +end_list(Visitor *v, Error **errp)
> +{
> + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> + siv->head = true;
> +}
> +
> static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
> Error **errp)
> {
> StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> - char *endp = (char *) siv->string;
> - long long val;
>
> - errno = 0;
> - if (siv->string) {
> - val = strtoll(siv->string, &endp, 0);
> - }
> - if (!siv->string || errno || endp == siv->string || *endp) {
> + if (!siv->string) {
> error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
> "integer");
> return;
> }
>
> - *obj = val;
> + parse_str(siv, errp);
> +
> + if (!siv->ranges) {
> + goto error;
> + }
> +
> + if (!siv->cur_range) {
> + siv->cur_range = QTAILQ_FIRST(siv->ranges);
> + if (siv->cur_range) {
> + siv->cur = siv->cur_range->start;
> + } else {
> + goto error;
> + }
> + }
> +
> + *obj = siv->cur;
> + siv->cur++;
> + return;
> +
> +error:
> + error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
> + "an int64 value or range");
> }
>
> static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
> @@ -140,6 +291,16 @@ Visitor *string_input_get_visitor(StringInputVisitor *v)
>
> void string_input_visitor_cleanup(StringInputVisitor *v)
> {
> + SignedRange *r, *next;
> +
> + if (v->ranges) {
> + QTAILQ_FOREACH_SAFE(r, v->ranges, entry, next) {
> + QTAILQ_REMOVE(v->ranges, r, entry);
> + g_free(r);
> + }
> + g_free(v->ranges);
> + }
> +
> g_free(v);
> }
>
> @@ -155,8 +316,12 @@ StringInputVisitor *string_input_visitor_new(const char *str)
> v->visitor.type_bool = parse_type_bool;
> v->visitor.type_str = parse_type_str;
> v->visitor.type_number = parse_type_number;
> + v->visitor.start_list = start_list;
> + v->visitor.next_list = next_list;
> + v->visitor.end_list = end_list;
> v->visitor.start_optional = parse_start_optional;
>
> v->string = str;
> + v->head = true;
> return v;
> }
> diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
> index 877e737..05b3dab 100644
> --- a/tests/test-string-input-visitor.c
> +++ b/tests/test-string-input-visitor.c
> @@ -64,6 +64,35 @@ static void test_visitor_in_int(TestInputVisitorData *data,
> g_assert_cmpint(res, ==, value);
> }
>
> +static void test_visitor_in_intList(TestInputVisitorData *data,
> + const void *unused)
> +{
> + int64_t value[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
> + int16List *res = NULL, *tmp;
> + Error *errp = NULL;
> + Visitor *v;
> + int i = 0;
> +
> + v = visitor_input_test_init(data, "1,2,-2-1,2-4,20,5-9,1-8");
> +
> + visit_type_int16List(v, &res, NULL, &errp);
> + g_assert(!error_is_set(&errp));
> + tmp = res;
> + while (i < sizeof(value) / sizeof(value[0])) {
> + g_assert(tmp);
> + g_assert_cmpint(tmp->value, ==, value[i++]);
> + tmp = tmp->next;
> + }
> + g_assert(!tmp);
> +
> + tmp = res;
> + while (tmp) {
> + res = res->next;
> + g_free(tmp);
> + tmp = res;
> + }
> +}
> +
> static void test_visitor_in_bool(TestInputVisitorData *data,
> const void *unused)
> {
> @@ -170,6 +199,7 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
> const void *unused)
> {
> int64_t ires;
> + intList *ilres;
> bool bres;
> double nres;
> char *sres;
> @@ -193,6 +223,11 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
>
> v = visitor_input_test_init(data, buf);
> visit_type_int(v, &ires, NULL, NULL);
> + visitor_input_teardown(data, NULL);
> +
> + v = visitor_input_test_init(data, buf);
> + visit_type_intList(v, &ilres, NULL, NULL);
> + visitor_input_teardown(data, NULL);
>
> v = visitor_input_test_init(data, buf);
> visit_type_bool(v, &bres, NULL, NULL);
> @@ -200,11 +235,13 @@ static void test_visitor_in_fuzz(TestInputVisitorData *data,
>
> v = visitor_input_test_init(data, buf);
> visit_type_number(v, &nres, NULL, NULL);
> + visitor_input_teardown(data, NULL);
>
> v = visitor_input_test_init(data, buf);
> sres = NULL;
> visit_type_str(v, &sres, NULL, NULL);
> g_free(sres);
> + visitor_input_teardown(data, NULL);
>
> v = visitor_input_test_init(data, buf);
> visit_type_EnumOne(v, &eres, NULL, NULL);
> @@ -228,6 +265,8 @@ int main(int argc, char **argv)
>
> input_visitor_test_add("/string-visitor/input/int",
> &in_visitor_data, test_visitor_in_int);
> + input_visitor_test_add("/string-visitor/input/intList",
> + &in_visitor_data, test_visitor_in_intList);
> input_visitor_test_add("/string-visitor/input/bool",
> &in_visitor_data, test_visitor_in_bool);
> input_visitor_test_add("/string-visitor/input/number",
> --
> 1.8.5.2.229.g4448466
>
next prev parent reply other threads:[~2014-06-08 10:10 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-14 9:43 [Qemu-devel] [PATCH v3.2 00/31] NUMA series, and hostmem improvements Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 01/31] NUMA: move numa related code to new file numa.c Hu Tao
2014-06-08 10:09 ` Michael S. Tsirkin
2014-06-09 2:22 ` Hu Tao
2014-06-09 6:26 ` Michael S. Tsirkin
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 02/31] NUMA: check if the total numa memory size is equal to ram_size Hu Tao
2014-06-08 10:09 ` Michael S. Tsirkin
2014-06-09 2:23 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 03/31] NUMA: Add numa_info structure to contain numa nodes info Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 04/31] NUMA: convert -numa option to use OptsVisitor Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 05/31] NUMA: expand MAX_NODES from 64 to 128 Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 06/31] man: improve -numa doc Hu Tao
2014-05-14 20:11 ` Eduardo Habkost
2014-06-08 10:09 ` Michael S. Tsirkin
2014-06-09 2:23 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 07/31] vl: redo -object parsing Hu Tao
2014-06-08 9:05 ` Michael S. Tsirkin
2014-06-09 2:13 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 08/31] qmp: allow object-add completion handler to get canonical path Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 09/31] qmp: improve error reporting for -object and object-add Hu Tao
2014-05-14 20:13 ` Eduardo Habkost
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 10/31] pc: pass QEMUMachineInitArgs to pc_memory_init Hu Tao
2014-05-14 20:14 ` Eduardo Habkost
2014-06-08 9:40 ` Michael S. Tsirkin
2014-06-09 2:13 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 11/31] numa: introduce memory_region_allocate_system_memory Hu Tao
2014-05-14 20:30 ` Eduardo Habkost
2014-06-09 2:24 ` Hu Tao
2014-06-08 10:10 ` Michael S. Tsirkin
2014-06-09 2:27 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 12/31] add memdev backend infrastructure Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 13/31] numa: add -numa node, memdev= option Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 14/31] memory: reorganize file-based allocation Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 15/31] memory: move mem_path handling to memory_region_allocate_system_memory Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 16/31] memory: add error propagation to file-based RAM allocation Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 17/31] memory: move preallocation code out of exec.c Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 18/31] memory: move RAM_PREALLOC_MASK to exec.c, rename Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 19/31] hostmem: add file-based HostMemoryBackend Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 20/31] hostmem: separate allocation from UserCreatable complete method Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 21/31] hostmem: add merge and dump properties Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 22/31] hostmem: allow preallocation of any memory region Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 23/31] hostmem: add property to map memory with MAP_SHARED Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 24/31] configure: add Linux libnuma detection Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 25/31] hostmem: add properties for NUMA memory policy Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 26/31] Introduce signed range Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 27/31] qapi: make string input visitor parse int list Hu Tao
2014-06-08 10:11 ` Michael S. Tsirkin [this message]
2014-06-09 2:28 ` Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 28/31] qapi: make string output " Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 29/31] qom: introduce object_property_get_enum and object_property_get_uint16List Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 30/31] qmp: add query-memdev Hu Tao
2014-05-14 9:43 ` [Qemu-devel] [PATCH v3.2 31/31] hmp: add info memdev Hu Tao
2014-06-08 10:10 ` Michael S. Tsirkin
2014-06-09 2:28 ` Hu Tao
2014-06-08 10:11 ` [Qemu-devel] [PATCH v3.2 00/31] NUMA series, and hostmem improvements Michael S. Tsirkin
2014-06-09 2:30 ` Hu Tao
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=20140608101103.GF21677@redhat.com \
--to=mst@redhat.com \
--cc=hutao@cn.fujitsu.com \
--cc=imammedo@redhat.com \
--cc=pbonzini@redhat.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).