From f90cb2846a0b167d47131ba4600dcc816bccb1c6 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 22 Aug 2017 08:52:19 +0200 Subject: qobject: Explain how QNum works, and why Suggested-by: Max Reitz Signed-off-by: Markus Armbruster Message-Id: <1503384739-17207-1-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau [Comment typos fixed] --- include/qapi/qmp/qnum.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include') diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h index 09d745c490..d6b0791139 100644 --- a/include/qapi/qmp/qnum.h +++ b/include/qapi/qmp/qnum.h @@ -23,6 +23,27 @@ typedef enum { QNUM_DOUBLE } QNumKind; +/* + * QNum encapsulates how our dialect of JSON fills in the blanks left + * by the JSON specification (RFC 7159) regarding numbers. + * + * Conceptually, we treat number as an abstract type with three + * concrete subtypes: floating-point, signed integer, unsigned + * integer. QNum implements this as a discriminated union of double, + * int64_t, uint64_t. + * + * The JSON parser picks the subtype as follows. If the number has a + * decimal point or an exponent, it is floating-point. Else if it + * fits into int64_t, it's signed integer. Else if it fits into + * uint64_t, it's unsigned integer. Else it's floating-point. + * + * Any number can serve as double: qnum_get_double() converts under + * the hood. + * + * An integer can serve as signed / unsigned integer as long as it is + * in range: qnum_get_try_int() / qnum_get_try_uint() check range and + * convert under the hood. + */ typedef struct QNum { QObject base; QNumKind kind; -- cgit v1.2.3-55-g7522 From 0f9afc2a8b5e78e511d79c936aa7b36deb3508bf Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:00 +0200 Subject: qdict: Add qdict_put_null() helper, and put it to use Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-2-marcandre.lureau@redhat.com> [Update to qobject.cocci squashed in, commit message tweaked] Signed-off-by: Markus Armbruster --- include/qapi/qmp/qdict.h | 4 +++- scripts/coccinelle/qobject.cocci | 3 +++ target/i386/cpu.c | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 363e431106..6588c7f0c8 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -53,13 +53,15 @@ void qdict_destroy_obj(QObject *obj); #define qdict_put(qdict, key, obj) \ qdict_put_obj(qdict, key, QOBJECT(obj)) -/* Helpers for int, bool, and string */ +/* Helpers for int, bool, null, and string */ #define qdict_put_int(qdict, key, value) \ qdict_put(qdict, key, qnum_from_int(value)) #define qdict_put_bool(qdict, key, value) \ qdict_put(qdict, key, qbool_from_bool(value)) #define qdict_put_str(qdict, key, value) \ qdict_put(qdict, key, qstring_from_str(value)) +#define qdict_put_null(qdict, key) \ + qdict_put(qdict, key, qnull()) /* High level helpers */ double qdict_get_double(const QDict *qdict, const char *key); diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci index c518caf7b1..1120eb1a42 100644 --- a/scripts/coccinelle/qobject.cocci +++ b/scripts/coccinelle/qobject.cocci @@ -20,6 +20,9 @@ expression Obj, Key, E; | - qdict_put(Obj, Key, qstring_from_str(E)); + qdict_put_str(Obj, Key, E); +| +- qdict_put(Obj, Key, qnull()); ++ qdict_put_null(Obj, Key); ) // Use QList macros where they make sense diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ddc45abd70..bec2009a9c 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2454,7 +2454,7 @@ static QDict *x86_cpu_static_props(void) d = qdict_new(); for (i = 0; props[i]; i++) { - qdict_put(d, props[i], qnull()); + qdict_put_null(d, props[i]); } for (w = 0; w < FEATURE_WORDS; w++) { @@ -2464,7 +2464,7 @@ static QDict *x86_cpu_static_props(void) if (!fi->feat_names[bit]) { continue; } - qdict_put(d, fi->feat_names[bit], qnull()); + qdict_put_null(d, fi->feat_names[bit]); } } -- cgit v1.2.3-55-g7522 From 28035bcdf4647245743cf87cea3788331bf67a5f Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:01 +0200 Subject: qlit: move qlit from check-qjson to qobject/ Fix code style issues while at it, to please checkpatch. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-3-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 49 +++++++++++++++++++++++++ qobject/Makefile.objs | 2 +- qobject/qlit.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ tests/check-qjson.c | 96 +------------------------------------------------ 4 files changed, 140 insertions(+), 96 deletions(-) create mode 100644 include/qapi/qmp/qlit.h create mode 100644 qobject/qlit.c (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h new file mode 100644 index 0000000000..280db5064a --- /dev/null +++ b/include/qapi/qmp/qlit.h @@ -0,0 +1,49 @@ +/* + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori + * Markus Armbruster + * Marc-André Lureau + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ +#ifndef QLIT_H +#define QLIT_H + +#include "qapi-types.h" +#include "qobject.h" + +typedef struct LiteralQDictEntry LiteralQDictEntry; +typedef struct LiteralQObject LiteralQObject; + +struct LiteralQObject { + int type; + union { + int64_t qnum; + const char *qstr; + LiteralQDictEntry *qdict; + LiteralQObject *qlist; + } value; +}; + +struct LiteralQDictEntry { + const char *key; + LiteralQObject value; +}; + +#define QLIT_QNUM(val) \ + (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} +#define QLIT_QSTR(val) \ + (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} +#define QLIT_QDICT(val) \ + (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} +#define QLIT_QLIST(val) \ + (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} + +int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); + +#endif /* QLIT_H */ diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index fc8885c9a4..002d25873a 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ -util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o +util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o qlit.o util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/qlit.c b/qobject/qlit.c new file mode 100644 index 0000000000..5917c3584e --- /dev/null +++ b/qobject/qlit.c @@ -0,0 +1,89 @@ +/* + * QLit literal qobject + * + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori + * Markus Armbruster + * Marc-André Lureau + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qapi/qmp/qlit.h" +#include "qapi/qmp/types.h" + +typedef struct QListCompareHelper { + int index; + LiteralQObject *objs; + int result; +} QListCompareHelper; + +static void compare_helper(QObject *obj, void *opaque) +{ + QListCompareHelper *helper = opaque; + + if (helper->result == 0) { + return; + } + + if (helper->objs[helper->index].type == QTYPE_NONE) { + helper->result = 0; + return; + } + + helper->result = + compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); +} + +int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) +{ + int64_t val; + + if (!rhs || lhs->type != qobject_type(rhs)) { + return 0; + } + + switch (lhs->type) { + case QTYPE_QNUM: + g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); + return lhs->value.qnum == val; + case QTYPE_QSTRING: + return (strcmp(lhs->value.qstr, + qstring_get_str(qobject_to_qstring(rhs))) == 0); + case QTYPE_QDICT: { + int i; + + for (i = 0; lhs->value.qdict[i].key; i++) { + QObject *obj = qdict_get(qobject_to_qdict(rhs), + lhs->value.qdict[i].key); + + if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { + return 0; + } + } + + return 1; + } + case QTYPE_QLIST: { + QListCompareHelper helper; + + helper.index = 0; + helper.objs = lhs->value.qlist; + helper.result = 1; + + qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); + + return helper.result; + } + default: + break; + } + + return 0; +} diff --git a/tests/check-qjson.c b/tests/check-qjson.c index a3a97b0d99..525f79e60b 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlit.h" #include "qemu-common.h" static void escaped_string(void) @@ -1059,101 +1060,6 @@ static void keyword_literal(void) QDECREF(null); } -typedef struct LiteralQDictEntry LiteralQDictEntry; -typedef struct LiteralQObject LiteralQObject; - -struct LiteralQObject -{ - int type; - union { - int64_t qnum; - const char *qstr; - LiteralQDictEntry *qdict; - LiteralQObject *qlist; - } value; -}; - -struct LiteralQDictEntry -{ - const char *key; - LiteralQObject value; -}; - -#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} -#define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} -#define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} -#define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} - -typedef struct QListCompareHelper -{ - int index; - LiteralQObject *objs; - int result; -} QListCompareHelper; - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); - -static void compare_helper(QObject *obj, void *opaque) -{ - QListCompareHelper *helper = opaque; - - if (helper->result == 0) { - return; - } - - if (helper->objs[helper->index].type == QTYPE_NONE) { - helper->result = 0; - return; - } - - helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); -} - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) -{ - int64_t val; - - if (!rhs || lhs->type != qobject_type(rhs)) { - return 0; - } - - switch (lhs->type) { - case QTYPE_QNUM: - g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); - return lhs->value.qnum == val; - case QTYPE_QSTRING: - return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); - case QTYPE_QDICT: { - int i; - - for (i = 0; lhs->value.qdict[i].key; i++) { - QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); - - if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { - return 0; - } - } - - return 1; - } - case QTYPE_QLIST: { - QListCompareHelper helper; - - helper.index = 0; - helper.objs = lhs->value.qlist; - helper.result = 1; - - qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); - - return helper.result; - } - default: - break; - } - - return 0; -} - static void simple_dict(void) { int i; -- cgit v1.2.3-55-g7522 From 082696e767db4d2b6c8c8c233d28291b83fc2b21 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:02 +0200 Subject: qlit: use QLit prefix consistently Rename from LiteralQ to QLit. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 24 ++++++++++++------------ qobject/qlit.c | 4 ++-- tests/check-qjson.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 34 insertions(+), 34 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index 280db5064a..a4ad91321b 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -17,33 +17,33 @@ #include "qapi-types.h" #include "qobject.h" -typedef struct LiteralQDictEntry LiteralQDictEntry; -typedef struct LiteralQObject LiteralQObject; +typedef struct QLitDictEntry QLitDictEntry; +typedef struct QLitObject QLitObject; -struct LiteralQObject { +struct QLitObject { int type; union { int64_t qnum; const char *qstr; - LiteralQDictEntry *qdict; - LiteralQObject *qlist; + QLitDictEntry *qdict; + QLitObject *qlist; } value; }; -struct LiteralQDictEntry { +struct QLitDictEntry { const char *key; - LiteralQObject value; + QLitObject value; }; #define QLIT_QNUM(val) \ - (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} + (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)} #define QLIT_QSTR(val) \ - (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} + (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)} #define QLIT_QDICT(val) \ - (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} + (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)} #define QLIT_QLIST(val) \ - (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} + (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)} -int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); +int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs); #endif /* QLIT_H */ diff --git a/qobject/qlit.c b/qobject/qlit.c index 5917c3584e..262d64988d 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -20,7 +20,7 @@ typedef struct QListCompareHelper { int index; - LiteralQObject *objs; + QLitObject *objs; int result; } QListCompareHelper; @@ -41,7 +41,7 @@ static void compare_helper(QObject *obj, void *opaque) compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); } -int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) +int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs) { int64_t val; diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 525f79e60b..82b3681327 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -1065,23 +1065,23 @@ static void simple_dict(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(42) }, { "bar", QLIT_QSTR("hello world") }, { } })), }, { .encoded = "{}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { } })), }, { .encoded = "{\"foo\": 43}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(43) }, { } })), @@ -1163,11 +1163,11 @@ static void simple_list(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "[43,42]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1175,21 +1175,21 @@ static void simple_list(void) }, { .encoded = "[43]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), { } })), }, { .encoded = "[]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ { } })), }, { .encoded = "[{}]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ + QLIT_QDICT(((QLitDictEntry[]){ {}, })), {}, @@ -1220,11 +1220,11 @@ static void simple_whitespace(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = " [ 43 , 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1232,12 +1232,12 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1245,13 +1245,13 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { "a", QLIT_QNUM(32) }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1282,10 +1282,10 @@ static void simple_varargs(void) { QObject *embedded_obj; QObject *obj; - LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){ + QLitObject decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(1), QLIT_QNUM(2), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(32), QLIT_QNUM(42), {}})), -- cgit v1.2.3-55-g7522 From d5cd8fbf130312bea91823c41de87d55818d599b Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:03 +0200 Subject: qlit: Change compound literals to initializers The QLIT_QFOO() macros expand into compound literals. Sadly, gcc doesn't recognizes these as constant expressions (clang does), which makes the macros useless for initializing objects with static storage duration. There is a gcc bug about it: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71713 Change the macros to expand into initializers. Signed-off-by: Marc-André Lureau Message-Id: <20170825105913.4060-5-marcandre.lureau@redhat.com> [Commit message improved] Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index a4ad91321b..f1d6eed317 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -36,13 +36,13 @@ struct QLitDictEntry { }; #define QLIT_QNUM(val) \ - (QLitObject){.type = QTYPE_QNUM, .value.qnum = (val)} + { .type = QTYPE_QNUM, .value.qnum = (val) } #define QLIT_QSTR(val) \ - (QLitObject){.type = QTYPE_QSTRING, .value.qstr = (val)} + { .type = QTYPE_QSTRING, .value.qstr = (val) } #define QLIT_QDICT(val) \ - (QLitObject){.type = QTYPE_QDICT, .value.qdict = (val)} + { .type = QTYPE_QDICT, .value.qdict = (val) } #define QLIT_QLIST(val) \ - (QLitObject){.type = QTYPE_QLIST, .value.qlist = (val)} + { .type = QTYPE_QLIST, .value.qlist = (val) } int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs); -- cgit v1.2.3-55-g7522 From 60cc2eb7afd40b9cbaa35a5e0b54f365ac6e49f1 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:04 +0200 Subject: qlit: rename compare_litqobj_to_qobj() to qlit_equal_qobject() compare_litqobj_to_qobj() lacks a qlit_ prefix. Moreover, "compare" suggests -1, 0, +1 for less than, equal and greater than. The function actually returns non-zero for equal, zero for unequal. Rename to qlit_equal_qobject(). Its return type will be cleaned up in the next patch. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-6-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 2 +- qobject/qlit.c | 6 +++--- tests/check-qjson.c | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index f1d6eed317..5a180477c8 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -44,6 +44,6 @@ struct QLitDictEntry { #define QLIT_QLIST(val) \ { .type = QTYPE_QLIST, .value.qlist = (val) } -int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs); +int qlit_equal_qobject(QLitObject *lhs, QObject *rhs); #endif /* QLIT_H */ diff --git a/qobject/qlit.c b/qobject/qlit.c index 262d64988d..0c4101898d 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -38,10 +38,10 @@ static void compare_helper(QObject *obj, void *opaque) } helper->result = - compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); + qlit_equal_qobject(&helper->objs[helper->index++], obj); } -int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs) +int qlit_equal_qobject(QLitObject *lhs, QObject *rhs) { int64_t val; @@ -63,7 +63,7 @@ int compare_litqobj_to_qobj(QLitObject *lhs, QObject *rhs) QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); - if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { + if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) { return 0; } } diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 82b3681327..e5ca273cbc 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -1094,13 +1094,13 @@ static void simple_dict(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); qobject_decref(obj); QDECREF(str); } @@ -1203,13 +1203,13 @@ static void simple_list(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); qobject_decref(obj); QDECREF(str); } @@ -1265,13 +1265,13 @@ static void simple_whitespace(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); qobject_decref(obj); QDECREF(str); @@ -1295,7 +1295,7 @@ static void simple_varargs(void) g_assert(embedded_obj != NULL); obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); - g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1); + g_assert(qlit_equal_qobject(&decoded, obj) == 1); qobject_decref(obj); } -- cgit v1.2.3-55-g7522 From d9eba57a6ad6d8fe8cf11bdd8345bbda66deb6d9 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:05 +0200 Subject: qlit: make qlit_equal_qobject return a bool Make it more obvious about the expected return values. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-7-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 2 +- qobject/qlit.c | 18 +++++++++--------- tests/check-qjson.c | 14 +++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index 5a180477c8..35aabbdc9f 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -44,6 +44,6 @@ struct QLitDictEntry { #define QLIT_QLIST(val) \ { .type = QTYPE_QLIST, .value.qlist = (val) } -int qlit_equal_qobject(QLitObject *lhs, QObject *rhs); +bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs); #endif /* QLIT_H */ diff --git a/qobject/qlit.c b/qobject/qlit.c index 0c4101898d..a2975bef3f 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -21,19 +21,19 @@ typedef struct QListCompareHelper { int index; QLitObject *objs; - int result; + bool result; } QListCompareHelper; static void compare_helper(QObject *obj, void *opaque) { QListCompareHelper *helper = opaque; - if (helper->result == 0) { + if (!helper->result) { return; } if (helper->objs[helper->index].type == QTYPE_NONE) { - helper->result = 0; + helper->result = false; return; } @@ -41,12 +41,12 @@ static void compare_helper(QObject *obj, void *opaque) qlit_equal_qobject(&helper->objs[helper->index++], obj); } -int qlit_equal_qobject(QLitObject *lhs, QObject *rhs) +bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs) { int64_t val; if (!rhs || lhs->type != qobject_type(rhs)) { - return 0; + return false; } switch (lhs->type) { @@ -64,18 +64,18 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs) lhs->value.qdict[i].key); if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) { - return 0; + return false; } } - return 1; + return true; } case QTYPE_QLIST: { QListCompareHelper helper; helper.index = 0; helper.objs = lhs->value.qlist; - helper.result = 1; + helper.result = true; qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); @@ -85,5 +85,5 @@ int qlit_equal_qobject(QLitObject *lhs, QObject *rhs) break; } - return 0; + return false; } diff --git a/tests/check-qjson.c b/tests/check-qjson.c index e5ca273cbc..59227934ce 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -1094,13 +1094,13 @@ static void simple_dict(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1203,13 +1203,13 @@ static void simple_list(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1265,13 +1265,13 @@ static void simple_whitespace(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); @@ -1295,7 +1295,7 @@ static void simple_varargs(void) g_assert(embedded_obj != NULL); obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); - g_assert(qlit_equal_qobject(&decoded, obj) == 1); + g_assert(qlit_equal_qobject(&decoded, obj)); qobject_decref(obj); } -- cgit v1.2.3-55-g7522 From e2346a19521c6cce417250c75adb0b3a7cd5535a Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:06 +0200 Subject: qlit: make qlit_equal_qobject() take const arguments Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-8-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 2 +- qobject/qlit.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index 35aabbdc9f..fc1a2d845d 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -44,6 +44,6 @@ struct QLitDictEntry { #define QLIT_QLIST(val) \ { .type = QTYPE_QLIST, .value.qlist = (val) } -bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs); +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs); #endif /* QLIT_H */ diff --git a/qobject/qlit.c b/qobject/qlit.c index a2975bef3f..ae2787ef35 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -41,7 +41,7 @@ static void compare_helper(QObject *obj, void *opaque) qlit_equal_qobject(&helper->objs[helper->index++], obj); } -bool qlit_equal_qobject(QLitObject *lhs, QObject *rhs) +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) { int64_t val; -- cgit v1.2.3-55-g7522 From 6c6084c1b0802f5265d5c7dc27f7125d9fd1cceb Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 25 Aug 2017 12:59:07 +0200 Subject: qlit: add QLIT_QNULL and QLIT_BOOL As they are going to be used in the following patches. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20170825105913.4060-9-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qlit.h | 5 +++++ qobject/qlit.c | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index fc1a2d845d..b18406bce9 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -23,6 +23,7 @@ typedef struct QLitObject QLitObject; struct QLitObject { int type; union { + bool qbool; int64_t qnum; const char *qstr; QLitDictEntry *qdict; @@ -35,6 +36,10 @@ struct QLitDictEntry { QLitObject value; }; +#define QLIT_QNULL \ + { .type = QTYPE_QNULL } +#define QLIT_QBOOL(val) \ + { .type = QTYPE_QBOOL, .value.qbool = (val) } #define QLIT_QNUM(val) \ { .type = QTYPE_QNUM, .value.qnum = (val) } #define QLIT_QSTR(val) \ diff --git a/qobject/qlit.c b/qobject/qlit.c index ae2787ef35..07ad6b05e8 100644 --- a/qobject/qlit.c +++ b/qobject/qlit.c @@ -50,6 +50,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) } switch (lhs->type) { + case QTYPE_QBOOL: + return lhs->value.qbool == qbool_get_bool(qobject_to_qbool(rhs)); case QTYPE_QNUM: g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); return lhs->value.qnum == val; @@ -81,6 +83,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) return helper.result; } + case QTYPE_QNULL: + return true; default: break; } -- cgit v1.2.3-55-g7522 From 06c60b6c468ca7cde004fe7c3ce35de312855f55 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 24 Aug 2017 10:45:57 +0200 Subject: qapi: Drop superfluous qapi_enum_parse() parameter max The lookup tables have a sentinel, no need to make callers pass their size. Signed-off-by: Markus Armbruster Message-Id: <1503564371-26090-3-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau Reviewed-by: Eric Blake [Rebased, commit message corrected] --- block.c | 1 - block/file-posix.c | 7 +++---- block/file-win32.c | 2 +- block/gluster.c | 6 ++---- block/parallels.c | 3 ++- block/qcow2.c | 6 ++---- blockdev.c | 1 - hmp.c | 2 +- include/qapi/util.h | 2 +- migration/global_state.c | 3 +-- qapi/qapi-util.c | 4 ++-- qemu-img.c | 3 +-- qemu-nbd.c | 1 - tests/qmp-test.c | 3 +-- tests/test-qapi-util.c | 15 +++++---------- 15 files changed, 22 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/block.c b/block.c index 3308814bba..af48b0d26b 100644 --- a/block.c +++ b/block.c @@ -1335,7 +1335,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, BlockdevDetectZeroesOptions value = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, detect_zeroes, - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { diff --git a/block/file-posix.c b/block/file-posix.c index cb3bfce147..97e8a92e23 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -439,7 +439,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), - BLOCKDEV_AIO_OPTIONS__MAX, aio_default, &local_err); + aio_default, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -448,7 +448,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, s->use_linux_aio = (aio == BLOCKDEV_AIO_OPTIONS_NATIVE); locking = qapi_enum_parse(OnOffAuto_lookup, qemu_opt_get(opts, "locking"), - ON_OFF_AUTO__MAX, ON_OFF_AUTO_AUTO, &local_err); + ON_OFF_AUTO_AUTO, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -1975,8 +1975,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + PREALLOC_MODE_OFF, &local_err); g_free(buf); if (local_err) { error_propagate(errp, local_err); diff --git a/block/file-win32.c b/block/file-win32.c index 4706335cff..978d8058fe 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -304,7 +304,7 @@ static bool get_aio_option(QemuOpts *opts, int flags, Error **errp) aio_default = (flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), - BLOCKDEV_AIO_OPTIONS__MAX, aio_default, errp); + aio_default, errp); switch (aio) { case BLOCKDEV_AIO_OPTIONS_NATIVE: diff --git a/block/gluster.c b/block/gluster.c index 3064a45047..8367e806d0 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -544,8 +544,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, if (!strcmp(ptr, "tcp")) { ptr = "inet"; /* accept legacy "tcp" */ } - type = qapi_enum_parse(SocketAddressType_lookup, ptr, - SOCKET_ADDRESS_TYPE__MAX, -1, NULL); + type = qapi_enum_parse(SocketAddressType_lookup, ptr, -1, NULL); if (type != SOCKET_ADDRESS_TYPE_INET && type != SOCKET_ADDRESS_TYPE_UNIX) { error_setg(&local_err, @@ -1002,8 +1001,7 @@ static int qemu_gluster_create(const char *filename, BDRV_SECTOR_SIZE); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, tmp, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, + prealloc = qapi_enum_parse(PreallocMode_lookup, tmp, PREALLOC_MODE_OFF, &local_err); g_free(tmp); if (local_err) { diff --git a/block/parallels.c b/block/parallels.c index e1e06d23cc..eb92366e51 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -697,7 +697,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS); buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE); s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf, - PRL_PREALLOC_MODE__MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err); + PRL_PREALLOC_MODE_FALLOCATE, + &local_err); g_free(buf); if (local_err != NULL) { goto fail_options; diff --git a/block/qcow2.c b/block/qcow2.c index a3679c69e8..470a0dedaa 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2917,8 +2917,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) } buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + PREALLOC_MODE_OFF, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -3608,8 +3607,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); prealloc = qapi_enum_parse(PreallocMode_lookup, optstr, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + PREALLOC_MODE_OFF, &local_err); g_free(optstr); if (local_err) { goto err; diff --git a/blockdev.c b/blockdev.c index 02cd69bc21..722a61e3fb 100644 --- a/blockdev.c +++ b/blockdev.c @@ -440,7 +440,6 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags, *detect_zeroes = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, qemu_opt_get(opts, "detect-zeroes"), - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_error); if (local_error) { diff --git a/hmp.c b/hmp.c index fd80dce758..03c1a783b6 100644 --- a/hmp.c +++ b/hmp.c @@ -1742,7 +1742,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) if (read_only) { read_only_mode = qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, - read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX, + read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); if (err) { hmp_handle_error(mon, &err); diff --git a/include/qapi/util.h b/include/qapi/util.h index 7436ed815c..4eb8a3fe2f 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -12,7 +12,7 @@ #define QAPI_UTIL_H int qapi_enum_parse(const char * const lookup[], const char *buf, - int max, int def, Error **errp); + int def, Error **errp); int parse_qapi_name(const char *name, bool complete); diff --git a/migration/global_state.c b/migration/global_state.c index dcbbcb28be..88c55f8cdb 100644 --- a/migration/global_state.c +++ b/migration/global_state.c @@ -89,8 +89,7 @@ static int global_state_post_load(void *opaque, int version_id) s->received = true; trace_migrate_global_state_post_load(runstate); - r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE__MAX, - -1, &local_err); + r = qapi_enum_parse(RunState_lookup, runstate, -1, &local_err); if (r == -1) { if (local_err) { diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index 46eda7d196..ee7594ff19 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -16,7 +16,7 @@ #include "qapi/util.h" int qapi_enum_parse(const char * const lookup[], const char *buf, - int max, int def, Error **errp) + int def, Error **errp) { int i; @@ -24,7 +24,7 @@ int qapi_enum_parse(const char * const lookup[], const char *buf, return def; } - for (i = 0; i < max; i++) { + for (i = 0; lookup[i]; i++) { if (!strcmp(buf, lookup[i])) { return i; } diff --git a/qemu-img.c b/qemu-img.c index 56ef49e214..611ab7ddf3 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3491,8 +3491,7 @@ static int img_resize(int argc, char **argv) break; case OPTION_PREALLOCATION: prealloc = qapi_enum_parse(PreallocMode_lookup, optarg, - PREALLOC_MODE__MAX, PREALLOC_MODE__MAX, - NULL); + PREALLOC_MODE__MAX, NULL); if (prealloc == PREALLOC_MODE__MAX) { error_report("Invalid preallocation mode '%s'", optarg); return 1; diff --git a/qemu-nbd.c b/qemu-nbd.c index 27164b8205..96e10d62dc 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -641,7 +641,6 @@ int main(int argc, char **argv) detect_zeroes = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, optarg, - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 5ce886312a..b5f21dfa57 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -182,8 +182,7 @@ static void test_query(const void *data) } else { g_assert(error); g_assert_cmpint(qapi_enum_parse(QapiErrorClass_lookup, error_class, - QAPI_ERROR_CLASS__MAX, -1, - &error_abort), + -1, &error_abort), ==, expected_error_class); } QDECREF(resp); diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c index e8697577a5..d72ee8c4e7 100644 --- a/tests/test-qapi-util.c +++ b/tests/test-qapi-util.c @@ -20,25 +20,20 @@ static void test_qapi_enum_parse(void) Error *err = NULL; int ret; - ret = qapi_enum_parse(QType_lookup, NULL, QTYPE__MAX, QTYPE_NONE, - &error_abort); + ret = qapi_enum_parse(QType_lookup, NULL, QTYPE_NONE, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - NULL); + ret = qapi_enum_parse(QType_lookup, "junk", -1, NULL); g_assert_cmpint(ret, ==, -1); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - &err); + ret = qapi_enum_parse(QType_lookup, "junk", -1, &err); error_free_or_abort(&err); - ret = qapi_enum_parse(QType_lookup, "none", QTYPE__MAX, -1, - &error_abort); + ret = qapi_enum_parse(QType_lookup, "none", -1, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); ret = qapi_enum_parse(QType_lookup, QType_lookup[QTYPE__MAX - 1], - QTYPE__MAX, QTYPE__MAX - 1, - &error_abort); + QTYPE__MAX - 1, &error_abort); g_assert_cmpint(ret, ==, QTYPE__MAX - 1); } -- cgit v1.2.3-55-g7522 From a9a72aeefbd3ef8bcbbeeccaf174ee10db2978ac Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Thu, 24 Aug 2017 10:45:58 +0200 Subject: tpm: Clean up driver registration & lookup We have a strict separation between enum TpmType and be_drivers[]: * TpmType may have any number of members. It just happens to have one. * tpm_register_driver() uses the first empty slot in be_drivers[]. If you register more than tpm_models[] has space, tpm_register_driver() fails. Its caller silently ignores the failure. If you register more than one with a given TpmType, tpm_display_backend_drivers() will shows all of them, but tpm_driver_find_by_type() and tpm_get_backend_driver() will find only the one one that registered first. Since we only ever register one driver, and be_drivers[] has space for just that one, this contraption even works. Turn be_drivers[] into a straight map from enum TpmType to driver. Much simpler, and has a decent chance to actually work should we ever acquire additional drivers. While there, use qapi_enum_parse() in tpm_get_backend_driver(). Signed-off-by: Marc-André Lureau Message-Id: <20170822132255.23945-8-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster [Rebased, superfluous initializer dropped, commit message rewritten] Cc: Stefan Berger Signed-off-by: Markus Armbruster Message-Id: <1503564371-26090-4-git-send-email-armbru@redhat.com> --- include/sysemu/tpm_backend.h | 2 +- tpm.c | 45 +++++++++++++------------------------------- 2 files changed, 14 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index b58f52d39f..1d21c6b19b 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -227,6 +227,6 @@ TPMBackend *qemu_find_tpm(const char *id); const TPMDriverOps *tpm_get_backend_driver(const char *type); int tpm_register_model(enum TpmModel model); -int tpm_register_driver(const TPMDriverOps *tdo); +void tpm_register_driver(const TPMDriverOps *tdo); #endif diff --git a/tpm.c b/tpm.c index 9a7c7114d3..6f39ec9192 100644 --- a/tpm.c +++ b/tpm.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "qapi/qmp/qerror.h" +#include "qapi/util.h" #include "sysemu/tpm_backend.h" #include "sysemu/tpm.h" #include "qemu/config-file.h" @@ -25,11 +26,8 @@ static QLIST_HEAD(, TPMBackend) tpm_backends = #define TPM_MAX_MODELS 1 -#define TPM_MAX_DRIVERS 1 -static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = { - NULL, -}; +static TPMDriverOps const *be_drivers[TPM_TYPE__MAX]; static enum TpmModel tpm_models[TPM_MAX_MODELS] = { TPM_MODEL__MAX, @@ -63,31 +61,18 @@ static bool tpm_model_is_registered(enum TpmModel model) const TPMDriverOps *tpm_get_backend_driver(const char *type) { - int i; - - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { - if (!strcmp(TpmType_lookup[be_drivers[i]->type], type)) { - return be_drivers[i]; - } - } + int i = qapi_enum_parse(TpmType_lookup, type, -1, NULL); - return NULL; + return i >= 0 ? be_drivers[i] : NULL; } #ifdef CONFIG_TPM -int tpm_register_driver(const TPMDriverOps *tdo) +void tpm_register_driver(const TPMDriverOps *tdo) { - int i; + assert(!be_drivers[tdo->type]); - for (i = 0; i < TPM_MAX_DRIVERS; i++) { - if (!be_drivers[i]) { - be_drivers[i] = tdo; - return 0; - } - } - error_report("Could not register TPM driver"); - return 1; + be_drivers[tdo->type] = tdo; } /* @@ -100,9 +85,12 @@ static void tpm_display_backend_drivers(void) fprintf(stderr, "Supported TPM types (choose only one):\n"); - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { + for (i = 0; i < TPM_TYPE__MAX; i++) { + if (be_drivers[i] == NULL) { + continue; + } fprintf(stderr, "%12s %s\n", - TpmType_lookup[be_drivers[i]->type], be_drivers[i]->desc()); + TpmType_lookup[i], be_drivers[i]->desc()); } fprintf(stderr, "\n"); } @@ -239,14 +227,7 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg) static const TPMDriverOps *tpm_driver_find_by_type(enum TpmType type) { - int i; - - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { - if (be_drivers[i]->type == type) { - return be_drivers[i]; - } - } - return NULL; + return be_drivers[type]; } static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv) -- cgit v1.2.3-55-g7522 From 00bbf50a50e6d6e1a4542db1c1205291395c4105 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 24 Aug 2017 10:45:59 +0200 Subject: tpm: Clean up model registration & lookup We have a strict separation between enum TpmModel and tpm_models[]: * TpmModel may have any number of members. It just happens to have one. * tpm_register_model() uses the first empty slot in tpm_models[]. If you register more than tpm_models[] has space, tpn_register_model() fails. Its caller silently ignores the failure. Register the same TpmModel more than once has no effect other than wasting tpm_models[] slots: tpm_model_is_registered() is happy with the first one it finds. Since we only ever register one model, and tpm_models[] has space for just that one, this contraption even works. Turn tpm_models[] into a straight map from enum TpmType to bool. Much simpler. Cc: Stefan Berger Signed-off-by: Markus Armbruster Message-Id: <1503564371-26090-5-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau [Commit message typo fixed] --- include/sysemu/tpm_backend.h | 2 +- tpm.c | 37 +++++-------------------------------- 2 files changed, 6 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index 1d21c6b19b..b0a9731aee 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -226,7 +226,7 @@ TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); TPMBackend *qemu_find_tpm(const char *id); const TPMDriverOps *tpm_get_backend_driver(const char *type); -int tpm_register_model(enum TpmModel model); +void tpm_register_model(enum TpmModel model); void tpm_register_driver(const TPMDriverOps *tdo); #endif diff --git a/tpm.c b/tpm.c index 6f39ec9192..7635fc779b 100644 --- a/tpm.c +++ b/tpm.c @@ -24,39 +24,12 @@ static QLIST_HEAD(, TPMBackend) tpm_backends = QLIST_HEAD_INITIALIZER(tpm_backends); - -#define TPM_MAX_MODELS 1 - static TPMDriverOps const *be_drivers[TPM_TYPE__MAX]; +static bool tpm_models[TPM_MODEL__MAX]; -static enum TpmModel tpm_models[TPM_MAX_MODELS] = { - TPM_MODEL__MAX, -}; - -int tpm_register_model(enum TpmModel model) -{ - int i; - - for (i = 0; i < TPM_MAX_MODELS; i++) { - if (tpm_models[i] == TPM_MODEL__MAX) { - tpm_models[i] = model; - return 0; - } - } - error_report("Could not register TPM model"); - return 1; -} - -static bool tpm_model_is_registered(enum TpmModel model) +void tpm_register_model(enum TpmModel model) { - int i; - - for (i = 0; i < TPM_MAX_MODELS; i++) { - if (tpm_models[i] == model) { - return true; - } - } - return false; + tpm_models[model] = true; } const TPMDriverOps *tpm_get_backend_driver(const char *type) @@ -270,7 +243,7 @@ TPMInfoList *qmp_query_tpm(Error **errp) TPMInfoList *info, *head = NULL, *cur_item = NULL; QLIST_FOREACH(drv, &tpm_backends, list) { - if (!tpm_model_is_registered(drv->fe_model)) { + if (!tpm_models[drv->fe_model]) { continue; } info = g_new0(TPMInfoList, 1); @@ -317,7 +290,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp) TpmModelList *head = NULL, *prev = NULL, *cur_item; for (i = 0; i < TPM_MODEL__MAX; i++) { - if (!tpm_model_is_registered(i)) { + if (!tpm_models[i]) { continue; } cur_item = g_new0(TpmModelList, 1); -- cgit v1.2.3-55-g7522 From 5b5f825d44306b18509cd10ba9ac6983e90d6e0f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 24 Aug 2017 10:46:07 +0200 Subject: qapi: Generate FOO_str() macro for QAPI enum FOO The next commit will put it to use. May look pointless now, but we're going to change the FOO_lookup's type, and then it'll help. Signed-off-by: Markus Armbruster Message-Id: <1503564371-26090-13-git-send-email-armbru@redhat.com> Reviewed-by: Marc-André Lureau --- block.c | 1 - block/blkdebug.c | 1 - block/file-posix.c | 1 - block/file-win32.c | 1 - block/gluster.c | 1 - block/parallels.c | 1 - block/qcow2.c | 1 - block/quorum.c | 1 - blockdev.c | 1 - crypto/block-luks.c | 1 - docs/devel/qapi-code-gen.txt | 3 +++ hmp.c | 1 - include/qapi/util.h | 1 + migration/global_state.c | 1 - migration/migration.c | 1 - qapi/qapi-util.c | 8 +++++++- qapi/qapi-visit-core.c | 1 - qemu-img.c | 1 - qemu-nbd.c | 1 - scripts/qapi-event.py | 1 + scripts/qapi-types.py | 4 ++++ scripts/qapi.py | 3 +++ tests/test-qapi-util.c | 1 - tpm.c | 1 - util/keyval.c | 1 - 25 files changed, 19 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/block.c b/block.c index af48b0d26b..845eff8177 100644 --- a/block.c +++ b/block.c @@ -42,7 +42,6 @@ #include "qapi-event.h" #include "qemu/cutils.h" #include "qemu/id.h" -#include "qapi/util.h" #ifdef CONFIG_BSD #include diff --git a/block/blkdebug.c b/block/blkdebug.c index f1bbee9497..b370fcedfb 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -32,7 +32,6 @@ #include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include "sysemu/qtest.h" typedef struct BDRVBlkdebugState { diff --git a/block/file-posix.c b/block/file-posix.c index 97e8a92e23..d81eccc191 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -31,7 +31,6 @@ #include "block/thread-pool.h" #include "qemu/iov.h" #include "block/raw-aio.h" -#include "qapi/util.h" #include "qapi/qmp/qstring.h" #if defined(__APPLE__) && (__MACH__) diff --git a/block/file-win32.c b/block/file-win32.c index 978d8058fe..192ea819d9 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -31,7 +31,6 @@ #include "block/thread-pool.h" #include "qemu/iov.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include #include diff --git a/block/gluster.c b/block/gluster.c index 8367e806d0..0614e0c8aa 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -12,7 +12,6 @@ #include "block/block_int.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" -#include "qapi/util.h" #include "qemu/uri.h" #include "qemu/error-report.h" #include "qemu/cutils.h" diff --git a/block/parallels.c b/block/parallels.c index eb92366e51..d812210b4f 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -35,7 +35,6 @@ #include "qemu/module.h" #include "qemu/bswap.h" #include "qemu/bitmap.h" -#include "qapi/util.h" /**************************************************************/ diff --git a/block/qcow2.c b/block/qcow2.c index 470a0dedaa..3a93983e3f 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -30,7 +30,6 @@ #include "qemu/error-report.h" #include "qapi/qmp/qerror.h" #include "qapi/qmp/qbool.h" -#include "qapi/util.h" #include "qapi/qmp/types.h" #include "qapi-event.h" #include "trace.h" diff --git a/block/quorum.c b/block/quorum.c index cb6617703c..8d1c9f6306 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -22,7 +22,6 @@ #include "qapi/qmp/qjson.h" #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include "qapi-event.h" #include "crypto/hash.h" diff --git a/blockdev.c b/blockdev.c index 722a61e3fb..f90bc9399a 100644 --- a/blockdev.c +++ b/blockdev.c @@ -44,7 +44,6 @@ #include "qapi-visit.h" #include "qapi/qmp/qerror.h" #include "qapi/qobject-output-visitor.h" -#include "qapi/util.h" #include "sysemu/sysemu.h" #include "block/block_int.h" #include "qmp-commands.h" diff --git a/crypto/block-luks.c b/crypto/block-luks.c index c3cacdb1ed..84d189a426 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/util.h" #include "qemu/bswap.h" #include "crypto/block-luks.h" diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index ae05327869..f04c63fe82 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -1275,6 +1275,9 @@ Example: EXAMPLE_QAPI_EVENT__MAX = 1, } example_QAPIEvent; + #define example_QAPIEvent_str(val) \ + qapi_enum_lookup(example_QAPIEvent_lookup, (val)) + extern const char *const example_QAPIEvent_lookup[]; #endif diff --git a/hmp.c b/hmp.c index 2b6e919501..5d980acb1e 100644 --- a/hmp.c +++ b/hmp.c @@ -31,7 +31,6 @@ #include "qapi/qmp/qerror.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" -#include "qapi/util.h" #include "qapi-visit.h" #include "qom/object_interfaces.h" #include "ui/console.h" diff --git a/include/qapi/util.h b/include/qapi/util.h index 4eb8a3fe2f..5e50d0c1ce 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -11,6 +11,7 @@ #ifndef QAPI_UTIL_H #define QAPI_UTIL_H +const char *qapi_enum_lookup(const char *const lookup[], int val); int qapi_enum_parse(const char * const lookup[], const char *buf, int def, Error **errp); diff --git a/migration/global_state.c b/migration/global_state.c index 88c55f8cdb..76cd3a13d4 100644 --- a/migration/global_state.c +++ b/migration/global_state.c @@ -14,7 +14,6 @@ #include "qemu/cutils.h" #include "qemu/error-report.h" #include "qapi/error.h" -#include "qapi/util.h" #include "migration.h" #include "migration/global_state.h" #include "migration/vmstate.h" diff --git a/migration/migration.c b/migration/migration.c index c3fe0ed9ca..1a2b3ebd1a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -31,7 +31,6 @@ #include "migration/vmstate.h" #include "block/block.h" #include "qapi/qmp/qerror.h" -#include "qapi/util.h" #include "qemu/rcu.h" #include "block.h" #include "postcopy-ram.h" diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index ee7594ff19..7af2f04d36 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -13,7 +13,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" -#include "qapi/util.h" + +const char *qapi_enum_lookup(const char *const lookup[], int val) +{ + assert(val >= 0); + + return lookup[val]; +} int qapi_enum_parse(const char * const lookup[], const char *buf, int def, Error **errp) diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index ec83ff68f9..f285879d72 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -14,7 +14,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/util.h" #include "qemu-common.h" #include "qapi/qmp/qobject.h" #include "qapi/qmp/qerror.h" diff --git a/qemu-img.c b/qemu-img.c index 611ab7ddf3..a72a2e3133 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -26,7 +26,6 @@ #include "qemu-version.h" #include "qapi/error.h" -#include "qapi/util.h" #include "qapi-visit.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qmp/qerror.h" diff --git a/qemu-nbd.c b/qemu-nbd.c index 96e10d62dc..a97f3f4540 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -34,7 +34,6 @@ #include "qemu/log.h" #include "qemu/systemd.h" #include "block/snapshot.h" -#include "qapi/util.h" #include "qapi/qmp/qstring.h" #include "qom/object_interfaces.h" #include "io/channel-socket.h" diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py index bcbef1035f..07b4b70199 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi-event.py @@ -217,6 +217,7 @@ fdef.write(mcgen(''' fdecl.write(mcgen(''' #include "qapi/error.h" +#include "qapi/util.h" #include "qapi/qmp/qdict.h" #include "%(prefix)sqapi-types.h" diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index b45e7b5634..7e3051dbb9 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -292,6 +292,10 @@ fdef.write(mcgen(''' ''', prefix=prefix)) +fdecl.write(mcgen(''' +#include "qapi/util.h" +''')) + schema = QAPISchema(input_file) gen = QAPISchemaGenTypeVisitor() schema.visit(gen) diff --git a/scripts/qapi.py b/scripts/qapi.py index 3693b520da..8736b9c786 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1894,6 +1894,9 @@ typedef enum %(c_name)s { ret += mcgen(''' +#define %(c_name)s_str(val) \\ + qapi_enum_lookup(%(c_name)s_lookup, (val)) + extern const char *const %(c_name)s_lookup[]; ''', c_name=c_name(name)) diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c index d72ee8c4e7..7e1be1d851 100644 --- a/tests/test-qapi-util.c +++ b/tests/test-qapi-util.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/util.h" #include "test-qapi-types.h" static void test_qapi_enum_parse(void) diff --git a/tpm.c b/tpm.c index 7635fc779b..38f3eb827f 100644 --- a/tpm.c +++ b/tpm.c @@ -14,7 +14,6 @@ #include "qemu/osdep.h" #include "qapi/qmp/qerror.h" -#include "qapi/util.h" #include "sysemu/tpm_backend.h" #include "sysemu/tpm.h" #include "qemu/config-file.h" diff --git a/util/keyval.c b/util/keyval.c index 7dbda62305..7dfc75cf01 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -82,7 +82,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include "qemu/cutils.h" #include "qemu/option.h" -- cgit v1.2.3-55-g7522 From f7abe0ecd4973dfe36944b916c5b9cf8ec199b8a Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Thu, 24 Aug 2017 10:46:10 +0200 Subject: qapi: Change data type of the FOO_lookup generated for enum FOO Currently, a FOO_lookup is an array of strings terminated by a NULL sentinel. A future patch will generate enums with "holes". NULL-termination will cease to work then. To prepare for that, store the length in the FOO_lookup by wrapping it in a struct and adding a member for the length. The sentinel will be dropped next. Signed-off-by: Marc-André Lureau Message-Id: <20170822132255.23945-13-marcandre.lureau@redhat.com> [Basically redone] Signed-off-by: Markus Armbruster Message-Id: <1503564371-26090-16-git-send-email-armbru@redhat.com> [Rebased] --- backends/hostmem.c | 2 +- block.c | 2 +- block/blkdebug.c | 4 ++-- block/file-posix.c | 8 +++++--- block/file-win32.c | 2 +- block/gluster.c | 4 ++-- block/parallels.c | 14 ++++++++------ block/qcow2.c | 4 ++-- block/quorum.c | 2 +- blockdev.c | 2 +- crypto/block-luks.c | 8 ++++---- crypto/secret.c | 2 +- crypto/tlscreds.c | 2 +- hmp.c | 6 +++--- hw/core/qdev-properties.c | 10 +++++----- include/hw/qdev-core.h | 2 +- include/qapi/util.h | 9 +++++++-- include/qapi/visitor.h | 2 +- include/qom/object.h | 4 ++-- migration/global_state.c | 2 +- net/filter.c | 2 +- qapi/qapi-util.c | 12 ++++++------ qapi/qapi-visit-core.c | 24 +++++++++++++----------- qemu-img.c | 2 +- qemu-nbd.c | 2 +- qom/object.c | 16 ++++++++-------- scripts/qapi-visit.py | 2 +- scripts/qapi.py | 13 ++++++++----- tests/check-qom-proplist.c | 15 +++++++++------ tests/qmp-test.c | 2 +- tests/test-qapi-util.c | 10 +++++----- tests/test-qobject-input-visitor.c | 2 +- tpm.c | 2 +- 33 files changed, 106 insertions(+), 89 deletions(-) (limited to 'include') diff --git a/backends/hostmem.c b/backends/hostmem.c index 06e8898e40..217cff6766 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -395,7 +395,7 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) host_memory_backend_set_host_nodes, NULL, NULL, &error_abort); object_class_property_add_enum(oc, "policy", "HostMemPolicy", - HostMemPolicy_lookup, + &HostMemPolicy_lookup, host_memory_backend_get_policy, host_memory_backend_set_policy, &error_abort); object_class_property_add_str(oc, "id", get_id, set_id, &error_abort); diff --git a/block.c b/block.c index 845eff8177..b749bd6404 100644 --- a/block.c +++ b/block.c @@ -1332,7 +1332,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, detect_zeroes = qemu_opt_get(opts, "detect-zeroes"); if (detect_zeroes) { BlockdevDetectZeroesOptions value = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, detect_zeroes, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); diff --git a/block/blkdebug.c b/block/blkdebug.c index b370fcedfb..8e385acf54 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -169,7 +169,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp) error_setg(errp, "Missing event name for rule"); return -1; } - event = qapi_enum_parse(BlkdebugEvent_lookup, event_name, -1, errp); + event = qapi_enum_parse(&BlkdebugEvent_lookup, event_name, -1, errp); if (event < 0) { return -1; } @@ -732,7 +732,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event, struct BlkdebugRule *rule; int blkdebug_event; - blkdebug_event = qapi_enum_parse(BlkdebugEvent_lookup, event, -1, NULL); + blkdebug_event = qapi_enum_parse(&BlkdebugEvent_lookup, event, -1, NULL); if (blkdebug_event < 0) { return -ENOENT; } diff --git a/block/file-posix.c b/block/file-posix.c index bfef91db63..6acbd56238 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -437,7 +437,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, aio_default = (bdrv_flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; - aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), + aio = qapi_enum_parse(&BlockdevAioOptions_lookup, + qemu_opt_get(opts, "aio"), aio_default, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -446,7 +447,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } s->use_linux_aio = (aio == BLOCKDEV_AIO_OPTIONS_NATIVE); - locking = qapi_enum_parse(OnOffAuto_lookup, qemu_opt_get(opts, "locking"), + locking = qapi_enum_parse(&OnOffAuto_lookup, + qemu_opt_get(opts, "locking"), ON_OFF_AUTO_AUTO, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -1973,7 +1975,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) BDRV_SECTOR_SIZE); nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, buf, + prealloc = qapi_enum_parse(&PreallocMode_lookup, buf, PREALLOC_MODE_OFF, &local_err); g_free(buf); if (local_err) { diff --git a/block/file-win32.c b/block/file-win32.c index f2a1830060..9e02214a69 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -302,7 +302,7 @@ static bool get_aio_option(QemuOpts *opts, int flags, Error **errp) aio_default = (flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; - aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), + aio = qapi_enum_parse(&BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), aio_default, errp); switch (aio) { diff --git a/block/gluster.c b/block/gluster.c index 29f9427e47..0f4265a3a4 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -543,7 +543,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, if (!strcmp(ptr, "tcp")) { ptr = "inet"; /* accept legacy "tcp" */ } - type = qapi_enum_parse(SocketAddressType_lookup, ptr, -1, NULL); + type = qapi_enum_parse(&SocketAddressType_lookup, ptr, -1, NULL); if (type != SOCKET_ADDRESS_TYPE_INET && type != SOCKET_ADDRESS_TYPE_UNIX) { error_setg(&local_err, @@ -1000,7 +1000,7 @@ static int qemu_gluster_create(const char *filename, BDRV_SECTOR_SIZE); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, tmp, PREALLOC_MODE_OFF, + prealloc = qapi_enum_parse(&PreallocMode_lookup, tmp, PREALLOC_MODE_OFF, &local_err); g_free(tmp); if (local_err) { diff --git a/block/parallels.c b/block/parallels.c index d812210b4f..cce7336cac 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -68,13 +68,15 @@ typedef enum ParallelsPreallocMode { PRL_PREALLOC_MODE__MAX = 2, } ParallelsPreallocMode; -static const char *prealloc_mode_lookup[] = { - "falloc", - "truncate", - NULL, +static QEnumLookup prealloc_mode_lookup = { + .array = (const char *const[]) { + "falloc", + "truncate", + NULL, + }, + .size = PRL_PREALLOC_MODE__MAX }; - typedef struct BDRVParallelsState { /** Locking is conservative, the lock protects * - image file extending (truncate, fallocate) @@ -695,7 +697,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, qemu_opt_get_size_del(opts, PARALLELS_OPT_PREALLOC_SIZE, 0); s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS); buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE); - s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf, + s->prealloc_mode = qapi_enum_parse(&prealloc_mode_lookup, buf, PRL_PREALLOC_MODE_FALLOCATE, &local_err); g_free(buf); diff --git a/block/qcow2.c b/block/qcow2.c index cbe9681fb0..2ec399663e 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2915,7 +2915,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) goto finish; } buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, buf, + prealloc = qapi_enum_parse(&PreallocMode_lookup, buf, PREALLOC_MODE_OFF, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -3605,7 +3605,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, } optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, optstr, + prealloc = qapi_enum_parse(&PreallocMode_lookup, optstr, PREALLOC_MODE_OFF, &local_err); g_free(optstr); if (local_err) { diff --git a/block/quorum.c b/block/quorum.c index 8d1c9f6306..272f9a5b77 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -912,7 +912,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, if (!pattern_str) { ret = QUORUM_READ_PATTERN_QUORUM; } else { - ret = qapi_enum_parse(QuorumReadPattern_lookup, pattern_str, + ret = qapi_enum_parse(&QuorumReadPattern_lookup, pattern_str, -EINVAL, NULL); } if (ret < 0) { diff --git a/blockdev.c b/blockdev.c index bfb2a95299..796beaed94 100644 --- a/blockdev.c +++ b/blockdev.c @@ -437,7 +437,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags, if (detect_zeroes) { *detect_zeroes = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, qemu_opt_get(opts, "detect-zeroes"), BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_error); diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 4e828951d4..36bc856084 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -264,7 +264,7 @@ qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, /* XXX replace with qapi_enum_parse() in future, when we can * make that function emit a more friendly error message */ static int qcrypto_block_luks_name_lookup(const char *name, - const char *const *map, + const QEnumLookup *map, const char *type, Error **errp) { @@ -279,19 +279,19 @@ static int qcrypto_block_luks_name_lookup(const char *name, #define qcrypto_block_luks_cipher_mode_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoCipherMode_lookup, \ + &QCryptoCipherMode_lookup, \ "Cipher mode", \ errp) #define qcrypto_block_luks_hash_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoHashAlgorithm_lookup, \ + &QCryptoHashAlgorithm_lookup, \ "Hash algorithm", \ errp) #define qcrypto_block_luks_ivgen_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoIVGenAlgorithm_lookup, \ + &QCryptoIVGenAlgorithm_lookup, \ "IV generator", \ errp) diff --git a/crypto/secret.c b/crypto/secret.c index 285ab7a63c..388abd7df5 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -378,7 +378,7 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data) NULL); object_class_property_add_enum(oc, "format", "QCryptoSecretFormat", - QCryptoSecretFormat_lookup, + &QCryptoSecretFormat_lookup, qcrypto_secret_prop_get_format, qcrypto_secret_prop_set_format, NULL); diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c index a8965531b6..3cd41035bb 100644 --- a/crypto/tlscreds.c +++ b/crypto/tlscreds.c @@ -233,7 +233,7 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, void *data) NULL); object_class_property_add_enum(oc, "endpoint", "QCryptoTLSCredsEndpoint", - QCryptoTLSCredsEndpoint_lookup, + &QCryptoTLSCredsEndpoint_lookup, qcrypto_tls_creds_prop_get_endpoint, qcrypto_tls_creds_prop_set_endpoint, NULL); diff --git a/hmp.c b/hmp.c index 30819fe602..cd046c6d71 100644 --- a/hmp.c +++ b/hmp.c @@ -1528,7 +1528,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); int val; - val = qapi_enum_parse(MigrationCapability_lookup, cap, -1, &err); + val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err); if (val < 0) { goto end; } @@ -1557,7 +1557,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) Error *err = NULL; int val, ret; - val = qapi_enum_parse(MigrationParameter_lookup, param, -1, &err); + val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err); if (val < 0) { goto cleanup; } @@ -1735,7 +1735,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) } else { if (read_only) { read_only_mode = - qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, + qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup, read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); if (err) { diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 7512bd4379..1dc80fcea2 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -587,7 +587,7 @@ const PropertyInfo qdev_prop_macaddr = { const PropertyInfo qdev_prop_on_off_auto = { .name = "OnOffAuto", .description = "on/off/auto", - .enum_table = OnOffAuto_lookup, + .enum_table = &OnOffAuto_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -599,7 +599,7 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); const PropertyInfo qdev_prop_losttickpolicy = { .name = "LostTickPolicy", - .enum_table = LostTickPolicy_lookup, + .enum_table = &LostTickPolicy_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -613,7 +613,7 @@ const PropertyInfo qdev_prop_blockdev_on_error = { .name = "BlockdevOnError", .description = "Error handling policy, " "report/ignore/enospc/stop/auto", - .enum_table = BlockdevOnError_lookup, + .enum_table = &BlockdevOnError_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -627,7 +627,7 @@ const PropertyInfo qdev_prop_bios_chs_trans = { .name = "BiosAtaTranslation", .description = "Logical CHS translation algorithm, " "auto/none/lba/large/rechs", - .enum_table = BiosAtaTranslation_lookup, + .enum_table = &BiosAtaTranslation_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -639,7 +639,7 @@ const PropertyInfo qdev_prop_fdc_drive_type = { .name = "FdcDriveType", .description = "FDC drive type, " "144/288/120/none/auto", - .enum_table = FloppyDriveType_lookup, + .enum_table = &FloppyDriveType_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index ae317286a4..089146197f 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -249,7 +249,7 @@ struct Property { struct PropertyInfo { const char *name; const char *description; - const char * const *enum_table; + const QEnumLookup *enum_table; int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); void (*set_default_value)(Object *obj, const Property *prop); void (*create)(Object *obj, Property *prop, Error **errp); diff --git a/include/qapi/util.h b/include/qapi/util.h index 5e50d0c1ce..a7c3c64148 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -11,8 +11,13 @@ #ifndef QAPI_UTIL_H #define QAPI_UTIL_H -const char *qapi_enum_lookup(const char *const lookup[], int val); -int qapi_enum_parse(const char * const lookup[], const char *buf, +typedef struct QEnumLookup { + const char *const *array; + int size; +} QEnumLookup; + +const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); +int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, int def, Error **errp); int parse_qapi_name(const char *name, bool complete); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 0f3b8cb459..62a51a54cb 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -469,7 +469,7 @@ bool visit_optional(Visitor *v, const char *name, bool *present); * that visit_type_str() must have no unwelcome side effects. */ void visit_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp); + const QEnumLookup *lookup, Error **errp); /* * Check if visitor is an input visitor. diff --git a/include/qom/object.h b/include/qom/object.h index 1b828994fa..f3e5cff37a 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1415,14 +1415,14 @@ void object_class_property_add_bool(ObjectClass *klass, const char *name, */ void object_property_add_enum(Object *obj, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp); void object_class_property_add_enum(ObjectClass *klass, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp); diff --git a/migration/global_state.c b/migration/global_state.c index 8db2f19459..dfdaf63910 100644 --- a/migration/global_state.c +++ b/migration/global_state.c @@ -88,7 +88,7 @@ static int global_state_post_load(void *opaque, int version_id) s->received = true; trace_migrate_global_state_post_load(runstate); - r = qapi_enum_parse(RunState_lookup, runstate, -1, &local_err); + r = qapi_enum_parse(&RunState_lookup, runstate, -1, &local_err); if (r == -1) { if (local_err) { diff --git a/net/filter.c b/net/filter.c index 1dfd2caa23..2fd7d7d663 100644 --- a/net/filter.c +++ b/net/filter.c @@ -179,7 +179,7 @@ static void netfilter_init(Object *obj) netfilter_get_netdev_id, netfilter_set_netdev_id, NULL); object_property_add_enum(obj, "queue", "NetFilterDirection", - NetFilterDirection_lookup, + &NetFilterDirection_lookup, netfilter_get_direction, netfilter_set_direction, NULL); object_property_add_str(obj, "status", diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index 7af2f04d36..e9b266bb70 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -14,14 +14,14 @@ #include "qapi/error.h" #include "qemu-common.h" -const char *qapi_enum_lookup(const char *const lookup[], int val) +const char *qapi_enum_lookup(const QEnumLookup *lookup, int val) { - assert(val >= 0); + assert(val >= 0 && val < lookup->size); - return lookup[val]; + return lookup->array[val]; } -int qapi_enum_parse(const char * const lookup[], const char *buf, +int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, int def, Error **errp) { int i; @@ -30,8 +30,8 @@ int qapi_enum_parse(const char * const lookup[], const char *buf, return def; } - for (i = 0; lookup[i]; i++) { - if (!strcmp(buf, lookup[i])) { + for (i = 0; i < lookup->size; i++) { + if (!strcmp(buf, lookup->array[i])) { return i; } } diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 30dc85b6f3..3dcb968867 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -333,24 +333,26 @@ void visit_type_null(Visitor *v, const char *name, QNull **obj, } static void output_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { - int i = 0; int value = *obj; char *enum_str; - while (strings[i++] != NULL); - if (value < 0 || value >= i - 1) { + /* + * TODO why is this an error, not an assertion? If assertion: + * delete, and rely on qapi_enum_lookup() + */ + if (value < 0 || value >= lookup->size) { error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null"); return; } - enum_str = (char *)qapi_enum_lookup(strings, value); + enum_str = (char *)qapi_enum_lookup(lookup, value); visit_type_str(v, name, &enum_str, errp); } static void input_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { Error *local_err = NULL; int64_t value; @@ -362,7 +364,7 @@ static void input_type_enum(Visitor *v, const char *name, int *obj, return; } - value = qapi_enum_parse(strings, enum_str, -1, NULL); + value = qapi_enum_parse(lookup, enum_str, -1, NULL); if (value < 0) { error_setg(errp, QERR_INVALID_PARAMETER, enum_str); g_free(enum_str); @@ -374,16 +376,16 @@ static void input_type_enum(Visitor *v, const char *name, int *obj, } void visit_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { - assert(obj && strings); + assert(obj && lookup); trace_visit_type_enum(v, name, obj); switch (v->type) { case VISITOR_INPUT: - input_type_enum(v, name, obj, strings, errp); + input_type_enum(v, name, obj, lookup, errp); break; case VISITOR_OUTPUT: - output_type_enum(v, name, obj, strings, errp); + output_type_enum(v, name, obj, lookup, errp); break; case VISITOR_CLONE: /* nothing further to do, scalar value was already copied by diff --git a/qemu-img.c b/qemu-img.c index a72a2e3133..df984b11b9 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3489,7 +3489,7 @@ static int img_resize(int argc, char **argv) image_opts = true; break; case OPTION_PREALLOCATION: - prealloc = qapi_enum_parse(PreallocMode_lookup, optarg, + prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg, PREALLOC_MODE__MAX, NULL); if (prealloc == PREALLOC_MODE__MAX) { error_report("Invalid preallocation mode '%s'", optarg); diff --git a/qemu-nbd.c b/qemu-nbd.c index a97f3f4540..d75ca51482 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -638,7 +638,7 @@ int main(int argc, char **argv) break; case QEMU_NBD_OPT_DETECT_ZEROES: detect_zeroes = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, optarg, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); diff --git a/qom/object.c b/qom/object.c index fe6e744b4d..3e18537e9b 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1246,7 +1246,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name, } typedef struct EnumProperty { - const char * const *strings; + const QEnumLookup *lookup; int (*get)(Object *, Error **); void (*set)(Object *, int, Error **); } EnumProperty; @@ -1284,7 +1284,7 @@ int object_property_get_enum(Object *obj, const char *name, visit_complete(v, &str); visit_free(v); v = string_input_visitor_new(str); - visit_type_enum(v, name, &ret, enumprop->strings, errp); + visit_type_enum(v, name, &ret, enumprop->lookup, errp); g_free(str); visit_free(v); @@ -1950,7 +1950,7 @@ static void property_get_enum(Object *obj, Visitor *v, const char *name, return; } - visit_type_enum(v, name, &value, prop->strings, errp); + visit_type_enum(v, name, &value, prop->lookup, errp); } static void property_set_enum(Object *obj, Visitor *v, const char *name, @@ -1960,7 +1960,7 @@ static void property_set_enum(Object *obj, Visitor *v, const char *name, int value; Error *err = NULL; - visit_type_enum(v, name, &value, prop->strings, &err); + visit_type_enum(v, name, &value, prop->lookup, &err); if (err) { error_propagate(errp, err); return; @@ -1977,7 +1977,7 @@ static void property_release_enum(Object *obj, const char *name, void object_property_add_enum(Object *obj, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp) @@ -1985,7 +1985,7 @@ void object_property_add_enum(Object *obj, const char *name, Error *local_err = NULL; EnumProperty *prop = g_malloc(sizeof(*prop)); - prop->strings = strings; + prop->lookup = lookup; prop->get = get; prop->set = set; @@ -2002,7 +2002,7 @@ void object_property_add_enum(Object *obj, const char *name, void object_class_property_add_enum(ObjectClass *klass, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp) @@ -2010,7 +2010,7 @@ void object_class_property_add_enum(ObjectClass *klass, const char *name, Error *local_err = NULL; EnumProperty *prop = g_malloc(sizeof(*prop)); - prop->strings = strings; + prop->lookup = lookup; prop->get = get; prop->set = set; diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index bd0b742236..7e1cfc13f0 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -153,7 +153,7 @@ def gen_visit_enum(name): void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp) { int value = *obj; - visit_type_enum(v, name, &value, %(c_name)s_lookup, errp); + visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp); *obj = value; } ''', diff --git a/scripts/qapi.py b/scripts/qapi.py index 8736b9c786..39a67270fc 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1849,19 +1849,22 @@ def guardend(name): def gen_enum_lookup(name, values, prefix=None): ret = mcgen(''' -const char *const %(c_name)s_lookup[] = { +const QEnumLookup %(c_name)s_lookup = { + .array = (const char *const[]) { ''', c_name=c_name(name)) for value in values: index = c_enum_const(name, value, prefix) ret += mcgen(''' - [%(index)s] = "%(value)s", + [%(index)s] = "%(value)s", ''', index=index, value=value) max_index = c_enum_const(name, '_MAX', prefix) ret += mcgen(''' - [%(max_index)s] = NULL, + [%(max_index)s] = NULL, + }, + .size = %(max_index)s }; ''', max_index=max_index) @@ -1895,9 +1898,9 @@ typedef enum %(c_name)s { ret += mcgen(''' #define %(c_name)s_str(val) \\ - qapi_enum_lookup(%(c_name)s_lookup, (val)) + qapi_enum_lookup(&%(c_name)s_lookup, (val)) -extern const char *const %(c_name)s_lookup[]; +extern const QEnumLookup %(c_name)s_lookup; ''', c_name=c_name(name)) return ret diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index c51e6e734d..07e351f950 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -46,11 +46,14 @@ enum DummyAnimal { DUMMY_LAST, }; -static const char *const dummy_animal_map[DUMMY_LAST + 1] = { - [DUMMY_FROG] = "frog", - [DUMMY_ALLIGATOR] = "alligator", - [DUMMY_PLATYPUS] = "platypus", - [DUMMY_LAST] = NULL, +const QEnumLookup dummy_animal_map = { + .array = (const char *const[]) { + [DUMMY_FROG] = "frog", + [DUMMY_ALLIGATOR] = "alligator", + [DUMMY_PLATYPUS] = "platypus", + [DUMMY_LAST] = NULL, + }, + .size = DUMMY_LAST }; struct DummyObject { @@ -142,7 +145,7 @@ static void dummy_class_init(ObjectClass *cls, void *data) NULL); object_class_property_add_enum(cls, "av", "DummyAnimal", - dummy_animal_map, + &dummy_animal_map, dummy_get_av, dummy_set_av, NULL); diff --git a/tests/qmp-test.c b/tests/qmp-test.c index b5f21dfa57..c5a5c10b41 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -181,7 +181,7 @@ static void test_query(const void *data) g_assert(qdict_haskey(resp, "return")); } else { g_assert(error); - g_assert_cmpint(qapi_enum_parse(QapiErrorClass_lookup, error_class, + g_assert_cmpint(qapi_enum_parse(&QapiErrorClass_lookup, error_class, -1, &error_abort), ==, expected_error_class); } diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c index 0992bdb218..4b5e4f8bd3 100644 --- a/tests/test-qapi-util.c +++ b/tests/test-qapi-util.c @@ -19,19 +19,19 @@ static void test_qapi_enum_parse(void) Error *err = NULL; int ret; - ret = qapi_enum_parse(QType_lookup, NULL, QTYPE_NONE, &error_abort); + ret = qapi_enum_parse(&QType_lookup, NULL, QTYPE_NONE, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, "junk", -1, NULL); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, NULL); g_assert_cmpint(ret, ==, -1); - ret = qapi_enum_parse(QType_lookup, "junk", -1, &err); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, &err); error_free_or_abort(&err); - ret = qapi_enum_parse(QType_lookup, "none", -1, &error_abort); + ret = qapi_enum_parse(&QType_lookup, "none", -1, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, QType_str(QTYPE__MAX - 1), + ret = qapi_enum_parse(&QType_lookup, QType_str(QTYPE__MAX - 1), QTYPE__MAX - 1, &error_abort); g_assert_cmpint(ret, ==, QTYPE__MAX - 1); } diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index f8720aa5eb..fe591814e4 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -1110,7 +1110,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, error_free_or_abort(&err); visit_optional(v, "optional", &present); g_assert(!present); - visit_type_enum(v, "enum", &en, EnumOne_lookup, &err); + visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); error_free_or_abort(&err); visit_type_int(v, "i64", &i64, &err); error_free_or_abort(&err); diff --git a/tpm.c b/tpm.c index 111f1ca63f..2d830d072a 100644 --- a/tpm.c +++ b/tpm.c @@ -33,7 +33,7 @@ void tpm_register_model(enum TpmModel model) const TPMDriverOps *tpm_get_backend_driver(const char *type) { - int i = qapi_enum_parse(TpmType_lookup, type, -1, NULL); + int i = qapi_enum_parse(&TpmType_lookup, type, -1, NULL); return i >= 0 ? be_drivers[i] : NULL; } -- cgit v1.2.3-55-g7522