From: Paolo Bonzini <pbonzini@redhat.com>
To: Hu Tao <hutao@cn.fujitsu.com>, qemu-devel@nongnu.org
Cc: imammedo@redhat.com, Hu Tao <hu.taoo@gmail.com>,
gaowanlong@cn.fujitsu.com
Subject: Re: [Qemu-devel] [PATCH v19 07/11] qapi: make string output visitor parse int list
Date: Tue, 04 Mar 2014 10:03:49 +0100 [thread overview]
Message-ID: <531596F5.3070001@redhat.com> (raw)
In-Reply-To: <b53310c63a7d8d368237dbc972cf392015475fd3.1393917248.git.hutao@cn.fujitsu.com>
Il 04/03/2014 08:28, Hu Tao ha scritto:
> From: Hu Tao <hu.taoo@gmail.com>
>
> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
> ---
> qapi/string-output-visitor.c | 156 +++++++++++++++++++++++++++++++++++--
> tests/test-string-output-visitor.c | 26 +++++++
> 2 files changed, 177 insertions(+), 5 deletions(-)
>
> diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
> index fb1d2e8..bc9bb36 100644
> --- a/qapi/string-output-visitor.c
> +++ b/qapi/string-output-visitor.c
> @@ -17,11 +17,57 @@
> #include "qemu/host-utils.h"
> #include <math.h>
>
> +enum ListMode {
> + LM_NONE, /* not traversing a list of repeated options */
> + LM_STARTED, /* start_list() succeeded */
> +
> + LM_IN_PROGRESS, /* next_list() has been called.
> + *
> + * Generating the next list link will consume the most
> + * recently parsed QemuOpt instance of the repeated
> + * option.
> + *
> + * Parsing a value into the list link will examine the
> + * next QemuOpt instance of the repeated option, and
> + * possibly enter LM_SIGNED_INTERVAL or
> + * LM_UNSIGNED_INTERVAL.
> + */
> +
> + LM_SIGNED_INTERVAL, /* next_list() has been called.
> + *
> + * Generating the next list link will consume the most
> + * recently stored element from the signed interval,
> + * parsed from the most recent QemuOpt instance of the
> + * repeated option. This may consume QemuOpt itself
> + * and return to LM_IN_PROGRESS.
> + *
> + * Parsing a value into the list link will store the
> + * next element of the signed interval.
> + */
> +
> + LM_UNSIGNED_INTERVAL,/* Same as above, only for an unsigned interval. */
> +
> + LM_END
> +};
> +
> +typedef enum ListMode ListMode;
> +
> struct StringOutputVisitor
> {
> Visitor visitor;
> bool human;
> + bool head;
> char *string;
> + ListMode list_mode;
> + /* When parsing a list of repeating options as integers, values of the form
> + * "a-b", representing a closed interval, are allowed. Elements in the
> + * range are generated individually.
> + */
> + union {
> + int64_t s;
> + uint64_t u;
> + } range_start, range_end;
> +
> };
>
> static void string_output_set(StringOutputVisitor *sov, char *string)
> @@ -34,13 +80,60 @@ static void print_type_int(Visitor *v, int64_t *obj, const char *name,
> Error **errp)
> {
> StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> - char *out;
> + char *out = NULL;
>
> - if (sov->human) {
> - out = g_strdup_printf("%lld (%#llx)", (long long) *obj, (long long) *obj);
> - } else {
> - out = g_strdup_printf("%lld", (long long) *obj);
> + switch (sov->list_mode) {
> + case LM_NONE:
> + if (sov->human) {
> + out = g_strdup_printf("%lld (%#llx)", (long long) *obj,
> + (long long) *obj);
> + } else {
> + out = g_strdup_printf("%lld", (long long) *obj);
> + }
> + sov->list_mode = LM_END;
> + break;
> +
> + case LM_STARTED:
> + sov->range_start.s = *obj;
> + sov->range_end.s = *obj;
> + sov->list_mode = LM_IN_PROGRESS;
> + break;
> +
> + case LM_IN_PROGRESS:
> + assert(sov->range_end.s + 1 == *obj);
> + sov->range_end.s++;
> + break;
> +
> + case LM_END:
> + assert(sov->range_end.s + 1 == *obj);
> + sov->range_end.s++;
> + if (sov->range_end.s == sov->range_start.s) {
> + if (sov->human) {
> + out = g_strdup_printf("%lld (%#llx)",
> + (long long)sov->range_start.s,
> + (long long)sov->range_start.s);
> + } else {
> + out = g_strdup_printf("%lld", (long long)sov->range_start.s);
> + }
> + } else {
> + if (sov->human) {
> + out = g_strdup_printf("%lld(%#llx)-%lld(%#llx)",
> + (long long) sov->range_start.s,
> + (long long) sov->range_start.s,
> + (long long) sov->range_end.s,
> + (long long) sov->range_end.s);
Perhaps "10-15 (0xa-0xf)"?
> + } else {
> + out = g_strdup_printf("%lld-%lld",
> + (long long) sov->range_start.s,
> + (long long) sov->range_end.s);
> + }
> + }
This looks wrong. You do not insert any separator, and you do not
handle things like "0-3,8-11". You probably should use a GString
instead of string_output_set.
Paolo
> + break;
> +
> + default:
> + abort();
> }
> +
> string_output_set(sov, out);
> }
>
> @@ -103,6 +196,56 @@ static void print_type_number(Visitor *v, double *obj, const char *name,
> string_output_set(sov, g_strdup_printf("%f", *obj));
> }
>
> +static void
> +start_list(Visitor *v, const char *name, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> +
> + /* we can't traverse a list in a list */
> + assert(sov->list_mode == LM_NONE);
> + sov->list_mode = LM_STARTED;
> + sov->head = true;
> +}
> +
> +static GenericList *
> +next_list(Visitor *v, GenericList **list, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> + GenericList *ret = NULL;
> + if (*list) {
> + if (sov->head) {
> + ret = *list;
> + } else {
> + ret = (*list)->next;
> + }
> +
> + if (sov->head) {
> + if (ret && ret->next == NULL) {
> + sov->list_mode = LM_NONE;
> + }
> + sov->head = false;
> + } else {
> + if (ret && ret->next == NULL) {
> + sov->list_mode = LM_END;
> + }
> + }
> + }
> +
> + return ret;
> +}
> +
> +static void
> +end_list(Visitor *v, Error **errp)
> +{
> + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);
> +
> + assert(sov->list_mode == LM_STARTED ||
> + sov->list_mode == LM_END ||
> + sov->list_mode == LM_IN_PROGRESS);
> + sov->list_mode = LM_NONE;
> + sov->head = true;
> +}
> +
> char *string_output_get_string(StringOutputVisitor *sov)
> {
> char *string = sov->string;
> @@ -134,6 +277,9 @@ StringOutputVisitor *string_output_visitor_new(bool human)
> v->visitor.type_bool = print_type_bool;
> v->visitor.type_str = print_type_str;
> v->visitor.type_number = print_type_number;
> + v->visitor.start_list = start_list;
> + v->visitor.next_list = next_list;
> + v->visitor.end_list = end_list;
>
> return v;
> }
> diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
> index 22363d1..511ef14 100644
> --- a/tests/test-string-output-visitor.c
> +++ b/tests/test-string-output-visitor.c
> @@ -57,6 +57,30 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
> g_free(str);
> }
>
> +static void test_visitor_out_intList(TestOutputVisitorData *data,
> + const void *unused)
> +{
> + int64_t value[] = {-2, -1, 0, 1, 2, 3, 4};
> + intList *list = NULL, **tmp = &list;
> + int i;
> + Error *errp = NULL;
> + char *str;
> +
> + for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
> + *tmp = g_malloc0(sizeof(**tmp));
> + (*tmp)->value = value[i];
> + tmp = &(*tmp)->next;
> + }
> +
> + visit_type_intList(data->ov, &list, NULL, &errp);
> + g_assert(error_is_set(&errp) == 0);
> +
> + str = string_output_get_string(data->sov);
> + g_assert(str != NULL);
> + g_assert_cmpstr(str, ==, "-2-4");
> + g_free(str);
> +}
> +
> static void test_visitor_out_bool(TestOutputVisitorData *data,
> const void *unused)
> {
> @@ -182,6 +206,8 @@ int main(int argc, char **argv)
> &out_visitor_data, test_visitor_out_enum);
> output_visitor_test_add("/string-visitor/output/enum-errors",
> &out_visitor_data, test_visitor_out_enum_errors);
> + output_visitor_test_add("/string-visitor/output/intList",
> + &out_visitor_data, test_visitor_out_intList);
>
> g_test_run();
>
>
next prev parent reply other threads:[~2014-03-04 9:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-04 7:28 [Qemu-devel] [PATCH v19 00/11] Add support for binding guest numa nodes to host numa nodes Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 01/11] object_add: allow completion handler to get canonical path Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 02/11] add memdev backend infrastructure Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 03/11] pc: pass QEMUMachineInitArgs to pc_memory_init Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 04/11] numa: introduce memory_region_allocate_system_memory Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 05/11] numa: add -numa node, memdev= option Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 06/11] qapi: make string input visitor parse int list Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 07/11] qapi: make string output " Hu Tao
2014-03-04 9:03 ` Paolo Bonzini [this message]
2014-03-04 9:23 ` Hu Tao
2014-03-04 9:33 ` Paolo Bonzini
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 08/11] Add Linux libnuma detection Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 09/11] hostmem backend: implement memory policy Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 10/11] qmp: add query-memdev Hu Tao
2014-03-04 7:28 ` [Qemu-devel] [PATCH v19 11/11] hmp: add info memdev 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=531596F5.3070001@redhat.com \
--to=pbonzini@redhat.com \
--cc=gaowanlong@cn.fujitsu.com \
--cc=hu.taoo@gmail.com \
--cc=hutao@cn.fujitsu.com \
--cc=imammedo@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.