All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C)
@ 2015-11-04  6:20 Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 01/27] qapi: Use generated TestStruct machinery in tests Eric Blake
                   ` (28 more replies)
  0 siblings, 29 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

No pending prerequisites; based on qemu.git master

Also available as a tag at this location:
git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv9c

and will soon be part of my branch with the rest of the v5 series, at:
http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi

v9 notes:
More patches added, and several reorganized.  Lots of new patches
from Markus, although not in the order originally proposed.

The first 8 patches are fairly straightforward, and could probably
be taken as-is. Patch 9 is a rewrite of v8 4/17, but in the opposite
direction (document that no sorting is done, rather than attempting
to sort), so it may need further fine-tuning.  Patches 12-21
represents a fusion of Markus' and my attempts to rewrite v5 7/17
into a more-reviewable set of patches, and caused further churn
later in the series.

Patch 23 still uses tag_member.type == None; I ran out of time to
work on Markus' idea of providing an instance of QAPISchemaBuiltinType
to fill the role for 'qtype_code' without being exposed through .json
files and without breaking the invariant of a valid member.type after
check(), and wanted to get the rest of the series started under revew.
So I may need a followup patch or even a v10 of the later half of
this series after exploring that idea more.

Here's what backport-diff has to say in relation to v8.

001/27:[----] [--] 'qapi: Use generated TestStruct machinery in tests'
002/27:[----] [--] 'qapi: Strengthen test of TestStructList'
003/27:[0001] [FC] 'qapi: Plug leaks in test-qmp-*'
004/27:[0010] [FC] 'qapi: Simplify error testing in test-qmp-*'
005/27:[down] 'qapi: More tests of alternate output'
006/27:[----] [--] 'qapi: Test failure in middle of array parse'
007/27:[----] [--] 'qapi: More tests of input arrays'
008/27:[----] [--] 'qapi: Provide nicer array names in introspection'
009/27:[down] 'qapi-introspect: Document lack of sorting'
010/27:[0008] [FC] 'qapi: Track simple union tag in object.local_members'
011/27:[0001] [FC] 'qapi-types: Consolidate gen_struct() and gen_union()'
012/27:[down] 'qapi-types: Simplify gen_struct_field[s]'
013/27:[down] 'qapi: Drop obsolete tag value collision assertions'
014/27:[down] 'qapi: Fix up commit 7618b91's clash sanity checking change'
015/27:[down] 'qapi: Simplify QAPISchemaObjectTypeMember.check()'
016/27:[down] 'qapi: Eliminate QAPISchemaObjectType.check() variable members'
017/27:[down] 'qapi: Clean up after previous commit'
018/27:[down] 'qapi: Factor out QAPISchemaObjectTypeMember.check_clash()'
019/27:[down] 'qapi: Check for qapi collisions of flat union branches'
020/27:[down] 'qapi: Simplify QAPISchemaObjectTypeVariants.check()'
021/27:[down] 'qapi: Factor out QAPISchemaObjectType.check_clash()'
022/27:[----] [--] 'qapi: Remove outdated tests related to QMP/branch collisions'
023/27:[0070] [FC] 'qapi: Simplify visiting of alternate types'
024/27:[0014] [FC] 'qapi: Fix alternates that accept 'number' but not 'int''
025/27:[0018] [FC] 'qapi: Add positive tests to qapi-schema-test'
026/27:[----] [--] 'qapi: Remove dead visitor code'
027/27:[----] [--] 'qapi: Simplify visits of optional fields'

v8 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg06674.html
Minor changes when rebasing to latest, improved commit messages in
a few places, plus the addition of a few new patches. Markus started
reviewing v7, but hadn't gotten very far.

v7 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg04112.html
Patches 1-3 of the previous round have moved to subset B; patch 7
is gone, and a couple of new patches are present in this round. The
latest version of subset B made it much easier to reason about
collision detection (namely, tag values can't collide with QMP values
thanks to a named rather than anonymous union in the C type), and I
like how things turned out.  I suspect the hardest part of the review
will be patches 5/14 and 7/14, although none of this has really
had much review in any earlier versions.

v6 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg01980.html
Add some patches and rebase onto work on subset B. Rearrange some
patches from v5 (this set includes 17-20, 23, 25-27). Backport diff
gets a bit confused by one patch title changing.

Not much direct review comments, although some of the changes here
are updated based on comments made on other patches in the v5 series.

Subset D (and more?) will come later.

In v5:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05410.html
I _did_ rearrange patches to try and group related features:

1-2: Groundwork cleanups
3-5: Add more test cases
6-16: Front-end cleanups
17-18: Introspection output cleanups
19-20: 'alternate' type cleanups
21-29: qapi visitor cleanups
30-45: qapi-ify netdev_add
46: add qapi shorthand for flat unions

Lots of fixes based on additional testing, and rebased to
track other changes that happened in the meantime.  The series
is huge; I can split off smaller portions as requested.

In v4:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg02580.html
add some more clean up patches
rebase to Markus' recent work
pull in part of Zoltán's work to make netdev_add a flat union,
further enhancing it to be introspectible

I might be able to rearrange some of these patches, or separate
it into smaller independent series, if requested; but I'm
posting now to get review started.

In v3:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg02059.html
redo cleanup of dealloc of partial struct
add patches to make all visit_type_*() avoid leaks on failure
add patches to allow boxed command arguments and events

In v2:
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg00900.html
rebase to Markus' v3 series
rework how comments are emitted for fields inherited from base
additional patches added for deleting colliding 'void *data'
documentation updates to match code changes

v1 was here:
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg05266.html
https://lists.gnu.org/archive/html/qemu-devel/2015-07/msg05325.html

Eric Blake (20):
  qapi: Use generated TestStruct machinery in tests
  qapi: Strengthen test of TestStructList
  qapi: Plug leaks in test-qmp-*
  qapi: Simplify error testing in test-qmp-*
  qapi: More tests of alternate output
  qapi: Test failure in middle of array parse
  qapi: More tests of input arrays
  qapi: Provide nicer array names in introspection
  qapi-introspect: Document lack of sorting
  qapi: Track simple union tag in object.local_members
  qapi-types: Consolidate gen_struct() and gen_union()
  qapi-types: Simplify gen_struct_field[s]
  qapi: Check for qapi collisions of flat union branches
  qapi: Factor out QAPISchemaObjectType.check_clash()
  qapi: Remove outdated tests related to QMP/branch collisions
  qapi: Simplify visiting of alternate types
  qapi: Fix alternates that accept 'number' but not 'int'
  qapi: Add positive tests to qapi-schema-test
  qapi: Remove dead visitor code
  qapi: Simplify visits of optional fields

Markus Armbruster (7):
  qapi: Drop obsolete tag value collision assertions
  qapi: Fix up commit 7618b91's clash sanity checking change
  qapi: Simplify QAPISchemaObjectTypeMember.check()
  qapi: Eliminate QAPISchemaObjectType.check() variable members
  qapi: Clean up after previous commits
  qapi: Factor out QAPISchemaObjectTypeMember.check_clash()
  qapi: Simplify QAPISchemaObjectTypeVariants.check()

 docs/qapi-code-gen.txt                         |  29 ++-
 include/qapi/visitor-impl.h                    |  27 ++-
 include/qapi/visitor.h                         |  22 +-
 qapi/introspect.json                           |  21 +-
 qapi/opts-visitor.c                            |   2 +-
 qapi/qapi-visit-core.c                         | 141 +++++--------
 qapi/qmp-input-visitor.c                       |  11 +-
 qapi/string-input-visitor.c                    |   3 +-
 scripts/qapi-introspect.py                     |   8 +-
 scripts/qapi-types.py                          | 102 +++-------
 scripts/qapi-visit.py                          |  28 ++-
 scripts/qapi.py                                | 115 ++++++-----
 tests/Makefile                                 |   3 -
 tests/qapi-schema/alternate-empty.out          |   1 -
 tests/qapi-schema/flat-union-clash-branch.err  |   0
 tests/qapi-schema/flat-union-clash-branch.exit |   1 -
 tests/qapi-schema/flat-union-clash-branch.json |  18 --
 tests/qapi-schema/flat-union-clash-branch.out  |  14 --
 tests/qapi-schema/flat-union-clash-type.err    |   1 -
 tests/qapi-schema/flat-union-clash-type.exit   |   1 -
 tests/qapi-schema/flat-union-clash-type.json   |  14 --
 tests/qapi-schema/flat-union-clash-type.out    |   0
 tests/qapi-schema/qapi-schema-test.json        |  22 +-
 tests/qapi-schema/qapi-schema-test.out         |  42 +++-
 tests/qapi-schema/union-clash-data.out         |   1 +
 tests/qapi-schema/union-clash-type.err         |   1 -
 tests/qapi-schema/union-clash-type.exit        |   1 -
 tests/qapi-schema/union-clash-type.json        |   9 -
 tests/qapi-schema/union-clash-type.out         |   0
 tests/qapi-schema/union-empty.out              |   1 +
 tests/test-qmp-input-strict.c                  | 108 +++-------
 tests/test-qmp-input-visitor.c                 | 268 +++++++++++--------------
 tests/test-qmp-output-visitor.c                | 153 ++++----------
 tests/test-visitor-serialization.c             |  76 ++-----
 34 files changed, 498 insertions(+), 746 deletions(-)
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.err
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.exit
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.json
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.out
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.err
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.exit
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.json
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.out
 delete mode 100644 tests/qapi-schema/union-clash-type.err
 delete mode 100644 tests/qapi-schema/union-clash-type.exit
 delete mode 100644 tests/qapi-schema/union-clash-type.json
 delete mode 100644 tests/qapi-schema/union-clash-type.out

-- 
2.4.3

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 01/27] qapi: Use generated TestStruct machinery in tests
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 02/27] qapi: Strengthen test of TestStructList Eric Blake
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Commit d88f5fd and friends first introduced the various test-qmp-*
tests in 2011, with duplicated hand-rolled TestStruct machinery,
to make sure the qapi visitor interface was tested.  Later, commit
4f193e3 in 2013 added a .json file for further testing use by the
files, but without consolidating any of the existing hand-rolled
visitors.  And with four copies, subtle differences have crept in,
between the tests themselves (mainly whitespace differences, but
also a question of whether to use NULL or "TestStruct" when
calling visit_start_struct()) and from what the generator produces
(the hand-rolled versions did not cater to partially-allocated
objects, because they did not have a deallocation usage).

Of course, just because the visitor interface is tested does not
mean it is a sane interface; and future patches will be changing
some of the visitor contracts.  Rather than having to duplicate
the cleanup work in each copy of the TestStruct visitor, and keep
each hand-rolled copy in sync with what the generator supplies, we
might as well just test what the generator should give us in the
first place.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: improve commit message
v7: rebase on top of subset B v9; defer unrelated trailing whitespace
cleanups to later in series
v6: new patch
---
 tests/qapi-schema/qapi-schema-test.json |  6 +++-
 tests/qapi-schema/qapi-schema-test.out  |  5 +++
 tests/test-qmp-input-strict.c           | 35 --------------------
 tests/test-qmp-input-visitor.c          | 34 -------------------
 tests/test-qmp-output-visitor.c         | 58 ---------------------------------
 tests/test-visitor-serialization.c      | 34 -------------------
 6 files changed, 10 insertions(+), 162 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 48e104b..44638da 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -3,6 +3,9 @@
 # This file is a stress test of supported qapi constructs that must
 # parse and compile correctly.

+{ 'struct': 'TestStruct',
+  'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } }
+
 # for testing enums
 { 'struct': 'NestedEnumsOne',
   'data': { 'enum1': 'EnumOne',   # Intentional forward reference
@@ -46,7 +49,8 @@

 # dummy struct to force generation of array types not otherwise mentioned
 { 'struct': 'ForceArrays',
-  'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'] } }
+  'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'],
+            'unused3':['TestStruct'] } }

 # for testing unions
 # Among other things, test that a name collision between branches does
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index a7e9aab..e20a823 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -92,6 +92,7 @@ object EventStructOne
 object ForceArrays
     member unused1: UserDefOneList optional=False
     member unused2: UserDefTwoList optional=False
+    member unused3: TestStructList optional=False
 enum MyEnum []
 object NestedEnumsOne
     member enum1: EnumOne optional=False
@@ -100,6 +101,10 @@ object NestedEnumsOne
     member enum4: EnumOne optional=True
 enum QEnumTwo ['value1', 'value2']
     prefix QENUM_TWO
+object TestStruct
+    member integer: int optional=False
+    member boolean: bool optional=False
+    member string: str optional=False
 object UserDefA
     member boolean: bool optional=False
     member a_b: int optional=True
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 53a7693..b44184f 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -89,41 +89,6 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
     return v;
 }

-typedef struct TestStruct
-{
-    int64_t integer;
-    bool boolean;
-    char *string;
-} TestStruct;
-
-static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
-                                  const char *name, Error **errp)
-{
-    Error *err = NULL;
-
-    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
-                       &err);
-    if (err) {
-        goto out;
-    }
-
-    visit_type_int(v, &(*obj)->integer, "integer", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_str(v, &(*obj)->string, "string", &err);
-
-out_end:
-    error_propagate(errp, err);
-    err = NULL;
-    visit_end_struct(v, &err);
-out:
-    error_propagate(errp, err);
-}

 static void test_validate_struct(TestInputVisitorData *data,
                                   const void *unused)
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index de65982..3f6bc4d 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -185,40 +185,6 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
     data->qiv = NULL;
 }

-typedef struct TestStruct
-{
-    int64_t integer;
-    bool boolean;
-    char *string;
-} TestStruct;
-
-static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
-                                  const char *name, Error **errp)
-{
-    Error *err = NULL;
-
-    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
-                       &err);
-    if (err) {
-        goto out;
-    }
-    visit_type_int(v, &(*obj)->integer, "integer", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_str(v, &(*obj)->string, "string", &err);
-
-out_end:
-    error_propagate(errp, err);
-    err = NULL;
-    visit_end_struct(v, &err);
-out:
-    error_propagate(errp, err);
-}

 static void test_visitor_in_struct(TestInputVisitorData *data,
                                    const void *unused)
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 09d0dd8..baf58dc 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -166,41 +166,6 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
     }
 }

-typedef struct TestStruct
-{
-    int64_t integer;
-    bool boolean;
-    char *string;
-} TestStruct;
-
-static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
-                                  const char *name, Error **errp)
-{
-    Error *err = NULL;
-
-    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
-                       &err);
-    if (err) {
-        goto out;
-    }
-
-    visit_type_int(v, &(*obj)->integer, "integer", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_str(v, &(*obj)->string, "string", &err);
-
-out_end:
-    error_propagate(errp, err);
-    err = NULL;
-    visit_end_struct(v, &err);
-out:
-    error_propagate(errp, err);
-}

 static void test_visitor_out_struct(TestOutputVisitorData *data,
                                     const void *unused)
@@ -314,29 +279,6 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
     }
 }

-typedef struct TestStructList
-{
-    union {
-        TestStruct *value;
-        uint64_t padding;
-    };
-    struct TestStructList *next;
-} TestStructList;
-
-static void visit_type_TestStructList(Visitor *v, TestStructList **obj,
-                                      const char *name, Error **errp)
-{
-    GenericList *i, **head = (GenericList **)obj;
-
-    visit_start_list(v, name, errp);
-
-    for (*head = i = visit_next_list(v, head, errp); i; i = visit_next_list(v, &i, errp)) {
-        TestStructList *native_i = (TestStructList *)i;
-        visit_type_TestStruct(v, &native_i->value, NULL, errp);
-    }
-
-    visit_end_list(v, errp);
-}

 static void test_visitor_out_list(TestOutputVisitorData *data,
                                   const void *unused)
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 634563b..c024e5e 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -186,40 +186,6 @@ static void visit_primitive_list(Visitor *v, void **native, Error **errp)
     }
 }

-typedef struct TestStruct
-{
-    int64_t integer;
-    bool boolean;
-    char *string;
-} TestStruct;
-
-static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
-                                  const char *name, Error **errp)
-{
-    Error *err = NULL;
-
-    visit_start_struct(v, (void **)obj, NULL, name, sizeof(TestStruct), &err);
-    if (err) {
-        goto out;
-    }
-
-    visit_type_int(v, &(*obj)->integer, "integer", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
-    if (err) {
-        goto out_end;
-    }
-    visit_type_str(v, &(*obj)->string, "string", &err);
-
-out_end:
-    error_propagate(errp, err);
-    err = NULL;
-    visit_end_struct(v, &err);
-out:
-    error_propagate(errp, err);
-}

 static TestStruct *struct_create(void)
 {
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 02/27] qapi: Strengthen test of TestStructList
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 01/27] qapi: Use generated TestStruct machinery in tests Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-* Eric Blake
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Make each list element different, to ensure that order is
preserved, and use the generated free function instead of
hand-rolling our own to ensure (under valgrind) that the
list is properly cleaned.

Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: no change
v7: new patch
---
 tests/test-qmp-output-visitor.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index baf58dc..9364843 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -283,7 +283,7 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
 static void test_visitor_out_list(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    char *value_str = (char *) "list value";
+    const char *value_str = "list value";
     TestStructList *p, *head = NULL;
     const int max_items = 10;
     bool value_bool = true;
@@ -294,12 +294,13 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     QList *qlist;
     int i;

+    /* Build the list in reverse order... */
     for (i = 0; i < max_items; i++) {
         p = g_malloc0(sizeof(*p));
         p->value = g_malloc0(sizeof(*p->value));
-        p->value->integer = value_int;
+        p->value->integer = value_int + (max_items - i - 1);
         p->value->boolean = value_bool;
-        p->value->string = value_str;
+        p->value->string = g_strdup(value_str);

         p->next = head;
         head = p;
@@ -315,6 +316,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     qlist = qobject_to_qlist(obj);
     g_assert(!qlist_empty(qlist));

+    /* ...and ensure that the visitor sees it in order */
     i = 0;
     QLIST_FOREACH_ENTRY(qlist, entry) {
         QDict *qdict;
@@ -322,7 +324,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
         g_assert(qobject_type(entry->value) == QTYPE_QDICT);
         qdict = qobject_to_qdict(entry->value);
         g_assert_cmpint(qdict_size(qdict), ==, 3);
-        g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int);
+        g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
         g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
         g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
         i++;
@@ -330,13 +332,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     g_assert_cmpint(i, ==, max_items);

     QDECREF(qlist);
-
-    for (p = head; p;) {
-        TestStructList *tmp = p->next;
-        g_free(p->value);
-        g_free(p);
-        p = tmp;
-    }
+    qapi_free_TestStructList(head);
 }

 static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-*
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 01/27] qapi: Use generated TestStruct machinery in tests Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 02/27] qapi: Strengthen test of TestStructList Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  8:19   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing " Eric Blake
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Make valgrind happy with the current state of the tests, so that
it is easier to see if future patches introduce new memory problems
without being drowned in noise.  Many of the leaks were due to
calling a second init without tearing down the data from an earlier
visit.  But since teardown is already idempotent, and we already
register teardown as part of input_visitor_test_add(), it is nicer
to just make init() safe to call multiple times than it is to have
to make all tests call teardown.

Another common leak was forgetting to clean up an error object,
after testing that an error was raised.

Another leak was in test_visitor_in_struct_nested(), failing to
clean the base member of UserDefTwo.  Cleaning that up left
check_and_free_str() as dead code (since using the qapi_free_*
takes care of recursion, and we don't want double frees).

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: move earlier in series (was 13/17)
v8: no change
v7: no change
v6: make init repeatable rather than adding teardown everywhere,
fix additional leak with UserDefTwo base, plug additional files
---
 tests/test-qmp-input-strict.c   | 10 ++++++++++
 tests/test-qmp-input-visitor.c  | 41 +++++++----------------------------------
 tests/test-qmp-output-visitor.c |  3 ++-
 3 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index b44184f..910e2f9 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -77,6 +77,8 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
 {
     Visitor *v;

+    validate_teardown(data, NULL);
+
     data->obj = qobject_from_json(json_string);
     g_assert(data->obj != NULL);

@@ -193,6 +195,8 @@ static void test_validate_fail_struct(TestInputVisitorData *data,

     visit_type_TestStruct(v, &p, NULL, &err);
     g_assert(err);
+    error_free(err);
+    /* FIXME: visitor should not allocate p when returning error */
     if (p) {
         g_free(p->string);
     }
@@ -210,6 +214,7 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,

     visit_type_UserDefTwo(v, &udp, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefTwo(udp);
 }

@@ -224,6 +229,7 @@ static void test_validate_fail_list(TestInputVisitorData *data,

     visit_type_UserDefOneList(v, &head, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefOneList(head);
 }

@@ -239,6 +245,7 @@ static void test_validate_fail_union_native_list(TestInputVisitorData *data,

     visit_type_UserDefNativeListUnion(v, &tmp, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefNativeListUnion(tmp);
 }

@@ -253,6 +260,7 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,

     visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefFlatUnion(tmp);
 }

@@ -268,6 +276,7 @@ static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,

     visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefFlatUnion2(tmp);
 }

@@ -282,6 +291,7 @@ static void test_validate_fail_alternate(TestInputVisitorData *data,

     visit_type_UserDefAlternate(v, &tmp, NULL, &err);
     g_assert(err);
+    error_free(err);
     qapi_free_UserDefAlternate(tmp);
 }

diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 3f6bc4d..03c3682 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -46,6 +46,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
     Visitor *v;
     va_list ap;

+    visitor_input_teardown(data, NULL);
+
     va_start(ap, json_string);
     data->obj = qobject_from_jsonv(json_string, &ap);
     va_end(ap);
@@ -177,12 +179,7 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
         visit_type_EnumOne(v, &res, NULL, &err);
         g_assert(!err);
         g_assert_cmpint(i, ==, res);
-
-        visitor_input_teardown(data, NULL);
     }
-
-    data->obj = NULL;
-    data->qiv = NULL;
 }


@@ -205,12 +202,6 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
     g_free(p);
 }

-static void check_and_free_str(char *str, const char *cmp)
-{
-    g_assert_cmpstr(str, ==, cmp);
-    g_free(str);
-}
-
 static void test_visitor_in_struct_nested(TestInputVisitorData *data,
                                           const void *unused)
 {
@@ -226,17 +217,14 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
     visit_type_UserDefTwo(v, &udp, NULL, &err);
     g_assert(!err);

-    check_and_free_str(udp->string0, "string0");
-    check_and_free_str(udp->dict1->string1, "string1");
+    g_assert_cmpstr(udp->string0, ==, "string0");
+    g_assert_cmpstr(udp->dict1->string1, ==, "string1");
     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
-    check_and_free_str(udp->dict1->dict2->userdef->string, "string");
-    check_and_free_str(udp->dict1->dict2->string, "string2");
+    g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
+    g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
     g_assert(udp->dict1->has_dict3 == false);

-    g_free(udp->dict1->dict2->userdef);
-    g_free(udp->dict1->dict2);
-    g_free(udp->dict1);
-    g_free(udp);
+    qapi_free_UserDefTwo(udp);
 }

 static void test_visitor_in_list(TestInputVisitorData *data,
@@ -346,14 +334,12 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
     g_assert_cmpint(tmp->u.i, ==, 42);
     qapi_free_UserDefAlternate(tmp);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "'string'");
     visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
     g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
     g_assert_cmpstr(tmp->u.s, ==, "string");
     qapi_free_UserDefAlternate(tmp);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "false");
     visit_type_UserDefAlternate(v, &tmp, NULL, &err);
@@ -361,7 +347,6 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     error_free(err);
     err = NULL;
     qapi_free_UserDefAlternate(tmp);
-    visitor_input_teardown(data, NULL);
 }

 static void test_visitor_in_alternate_number(TestInputVisitorData *data,
@@ -384,7 +369,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     error_free(err);
     err = NULL;
     qapi_free_AltStrBool(asb);
-    visitor_input_teardown(data, NULL);

     /* FIXME: Order of alternate should not affect semantics; asn should
      * parse the same as ans */
@@ -396,35 +380,30 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     error_free(err);
     err = NULL;
     qapi_free_AltStrNum(asn);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42");
     visit_type_AltNumStr(v, &ans, NULL, &error_abort);
     g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
     g_assert_cmpfloat(ans->u.n, ==, 42);
     qapi_free_AltNumStr(ans);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42");
     visit_type_AltStrInt(v, &asi, NULL, &error_abort);
     g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
     g_assert_cmpint(asi->u.i, ==, 42);
     qapi_free_AltStrInt(asi);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
     g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
     g_assert_cmpint(ain->u.i, ==, 42);
     qapi_free_AltIntNum(ain);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
     g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
     g_assert_cmpint(ani->u.i, ==, 42);
     qapi_free_AltNumInt(ani);
-    visitor_input_teardown(data, NULL);

     /* Parsing a double */

@@ -434,21 +413,18 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     error_free(err);
     err = NULL;
     qapi_free_AltStrBool(asb);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltStrNum(v, &asn, NULL, &error_abort);
     g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
     g_assert_cmpfloat(asn->u.n, ==, 42.5);
     qapi_free_AltStrNum(asn);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumStr(v, &ans, NULL, &error_abort);
     g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
     g_assert_cmpfloat(ans->u.n, ==, 42.5);
     qapi_free_AltNumStr(ans);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltStrInt(v, &asi, NULL, &err);
@@ -456,21 +432,18 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     error_free(err);
     err = NULL;
     qapi_free_AltStrInt(asi);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
     g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
     g_assert_cmpfloat(ain->u.n, ==, 42.5);
     qapi_free_AltIntNum(ain);
-    visitor_input_teardown(data, NULL);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
     g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
     g_assert_cmpfloat(ani->u.n, ==, 42.5);
     qapi_free_AltNumInt(ani);
-    visitor_input_teardown(data, NULL);
 }

 static void test_native_list_integer_helper(TestInputVisitorData *data,
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 9364843..8606111 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -391,6 +391,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     qobj = QOBJECT(qdict);
     visit_type_any(data->ov, &qobj, NULL, &err);
     g_assert(!err);
+    qobject_decref(qobj);
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
     qdict = qobject_to_qdict(obj);
@@ -411,7 +412,6 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     g_assert(qstring);
     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
     qobject_decref(obj);
-    qobject_decref(qobj);
 }

 static void test_visitor_out_union_flat(TestOutputVisitorData *data,
@@ -463,6 +463,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);

     qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 }

 static void test_visitor_out_empty(TestOutputVisitorData *data,
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing in test-qmp-*
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (2 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-* Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  8:40   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output Eric Blake
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

By using &error_abort, we can avoid a local err variable in
situations where we expect success.

By moving err into data, we can let test teardown take care
of cleaning up any collected error; it also gives us fewer
lines of code between repeated tests where init runs teardown
on our behalf.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: move earlier in series (was 14/17), reword commit message
v8: no change
v7: pick up whitespace changes dropped from earlier commit
v6: new patch
---
 tests/test-qmp-input-strict.c      |  77 +++++++++-----------------
 tests/test-qmp-input-visitor.c     | 107 ++++++++++++-------------------------
 tests/test-qmp-output-visitor.c    |  56 +++++--------------
 tests/test-visitor-serialization.c |  42 ++++++---------
 4 files changed, 89 insertions(+), 193 deletions(-)

diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 910e2f9..f8da75c 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -26,6 +26,7 @@
 typedef struct TestInputVisitorData {
     QObject *obj;
     QmpInputVisitor *qiv;
+    Error *err;
 } TestInputVisitorData;

 static void validate_teardown(TestInputVisitorData *data,
@@ -34,6 +35,9 @@ static void validate_teardown(TestInputVisitorData *data,
     qobject_decref(data->obj);
     data->obj = NULL;

+    error_free(data->err);
+    data->err = NULL;
+
     if (data->qiv) {
         qmp_input_visitor_cleanup(data->qiv);
         data->qiv = NULL;
@@ -96,13 +100,11 @@ static void test_validate_struct(TestInputVisitorData *data,
                                   const void *unused)
 {
     TestStruct *p = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");

-    visit_type_TestStruct(v, &p, NULL, &err);
-    g_assert(!err);
+    visit_type_TestStruct(v, &p, NULL, &error_abort);
     g_free(p->string);
     g_free(p);
 }
@@ -111,7 +113,6 @@ static void test_validate_struct_nested(TestInputVisitorData *data,
                                          const void *unused)
 {
     UserDefTwo *udp = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "{ 'string0': 'string0', "
@@ -119,8 +120,7 @@ static void test_validate_struct_nested(TestInputVisitorData *data,
                            "'dict2': { 'userdef': { 'integer': 42, "
                            "'string': 'string' }, 'string': 'string2'}}}");

-    visit_type_UserDefTwo(v, &udp, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefTwo(v, &udp, NULL, &error_abort);
     qapi_free_UserDefTwo(udp);
 }

@@ -128,13 +128,11 @@ static void test_validate_list(TestInputVisitorData *data,
                                 const void *unused)
 {
     UserDefOneList *head = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");

-    visit_type_UserDefOneList(v, &head, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefOneList(v, &head, NULL, &error_abort);
     qapi_free_UserDefOneList(head);
 }

@@ -143,12 +141,10 @@ static void test_validate_union_native_list(TestInputVisitorData *data,
 {
     UserDefNativeListUnion *tmp = NULL;
     Visitor *v;
-    Error *err = NULL;

     v = validate_test_init(data, "{ 'type': 'integer', 'data' : [ 1, 2 ] }");

-    visit_type_UserDefNativeListUnion(v, &tmp, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefNativeListUnion(v, &tmp, NULL, &error_abort);
     qapi_free_UserDefNativeListUnion(tmp);
 }

@@ -157,7 +153,6 @@ static void test_validate_union_flat(TestInputVisitorData *data,
 {
     UserDefFlatUnion *tmp = NULL;
     Visitor *v;
-    Error *err = NULL;

     v = validate_test_init(data,
                            "{ 'enum1': 'value1', "
@@ -165,8 +160,7 @@ static void test_validate_union_flat(TestInputVisitorData *data,
                            "'string': 'str', "
                            "'boolean': true }");

-    visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefFlatUnion(v, &tmp, NULL, &error_abort);
     qapi_free_UserDefFlatUnion(tmp);
 }

@@ -175,12 +169,10 @@ static void test_validate_alternate(TestInputVisitorData *data,
 {
     UserDefAlternate *tmp = NULL;
     Visitor *v;
-    Error *err = NULL;

     v = validate_test_init(data, "42");

-    visit_type_UserDefAlternate(v, &tmp, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
     qapi_free_UserDefAlternate(tmp);
 }

@@ -188,14 +180,12 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
                                        const void *unused)
 {
     TestStruct *p = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");

-    visit_type_TestStruct(v, &p, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_TestStruct(v, &p, NULL, &data->err);
+    g_assert(data->err);
     /* FIXME: visitor should not allocate p when returning error */
     if (p) {
         g_free(p->string);
@@ -207,14 +197,12 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
                                               const void *unused)
 {
     UserDefTwo *udp = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");

-    visit_type_UserDefTwo(v, &udp, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefTwo(v, &udp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefTwo(udp);
 }

@@ -222,14 +210,12 @@ static void test_validate_fail_list(TestInputVisitorData *data,
                                      const void *unused)
 {
     UserDefOneList *head = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");

-    visit_type_UserDefOneList(v, &head, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefOneList(v, &head, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefOneList(head);
 }

@@ -237,15 +223,13 @@ static void test_validate_fail_union_native_list(TestInputVisitorData *data,
                                                  const void *unused)
 {
     UserDefNativeListUnion *tmp = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data,
                            "{ 'type': 'integer', 'data' : [ 'string' ] }");

-    visit_type_UserDefNativeListUnion(v, &tmp, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefNativeListUnion(v, &tmp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefNativeListUnion(tmp);
 }

@@ -253,14 +237,12 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
                                           const void *unused)
 {
     UserDefFlatUnion *tmp = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");

-    visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefFlatUnion(v, &tmp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefFlatUnion(tmp);
 }

@@ -268,15 +250,13 @@ static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
                                                      const void *unused)
 {
     UserDefFlatUnion2 *tmp = NULL;
-    Error *err = NULL;
     Visitor *v;

     /* test situation where discriminator field ('enum1' here) is missing */
     v = validate_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");

-    visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefFlatUnion2(v, &tmp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefFlatUnion2(tmp);
 }

@@ -285,13 +265,11 @@ static void test_validate_fail_alternate(TestInputVisitorData *data,
 {
     UserDefAlternate *tmp = NULL;
     Visitor *v;
-    Error *err = NULL;

     v = validate_test_init(data, "3.14");

-    visit_type_UserDefAlternate(v, &tmp, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_UserDefAlternate(v, &tmp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefAlternate(tmp);
 }

@@ -299,16 +277,11 @@ static void do_test_validate_qmp_introspect(TestInputVisitorData *data,
                                             const char *schema_json)
 {
     SchemaInfoList *schema = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = validate_test_init_raw(data, schema_json);

-    visit_type_SchemaInfoList(v, &schema, NULL, &err);
-    if (err) {
-        fprintf(stderr, "%s", error_get_pretty(err));
-    }
-    g_assert(!err);
+    visit_type_SchemaInfoList(v, &schema, NULL, &error_abort);
     g_assert(schema);

     qapi_free_SchemaInfoList(schema);
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 03c3682..d63c470 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -22,6 +22,7 @@
 typedef struct TestInputVisitorData {
     QObject *obj;
     QmpInputVisitor *qiv;
+    Error *err;
 } TestInputVisitorData;

 static void visitor_input_teardown(TestInputVisitorData *data,
@@ -30,6 +31,9 @@ static void visitor_input_teardown(TestInputVisitorData *data,
     qobject_decref(data->obj);
     data->obj = NULL;

+    error_free(data->err);
+    data->err = NULL;
+
     if (data->qiv) {
         qmp_input_visitor_cleanup(data->qiv);
         data->qiv = NULL;
@@ -92,13 +96,11 @@ static void test_visitor_in_int(TestInputVisitorData *data,
                                 const void *unused)
 {
     int64_t res = 0, value = -42;
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "%" PRId64, value);

-    visit_type_int(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_int(v, &res, NULL, &error_abort);
     g_assert_cmpint(res, ==, value);
 }

@@ -106,7 +108,6 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
                                          const void *unused)
 {
     int64_t res = 0;
-    Error *err = NULL;
     Visitor *v;

     /* this will overflow a Qint/int64, so should be deserialized into
@@ -115,22 +116,19 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
      */
     v = visitor_input_test_init(data, "%f", DBL_MAX);

-    visit_type_int(v, &res, NULL, &err);
-    g_assert(err);
-    error_free(err);
+    visit_type_int(v, &res, NULL, &data->err);
+    g_assert(data->err);
 }

 static void test_visitor_in_bool(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *err = NULL;
     bool res = false;
     Visitor *v;

     v = visitor_input_test_init(data, "true");

-    visit_type_bool(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_bool(v, &res, NULL, &error_abort);
     g_assert_cmpint(res, ==, true);
 }

@@ -138,13 +136,11 @@ static void test_visitor_in_number(TestInputVisitorData *data,
                                    const void *unused)
 {
     double res = 0, value = 3.14;
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "%f", value);

-    visit_type_number(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_number(v, &res, NULL, &error_abort);
     g_assert_cmpfloat(res, ==, value);
 }

@@ -152,13 +148,11 @@ static void test_visitor_in_string(TestInputVisitorData *data,
                                    const void *unused)
 {
     char *res = NULL, *value = (char *) "Q E M U";
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "%s", value);

-    visit_type_str(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_str(v, &res, NULL, &error_abort);
     g_assert_cmpstr(res, ==, value);

     g_free(res);
@@ -167,7 +161,6 @@ static void test_visitor_in_string(TestInputVisitorData *data,
 static void test_visitor_in_enum(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *err = NULL;
     Visitor *v;
     EnumOne i;

@@ -176,8 +169,7 @@ static void test_visitor_in_enum(TestInputVisitorData *data,

         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);

-        visit_type_EnumOne(v, &res, NULL, &err);
-        g_assert(!err);
+        visit_type_EnumOne(v, &res, NULL, &error_abort);
         g_assert_cmpint(i, ==, res);
     }
 }
@@ -187,13 +179,11 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
                                    const void *unused)
 {
     TestStruct *p = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");

-    visit_type_TestStruct(v, &p, NULL, &err);
-    g_assert(!err);
+    visit_type_TestStruct(v, &p, NULL, &error_abort);
     g_assert_cmpint(p->integer, ==, -42);
     g_assert(p->boolean == true);
     g_assert_cmpstr(p->string, ==, "foo");
@@ -206,7 +196,6 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
                                           const void *unused)
 {
     UserDefTwo *udp = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
@@ -214,8 +203,7 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
                                 "'dict2': { 'userdef': { 'integer': 42, "
                                 "'string': 'string' }, 'string': 'string2'}}}");

-    visit_type_UserDefTwo(v, &udp, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefTwo(v, &udp, NULL, &error_abort);

     g_assert_cmpstr(udp->string0, ==, "string0");
     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
@@ -231,14 +219,12 @@ static void test_visitor_in_list(TestInputVisitorData *data,
                                  const void *unused)
 {
     UserDefOneList *item, *head = NULL;
-    Error *err = NULL;
     Visitor *v;
     int i;

     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");

-    visit_type_UserDefOneList(v, &head, NULL, &err);
-    g_assert(!err);
+    visit_type_UserDefOneList(v, &head, NULL, &error_abort);
     g_assert(head != NULL);

     for (i = 0, item = head; item; item = item->next, i++) {
@@ -256,7 +242,6 @@ static void test_visitor_in_any(TestInputVisitorData *data,
                                 const void *unused)
 {
     QObject *res = NULL;
-    Error *err = NULL;
     Visitor *v;
     QInt *qint;
     QBool *qbool;
@@ -265,16 +250,14 @@ static void test_visitor_in_any(TestInputVisitorData *data,
     QObject *qobj;

     v = visitor_input_test_init(data, "-42");
-    visit_type_any(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_any(v, &res, NULL, &error_abort);
     qint = qobject_to_qint(res);
     g_assert(qint);
     g_assert_cmpint(qint_get_int(qint), ==, -42);
     qobject_decref(res);

     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
-    visit_type_any(v, &res, NULL, &err);
-    g_assert(!err);
+    visit_type_any(v, &res, NULL, &error_abort);
     qdict = qobject_to_qdict(res);
     g_assert(qdict && qdict_size(qdict) == 3);
     qobj = qdict_get(qdict, "integer");
@@ -299,7 +282,6 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
                                        const void *unused)
 {
     Visitor *v;
-    Error *err = NULL;
     UserDefFlatUnion *tmp;
     UserDefUnionBase *base;

@@ -309,8 +291,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
                                 "'string': 'str', "
                                 "'boolean': true }");

-    visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefFlatUnion(v, &tmp, NULL, &error_abort);
     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
     g_assert_cmpstr(tmp->string, ==, "str");
     g_assert_cmpint(tmp->integer, ==, 41);
@@ -326,7 +307,6 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
                                       const void *unused)
 {
     Visitor *v;
-    Error *err = NULL;
     UserDefAlternate *tmp;

     v = visitor_input_test_init(data, "42");
@@ -342,10 +322,8 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     qapi_free_UserDefAlternate(tmp);

     v = visitor_input_test_init(data, "false");
-    visit_type_UserDefAlternate(v, &tmp, NULL, &err);
-    g_assert(err);
-    error_free(err);
-    err = NULL;
+    visit_type_UserDefAlternate(v, &tmp, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_UserDefAlternate(tmp);
 }

@@ -353,7 +331,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
                                              const void *unused)
 {
     Visitor *v;
-    Error *err = NULL;
     AltStrBool *asb;
     AltStrNum *asn;
     AltNumStr *ans;
@@ -364,21 +341,17 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     /* Parsing an int */

     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrBool(v, &asb, NULL, &err);
-    g_assert(err);
-    error_free(err);
-    err = NULL;
+    visit_type_AltStrBool(v, &asb, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_AltStrBool(asb);

     /* FIXME: Order of alternate should not affect semantics; asn should
      * parse the same as ans */
     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrNum(v, &asn, NULL, &err);
+    visit_type_AltStrNum(v, &asn, NULL, &data->err);
     /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
     /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
-    g_assert(err);
-    error_free(err);
-    err = NULL;
+    g_assert(data->err);
     qapi_free_AltStrNum(asn);

     v = visitor_input_test_init(data, "42");
@@ -408,10 +381,8 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     /* Parsing a double */

     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltStrBool(v, &asb, NULL, &err);
-    g_assert(err);
-    error_free(err);
-    err = NULL;
+    visit_type_AltStrBool(v, &asb, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_AltStrBool(asb);

     v = visitor_input_test_init(data, "42.5");
@@ -427,10 +398,8 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     qapi_free_AltNumStr(ans);

     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltStrInt(v, &asi, NULL, &err);
-    g_assert(err);
-    error_free(err);
-    err = NULL;
+    visit_type_AltStrInt(v, &asi, NULL, &data->err);
+    g_assert(data->err);
     qapi_free_AltStrInt(asi);

     v = visitor_input_test_init(data, "42.5");
@@ -451,7 +420,6 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
                                             UserDefNativeListUnionKind kind)
 {
     UserDefNativeListUnion *cvalue = NULL;
-    Error *err = NULL;
     Visitor *v;
     GString *gstr_list = g_string_new("");
     GString *gstr_union = g_string_new("");
@@ -468,8 +436,7 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
                            gstr_list->str);
     v = visitor_input_test_init_raw(data,  gstr_union->str);

-    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
     g_assert_cmpint(cvalue->type, ==, kind);

@@ -614,7 +581,6 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
 {
     UserDefNativeListUnion *cvalue = NULL;
     boolList *elem = NULL;
-    Error *err = NULL;
     Visitor *v;
     GString *gstr_list = g_string_new("");
     GString *gstr_union = g_string_new("");
@@ -631,8 +597,7 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
                            gstr_list->str);
     v = visitor_input_test_init_raw(data,  gstr_union->str);

-    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);

@@ -650,7 +615,6 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
 {
     UserDefNativeListUnion *cvalue = NULL;
     strList *elem = NULL;
-    Error *err = NULL;
     Visitor *v;
     GString *gstr_list = g_string_new("");
     GString *gstr_union = g_string_new("");
@@ -666,8 +630,7 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
                            gstr_list->str);
     v = visitor_input_test_init_raw(data,  gstr_union->str);

-    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);

@@ -689,7 +652,6 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
 {
     UserDefNativeListUnion *cvalue = NULL;
     numberList *elem = NULL;
-    Error *err = NULL;
     Visitor *v;
     GString *gstr_list = g_string_new("");
     GString *gstr_union = g_string_new("");
@@ -705,8 +667,7 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
                            gstr_list->str);
     v = visitor_input_test_init_raw(data,  gstr_union->str);

-    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);

@@ -739,18 +700,16 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
                                    const void *unused)
 {
     TestStruct *p = NULL;
-    Error *err = NULL;
     Visitor *v;

     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");

-    visit_type_TestStruct(v, &p, NULL, &err);
-    g_assert(err);
+    visit_type_TestStruct(v, &p, NULL, &data->err);
+    g_assert(data->err);
     /* FIXME - a failed parse should not leave a partially-allocated p
      * for us to clean up; this could cause callers to leak memory. */
     g_assert(p->string == NULL);

-    error_free(err);
     g_free(p->string);
     g_free(p);
 }
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 8606111..0164984 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -45,11 +45,9 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
                                  const void *unused)
 {
     int64_t value = -42;
-    Error *err = NULL;
     QObject *obj;

-    visit_type_int(data->ov, &value, NULL, &err);
-    g_assert(!err);
+    visit_type_int(data->ov, &value, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -62,12 +60,10 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
 static void test_visitor_out_bool(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *err = NULL;
     bool value = true;
     QObject *obj;

-    visit_type_bool(data->ov, &value, NULL, &err);
-    g_assert(!err);
+    visit_type_bool(data->ov, &value, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -81,11 +77,9 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
                                     const void *unused)
 {
     double value = 3.14;
-    Error *err = NULL;
     QObject *obj;

-    visit_type_number(data->ov, &value, NULL, &err);
-    g_assert(!err);
+    visit_type_number(data->ov, &value, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -99,11 +93,9 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
                                     const void *unused)
 {
     char *string = (char *) "Q E M U";
-    Error *err = NULL;
     QObject *obj;

-    visit_type_str(data->ov, &string, NULL, &err);
-    g_assert(!err);
+    visit_type_str(data->ov, &string, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -117,12 +109,10 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
                                        const void *unused)
 {
     char *string = NULL;
-    Error *err = NULL;
     QObject *obj;

     /* A null string should return "" */
-    visit_type_str(data->ov, &string, NULL, &err);
-    g_assert(!err);
+    visit_type_str(data->ov, &string, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -135,13 +125,11 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
 static void test_visitor_out_enum(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *err = NULL;
     QObject *obj;
     EnumOne i;

     for (i = 0; i < ENUM_ONE_MAX; i++) {
-        visit_type_EnumOne(data->ov, &i, "unused", &err);
-        g_assert(!err);
+        visit_type_EnumOne(data->ov, &i, "unused", &error_abort);

         obj = qmp_output_get_qobject(data->qov);
         g_assert(obj != NULL);
@@ -174,12 +162,10 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
                                .boolean = false,
                                .string = (char *) "foo"};
     TestStruct *p = &test_struct;
-    Error *err = NULL;
     QObject *obj;
     QDict *qdict;

-    visit_type_TestStruct(data->ov, &p, NULL, &err);
-    g_assert(!err);
+    visit_type_TestStruct(data->ov, &p, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -198,7 +184,6 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
                                            const void *unused)
 {
     int64_t value = 42;
-    Error *err = NULL;
     UserDefTwo *ud2;
     QObject *obj;
     QDict *qdict, *dict1, *dict2, *dict3, *userdef;
@@ -225,8 +210,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
     ud2->dict1->dict3->userdef->integer = value;
     ud2->dict1->dict3->string = g_strdup(strings[3]);

-    visit_type_UserDefTwo(data->ov, &ud2, "unused", &err);
-    g_assert(!err);
+    visit_type_UserDefTwo(data->ov, &ud2, "unused", &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -288,7 +272,6 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     const int max_items = 10;
     bool value_bool = true;
     int value_int = 10;
-    Error *err = NULL;
     QListEntry *entry;
     QObject *obj;
     QList *qlist;
@@ -306,8 +289,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
         head = p;
     }

-    visit_type_TestStructList(data->ov, &head, NULL, &err);
-    g_assert(!err);
+    visit_type_TestStructList(data->ov, &head, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -367,7 +349,6 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
                                  const void *unused)
 {
     QObject *qobj;
-    Error *err = NULL;
     QInt *qint;
     QBool *qbool;
     QString *qstring;
@@ -375,8 +356,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     QObject *obj;

     qobj = QOBJECT(qint_from_int(-42));
-    visit_type_any(data->ov, &qobj, NULL, &err);
-    g_assert(!err);
+    visit_type_any(data->ov, &qobj, NULL, &error_abort);
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QINT);
@@ -389,8 +369,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     qdict_put(qdict, "boolean", qbool_from_bool(true));
     qdict_put(qdict, "string", qstring_from_str("foo"));
     qobj = QOBJECT(qdict);
-    visit_type_any(data->ov, &qobj, NULL, &err);
-    g_assert(!err);
+    visit_type_any(data->ov, &qobj, NULL, &error_abort);
     qobject_decref(qobj);
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -420,8 +399,6 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
     QObject *arg;
     QDict *qdict;

-    Error *err = NULL;
-
     UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
     tmp->enum1 = ENUM_ONE_VALUE1;
     tmp->string = g_strdup("str");
@@ -429,8 +406,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
     tmp->integer = 41;
     tmp->u.value1->boolean = true;

-    visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &error_abort);
     arg = qmp_output_get_qobject(data->qov);

     g_assert(qobject_type(arg) == QTYPE_QDICT);
@@ -449,14 +425,12 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
                                        const void *unused)
 {
     QObject *arg;
-    Error *err = NULL;

     UserDefAlternate *tmp = g_malloc0(sizeof(UserDefAlternate));
     tmp->type = USER_DEF_ALTERNATE_KIND_I;
     tmp->u.i = 42;

-    visit_type_UserDefAlternate(data->ov, &tmp, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
     arg = qmp_output_get_qobject(data->qov);

     g_assert(qobject_type(arg) == QTYPE_QINT);
@@ -697,14 +671,12 @@ static void test_native_list(TestOutputVisitorData *data,
                              UserDefNativeListUnionKind kind)
 {
     UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
-    Error *err = NULL;
     QObject *obj;

     cvalue->type = kind;
     init_native_list(cvalue);

-    visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err);
-    g_assert(err == NULL);
+    visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &error_abort);

     obj = qmp_output_get_qobject(data->qov);
     check_native_list(obj, cvalue->type);
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index c024e5e..9f67f9e 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -302,14 +302,13 @@ static void test_primitives(gconstpointer opaque)
     const SerializeOps *ops = args->ops;
     PrimitiveType *pt = args->test_data;
     PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
-    Error *err = NULL;
     void *serialize_data;

     pt_copy->type = pt->type;
-    ops->serialize(pt, &serialize_data, visit_primitive_type, &err);
-    ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type, &err);
+    ops->serialize(pt, &serialize_data, visit_primitive_type, &error_abort);
+    ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type,
+                     &error_abort);

-    g_assert(err == NULL);
     g_assert(pt_copy != NULL);
     if (pt->type == PTYPE_STRING) {
         g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);
@@ -345,7 +344,6 @@ static void test_primitive_lists(gconstpointer opaque)
     PrimitiveList pl = { .value = { NULL } };
     PrimitiveList pl_copy = { .value = { NULL } };
     PrimitiveList *pl_copy_ptr = &pl_copy;
-    Error *err = NULL;
     void *serialize_data;
     void *cur_head = NULL;
     int i;
@@ -492,10 +490,11 @@ static void test_primitive_lists(gconstpointer opaque)
         }
     }

-    ops->serialize((void **)&pl, &serialize_data, visit_primitive_list, &err);
-    ops->deserialize((void **)&pl_copy_ptr, serialize_data, visit_primitive_list, &err);
+    ops->serialize((void **)&pl, &serialize_data, visit_primitive_list,
+                   &error_abort);
+    ops->deserialize((void **)&pl_copy_ptr, serialize_data,
+                     visit_primitive_list, &error_abort);

-    g_assert(err == NULL);
     i = 0;

     /* compare our deserialized list of primitives to the original */
@@ -652,10 +651,8 @@ static void test_primitive_lists(gconstpointer opaque)
     g_assert_cmpint(i, ==, 33);

     ops->cleanup(serialize_data);
-    dealloc_helper(&pl, visit_primitive_list, &err);
-    g_assert(!err);
-    dealloc_helper(&pl_copy, visit_primitive_list, &err);
-    g_assert(!err);
+    dealloc_helper(&pl, visit_primitive_list, &error_abort);
+    dealloc_helper(&pl_copy, visit_primitive_list, &error_abort);
     g_free(args);
 }

@@ -665,13 +662,12 @@ static void test_struct(gconstpointer opaque)
     const SerializeOps *ops = args->ops;
     TestStruct *ts = struct_create();
     TestStruct *ts_copy = NULL;
-    Error *err = NULL;
     void *serialize_data;

-    ops->serialize(ts, &serialize_data, visit_struct, &err);
-    ops->deserialize((void **)&ts_copy, serialize_data, visit_struct, &err); 
+    ops->serialize(ts, &serialize_data, visit_struct, &error_abort);
+    ops->deserialize((void **)&ts_copy, serialize_data, visit_struct,
+                     &error_abort);

-    g_assert(err == NULL);
     struct_compare(ts, ts_copy);

     struct_cleanup(ts);
@@ -687,14 +683,12 @@ static void test_nested_struct(gconstpointer opaque)
     const SerializeOps *ops = args->ops;
     UserDefTwo *udnp = nested_struct_create();
     UserDefTwo *udnp_copy = NULL;
-    Error *err = NULL;
     void *serialize_data;

-    ops->serialize(udnp, &serialize_data, visit_nested_struct, &err);
+    ops->serialize(udnp, &serialize_data, visit_nested_struct, &error_abort);
     ops->deserialize((void **)&udnp_copy, serialize_data, visit_nested_struct,
-                     &err);
+                     &error_abort);

-    g_assert(err == NULL);
     nested_struct_compare(udnp, udnp_copy);

     nested_struct_cleanup(udnp);
@@ -709,7 +703,6 @@ static void test_nested_struct_list(gconstpointer opaque)
     TestArgs *args = (TestArgs *) opaque;
     const SerializeOps *ops = args->ops;
     UserDefTwoList *listp = NULL, *tmp, *tmp_copy, *listp_copy = NULL;
-    Error *err = NULL;
     void *serialize_data;
     int i = 0;

@@ -720,11 +713,10 @@ static void test_nested_struct_list(gconstpointer opaque)
         listp = tmp;
     }

-    ops->serialize(listp, &serialize_data, visit_nested_struct_list, &err);
+    ops->serialize(listp, &serialize_data, visit_nested_struct_list,
+                   &error_abort);
     ops->deserialize((void **)&listp_copy, serialize_data,
-                     visit_nested_struct_list, &err); 
-
-    g_assert(err == NULL);
+                     visit_nested_struct_list, &error_abort);

     tmp = listp;
     tmp_copy = listp_copy;
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (3 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing " Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  9:04   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse Eric Blake
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

The testsuite was only covering that we could output a built-in
branch of an alternate; make sure that things still work even
when a branch involves allocation, to ensure that we don't leak
when run under valgrind.

Update to modern style of g_new0() over g_malloc0() while
touching it.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch, split off of 10/17
---
 tests/test-qmp-output-visitor.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 0164984..0d0c859 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -425,8 +425,9 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
                                        const void *unused)
 {
     QObject *arg;
+    UserDefAlternate *tmp;

-    UserDefAlternate *tmp = g_malloc0(sizeof(UserDefAlternate));
+    tmp = g_new0(UserDefAlternate, 1);
     tmp->type = USER_DEF_ALTERNATE_KIND_I;
     tmp->u.i = 42;

@@ -438,6 +439,19 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,

     qapi_free_UserDefAlternate(tmp);
     qobject_decref(arg);
+
+    tmp = g_new0(UserDefAlternate, 1);
+    tmp->type = USER_DEF_ALTERNATE_KIND_S;
+    tmp->u.s = g_strdup("hello");
+
+    visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
+    arg = qmp_output_get_qobject(data->qov);
+
+    g_assert(qobject_type(arg) == QTYPE_QSTRING);
+    g_assert_cmpstr(qstring_get_str(qobject_to_qstring(arg)), ==, "hello");
+
+    qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 }

 static void test_visitor_out_empty(TestOutputVisitorData *data,
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (4 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  9:07   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays Eric Blake
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Our generated list visitors have the same problem as has been
mentioned elsewhere (see commit 2f52e20): they allocate data
even on failure. An upcoming patch will correct things to
provide saner guarantees, but first we need to expose the
behavior in the testsuite to ensure we aren't introducing any
memory usage bugs.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: move earlier in series (was 15/17)
v8: no change
v7: no change
v6: rebase onto earlier gen_err_check() and testsuite improvements
---
 scripts/qapi-visit.py          |  4 ++++
 tests/test-qmp-input-visitor.c | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index f40c3c7..3ef5c16 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -138,6 +138,10 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error


 def gen_visit_list(name, element_type):
+    # FIXME: if *obj is NULL on entry, and the first visit_next_list()
+    # assigns to *obj, while a later one fails, we should clean up *obj
+    # rather than leaving it non-NULL. As currently written, the caller must
+    # call qapi_free_FOOList() to avoid a memory leak of the partial FOOList.
     return mcgen('''

 void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp)
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index d63c470..fc30bd1 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -701,6 +701,7 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
 {
     TestStruct *p = NULL;
     Visitor *v;
+    strList *q = NULL;

     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");

@@ -712,6 +713,15 @@ static void test_visitor_in_errors(TestInputVisitorData *data,

     g_free(p->string);
     g_free(p);
+
+    v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
+    /* FIXME - a failed parse should not leave a partially-allocated
+     * array for us to clean up; this could cause callers to leak
+     * memory. */
+    visit_type_strList(v, &q, NULL, &data->err);
+    assert(q);
+    assert(data->err);
+    qapi_free_strList(q);
 }

 int main(int argc, char **argv)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (5 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  9:11   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 08/27] qapi: Provide nicer array names in introspection Eric Blake
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Our testsuite had no coverage of empty arrays, nor of what
happens when the input does not match the expected type.
Useful to have, especially if we start changing the visitor
contracts.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: move earlier in series (was 16/17)
v8: no change
v7: no change
v6: new patch
---
 tests/test-qmp-input-visitor.c | 51 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index fc30bd1..e9a66a7 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -236,6 +236,12 @@ static void test_visitor_in_list(TestInputVisitorData *data,
     }

     qapi_free_UserDefOneList(head);
+    head = NULL;
+
+    /* An empty list is valid */
+    v = visitor_input_test_init(data, "[]");
+    visit_type_UserDefOneList(v, &head, NULL, &error_abort);
+    g_assert(!head);
 }

 static void test_visitor_in_any(TestInputVisitorData *data,
@@ -724,6 +730,49 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
     qapi_free_strList(q);
 }

+static void test_visitor_in_wrong_type(TestInputVisitorData *data,
+                                       const void *unused)
+{
+    TestStruct *p = NULL;
+    Visitor *v;
+    strList *q = NULL;
+    int64_t i;
+
+    /* Make sure arrays and structs cannot be confused */
+
+    v = visitor_input_test_init(data, "[]");
+    visit_type_TestStruct(v, &p, NULL, &data->err);
+    g_assert(data->err);
+    g_assert(!p);
+
+    v = visitor_input_test_init(data, "{}");
+    visit_type_strList(v, &q, NULL, &data->err);
+    assert(data->err);
+    assert(!q);
+
+    /* Make sure primitives and struct cannot be confused */
+
+    v = visitor_input_test_init(data, "1");
+    visit_type_TestStruct(v, &p, NULL, &data->err);
+    g_assert(data->err);
+    g_assert(!p);
+
+    v = visitor_input_test_init(data, "{}");
+    visit_type_int(v, &i, NULL, &data->err);
+    assert(data->err);
+
+    /* Make sure primitives and arrays cannot be confused */
+
+    v = visitor_input_test_init(data, "1");
+    visit_type_strList(v, &q, NULL, &data->err);
+    assert(data->err);
+    assert(!q);
+
+    v = visitor_input_test_init(data, "[]");
+    visit_type_int(v, &i, NULL, &data->err);
+    assert(data->err);
+}
+
 int main(int argc, char **argv)
 {
     TestInputVisitorData in_visitor_data;
@@ -756,6 +805,8 @@ int main(int argc, char **argv)
                            &in_visitor_data, test_visitor_in_alternate);
     input_visitor_test_add("/visitor/input/errors",
                            &in_visitor_data, test_visitor_in_errors);
+    input_visitor_test_add("/visitor/input/wrong-type",
+                           &in_visitor_data, test_visitor_in_wrong_type);
     input_visitor_test_add("/visitor/input/alternate-number",
                            &in_visitor_data, test_visitor_in_alternate_number);
     input_visitor_test_add("/visitor/input/native_list/int",
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 08/27] qapi: Provide nicer array names in introspection
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (6 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting Eric Blake
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

For the sake of humans reading introspection output, it is nice
to have the name of implicit array types be recognizable as
arrays of the underlying type.  However, while this patch allows
humans to skip from a command with return type "[123]" straight
to the definition of type "123" without having to first inspect
type "[123]", document that this shortcut should not be taken by
client apps.

This makes the resulting introspection string slightly larger by
default (just over 200 bytes), but it's in the noise (less than
0.3% of the overall 70k size of 'query-qmp-capabilities').

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: commit message stats on the size increase
v7: no change
v6: no change
---
 docs/qapi-code-gen.txt     | 7 +++++--
 scripts/qapi-introspect.py | 8 +++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 4d8c2fc..ba29bc6 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -662,11 +662,14 @@ Example: the SchemaInfo for BlockRef from section Alternate types

 The SchemaInfo for an array type has meta-type "array", and variant
 member "element-type", which names the array's element type.  Array
-types are implicitly defined.
+types are implicitly defined.  For convenience, the array's name may
+resemble the element type; however, clients should examine member
+"element-type" instead of making assumptions based on parsing member
+"name".

 Example: the SchemaInfo for ['str']

-    { "name": "strList", "meta-type": "array",
+    { "name": "[str]", "meta-type": "array",
       "element-type": "str" }

 The SchemaInfo for an enumeration type has meta-type "enum" and
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index c0dad66..64f2cd0 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -107,10 +107,12 @@ const char %(c_name)s[] = %(c_string)s;
         # characters.
         if isinstance(typ, QAPISchemaBuiltinType):
             return typ.name
+        if isinstance(typ, QAPISchemaArrayType):
+            return '[' + self._use_type(typ.element_type) + ']'
         return self._name(typ.name)

     def _gen_json(self, name, mtype, obj):
-        if mtype != 'command' and mtype != 'event' and mtype != 'builtin':
+        if mtype not in ('command', 'event', 'builtin', 'array'):
             name = self._name(name)
         obj['name'] = name
         obj['meta-type'] = mtype
@@ -136,8 +138,8 @@ const char %(c_name)s[] = %(c_string)s;
         self._gen_json(name, 'enum', {'values': values})

     def visit_array_type(self, name, info, element_type):
-        self._gen_json(name, 'array',
-                       {'element-type': self._use_type(element_type)})
+        element = self._use_type(element_type)
+        self._gen_json('[' + element + ']', 'array', {'element-type': element})

     def visit_object_type_flat(self, name, info, members, variants):
         obj = {'members': [self._gen_member(m) for m in members]}
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (7 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 08/27] qapi: Provide nicer array names in introspection Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 10:09   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members Eric Blake
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

qapi-code-gen.txt already claims that types, commands, and
events share a common namespace; set this in stone by further
documenting that our introspection output will never have
collisions with the same name tied to more than one meta-type.

Our largest QMP enum currently has 125 values, our largest
object type has 27 members, and the mean for each is less than
10.  These sizes are small enough that the per-element overhead
of O(log n) binary searching probably outweighs the speed
possible with direct O(n) linear searching (a better algorithm
with more overhead will only beat a leaner naive algorithm only
as you scale to larger input sizes).

Arguably, the overall SchemaInfo array could be sorted by name;
there, we currently have 531 entities, large enough for a binary
search to be faster than linear.  However, remember that we have
mutually-recursive types, which means there is no topological
ordering that will allow clients to learn all information about
that type in a single linear pass; thus clients will want to do
random access over the data, and they will probably read the
introspection output into a hashtable for O(1) lookup rather
than O(log n) binary searching, at which point, pre-sorting our
introspection output doesn't help the client.

Finally, I am not sure how to guarantee that python sorts strings
for the C locale even if the generator is run under a different
locale.  Our current output order is deterministic (based on the
order present in .json files, even if that order has no inherent
bearing on how a client will present their QMP commands), while
sorting data risks non-determinism if the generator is subject to
any locale differences.

For these reasons, we simply document that clients should not
rely on any particular order of items in introspection output.
Additionally, this gives us the freedom to later change our mind,
so that we could rearrange output in a different order than the
way it was listed in the .json file, without breaking any client
that was already aware it had to do a linear search.

Document these conventions, so that clients will know what can
and cannot be relied on.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: retitle; and swing in the opposite direction: give the user
no guarantee about order
v8: no change
v7: tweak commit wording
v6: no change from v5
---
 docs/qapi-code-gen.txt | 19 +++++++++++++++----
 qapi/introspect.json   | 21 ++++++++++++++++-----
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index ba29bc6..20e6907 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -516,6 +516,10 @@ query-qmp-schema.  QGA currently doesn't support introspection.

 query-qmp-schema returns a JSON array of SchemaInfo objects.  These
 objects together describe the wire ABI, as defined in the QAPI schema.
+There is no specified order to the SchemaInfo objects returned; a
+client must search for a particular name throughout the entire array
+to learn more about that name, but is at least guaranteed that there
+will be no collisions between type, command, and event names.

 However, the SchemaInfo can't reflect all the rules and restrictions
 that apply to QMP.  It's interface introspection (figuring out what's
@@ -596,7 +600,9 @@ any.  Each element is a JSON object with members "name" (the member's
 name), "type" (the name of its type), and optionally "default".  The
 member is optional if "default" is present.  Currently, "default" can
 only have value null.  Other values are reserved for future
-extensions.
+extensions.  The "members" array is in no particular order; clients
+must search every member when learning whether a particular member is
+supported.

 Example: the SchemaInfo for MyType from section Struct types

@@ -610,7 +616,9 @@ Example: the SchemaInfo for MyType from section Struct types
 "variants" is a JSON array describing the object's variant members.
 Each element is a JSON object with members "case" (the value of type
 tag this element applies to) and "type" (the name of an object type
-that provides the variant members for this type tag value).
+that provides the variant members for this type tag value).  The
+"variants" array is in no particular order, and is not guaranteed to
+list cases in the same order as the corresponding "tag" enum type.

 Example: the SchemaInfo for flat union BlockdevOptions from section
 Union types
@@ -651,7 +659,8 @@ Union types
 The SchemaInfo for an alternate type has meta-type "alternate", and
 variant member "members".  "members" is a JSON array.  Each element is
 a JSON object with member "type", which names a type.  Values of the
-alternate type conform to exactly one of its member types.
+alternate type conform to exactly one of its member types.  There is
+no guarantee on the order in which "members" will be listed.

 Example: the SchemaInfo for BlockRef from section Alternate types

@@ -673,7 +682,9 @@ Example: the SchemaInfo for ['str']
       "element-type": "str" }

 The SchemaInfo for an enumeration type has meta-type "enum" and
-variant member "values".
+variant member "values".  The values are listed in no particular
+order; clients must search every value when learning whether a
+particular value is supported.

 Example: the SchemaInfo for MyEnum from section Enumeration types

diff --git a/qapi/introspect.json b/qapi/introspect.json
index cc50dc6..f86d552 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -25,6 +25,10 @@
 # Returns: array of @SchemaInfo, where each element describes an
 # entity in the ABI: command, event, type, ...
 #
+# The order of the various SchemaInfo is unspecified; however, all
+# names are guaranteed to be unique (no name will be duplicated with
+# different meta-types).
+#
 # Note: the QAPI schema is also used to help define *internal*
 # interfaces, by defining QAPI types.  These are not part of the QMP
 # wire ABI, and therefore not returned by this command.
@@ -78,7 +82,8 @@
 #        Commands and events have the name defined in the QAPI schema.
 #        Unlike command and event names, type names are not part of
 #        the wire ABI.  Consequently, type names are meaningless
-#        strings here.
+#        strings here, although they are still guaranteed unique
+#        regardless of @meta-type.
 #
 # All references to other SchemaInfo are by name.
 #
@@ -130,7 +135,9 @@
 #
 # Additional SchemaInfo members for meta-type 'enum'.
 #
-# @values: the enumeration type's values.
+# @values: the enumeration type's values.  The values are in no particular
+#          order, so clients must search every value when learning if a
+#          particular value is present.
 #
 # Values of this type are JSON string on the wire.
 #
@@ -158,14 +165,18 @@
 #
 # Additional SchemaInfo members for meta-type 'object'.
 #
-# @members: the object type's (non-variant) members.
+# @members: the object type's (non-variant) members.  The members are
+#           in no particular order, so clients must search every member
+#           when learning if a particular member is present.
 #
 # @tag: #optional the name of the member serving as type tag.
 #       An element of @members with this name must exist.
 #
 # @variants: #optional variant members, i.e. additional members that
 #            depend on the type tag's value.  Present exactly when
-#            @tag is present.
+#            @tag is present.  The variants are in no particular order,
+#            and may even differ from the order of the values of the
+#            enum type of the @tag.
 #
 # Values of this type are JSON object on the wire.
 #
@@ -219,7 +230,7 @@
 #
 # Additional SchemaInfo members for meta-type 'alternate'.
 #
-# @members: the alternate type's members.
+# @members: the alternate type's members, in no particular order.
 #           The members' wire encoding is distinct, see
 #           docs/qapi-code-gen.txt section Alternate types.
 #
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (8 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 11:02   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 11/27] qapi-types: Consolidate gen_struct() and gen_union() Eric Blake
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

We were previously creating all unions with an empty list for
local_members.  However, it will make it easier to unify struct
and union generation if we include the generated tag member in
local_members.  That way, we can have a common code pattern:
visit the base (if any), visit the local members (if any), visit
the variants (if any).  The local_members of a flat union
remains empty (because the discriminator is already visited as
part of the base).  Then, by visiting tag_member.check() during
AlternateType.check(), we no longer need to call it during
Variants.check().

The various front end entities now exist as follows:
struct: optional base, optional local_members, no variants
simple union: no base, one-element local_members, variants with tag_member
  from local_members
flat union: base, no local_members, variants with tag_member from base
alternate: no base, no local_members, variants

With the new local members, we require a bit of finesse to
avoid assertions in the clients.

No change to generated code.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: improve commit message, add comments, tweak how alternates
check tag_member
v8: new patch
---
 scripts/qapi-types.py                  |  5 ++++-
 scripts/qapi-visit.py                  |  5 ++++-
 scripts/qapi.py                        | 16 +++++++++++-----
 tests/qapi-schema/qapi-schema-test.out |  2 ++
 tests/qapi-schema/union-clash-data.out |  1 +
 tests/qapi-schema/union-empty.out      |  1 +
 6 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index b37900f..946afab 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -269,7 +269,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
     def visit_object_type(self, name, info, base, members, variants):
         self._fwdecl += gen_fwd_object_or_array(name)
         if variants:
-            assert not members      # not implemented
+            if members:
+                # Members other than variants.tag_member not implemented
+                assert len(members) == 1
+                assert members[0] == variants.tag_member
             self.decl += gen_union(name, base, variants)
         else:
             self.decl += gen_struct(name, base, members)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 3ef5c16..94cd113 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -364,7 +364,10 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
     def visit_object_type(self, name, info, base, members, variants):
         self.decl += gen_visit_decl(name)
         if variants:
-            assert not members      # not implemented
+            if members:
+                # Members other than variants.tag_member not implemented
+                assert len(members) == 1
+                assert members[0] == variants.tag_member
             self.defn += gen_visit_union(name, base, variants)
         else:
             self.defn += gen_visit_struct(name, base, members)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 7c50cc4..a814e20 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -957,6 +957,9 @@ class QAPISchemaArrayType(QAPISchemaType):

 class QAPISchemaObjectType(QAPISchemaType):
     def __init__(self, name, info, base, local_members, variants):
+        # struct has local_members, optional base, and no variants
+        # flat union has base, variants, and no local_members
+        # simple union has local_members, variants, and no base
         QAPISchemaType.__init__(self, name, info)
         assert base is None or isinstance(base, str)
         for m in local_members:
@@ -1048,10 +1051,11 @@ class QAPISchemaObjectTypeVariants(object):
         self.variants = variants

     def check(self, schema, members, seen):
-        if self.tag_name:
+        # seen is non-empty for unions, empty for alternates
+        if self.tag_name:    # flat union
             self.tag_member = seen[self.tag_name]
-        else:
-            self.tag_member.check(schema, members, seen)
+        if seen:
+            assert self.tag_member in seen.itervalues()
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         for v in self.variants:
             vseen = dict(seen)
@@ -1085,6 +1089,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
         self.variants = variants

     def check(self, schema):
+        self.variants.tag_member.check(schema, [], {})
         self.variants.check(schema, [], {})

     def json_type(self):
@@ -1270,13 +1275,14 @@ class QAPISchema(object):
         if tag_name:
             variants = [self._make_variant(key, value)
                         for (key, value) in data.iteritems()]
+            members = []
         else:
             variants = [self._make_simple_variant(key, value, info)
                         for (key, value) in data.iteritems()]
             tag_member = self._make_implicit_tag(name, info, variants)
+            members = [tag_member]
         self._def_entity(
-            QAPISchemaObjectType(name, info, base,
-                                 self._make_members(OrderedDict(), info),
+            QAPISchemaObjectType(name, info, base, members,
                                  QAPISchemaObjectTypeVariants(tag_name,
                                                               tag_member,
                                                               variants)))
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index e20a823..786024e 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -132,6 +132,7 @@ object UserDefFlatUnion2
     case value2: UserDefB
     case value3: UserDefA
 object UserDefNativeListUnion
+    member type: UserDefNativeListUnionKind optional=False
     case integer: :obj-intList-wrapper
     case s8: :obj-int8List-wrapper
     case s16: :obj-int16List-wrapper
@@ -187,6 +188,7 @@ object __org.qemu_x-Struct
 object __org.qemu_x-Struct2
     member array: __org.qemu_x-Union1List optional=False
 object __org.qemu_x-Union1
+    member type: __org.qemu_x-Union1Kind optional=False
     case __org.qemu_x-branch: :obj-str-wrapper
 enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
 object __org.qemu_x-Union2
diff --git a/tests/qapi-schema/union-clash-data.out b/tests/qapi-schema/union-clash-data.out
index 6277239..cea8551 100644
--- a/tests/qapi-schema/union-clash-data.out
+++ b/tests/qapi-schema/union-clash-data.out
@@ -2,5 +2,6 @@ object :empty
 object :obj-int-wrapper
     member data: int optional=False
 object TestUnion
+    member type: TestUnionKind optional=False
     case data: :obj-int-wrapper
 enum TestUnionKind ['data']
diff --git a/tests/qapi-schema/union-empty.out b/tests/qapi-schema/union-empty.out
index 8b5a7bf..9c89fd1 100644
--- a/tests/qapi-schema/union-empty.out
+++ b/tests/qapi-schema/union-empty.out
@@ -1,3 +1,4 @@
 object :empty
 object Union
+    member type: UnionKind optional=False
 enum UnionKind []
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 11/27] qapi-types: Consolidate gen_struct() and gen_union()
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (9 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 12/27] qapi-types: Simplify gen_struct_field[s] Eric Blake
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

These two methods are now close enough that we can finally merge
them, relying on the fact that simple unions now provide a
reasonable local_members.  Change gen_struct() to gen_object()
that handles all forms of QAPISchemaObjectType, and rename and
shrink gen_union() to gen_variants() to handle the portion of
gen_object() needed when variants are present.

gen_struct_fields() now has a single caller, so it no longer
needs an optional parameter; however, I did not choose to inline
it into the caller.

No difference to generated code.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: rebase to earlier changes
v8: new patch
---
 scripts/qapi-types.py | 37 +++++++++++--------------------------
 1 file changed, 11 insertions(+), 26 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 946afab..403768b 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -51,7 +51,7 @@ def gen_struct_field(member):
     return ret


-def gen_struct_fields(local_members, base=None):
+def gen_struct_fields(local_members, base):
     ret = ''

     if base:
@@ -70,7 +70,7 @@ def gen_struct_fields(local_members, base=None):
     return ret


-def gen_struct(name, base, members):
+def gen_object(name, base, members, variants):
     ret = mcgen('''

 struct %(c_name)s {
@@ -79,11 +79,14 @@ struct %(c_name)s {

     ret += gen_struct_fields(members, base)

+    if variants:
+        ret += gen_variants(variants)
+
     # Make sure that all structs have at least one field; this avoids
     # potential issues with attempting to malloc space for zero-length
     # structs in C, and also incompatibility with C++ (where an empty
     # struct is size 1).
-    if not (base and base.members) and not members:
+    if not (base and base.members) and not members and not variants:
         ret += mcgen('''
     char qapi_dummy_field_for_empty_struct;
 ''')
@@ -140,17 +143,7 @@ const int %(c_name)s_qtypes[QTYPE_MAX] = {
     return ret


-def gen_union(name, base, variants):
-    ret = mcgen('''
-
-struct %(c_name)s {
-''',
-                c_name=c_name(name))
-    if base:
-        ret += gen_struct_fields([], base)
-    else:
-        ret += gen_struct_field(variants.tag_member)
-
+def gen_variants(variants):
     # FIXME: What purpose does data serve, besides preventing a union that
     # has a branch named 'data'? We use it in qapi-visit.py to decide
     # whether to bypass the switch statement if visiting the discriminator
@@ -159,11 +152,11 @@ struct %(c_name)s {
     # should not be any data leaks even without a data pointer.  Or, if
     # 'data' is merely added to guarantee we don't have an empty union,
     # shouldn't we enforce that at .json parse time?
-    ret += mcgen('''
+    ret = mcgen('''
     union { /* union tag is @%(c_name)s */
         void *data;
 ''',
-                 c_name=c_name(variants.tag_member.name))
+                c_name=c_name(variants.tag_member.name))

     for var in variants.variants:
         # Ugly special case for simple union TODO get rid of it
@@ -176,7 +169,6 @@ struct %(c_name)s {

     ret += mcgen('''
     } u;
-};
 ''')

     return ret
@@ -268,14 +260,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):

     def visit_object_type(self, name, info, base, members, variants):
         self._fwdecl += gen_fwd_object_or_array(name)
-        if variants:
-            if members:
-                # Members other than variants.tag_member not implemented
-                assert len(members) == 1
-                assert members[0] == variants.tag_member
-            self.decl += gen_union(name, base, variants)
-        else:
-            self.decl += gen_struct(name, base, members)
+        self.decl += gen_object(name, base, members, variants)
         if base:
             self.decl += gen_upcast(name, base)
         self._gen_type_cleanup(name)
@@ -283,7 +268,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
     def visit_alternate_type(self, name, info, variants):
         self._fwdecl += gen_fwd_object_or_array(name)
         self._fwdefn += gen_alternate_qtypes(name, variants)
-        self.decl += gen_union(name, None, variants)
+        self.decl += gen_object(name, None, [variants.tag_member], variants)
         self.decl += gen_alternate_qtypes_decl(name)
         self._gen_type_cleanup(name)

-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 12/27] qapi-types: Simplify gen_struct_field[s]
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (10 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 11/27] qapi-types: Consolidate gen_struct() and gen_union() Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions Eric Blake
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Simplify gen_struct_fields() back to a single iteration over a
list of fields (like it was prior to commit f87ab7f9), by moving
the generated comments to gen_object().  Then, inline
gen_struct_field() into its only caller.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi-types.py | 40 +++++++++++++++-------------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 403768b..2f2f7df 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -36,48 +36,38 @@ struct %(c_name)s {
                  c_name=c_name(name), c_type=element_type.c_type())


-def gen_struct_field(member):
+def gen_struct_fields(members):
     ret = ''
-
-    if member.optional:
-        ret += mcgen('''
+    for memb in members:
+        if memb.optional:
+            ret += mcgen('''
     bool has_%(c_name)s;
 ''',
-                     c_name=c_name(member.name))
-    ret += mcgen('''
+                         c_name=c_name(memb.name))
+        ret += mcgen('''
     %(c_type)s %(c_name)s;
 ''',
-                 c_type=member.type.c_type(), c_name=c_name(member.name))
+                     c_type=memb.type.c_type(), c_name=c_name(memb.name))
     return ret


-def gen_struct_fields(local_members, base):
-    ret = ''
+def gen_object(name, base, members, variants):
+    ret = mcgen('''
+
+struct %(c_name)s {
+''',
+                c_name=c_name(name))

     if base:
         ret += mcgen('''
     /* Members inherited from %(c_name)s: */
 ''',
                      c_name=base.c_name())
-        for memb in base.members:
-            ret += gen_struct_field(memb)
+        ret += gen_struct_fields(base.members)
         ret += mcgen('''
     /* Own members: */
 ''')
-
-    for memb in local_members:
-        ret += gen_struct_field(memb)
-    return ret
-
-
-def gen_object(name, base, members, variants):
-    ret = mcgen('''
-
-struct %(c_name)s {
-''',
-                c_name=c_name(name))
-
-    ret += gen_struct_fields(members, base)
+    ret += gen_struct_fields(members)

     if variants:
         ret += gen_variants(variants)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (11 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 12/27] qapi-types: Simplify gen_struct_field[s] Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 13:30   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

Union tag values can't clash with member names in generated C anymore
since commit e4ba22b, but QAPISchemaObjectTypeVariant.check() still
asserts they don't.  Drop it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-1-git-send-email-armbru@redhat.com>
[A later patch will still need to pass vseen from Variants.check()
to Variant.check(), so to avoid churn, change the cleanup to occur
lower in Variant.check()]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index a814e20..145dbfe 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1067,7 +1067,7 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
         QAPISchemaObjectTypeMember.__init__(self, name, typ, False)

     def check(self, schema, tag_type, seen):
-        QAPISchemaObjectTypeMember.check(self, schema, [], seen)
+        QAPISchemaObjectTypeMember.check(self, schema, [], {})
         assert self.name in tag_type.values

     # This function exists to support ugly simple union special cases
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (12 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 13:36   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 15/27] qapi: Simplify QAPISchemaObjectTypeMember.check() Eric Blake
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

This hunk

    @@ -964,6 +965,7 @@ class QAPISchemaObjectType(QAPISchemaType):
                 members = []
             seen = {}
             for m in members:
    +            assert c_name(m.name) not in seen
                 seen[m.name] = m
             for m in self.local_members:
                 m.check(schema, members, seen)

is plainly broken.

Asserting the members inherited from base don't clash is somewhat
redundant, because self.base.check() just checked that.  But it
doesn't hurt.

The idea to use c_name(m.name) instead of m.name for collision
checking is sound, because we need to catch clashes between the m.name
and between the c_name(m.name), and when two m.name clash, then their
c_name() also clash.

However, using c_name(m.name) instead of m.name in one of several
places doesn't work.  See the very next line.

Keep the assertion, but drop the c_name() for now.  A future commit
will bring it back.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-4-git-send-email-armbru@redhat.com>
[change TAB to space]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 145dbfe..c910715 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -987,7 +987,7 @@ class QAPISchemaObjectType(QAPISchemaType):
             members = []
         seen = {}
         for m in members:
-            assert c_name(m.name) not in seen
+            assert m.name not in seen
             seen[m.name] = m
         for m in self.local_members:
             m.check(schema, members, seen)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 15/27] qapi: Simplify QAPISchemaObjectTypeMember.check()
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (13 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 16/27] qapi: Eliminate QAPISchemaObjectType.check() variable members Eric Blake
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

QAPISchemaObjectTypeMember.check() currently does four things:

1. Compute self.type

2. Accumulate members in all_members

   Only one caller cares: QAPISchemaObjectType.check() uses it to
   compute self.members.  The other callers pass a throw-away
   accumulator.

3. Accumulate a map from names to members in seen

   Only one caller cares: QAPISchemaObjectType.check() uses it to
   compute its local variable seen, for self.variants.check(), which
   uses it to compute self.variants.tag_member from
   self.variants.tag_name.  The other callers pass a throw-away
   accumulator.

4. Check for collisions

   This piggybacks on 3: before adding a new entry, we assert it's new.

   Only one caller cares: QAPISchemaObjectType.check() uses it to
   assert non-variant members don't clash.

Simplify QAPISchemaObjectType.check(): move 2.-4. to
QAPISchemaObjectType.check(), and drop parameters all_members and
seen.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-2-git-send-email-armbru@redhat.com>
[reorder patch; commit wording touch ups; resolve conflicts because
AlternateType.check() already calls tag_member.check() locally rather
than in Variants.check()]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index c910715..bf03c24 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -990,7 +990,10 @@ class QAPISchemaObjectType(QAPISchemaType):
             assert m.name not in seen
             seen[m.name] = m
         for m in self.local_members:
-            m.check(schema, members, seen)
+            m.check(schema)
+            assert m.name not in seen
+            seen[m.name] = m
+            members.append(m)
         if self.variants:
             self.variants.check(schema, members, seen)
         self.members = members
@@ -1027,12 +1030,9 @@ class QAPISchemaObjectTypeMember(object):
         self.type = None
         self.optional = optional

-    def check(self, schema, all_members, seen):
-        assert self.name not in seen
+    def check(self, schema):
         self.type = schema.lookup_type(self._type_name)
         assert self.type
-        all_members.append(self)
-        seen[self.name] = self


 class QAPISchemaObjectTypeVariants(object):
@@ -1067,7 +1067,7 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
         QAPISchemaObjectTypeMember.__init__(self, name, typ, False)

     def check(self, schema, tag_type, seen):
-        QAPISchemaObjectTypeMember.check(self, schema, [], {})
+        QAPISchemaObjectTypeMember.check(self, schema)
         assert self.name in tag_type.values

     # This function exists to support ugly simple union special cases
@@ -1089,7 +1089,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
         self.variants = variants

     def check(self, schema):
-        self.variants.tag_member.check(schema, [], {})
+        self.variants.tag_member.check(schema)
         self.variants.check(schema, [], {})

     def json_type(self):
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 16/27] qapi: Eliminate QAPISchemaObjectType.check() variable members
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (14 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 15/27] qapi: Simplify QAPISchemaObjectTypeMember.check() Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit Eric Blake
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

We can use seen.values() instead if we make it an OrderedDict.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-5-git-send-email-armbru@redhat.com>
[reorder series]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index bf03c24..4019389 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -977,26 +977,22 @@ class QAPISchemaObjectType(QAPISchemaType):
         if self.members:
             return
         self.members = False                    # mark as being checked
+        seen = OrderedDict()
         if self._base_name:
             self.base = schema.lookup_type(self._base_name)
             assert isinstance(self.base, QAPISchemaObjectType)
             assert not self.base.variants       # not implemented
             self.base.check(schema)
-            members = list(self.base.members)
-        else:
-            members = []
-        seen = {}
-        for m in members:
-            assert m.name not in seen
-            seen[m.name] = m
+            for m in self.base.members:
+                assert m.name not in seen
+                seen[m.name] = m
         for m in self.local_members:
             m.check(schema)
             assert m.name not in seen
             seen[m.name] = m
-            members.append(m)
         if self.variants:
-            self.variants.check(schema, members, seen)
-        self.members = members
+            self.variants.check(schema, [], seen)
+        self.members = seen.values()

     def is_implicit(self):
         # See QAPISchema._make_implicit_object_type()
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (15 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 16/27] qapi: Eliminate QAPISchemaObjectType.check() variable members Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 13:43   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 18/27] qapi: Factor out QAPISchemaObjectTypeMember.check_clash() Eric Blake
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

QAPISchemaObjectTypeVariants.check() parameter members is no
longer used, drop it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-3-git-send-email-armbru@redhat.com>
[Variant.check(seen) is used after all, so reword and reduce scope
of this patch; rearrange later in the series]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 4019389..3af5edb 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -991,7 +991,7 @@ class QAPISchemaObjectType(QAPISchemaType):
             assert m.name not in seen
             seen[m.name] = m
         if self.variants:
-            self.variants.check(schema, [], seen)
+            self.variants.check(schema, seen)
         self.members = seen.values()

     def is_implicit(self):
@@ -1046,7 +1046,7 @@ class QAPISchemaObjectTypeVariants(object):
         self.tag_member = tag_member
         self.variants = variants

-    def check(self, schema, members, seen):
+    def check(self, schema, seen):
         # seen is non-empty for unions, empty for alternates
         if self.tag_name:    # flat union
             self.tag_member = seen[self.tag_name]
@@ -1086,7 +1086,7 @@ class QAPISchemaAlternateType(QAPISchemaType):

     def check(self, schema):
         self.variants.tag_member.check(schema)
-        self.variants.check(schema, [], {})
+        self.variants.check(schema, {})

     def json_type(self):
         return 'value'
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 18/27] qapi: Factor out QAPISchemaObjectTypeMember.check_clash()
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (16 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches Eric Blake
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

While there, stick in a TODO change key of seen from QAPI name to C
name.  Can't do it right away, because it would fail the assertion for
tests/qapi-schema/args-has-clash.json.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-6-git-send-email-armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3af5edb..a20abda 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -984,12 +984,10 @@ class QAPISchemaObjectType(QAPISchemaType):
             assert not self.base.variants       # not implemented
             self.base.check(schema)
             for m in self.base.members:
-                assert m.name not in seen
-                seen[m.name] = m
+                m.check_clash(seen)
         for m in self.local_members:
             m.check(schema)
-            assert m.name not in seen
-            seen[m.name] = m
+            m.check_clash(seen)
         if self.variants:
             self.variants.check(schema, seen)
         self.members = seen.values()
@@ -1030,6 +1028,11 @@ class QAPISchemaObjectTypeMember(object):
         self.type = schema.lookup_type(self._type_name)
         assert self.type

+    def check_clash(self, seen):
+        # TODO change key of seen from QAPI name to C name
+        assert self.name not in seen
+        seen[self.name] = self
+

 class QAPISchemaObjectTypeVariants(object):
     def __init__(self, tag_name, tag_member, variants):
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (17 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 18/27] qapi: Factor out QAPISchemaObjectTypeMember.check_clash() Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 19:01   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Right now, our ad hoc parser ensures that we cannot have a
flat union that introduces any qapi member names that would
conflict with the non-variant qapi members already present
from the union's base type (see flat-union-clash-member.json).
We want QAPISchema*.check() to make the same check, so we can
later reduce some of the ad hoc checks.

We already ensure that all branches of a flat union are qapi
structs with no variants, at which point those members appear
in the same JSON object as all non-variant members.  And we
already have a map 'seen' of all non-variant members passed
in to QAPISchemaObjectTypeVariants.check(), which we clone for
each particular variant (since the members of one variant do
not clash with another).  So all that is additionally needed
is to actually check the each member of the variant type do
not add any collisions.

In general, a type used as a branch of a flat union cannot
also be the base type of the flat union, so even though we are
adding a call to variant.type.check() in order to populate
variant.type.members, this is merely a case of gaining
topological sorting of how types are visited (and type.check()
is already set up to allow multiple calls due to base types).

For simple unions, the same code happens to work by design,
because of our synthesized wrapper classes (however, the
wrapper has a single member 'data' which will never collide
with the one non-variant member 'type', so it doesn't really
matter).

But for alternates, we do NOT want to check the type members
for adding collisions (an alternate has no parent JSON object
that is merging in member names, the way a flat union does), so
we branch on whether seen is empty to distinguish whether we
are checking a union or an alternate.

No change to generated code.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch, split off from v8 7/17
---
 scripts/qapi.py | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index a20abda..3054628 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1057,8 +1057,9 @@ class QAPISchemaObjectTypeVariants(object):
             assert self.tag_member in seen.itervalues()
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         for v in self.variants:
-            vseen = dict(seen)
-            v.check(schema, self.tag_member.type, vseen)
+            # Reset seen array for each variant, since qapi names from one
+            # branch do not affect another branch
+            v.check(schema, self.tag_member.type, dict(seen))


 class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
@@ -1068,6 +1069,14 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
     def check(self, schema, tag_type, seen):
         QAPISchemaObjectTypeMember.check(self, schema)
         assert self.name in tag_type.values
+        if seen:
+            # This variant is used within a union; ensure each qapi member
+            # field does not collide with the union's non-variant members.
+            assert isinstance(self.type, QAPISchemaObjectType)
+            assert not self.type.variants       # not implemented
+            self.type.check(schema)
+            for m in self.type.members:
+                m.check_clash(seen)

     # This function exists to support ugly simple union special cases
     # TODO get rid of them, and drop the function
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check()
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (18 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 19:02   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 21/27] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
                   ` (8 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

From: Markus Armbruster <armbru@redhat.com>

Avoid the 'if seen' conditional by doing just the essential work
here, namely setting self.tag_member for flat unions.
Move the rest to callers.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1446559499-26984-7-git-send-email-armbru@redhat.com>
[reword commit, rebase to earlier AlternateType.check() changes]
Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 scripts/qapi.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3054628..6653c70 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -988,9 +988,10 @@ class QAPISchemaObjectType(QAPISchemaType):
         for m in self.local_members:
             m.check(schema)
             m.check_clash(seen)
+        self.members = seen.values()
         if self.variants:
             self.variants.check(schema, seen)
-        self.members = seen.values()
+            assert self.variants.tag_member in self.members

     def is_implicit(self):
         # See QAPISchema._make_implicit_object_type()
@@ -1053,8 +1054,6 @@ class QAPISchemaObjectTypeVariants(object):
         # seen is non-empty for unions, empty for alternates
         if self.tag_name:    # flat union
             self.tag_member = seen[self.tag_name]
-        if seen:
-            assert self.tag_member in seen.itervalues()
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         for v in self.variants:
             # Reset seen array for each variant, since qapi names from one
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 21/27] qapi: Factor out QAPISchemaObjectType.check_clash()
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (19 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 22/27] qapi: Remove outdated tests related to QMP/branch collisions Eric Blake
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Consolidate two common sequences of clash detection into a
new QAPISchemaObjectType.check_clash() helper method.

No change to generated code.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch, split off from v8 7/17
---
 scripts/qapi.py | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 6653c70..843e364 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -980,11 +980,7 @@ class QAPISchemaObjectType(QAPISchemaType):
         seen = OrderedDict()
         if self._base_name:
             self.base = schema.lookup_type(self._base_name)
-            assert isinstance(self.base, QAPISchemaObjectType)
-            assert not self.base.variants       # not implemented
-            self.base.check(schema)
-            for m in self.base.members:
-                m.check_clash(seen)
+            self.base.check_clash(schema, seen)
         for m in self.local_members:
             m.check(schema)
             m.check_clash(seen)
@@ -993,6 +989,12 @@ class QAPISchemaObjectType(QAPISchemaType):
             self.variants.check(schema, seen)
             assert self.variants.tag_member in self.members

+    def check_clash(self, schema, seen):
+        self.check(schema)
+        assert not self.variants       # not implemented
+        for m in self.members:
+            m.check_clash(seen)
+
     def is_implicit(self):
         # See QAPISchema._make_implicit_object_type()
         return self.name[0] == ':'
@@ -1071,11 +1073,7 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
         if seen:
             # This variant is used within a union; ensure each qapi member
             # field does not collide with the union's non-variant members.
-            assert isinstance(self.type, QAPISchemaObjectType)
-            assert not self.type.variants       # not implemented
-            self.type.check(schema)
-            for m in self.type.members:
-                m.check_clash(seen)
+            self.type.check_clash(schema, seen)

     # This function exists to support ugly simple union special cases
     # TODO get rid of them, and drop the function
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 22/27] qapi: Remove outdated tests related to QMP/branch collisions
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (20 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 21/27] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types Eric Blake
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Now that branches are in a separate C namespace, we can remove
the restrictions in the parser that claim a branch name would
collide with QMP, and delete the negative tests that are no
longer problematic.  A separate patch can then add positive
tests to qapi-schema-test to test that any corner cases will
compile correctly.

This reverts the scripts/qapi.py portion of commit 7b2a5c2,
now that the assertions that it plugged are no longer possible.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: retitle and update commit message, finish reversion of 7b2a5c2
v7: new patch (also temporarily appeared in subset B v10)
---
 scripts/qapi.py                                | 11 ++---------
 tests/Makefile                                 |  3 ---
 tests/qapi-schema/flat-union-clash-branch.err  |  0
 tests/qapi-schema/flat-union-clash-branch.exit |  1 -
 tests/qapi-schema/flat-union-clash-branch.json | 18 ------------------
 tests/qapi-schema/flat-union-clash-branch.out  | 14 --------------
 tests/qapi-schema/flat-union-clash-type.err    |  1 -
 tests/qapi-schema/flat-union-clash-type.exit   |  1 -
 tests/qapi-schema/flat-union-clash-type.json   | 14 --------------
 tests/qapi-schema/flat-union-clash-type.out    |  0
 tests/qapi-schema/union-clash-type.err         |  1 -
 tests/qapi-schema/union-clash-type.exit        |  1 -
 tests/qapi-schema/union-clash-type.json        |  9 ---------
 tests/qapi-schema/union-clash-type.out         |  0
 14 files changed, 2 insertions(+), 72 deletions(-)
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.err
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.exit
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.json
 delete mode 100644 tests/qapi-schema/flat-union-clash-branch.out
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.err
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.exit
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.json
 delete mode 100644 tests/qapi-schema/flat-union-clash-type.out
 delete mode 100644 tests/qapi-schema/union-clash-type.err
 delete mode 100644 tests/qapi-schema/union-clash-type.exit
 delete mode 100644 tests/qapi-schema/union-clash-type.json
 delete mode 100644 tests/qapi-schema/union-clash-type.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 843e364..f5aa1d5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -548,8 +548,7 @@ def check_union(expr, expr_info):
     base = expr.get('base')
     discriminator = expr.get('discriminator')
     members = expr['data']
-    values = {'MAX': '(automatic)', 'KIND': '(automatic)',
-              'TYPE': '(automatic)'}
+    values = {'MAX': '(automatic)'}

     # Two types of unions, determined by discriminator.

@@ -607,19 +606,13 @@ def check_union(expr, expr_info):
                                " of branch '%s'" % key)

         # If the discriminator names an enum type, then all members
-        # of 'data' must also be members of the enum type, which in turn
-        # must not collide with the discriminator name.
+        # of 'data' must also be members of the enum type.
         if enum_define:
             if key not in enum_define['enum_values']:
                 raise QAPIExprError(expr_info,
                                     "Discriminator value '%s' is not found in "
                                     "enum '%s'" %
                                     (key, enum_define["enum_name"]))
-            if discriminator in enum_define['enum_values']:
-                raise QAPIExprError(expr_info,
-                                    "Discriminator name '%s' collides with "
-                                    "enum value in '%s'" %
-                                    (discriminator, enum_define["enum_name"]))

         # Otherwise, check for conflicts in the generated enum
         else:
diff --git a/tests/Makefile b/tests/Makefile
index 92969e8..c84c6cb 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -277,9 +277,7 @@ qapi-schema += flat-union-bad-base.json
 qapi-schema += flat-union-bad-discriminator.json
 qapi-schema += flat-union-base-any.json
 qapi-schema += flat-union-base-union.json
-qapi-schema += flat-union-clash-branch.json
 qapi-schema += flat-union-clash-member.json
-qapi-schema += flat-union-clash-type.json
 qapi-schema += flat-union-empty.json
 qapi-schema += flat-union-inline.json
 qapi-schema += flat-union-int-branch.json
@@ -341,7 +339,6 @@ qapi-schema += union-bad-branch.json
 qapi-schema += union-base-no-discriminator.json
 qapi-schema += union-clash-branches.json
 qapi-schema += union-clash-data.json
-qapi-schema += union-clash-type.json
 qapi-schema += union-empty.json
 qapi-schema += union-invalid-base.json
 qapi-schema += union-max.json
diff --git a/tests/qapi-schema/flat-union-clash-branch.err b/tests/qapi-schema/flat-union-clash-branch.err
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/qapi-schema/flat-union-clash-branch.exit b/tests/qapi-schema/flat-union-clash-branch.exit
deleted file mode 100644
index 573541a..0000000
--- a/tests/qapi-schema/flat-union-clash-branch.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/tests/qapi-schema/flat-union-clash-branch.json b/tests/qapi-schema/flat-union-clash-branch.json
deleted file mode 100644
index e593336..0000000
--- a/tests/qapi-schema/flat-union-clash-branch.json
+++ /dev/null
@@ -1,18 +0,0 @@
-# Flat union branch name collision
-# FIXME: this parses, but then fails to compile due to a duplicate 'c_d'
-# (one from the base member, the other from the branch name).  We should
-# either reject the collision at parse time, or munge the generated branch
-# name to allow this to compile.
-{ 'enum': 'TestEnum',
-  'data': [ 'base', 'c-d' ] }
-{ 'struct': 'Base',
-  'data': { 'enum1': 'TestEnum', '*c_d': 'str' } }
-{ 'struct': 'Branch1',
-  'data': { 'string': 'str' } }
-{ 'struct': 'Branch2',
-  'data': { 'value': 'int' } }
-{ 'union': 'TestUnion',
-  'base': 'Base',
-  'discriminator': 'enum1',
-  'data': { 'base': 'Branch1',
-            'c-d': 'Branch2' } }
diff --git a/tests/qapi-schema/flat-union-clash-branch.out b/tests/qapi-schema/flat-union-clash-branch.out
deleted file mode 100644
index 8e0da73..0000000
--- a/tests/qapi-schema/flat-union-clash-branch.out
+++ /dev/null
@@ -1,14 +0,0 @@
-object :empty
-object Base
-    member enum1: TestEnum optional=False
-    member c_d: str optional=True
-object Branch1
-    member string: str optional=False
-object Branch2
-    member value: int optional=False
-enum TestEnum ['base', 'c-d']
-object TestUnion
-    base Base
-    tag enum1
-    case base: Branch1
-    case c-d: Branch2
diff --git a/tests/qapi-schema/flat-union-clash-type.err b/tests/qapi-schema/flat-union-clash-type.err
deleted file mode 100644
index b44dd40..0000000
--- a/tests/qapi-schema/flat-union-clash-type.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/flat-union-clash-type.json:11: Discriminator name 'type' collides with enum value in 'TestEnum'
diff --git a/tests/qapi-schema/flat-union-clash-type.exit b/tests/qapi-schema/flat-union-clash-type.exit
deleted file mode 100644
index d00491f..0000000
--- a/tests/qapi-schema/flat-union-clash-type.exit
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/flat-union-clash-type.json b/tests/qapi-schema/flat-union-clash-type.json
deleted file mode 100644
index 8f710f0..0000000
--- a/tests/qapi-schema/flat-union-clash-type.json
+++ /dev/null
@@ -1,14 +0,0 @@
-# Flat union branch 'type'
-# Reject this, because we would have a clash in generated C, between the
-# outer tag 'type' and the branch name 'type' within the union.
-# TODO: We could munge the generated C branch name to let it compile.
-{ 'enum': 'TestEnum',
-  'data': [ 'type' ] }
-{ 'struct': 'Base',
-  'data': { 'type': 'TestEnum' } }
-{ 'struct': 'Branch1',
-  'data': { 'string': 'str' } }
-{ 'union': 'TestUnion',
-  'base': 'Base',
-  'discriminator': 'type',
-  'data': { 'type': 'Branch1' } }
diff --git a/tests/qapi-schema/flat-union-clash-type.out b/tests/qapi-schema/flat-union-clash-type.out
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/qapi-schema/union-clash-type.err b/tests/qapi-schema/union-clash-type.err
deleted file mode 100644
index a5dead1..0000000
--- a/tests/qapi-schema/union-clash-type.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/union-clash-type.json:8: Union 'TestUnion' member 'kind' clashes with '(automatic)'
diff --git a/tests/qapi-schema/union-clash-type.exit b/tests/qapi-schema/union-clash-type.exit
deleted file mode 100644
index d00491f..0000000
--- a/tests/qapi-schema/union-clash-type.exit
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/union-clash-type.json b/tests/qapi-schema/union-clash-type.json
deleted file mode 100644
index cfc256b..0000000
--- a/tests/qapi-schema/union-clash-type.json
+++ /dev/null
@@ -1,9 +0,0 @@
-# Union branch 'type'
-# Reject this, because we would have a clash in generated C, between the
-# simple union's implicit tag member 'kind' and the branch name 'kind'
-# within the union.
-# TODO: Even when the generated C is switched to use 'type' rather than
-# 'kind', to match the QMP spelling, the collision should still be detected.
-# Or, we could munge the branch name to allow compilation.
-{ 'union': 'TestUnion',
-  'data': { 'kind': 'int', 'type': 'str' } }
diff --git a/tests/qapi-schema/union-clash-type.out b/tests/qapi-schema/union-clash-type.out
deleted file mode 100644
index e69de29..0000000
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (21 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 22/27] qapi: Remove outdated tests related to QMP/branch collisions Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-05 17:01   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 24/27] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
                   ` (5 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Previously, working with alternates required two lookup arrays
and some indirection: for type Foo, we created Foo_qtypes[]
which maps each qtype to a value of the generated FooKind enum,
then look up that value in FooKind_lookup[] like we do for other
union types.

This has a couple of subtle bugs.  First, the generator was
creating a call with a parameter '(int *) &(*obj)->type' where
type is an enum type; this is unsafe if the compiler chooses
to store the enum type in a different size than int, where
assigning through the wrong size pointer can corrupt data or
cause a SIGBUS.

Second, since the values of the FooKind enum start at zero, all
entries of the Foo_qtypes[] array that were not explicitly
initialized will map to the same branch of the union as the
first member of the alternate, rather than triggering a desired
failure in visit_get_next_type().  Fortunately, the bug seldom
bites; the very next thing the input visitor does is try to
parse the incoming JSON with the wrong parser, which normally
fails; the output visitor is not used with a C struct in that
state, and the dealloc visitor has nothing to clean up (so
there is no leak).

However, the second bug IS observable in one case: the behavior
of an alternate that contains a 'number' member but no 'int'
member differs according to whether the 'number' was first in
the qapi definition, and when the input being parsed is an
integer; this is because the 'number' parser accepts QTYPE_QINT
in addition to the expected QTYPE_QFLOAT.  A later patch will
worry about fixing alternates to parse all inputs that a
non-alternate 'number' would accept, for now this is still
marked FIXME, and the test merely updated to point out that
new undesired behavior of 'ans' matches the existing undesired
behavior of 'asn'.

This patch fixes the validation bug by deleting the indirection,
and modifying get_next_type() to directly assign a qtype_code
parameter.  This in turn fixes the type-casting bug, as we are
no longer casting a pointer to enum to a questionable size.
There is no longer a need to generate an implicit FooKind enum
associated with the alternate type (since the QMP wire format
never uses the stringized counterparts of the C union member
names); that also means we no longer have a collision with an
alternate branch named 'max'.  Since visit_get_next_type() does
not know which qtypes are expected, the generated visitor is
modified to generate an error statement if an unexpected type
is encountered.

The code relies on a new QAPISchemaAlternateTypeTag subclass
and the use of a new member.c_type() method for generating
qapi-types.h; this is because we don't want to expose
'qtype_code' as a built-in type usable from .json files.
The new subtype happens to work by keeping tag_member.type
as None, although this feels a bit unclean, and may be touched
up further in a later patch.

Callers now have to know the QTYPE_* mapping when looking at the
discriminator; but so far, only the testsuite was even using the
C struct of an alternate types.  I considered the possibility of
keeping the internal enum FooKind, but initialized differently
than most generated arrays, as in:
  typedef enum FooKind {
      FOO_KIND_A = QTYPE_QDICT,
      FOO_KIND_B = QTYPE_QINT,
  } FooKind;
to create nicer aliases for knowing when to use foo->a or foo->b
when inspecting foo->type; but it turned out to add too much
complexity, especially without a client.

There is a user-visible side effect to this change, but I
consider it to be an improvement. Previously,
the invalid QMP command:
  {"execute":"blockdev-add", "arguments":{"options":
    {"driver":"raw", "id":"a", "file":true}}}
failed with:
  {"error": {"class": "GenericError",
    "desc": "Invalid parameter type for 'file', expected: QDict"}}
(visit_get_next_type() succeeded, and the error comes from the
visit_type_BlockdevOptions() expecting {}; there is no mention of
the fact that a string would also work).  Now it fails with:
  {"error": {"class": "GenericError",
    "desc": "Invalid parameter type for 'file', expected: BlockdevRef"}}
(the error when the next type doesn't match any expected types for
the overall alternate).

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: rebase to earlier changes, rework commit message to mention second
bug fix; move positive test in qapi-schema-test to later patch
v8: no change
v7: rebase onto earlier changes, rework how subtype makes things work
v6: rebase onto tag_member subclass, testsuite, gen_err_check(),
and info improvements
---
 docs/qapi-code-gen.txt                 |  3 ---
 include/qapi/visitor-impl.h            |  3 ++-
 include/qapi/visitor.h                 |  8 ++++++-
 qapi/qapi-visit-core.c                 |  4 ++--
 qapi/qmp-input-visitor.c               |  4 ++--
 scripts/qapi-types.py                  | 36 +---------------------------
 scripts/qapi-visit.py                  | 14 +++++++----
 scripts/qapi.py                        | 44 +++++++++++++++++++++++++---------
 tests/qapi-schema/alternate-empty.out  |  1 -
 tests/qapi-schema/qapi-schema-test.out |  8 -------
 tests/test-qmp-input-visitor.c         | 31 ++++++++++++------------
 tests/test-qmp-output-visitor.c        |  4 ++--
 12 files changed, 74 insertions(+), 86 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 20e6907..9196e5c 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -383,9 +383,6 @@ where each branch of the union names a QAPI type.  For example:
    'data': { 'definition': 'BlockdevOptions',
              'reference': 'str' } }

-Just like for a simple union, an implicit C enum 'NameKind' is created
-to enumerate the branches for the alternate 'Name'.
-
 Unlike a union, the discriminator string is never passed on the wire
 for the Client JSON Protocol.  Instead, the value's JSON type serves
 as an implicit discriminator, which in turn means that an alternate
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 8c0ba57..6d95b36 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -32,7 +32,8 @@ struct Visitor

     void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
                       const char *kind, const char *name, Error **errp);
-    void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
+    /* May be NULL; most useful for input visitors. */
+    void (*get_next_type)(Visitor *v, qtype_code *type,
                           const char *name, Error **errp);

     void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index cfc19a6..b765993 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -41,7 +41,13 @@ GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
 void visit_end_list(Visitor *v, Error **errp);
 void visit_optional(Visitor *v, bool *present, const char *name,
                     Error **errp);
-void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
+
+/**
+ * Determine the qtype of the item @name in the current object visit.
+ * For input visitors, set *@type to the correct qtype of a qapi
+ * alternate type; for other visitors, leave *@type unchanged.
+ */
+void visit_get_next_type(Visitor *v, qtype_code *type,
                          const char *name, Error **errp);
 void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
                      const char *kind, const char *name, Error **errp);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 59ed506..3f24daa 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -81,11 +81,11 @@ void visit_optional(Visitor *v, bool *present, const char *name,
     }
 }

-void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
+void visit_get_next_type(Visitor *v, qtype_code *type,
                          const char *name, Error **errp)
 {
     if (v->get_next_type) {
-        v->get_next_type(v, obj, qtypes, name, errp);
+        v->get_next_type(v, type, name, errp);
     }
 }

diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index eb6e110..c1e7ec8 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -208,7 +208,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp)
     qmp_input_pop(qiv, errp);
 }

-static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
+static void qmp_input_get_next_type(Visitor *v, qtype_code *type,
                                     const char *name, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
@@ -218,7 +218,7 @@ static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
         error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
         return;
     }
-    *kind = qobjects[qobject_type(qobj)];
+    *type = qobject_type(qobj);
 }

 static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2f2f7df..2ac1405 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -47,7 +47,7 @@ def gen_struct_fields(members):
         ret += mcgen('''
     %(c_type)s %(c_name)s;
 ''',
-                     c_type=memb.type.c_type(), c_name=c_name(memb.name))
+                     c_type=memb.c_type(), c_name=c_name(memb.name))
     return ret


@@ -101,38 +101,6 @@ static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
                  c_name=c_name(name), base=base.c_name())


-def gen_alternate_qtypes_decl(name):
-    return mcgen('''
-
-extern const int %(c_name)s_qtypes[];
-''',
-                 c_name=c_name(name))
-
-
-def gen_alternate_qtypes(name, variants):
-    ret = mcgen('''
-
-const int %(c_name)s_qtypes[QTYPE_MAX] = {
-''',
-                c_name=c_name(name))
-
-    for var in variants.variants:
-        qtype = var.type.alternate_qtype()
-        assert qtype
-
-        ret += mcgen('''
-    [%(qtype)s] = %(enum_const)s,
-''',
-                     qtype=qtype,
-                     enum_const=c_enum_const(variants.tag_member.type.name,
-                                             var.name))
-
-    ret += mcgen('''
-};
-''')
-    return ret
-
-
 def gen_variants(variants):
     # FIXME: What purpose does data serve, besides preventing a union that
     # has a branch named 'data'? We use it in qapi-visit.py to decide
@@ -257,9 +225,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):

     def visit_alternate_type(self, name, info, variants):
         self._fwdecl += gen_fwd_object_or_array(name)
-        self._fwdefn += gen_alternate_qtypes(name, variants)
         self.decl += gen_object(name, None, [variants.tag_member], variants)
-        self.decl += gen_alternate_qtypes_decl(name)
         self._gen_type_cleanup(name)

 # If you link code generated from multiple schemata, you want only one
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 94cd113..af80e6d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -193,7 +193,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
     if (err) {
         goto out;
     }
-    visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err);
+    visit_get_next_type(v, &(*obj)->type, name, &err);
     if (err) {
         goto out_obj;
     }
@@ -201,20 +201,22 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
 ''',
                 c_name=c_name(name))

+    # FIXME: When 'number' but not 'int' is present in the alternate, we
+    # should allow QTYPE_INT to promote to QTYPE_FLOAT.
     for var in variants.variants:
         ret += mcgen('''
     case %(case)s:
         visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
         break;
 ''',
-                     case=c_enum_const(variants.tag_member.type.name,
-                                       var.name),
+                     case=var.type.alternate_qtype(),
                      c_type=var.type.c_name(),
                      c_name=c_name(var.name))

     ret += mcgen('''
     default:
-        abort();
+        error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+                   "%(name)s");
     }
 out_obj:
     error_propagate(errp, err);
@@ -223,7 +225,8 @@ out_obj:
 out:
     error_propagate(errp, err);
 }
-''')
+''',
+                 name=name)

     return ret

@@ -430,6 +433,7 @@ fdef.write(mcgen('''

 fdecl.write(mcgen('''
 #include "qapi/visitor.h"
+#include "qapi/qmp/qerror.h"
 #include "%(prefix)sqapi-types.h"

 ''',
diff --git a/scripts/qapi.py b/scripts/qapi.py
index f5aa1d5..9a1f0ac 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -627,15 +627,15 @@ def check_union(expr, expr_info):
 def check_alternate(expr, expr_info):
     name = expr['alternate']
     members = expr['data']
-    values = {'MAX': '(automatic)'}
+    values = {}
     types_seen = {}

     # Check every branch
     for (key, value) in members.items():
         check_name(expr_info, "Member of alternate '%s'" % name, key)

-        # Check for conflicts in the generated enum
-        c_key = camel_to_upper(key)
+        # Check for conflicts in the branch names
+        c_key = c_name(key)
         if c_key in values:
             raise QAPIExprError(expr_info,
                                 "Alternate '%s' member '%s' clashes with '%s'"
@@ -1029,13 +1029,17 @@ class QAPISchemaObjectTypeMember(object):
         assert self.name not in seen
         seen[self.name] = self

+    def c_type(self):
+        return self.type.c_type()
+

 class QAPISchemaObjectTypeVariants(object):
     def __init__(self, tag_name, tag_member, variants):
         # Flat unions pass tag_name but not tag_member.
         # Simple unions and alternates pass tag_member but not tag_name.
         # After check(), tag_member is always set, and tag_name remains
-        # a reliable witness of being used by a flat union.
+        # a reliable witness of being used by a flat union, and
+        # tag_member.type being None is a reliable witness of an alternate.
         assert bool(tag_member) != bool(tag_name)
         assert (isinstance(tag_name, str) or
                 isinstance(tag_member, QAPISchemaObjectTypeMember))
@@ -1049,7 +1053,11 @@ class QAPISchemaObjectTypeVariants(object):
         # seen is non-empty for unions, empty for alternates
         if self.tag_name:    # flat union
             self.tag_member = seen[self.tag_name]
-        assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+        if seen:
+            assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+        else:
+            assert isinstance(self.tag_member, QAPISchemaAlternateTypeTag)
+            assert not self.tag_member.type
         for v in self.variants:
             # Reset seen array for each variant, since qapi names from one
             # branch do not affect another branch
@@ -1062,10 +1070,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):

     def check(self, schema, tag_type, seen):
         QAPISchemaObjectTypeMember.check(self, schema)
-        assert self.name in tag_type.values
-        if seen:
-            # This variant is used within a union; ensure each qapi member
-            # field does not collide with the union's non-variant members.
+        if seen:     # in a union
+            assert self.name in tag_type.values
             self.type.check_clash(schema, seen)

     # This function exists to support ugly simple union special cases
@@ -1087,8 +1093,12 @@ class QAPISchemaAlternateType(QAPISchemaType):
         self.variants = variants

     def check(self, schema):
-        self.variants.tag_member.check(schema)
         self.variants.check(schema, {})
+        # Since we have no enum mapping, we have to check for potential
+        # case name collisions ourselves.
+        cases = {}
+        for var in self.variants.variants:
+            var.check_clash(cases)

     def json_type(self):
         return 'value'
@@ -1097,6 +1107,18 @@ class QAPISchemaAlternateType(QAPISchemaType):
         visitor.visit_alternate_type(self.name, self.info, self.variants)


+class QAPISchemaAlternateTypeTag(QAPISchemaObjectTypeMember):
+    # TODO: This subclass intentionally leaves self.tag_type as None,
+    # and intentionally has no check() method. It might be easier to
+    # reason about the overall QAPISchema if we also subclassed
+    # QAPISchemaBuiltinType to supply an internal-only 'qtype_code' type.
+    def __init__(self):
+        QAPISchemaObjectTypeMember.__init__(self, 'type', '', False)
+
+    def c_type(self):
+        return 'qtype_code'
+
+
 class QAPISchemaCommand(QAPISchemaEntity):
     def __init__(self, name, info, arg_type, ret_type, gen, success_response):
         QAPISchemaEntity.__init__(self, name, info)
@@ -1290,7 +1312,7 @@ class QAPISchema(object):
         data = expr['data']
         variants = [self._make_variant(key, value)
                     for (key, value) in data.iteritems()]
-        tag_member = self._make_implicit_tag(name, info, variants)
+        tag_member = QAPISchemaAlternateTypeTag()
         self._def_entity(
             QAPISchemaAlternateType(name, info,
                                     QAPISchemaObjectTypeVariants(None,
diff --git a/tests/qapi-schema/alternate-empty.out b/tests/qapi-schema/alternate-empty.out
index 0f153b6..9b010d8 100644
--- a/tests/qapi-schema/alternate-empty.out
+++ b/tests/qapi-schema/alternate-empty.out
@@ -1,4 +1,3 @@
 object :empty
 alternate Alt
     case i: int
-enum AltKind ['i']
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 786024e..3430f37 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -56,27 +56,21 @@ object :obj-user_def_cmd2-arg
 alternate AltIntNum
     case i: int
     case n: number
-enum AltIntNumKind ['i', 'n']
 alternate AltNumInt
     case n: number
     case i: int
-enum AltNumIntKind ['n', 'i']
 alternate AltNumStr
     case n: number
     case s: str
-enum AltNumStrKind ['n', 's']
 alternate AltStrBool
     case s: str
     case b: bool
-enum AltStrBoolKind ['s', 'b']
 alternate AltStrInt
     case s: str
     case i: int
-enum AltStrIntKind ['s', 'i']
 alternate AltStrNum
     case s: str
     case n: number
-enum AltStrNumKind ['s', 'n']
 event EVENT_A None
 event EVENT_B None
 event EVENT_C :obj-EVENT_C-arg
@@ -112,7 +106,6 @@ alternate UserDefAlternate
     case uda: UserDefA
     case s: str
     case i: int
-enum UserDefAlternateKind ['uda', 's', 'i']
 object UserDefB
     member intb: int optional=False
     member a-b: bool optional=True
@@ -178,7 +171,6 @@ event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
 alternate __org.qemu_x-Alt
     case __org.qemu_x-branch: str
     case b: __org.qemu_x-Base
-enum __org.qemu_x-AltKind ['__org.qemu_x-branch', 'b']
 object __org.qemu_x-Base
     member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
 enum __org.qemu_x-Enum ['__org.qemu_x-value']
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index e9a66a7..06c8830 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -317,13 +317,13 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,

     v = visitor_input_test_init(data, "42");
     visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
-    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
+    g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
     g_assert_cmpint(tmp->u.i, ==, 42);
     qapi_free_UserDefAlternate(tmp);

     v = visitor_input_test_init(data, "'string'");
     visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
-    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
+    g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
     g_assert_cmpstr(tmp->u.s, ==, "string");
     qapi_free_UserDefAlternate(tmp);

@@ -351,36 +351,37 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     g_assert(data->err);
     qapi_free_AltStrBool(asb);

-    /* FIXME: Order of alternate should not affect semantics; asn should
-     * parse the same as ans */
+    /* FIXME: integer should parse as number */
     v = visitor_input_test_init(data, "42");
     visit_type_AltStrNum(v, &asn, NULL, &data->err);
-    /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
+    /* FIXME g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); */
     /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
     g_assert(data->err);
     qapi_free_AltStrNum(asn);

+    /* FIXME: integer should parse as number */
     v = visitor_input_test_init(data, "42");
-    visit_type_AltNumStr(v, &ans, NULL, &error_abort);
-    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
-    g_assert_cmpfloat(ans->u.n, ==, 42);
+    visit_type_AltNumStr(v, &ans, NULL, &data->err);
+    /* FIXME g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); */
+    /* FIXME g_assert_cmpfloat(ans->u.n, ==, 42); */
+    g_assert(data->err);
     qapi_free_AltNumStr(ans);

     v = visitor_input_test_init(data, "42");
     visit_type_AltStrInt(v, &asi, NULL, &error_abort);
-    g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
+    g_assert_cmpint(asi->type, ==, QTYPE_QINT);
     g_assert_cmpint(asi->u.i, ==, 42);
     qapi_free_AltStrInt(asi);

     v = visitor_input_test_init(data, "42");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
-    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
+    g_assert_cmpint(ain->type, ==, QTYPE_QINT);
     g_assert_cmpint(ain->u.i, ==, 42);
     qapi_free_AltIntNum(ain);

     v = visitor_input_test_init(data, "42");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
-    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
+    g_assert_cmpint(ani->type, ==, QTYPE_QINT);
     g_assert_cmpint(ani->u.i, ==, 42);
     qapi_free_AltNumInt(ani);

@@ -393,13 +394,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltStrNum(v, &asn, NULL, &error_abort);
-    g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
+    g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(asn->u.n, ==, 42.5);
     qapi_free_AltStrNum(asn);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumStr(v, &ans, NULL, &error_abort);
-    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
+    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(ans->u.n, ==, 42.5);
     qapi_free_AltNumStr(ans);

@@ -410,13 +411,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
-    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
+    g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(ain->u.n, ==, 42.5);
     qapi_free_AltIntNum(ain);

     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
-    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
+    g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(ani->u.n, ==, 42.5);
     qapi_free_AltNumInt(ani);
 }
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 0d0c859..b962900 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -428,7 +428,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     UserDefAlternate *tmp;

     tmp = g_new0(UserDefAlternate, 1);
-    tmp->type = USER_DEF_ALTERNATE_KIND_I;
+    tmp->type = QTYPE_QINT;
     tmp->u.i = 42;

     visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
@@ -441,7 +441,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     qobject_decref(arg);

     tmp = g_new0(UserDefAlternate, 1);
-    tmp->type = USER_DEF_ALTERNATE_KIND_S;
+    tmp->type = QTYPE_QSTRING;
     tmp->u.s = g_strdup("hello");

     visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 24/27] qapi: Fix alternates that accept 'number' but not 'int'
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (22 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test Eric Blake
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

The QMP input visitor allows integral values to be assigned by
promotion to a QTYPE_QFLOAT.  However, when parsing an alternate,
we did not take this into account, such that an alternate that
accepts 'number' but not 'int' would reject integral values.

With this patch, we now have the following desirable table:

    alternate has      case selected for
    'int'  'number'    QTYPE_QINT  QTYPE_QFLOAT
      no        no     error       error
      no       yes     'number'    'number'
     yes        no     'int'       error
     yes       yes     'int'       'number'

While it is unlikely that we will ever use 'number' in an
alternate other than in the testsuite, it never hurts to be
more precise in what we allow.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: rebase to earlier changes
v8: no change
v7: rebase to named .u union
v6: rebase onto earlier testsuite and gen_err_check() improvements
---
 include/qapi/visitor-impl.h    |  2 +-
 include/qapi/visitor.h         |  3 ++-
 qapi/qapi-visit-core.c         |  4 ++--
 qapi/qmp-input-visitor.c       |  4 ++++
 scripts/qapi-visit.py          | 11 +++++++----
 tests/test-qmp-input-visitor.c | 16 ++++++----------
 6 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 6d95b36..1d09b7b 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -33,7 +33,7 @@ struct Visitor
     void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
                       const char *kind, const char *name, Error **errp);
     /* May be NULL; most useful for input visitors. */
-    void (*get_next_type)(Visitor *v, qtype_code *type,
+    void (*get_next_type)(Visitor *v, qtype_code *type, bool promote_int,
                           const char *name, Error **errp);

     void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index b765993..baea594 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -46,8 +46,9 @@ void visit_optional(Visitor *v, bool *present, const char *name,
  * Determine the qtype of the item @name in the current object visit.
  * For input visitors, set *@type to the correct qtype of a qapi
  * alternate type; for other visitors, leave *@type unchanged.
+ * If @promote_int, treat integers as QTYPE_FLOAT.
  */
-void visit_get_next_type(Visitor *v, qtype_code *type,
+void visit_get_next_type(Visitor *v, qtype_code *type, bool promote_int,
                          const char *name, Error **errp);
 void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
                      const char *kind, const char *name, Error **errp);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 3f24daa..884fe94 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -81,11 +81,11 @@ void visit_optional(Visitor *v, bool *present, const char *name,
     }
 }

-void visit_get_next_type(Visitor *v, qtype_code *type,
+void visit_get_next_type(Visitor *v, qtype_code *type, bool promote_int,
                          const char *name, Error **errp)
 {
     if (v->get_next_type) {
-        v->get_next_type(v, type, name, errp);
+        v->get_next_type(v, type, promote_int, name, errp);
     }
 }

diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index c1e7ec8..60be2ff 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -209,6 +209,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp)
 }

 static void qmp_input_get_next_type(Visitor *v, qtype_code *type,
+                                    bool promote_int,
                                     const char *name, Error **errp)
 {
     QmpInputVisitor *qiv = to_qiv(v);
@@ -219,6 +220,9 @@ static void qmp_input_get_next_type(Visitor *v, qtype_code *type,
         return;
     }
     *type = qobject_type(qobj);
+    if (promote_int && *type == QTYPE_QINT) {
+        *type = QTYPE_QFLOAT;
+    }
 }

 static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index af80e6d..f16770a 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -183,6 +183,11 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error


 def gen_visit_alternate(name, variants):
+    promote_int = 'true'
+    for var in variants.variants:
+        if var.type.alternate_qtype() == 'QTYPE_QINT':
+            promote_int = 'false'
+
     ret = mcgen('''

 void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp)
@@ -193,16 +198,14 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
     if (err) {
         goto out;
     }
-    visit_get_next_type(v, &(*obj)->type, name, &err);
+    visit_get_next_type(v, &(*obj)->type, %(promote_int)s, name, &err);
     if (err) {
         goto out_obj;
     }
     switch ((*obj)->type) {
 ''',
-                c_name=c_name(name))
+                c_name=c_name(name), promote_int=promote_int)

-    # FIXME: When 'number' but not 'int' is present in the alternate, we
-    # should allow QTYPE_INT to promote to QTYPE_FLOAT.
     for var in variants.variants:
         ret += mcgen('''
     case %(case)s:
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 06c8830..b93f698 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -351,20 +351,16 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     g_assert(data->err);
     qapi_free_AltStrBool(asb);

-    /* FIXME: integer should parse as number */
     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrNum(v, &asn, NULL, &data->err);
-    /* FIXME g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); */
-    /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
-    g_assert(data->err);
+    visit_type_AltStrNum(v, &asn, NULL, &error_abort);
+    g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpfloat(asn->u.n, ==, 42);
     qapi_free_AltStrNum(asn);

-    /* FIXME: integer should parse as number */
     v = visitor_input_test_init(data, "42");
-    visit_type_AltNumStr(v, &ans, NULL, &data->err);
-    /* FIXME g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); */
-    /* FIXME g_assert_cmpfloat(ans->u.n, ==, 42); */
-    g_assert(data->err);
+    visit_type_AltNumStr(v, &ans, NULL, &error_abort);
+    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpfloat(ans->u.n, ==, 42);
     qapi_free_AltNumStr(ans);

     v = visitor_input_test_init(data, "42");
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (23 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 24/27] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-05 18:44   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code Eric Blake
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Add positive tests to qapi-schema-test for things that were
made possible by recent patches but which caused compile errors
due to collisions prior to that point.  The focus is mainly on
collisions due to names we have reserved for qapi, even though
it is unlikely that anyone will want to abuse these names in
actual .json files.

The added tests includes:
Use of a member name ending in 'Kind' or 'List' [1, 4]
Use of a type name starting with 'has_' [1, 5]
Use of a type named 'u' [1, 6]
Use of a union branch name of 'u' [2, 6]
Use of a union branch name starting with 'has_' [2, 5]
Use of an alternate branch name of 'max' [3]

[1] Never broken, but could break if reservations are too strict
[2] Broken prior to commit e4ba22b
[3] Broken prior to previous commit
[4] See reservations in commit 4dc2e69 and 255960d
[5] See reservations in commit 9fb081e
[6] See reservation in commit 5e59baf

Not worth testing here: we no longer have a collision with a
member named 'base' (commit ddf2190) or with a branch named
'type' (commit e4ba22b).

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: reorder in series (was 9/17); fewer tests of 'base' and
'type' non-collision; fold in alternate 'max' test; update commit
message
v8: new, but collects portions of subset B v10 patches 2, 3, and
16 and subset C v7 patch 6 that were deferred to later.

It might be worth dropping or simplifying this patch, depending
on how many corner cases we actually want to test.
---
 tests/qapi-schema/qapi-schema-test.json | 16 ++++++++++++++++
 tests/qapi-schema/qapi-schema-test.out  | 27 +++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 44638da..c490f32 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -113,6 +113,22 @@
             'sizes': ['size'],
             'any': ['any'] } }

+# Even though 'u' and 'has_*' are forbidden as struct member names, they
+# should still be valid as a type or union branch name. And although
+# '*Kind' and '*List' are forbidden as type names, they should not be
+# forbidden as a member or branch name.  Flat union branches do not
+# collide with base members.
+{ 'enum': 'EnumName', 'data': [ 'value1', 'has_a', 'u' ] }
+{ 'struct': 'has_a', 'data': { 'MyKind': 'int', 'MyList': ['int'],
+                               'value1': 'EnumName' } }
+{ 'union': 'u', 'data': { 'u': 'uint8', 'myKind': 'has_a',
+                          'myList': 'has_a', 'has_a': 'has_a' } }
+{ 'union': 'UnionName', 'base': 'has_a', 'discriminator': 'value1',
+  'data': { 'value1': 'UserDefZero', 'has_a': 'UserDefZero',
+            'u': 'UserDefZero' } }
+{ 'alternate': 'AltName', 'data': { 'type': 'int', 'u': 'bool',
+                                    'myKind': 'has_a', 'max': 'str' } }
+
 # testing commands
 { 'command': 'user_def_cmd', 'data': {} }
 { 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3430f37..0139ae6 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -22,6 +22,8 @@ object :obj-guest-get-time-arg
     member b: int optional=True
 object :obj-guest-sync-arg
     member arg: any optional=False
+object :obj-has_a-wrapper
+    member data: has_a optional=False
 object :obj-int16List-wrapper
     member data: int16List optional=False
 object :obj-int32List-wrapper
@@ -46,6 +48,8 @@ object :obj-uint32List-wrapper
     member data: uint32List optional=False
 object :obj-uint64List-wrapper
     member data: uint64List optional=False
+object :obj-uint8-wrapper
+    member data: uint8 optional=False
 object :obj-uint8List-wrapper
     member data: uint8List optional=False
 object :obj-user_def_cmd1-arg
@@ -56,6 +60,11 @@ object :obj-user_def_cmd2-arg
 alternate AltIntNum
     case i: int
     case n: number
+alternate AltName
+    case type: int
+    case u: bool
+    case myKind: has_a
+    case max: str
 alternate AltNumInt
     case n: number
     case i: int
@@ -78,6 +87,7 @@ event EVENT_D :obj-EVENT_D-arg
 object Empty1
 object Empty2
     base Empty1
+enum EnumName ['value1', 'has_a', 'u']
 enum EnumOne ['value1', 'value2', 'value3']
 object EventStructOne
     member struct1: UserDefOne optional=False
@@ -99,6 +109,12 @@ object TestStruct
     member integer: int optional=False
     member boolean: bool optional=False
     member string: str optional=False
+object UnionName
+    base has_a
+    tag value1
+    case value1: UserDefZero
+    case has_a: UserDefZero
+    case u: UserDefZero
 object UserDefA
     member boolean: bool optional=False
     member a_b: int optional=True
@@ -193,6 +209,17 @@ command guest-get-time :obj-guest-get-time-arg -> int
    gen=True success_response=True
 command guest-sync :obj-guest-sync-arg -> any
    gen=True success_response=True
+object has_a
+    member MyKind: int optional=False
+    member MyList: intList optional=False
+    member value1: EnumName optional=False
+object u
+    member type: uKind optional=False
+    case u: :obj-uint8-wrapper
+    case myKind: :obj-has_a-wrapper
+    case myList: :obj-has_a-wrapper
+    case has_a: :obj-has_a-wrapper
+enum uKind ['u', 'myKind', 'myList', 'has_a']
 command user_def_cmd None -> None
    gen=True success_response=True
 command user_def_cmd1 :obj-user_def_cmd1-arg -> None
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (24 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-05 19:05   ` Markus Armbruster
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 27/27] qapi: Simplify visits of optional fields Eric Blake
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

Commit cbc95538 removed unused start_handle() and end_handle(),
but forgot got remove their declarations.

Commit 4e27e819 introduced optional visitor callbacks for all
sorts of int types, but except for type_uint64 and type_size,
none of them have ever been supplied (the generic implementation
based on using type_int then bounds-checking works just fine).
In the interest of simplicity, it's easier to make the visitor
callback interface not have to worry about the other sizes.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: no change
v7: no change
v6: no change
---
 include/qapi/visitor-impl.h |  19 +++----
 include/qapi/visitor.h      |   3 -
 qapi/qapi-visit-core.c      | 131 +++++++++++++++++---------------------------
 3 files changed, 58 insertions(+), 95 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 1d09b7b..370935a 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -1,7 +1,7 @@
 /*
  * Core Definitions for QAPI Visitor implementations
  *
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2015 Red Hat, Inc.
  *
  * Author: Paolo Bonizni <pbonzini@redhat.com>
  *
@@ -48,18 +48,15 @@ struct Visitor
     void (*optional)(Visitor *v, bool *present, const char *name,
                      Error **errp);

-    void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
-    void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
-    void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
-    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
-    void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
-    void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
-    void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
-    void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
-    /* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
-    void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
     bool (*start_union)(Visitor *v, bool data_present, Error **errp);
     void (*end_union)(Visitor *v, bool data_present, Error **errp);
+
+    /* Only required to visit uint64 differently than (*type_int)().  */
+    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name,
+                        Error **errp);
+    /* Only required to visit sizes differently than (*type_uint64)().  */
+    void (*type_size)(Visitor *v, uint64_t *obj, const char *name,
+                      Error **errp);
 };

 void input_type_enum(Visitor *v, int *obj, const char * const strings[],
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index baea594..67ddd83 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -27,9 +27,6 @@ typedef struct GenericList
     struct GenericList *next;
 } GenericList;

-void visit_start_handle(Visitor *v, void **obj, const char *kind,
-                        const char *name, Error **errp);
-void visit_end_handle(Visitor *v, Error **errp);
 void visit_start_struct(Visitor *v, void **obj, const char *kind,
                         const char *name, size_t size, Error **errp);
 void visit_end_struct(Visitor *v, Error **errp);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 884fe94..cbf7780 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -104,57 +104,48 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
 {
     int64_t value;

-    if (v->type_uint8) {
-        v->type_uint8(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < 0 || value > UINT8_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "uint8_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < 0 || value > UINT8_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "uint8_t");
+        return;
     }
+    *obj = value;
 }

-void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
+void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name,
+                       Error **errp)
 {
     int64_t value;

-    if (v->type_uint16) {
-        v->type_uint16(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < 0 || value > UINT16_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "uint16_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < 0 || value > UINT16_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "uint16_t");
+        return;
     }
+    *obj = value;
 }

-void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
+void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name,
+                       Error **errp)
 {
     int64_t value;

-    if (v->type_uint32) {
-        v->type_uint32(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < 0 || value > UINT32_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "uint32_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < 0 || value > UINT32_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "uint32_t");
+        return;
     }
+    *obj = value;
 }

-void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
+void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name,
+                       Error **errp)
 {
     int64_t value;

@@ -171,77 +162,55 @@ void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
 {
     int64_t value;

-    if (v->type_int8) {
-        v->type_int8(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < INT8_MIN || value > INT8_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "int8_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < INT8_MIN || value > INT8_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "int8_t");
+        return;
     }
+    *obj = value;
 }

 void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
 {
     int64_t value;

-    if (v->type_int16) {
-        v->type_int16(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < INT16_MIN || value > INT16_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "int16_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < INT16_MIN || value > INT16_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "int16_t");
+        return;
     }
+    *obj = value;
 }

 void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
 {
     int64_t value;

-    if (v->type_int32) {
-        v->type_int32(v, obj, name, errp);
-    } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        if (value < INT32_MIN || value > INT32_MAX) {
-            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                       name ? name : "null", "int32_t");
-            return;
-        }
-        *obj = value;
+    value = *obj;
+    v->type_int(v, &value, name, errp);
+    if (value < INT32_MIN || value > INT32_MAX) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   name ? name : "null", "int32_t");
+        return;
     }
+    *obj = value;
 }

 void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
 {
-    if (v->type_int64) {
-        v->type_int64(v, obj, name, errp);
-    } else {
-        v->type_int(v, obj, name, errp);
-    }
+    v->type_int(v, obj, name, errp);
 }

 void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
 {
-    int64_t value;
-
     if (v->type_size) {
         v->type_size(v, obj, name, errp);
-    } else if (v->type_uint64) {
-        v->type_uint64(v, obj, name, errp);
     } else {
-        value = *obj;
-        v->type_int(v, &value, name, errp);
-        *obj = value;
+        visit_type_uint64(v, obj, name, errp);
     }
 }

-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH v9 27/27] qapi: Simplify visits of optional fields
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (25 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code Eric Blake
@ 2015-11-04  6:20 ` Eric Blake
  2015-11-04 10:22 ` [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Markus Armbruster
  2015-11-05 19:45 ` Markus Armbruster
  28 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04  6:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Michael Roth

None of the visitor callbacks would set an error when testing
if an optional field was present; make this part of the interface
contract by eliminating the errp argument.  Then, for less code,
reflect the determined boolean value back to the caller instead
of making the caller read the boolean after the fact.

The resulting generated code has a nice diff:

|-    visit_optional(v, &has_fdset_id, "fdset-id", &err);
|-    if (err) {
|-        goto out;
|-    }
|-    if (has_fdset_id) {
|+    if (visit_optional(v, &has_fdset_id, "fdset-id")) {
|         visit_type_int(v, &fdset_id, "fdset-id", &err);
|         if (err) {
|             goto out;
|         }
|     }

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: no change
v8: no change
v7: rebase to no member.c_name()
v6: rebase onto earlier testsuite and gen_err_check() improvements
---
 include/qapi/visitor-impl.h |  5 ++---
 include/qapi/visitor.h      | 10 ++++++++--
 qapi/opts-visitor.c         |  2 +-
 qapi/qapi-visit-core.c      |  6 +++---
 qapi/qmp-input-visitor.c    |  3 +--
 qapi/string-input-visitor.c |  3 +--
 scripts/qapi.py             |  7 +------
 7 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 370935a..fd2e905 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -44,9 +44,8 @@ struct Visitor
     void (*type_any)(Visitor *v, QObject **obj, const char *name,
                      Error **errp);

-    /* May be NULL */
-    void (*optional)(Visitor *v, bool *present, const char *name,
-                     Error **errp);
+    /* May be NULL; most useful for input visitors. */
+    void (*optional)(Visitor *v, bool *present, const char *name);

     bool (*start_union)(Visitor *v, bool data_present, Error **errp);
     void (*end_union)(Visitor *v, bool data_present, Error **errp);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 67ddd83..e52ad39 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -36,8 +36,14 @@ void visit_end_implicit_struct(Visitor *v, Error **errp);
 void visit_start_list(Visitor *v, const char *name, Error **errp);
 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
 void visit_end_list(Visitor *v, Error **errp);
-void visit_optional(Visitor *v, bool *present, const char *name,
-                    Error **errp);
+
+/**
+ * Check if an optional member @name of an object needs visiting.
+ * For input visitors, set *@present according to whether the
+ * corresponding visit_type_*() needs calling; for other visitors,
+ * leave *@present unchanged.  Return *@present for convenience.
+ */
+bool visit_optional(Visitor *v, bool *present, const char *name);

 /**
  * Determine the qtype of the item @name in the current object visit.
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index cd10392..ef5fb8b 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -488,7 +488,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)


 static void
-opts_optional(Visitor *v, bool *present, const char *name, Error **errp)
+opts_optional(Visitor *v, bool *present, const char *name)
 {
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);

diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index cbf7780..2594147 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -73,12 +73,12 @@ void visit_end_union(Visitor *v, bool data_present, Error **errp)
     }
 }

-void visit_optional(Visitor *v, bool *present, const char *name,
-                    Error **errp)
+bool visit_optional(Visitor *v, bool *present, const char *name)
 {
     if (v->optional) {
-        v->optional(v, present, name, errp);
+        v->optional(v, present, name);
     }
+    return *present;
 }

 void visit_get_next_type(Visitor *v, qtype_code *type, bool promote_int,
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 60be2ff..ced0569 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -304,8 +304,7 @@ static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name,
     *obj = qobj;
 }

-static void qmp_input_optional(Visitor *v, bool *present, const char *name,
-                               Error **errp)
+static void qmp_input_optional(Visitor *v, bool *present, const char *name)
 {
     QmpInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qmp_input_get_object(qiv, name, true);
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index bbd6a54..dee780a 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -299,8 +299,7 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
     *obj = val;
 }

-static void parse_optional(Visitor *v, bool *present, const char *name,
-                           Error **errp)
+static void parse_optional(Visitor *v, bool *present, const char *name)
 {
     StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9a1f0ac..e60b72c 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1620,15 +1620,10 @@ def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False):
     for memb in members:
         if memb.optional:
             ret += mcgen('''
-    visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s);
+    if (visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s")) {
 ''',
                          prefix=prefix, c_name=c_name(memb.name),
                          name=memb.name, errp=errparg)
-            ret += gen_err_check(skiperr=skiperr)
-            ret += mcgen('''
-    if (%(prefix)shas_%(c_name)s) {
-''',
-                         prefix=prefix, c_name=c_name(memb.name))
             push_indent()

         # Ugly: sometimes we need to cast away const
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-*
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-* Eric Blake
@ 2015-11-04  8:19   ` Markus Armbruster
  2015-11-04 17:24     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04  8:19 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Make valgrind happy with the current state of the tests, so that
> it is easier to see if future patches introduce new memory problems
> without being drowned in noise.  Many of the leaks were due to
> calling a second init without tearing down the data from an earlier
> visit.  But since teardown is already idempotent, and we already
> register teardown as part of input_visitor_test_add(), it is nicer
> to just make init() safe to call multiple times than it is to have
> to make all tests call teardown.
>
> Another common leak was forgetting to clean up an error object,
> after testing that an error was raised.
>
> Another leak was in test_visitor_in_struct_nested(), failing to
> clean the base member of UserDefTwo.  Cleaning that up left
> check_and_free_str() as dead code (since using the qapi_free_*
> takes care of recursion, and we don't want double frees).
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: move earlier in series (was 13/17)
> v8: no change
> v7: no change
> v6: make init repeatable rather than adding teardown everywhere,
> fix additional leak with UserDefTwo base, plug additional files
> ---
>  tests/test-qmp-input-strict.c   | 10 ++++++++++
>  tests/test-qmp-input-visitor.c  | 41 +++++++----------------------------------
>  tests/test-qmp-output-visitor.c |  3 ++-
>  3 files changed, 19 insertions(+), 35 deletions(-)

No leaks to plug in test/-qmp-commands.c and test-qmp-event.c?

> diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
> index b44184f..910e2f9 100644
> --- a/tests/test-qmp-input-strict.c
> +++ b/tests/test-qmp-input-strict.c
> @@ -77,6 +77,8 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
>  {
>      Visitor *v;
>
> +    validate_teardown(data, NULL);
> +
>      data->obj = qobject_from_json(json_string);
>      g_assert(data->obj != NULL);
>

A test added with validate_test_add() may call validate_test_init_raw()
any number of time.  Since validate_test_add() passes
validate_teardown() as fixture teardown function, the last one will be
cleaned up on test finalization.  The others will be cleaned up by the
next validate_test_init_raw().  Okay.  Actually, the whole fixture
business starts to make sense only now.

But why only validate_test_init_raw() and not validate_test_init()?

The two duplicate code, by the way.

> @@ -193,6 +195,8 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
>
>      visit_type_TestStruct(v, &p, NULL, &err);
>      g_assert(err);
> +    error_free(err);
> +    /* FIXME: visitor should not allocate p when returning error */

Indeed.

Recommend to always mention new FIXMEs in the commit message.

>      if (p) {
>          g_free(p->string);
>      }
> @@ -210,6 +214,7 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
>
>      visit_type_UserDefTwo(v, &udp, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefTwo(udp);
>  }
>
> @@ -224,6 +229,7 @@ static void test_validate_fail_list(TestInputVisitorData *data,
>
>      visit_type_UserDefOneList(v, &head, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefOneList(head);
>  }
>
> @@ -239,6 +245,7 @@ static void test_validate_fail_union_native_list(TestInputVisitorData *data,
>
>      visit_type_UserDefNativeListUnion(v, &tmp, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefNativeListUnion(tmp);
>  }
>
> @@ -253,6 +260,7 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
>
>      visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefFlatUnion(tmp);
>  }
>
> @@ -268,6 +276,7 @@ static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
>
>      visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefFlatUnion2(tmp);
>  }
>
> @@ -282,6 +291,7 @@ static void test_validate_fail_alternate(TestInputVisitorData *data,
>
>      visit_type_UserDefAlternate(v, &tmp, NULL, &err);
>      g_assert(err);
> +    error_free(err);
>      qapi_free_UserDefAlternate(tmp);
>  }
>
> diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
> index 3f6bc4d..03c3682 100644
> --- a/tests/test-qmp-input-visitor.c
> +++ b/tests/test-qmp-input-visitor.c
> @@ -46,6 +46,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
>      Visitor *v;
>      va_list ap;
>
> +    visitor_input_teardown(data, NULL);
> +
>      va_start(ap, json_string);
>      data->obj = qobject_from_jsonv(json_string, &ap);
>      va_end(ap);

Here, you add it to visitor_input_test_init(), but not
visitor_input_test_init_raw().

These two duplicate code, too.

> @@ -177,12 +179,7 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
>          visit_type_EnumOne(v, &res, NULL, &err);
>          g_assert(!err);
>          g_assert_cmpint(i, ==, res);
> -
> -        visitor_input_teardown(data, NULL);
>      }
> -
> -    data->obj = NULL;
> -    data->qiv = NULL;
>  }
>
>
> @@ -205,12 +202,6 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
>      g_free(p);
>  }
>
> -static void check_and_free_str(char *str, const char *cmp)
> -{
> -    g_assert_cmpstr(str, ==, cmp);
> -    g_free(str);
> -}
> -
>  static void test_visitor_in_struct_nested(TestInputVisitorData *data,
>                                            const void *unused)
>  {
> @@ -226,17 +217,14 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
>      visit_type_UserDefTwo(v, &udp, NULL, &err);
>      g_assert(!err);
>
> -    check_and_free_str(udp->string0, "string0");
> -    check_and_free_str(udp->dict1->string1, "string1");
> +    g_assert_cmpstr(udp->string0, ==, "string0");
> +    g_assert_cmpstr(udp->dict1->string1, ==, "string1");
>      g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
> -    check_and_free_str(udp->dict1->dict2->userdef->string, "string");
> -    check_and_free_str(udp->dict1->dict2->string, "string2");
> +    g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
> +    g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
>      g_assert(udp->dict1->has_dict3 == false);
>
> -    g_free(udp->dict1->dict2->userdef);
> -    g_free(udp->dict1->dict2);
> -    g_free(udp->dict1);
> -    g_free(udp);
> +    qapi_free_UserDefTwo(udp);
>  }
>
>  static void test_visitor_in_list(TestInputVisitorData *data,
> @@ -346,14 +334,12 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
>      g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
>      g_assert_cmpint(tmp->u.i, ==, 42);
>      qapi_free_UserDefAlternate(tmp);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "'string'");
>      visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
>      g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
>      g_assert_cmpstr(tmp->u.s, ==, "string");
>      qapi_free_UserDefAlternate(tmp);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "false");
>      visit_type_UserDefAlternate(v, &tmp, NULL, &err);
> @@ -361,7 +347,6 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
>      error_free(err);
>      err = NULL;
>      qapi_free_UserDefAlternate(tmp);
> -    visitor_input_teardown(data, NULL);
>  }
>
>  static void test_visitor_in_alternate_number(TestInputVisitorData *data,
> @@ -384,7 +369,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>      error_free(err);
>      err = NULL;
>      qapi_free_AltStrBool(asb);
> -    visitor_input_teardown(data, NULL);
>
>      /* FIXME: Order of alternate should not affect semantics; asn should
>       * parse the same as ans */
> @@ -396,35 +380,30 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>      error_free(err);
>      err = NULL;
>      qapi_free_AltStrNum(asn);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltNumStr(v, &ans, NULL, &error_abort);
>      g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
>      g_assert_cmpfloat(ans->u.n, ==, 42);
>      qapi_free_AltNumStr(ans);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltStrInt(v, &asi, NULL, &error_abort);
>      g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
>      g_assert_cmpint(asi->u.i, ==, 42);
>      qapi_free_AltStrInt(asi);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltIntNum(v, &ain, NULL, &error_abort);
>      g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
>      g_assert_cmpint(ain->u.i, ==, 42);
>      qapi_free_AltIntNum(ain);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltNumInt(v, &ani, NULL, &error_abort);
>      g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
>      g_assert_cmpint(ani->u.i, ==, 42);
>      qapi_free_AltNumInt(ani);
> -    visitor_input_teardown(data, NULL);
>
>      /* Parsing a double */
>
> @@ -434,21 +413,18 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>      error_free(err);
>      err = NULL;
>      qapi_free_AltStrBool(asb);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltStrNum(v, &asn, NULL, &error_abort);
>      g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
>      g_assert_cmpfloat(asn->u.n, ==, 42.5);
>      qapi_free_AltStrNum(asn);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltNumStr(v, &ans, NULL, &error_abort);
>      g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
>      g_assert_cmpfloat(ans->u.n, ==, 42.5);
>      qapi_free_AltNumStr(ans);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltStrInt(v, &asi, NULL, &err);
> @@ -456,21 +432,18 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>      error_free(err);
>      err = NULL;
>      qapi_free_AltStrInt(asi);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltIntNum(v, &ain, NULL, &error_abort);
>      g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
>      g_assert_cmpfloat(ain->u.n, ==, 42.5);
>      qapi_free_AltIntNum(ain);
> -    visitor_input_teardown(data, NULL);
>
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltNumInt(v, &ani, NULL, &error_abort);
>      g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
>      g_assert_cmpfloat(ani->u.n, ==, 42.5);
>      qapi_free_AltNumInt(ani);
> -    visitor_input_teardown(data, NULL);
>  }
>
>  static void test_native_list_integer_helper(TestInputVisitorData *data,
> diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
> index 9364843..8606111 100644
> --- a/tests/test-qmp-output-visitor.c
> +++ b/tests/test-qmp-output-visitor.c
> @@ -391,6 +391,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
>      qobj = QOBJECT(qdict);
>      visit_type_any(data->ov, &qobj, NULL, &err);
>      g_assert(!err);
> +    qobject_decref(qobj);
>      obj = qmp_output_get_qobject(data->qov);
>      g_assert(obj != NULL);
>      qdict = qobject_to_qdict(obj);
> @@ -411,7 +412,6 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
       qobj = qdict_get(qdict, "string");
       g_assert(qobj);
       qstring = qobject_to_qstring(qobj);
>      g_assert(qstring);
>      g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
>      qobject_decref(obj);
> -    qobject_decref(qobj);

Hmm...  obj is an alias for qdict, qobj is a member of qdict, freeing
obj frees qobj (unless there's another reference to qobj I can't see).
The line you delete then is a use-after-free bug that underflows the
reference counter.  Correct?

If yes, commit message should mention it briefly, because this isn't
just a leak.  Actually, I'd make it a separate commit, to keep commit
messages simple, particularly the headlines.

Aside: qobject_decref() neglects to assert(!obj || obj->refcnt > 0).

>  }
>
>  static void test_visitor_out_union_flat(TestOutputVisitorData *data,
> @@ -463,6 +463,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
>      g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);
>
>      qapi_free_UserDefAlternate(tmp);
> +    qobject_decref(arg);
>  }
>
>  static void test_visitor_out_empty(TestOutputVisitorData *data,

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing in test-qmp-*
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing " Eric Blake
@ 2015-11-04  8:40   ` Markus Armbruster
  2015-11-04 21:05     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04  8:40 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> By using &error_abort, we can avoid a local err variable in
> situations where we expect success.

This part is a no-brainer.

Bonus: before we abort(), we print

    Unexpected error in FUNC() at FILE:LINE:
    THE-ERROR-MESSAGE

to stdout on unexpected errors, which is a whole lot more useful than
what g_assert(!err) prints.

By the way: Coccinelle job :)

> By moving err into data, we can let test teardown take care
> of cleaning up any collected error; it also gives us fewer
> lines of code between repeated tests where init runs teardown
> on our behalf.

This part isn't as obvious.

Having two parts of differing obviousness indicates patch splitting
could make sense.  Especially when the parts are large and mechanical,
because reviewing large mechanical changes is much easier when there's
just one kind of it.

> Signed-off-by: Eric Blake <eblake@redhat.com>
[...]
> diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
> index 03c3682..d63c470 100644
[...]
> @@ -364,21 +341,17 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>      /* Parsing an int */
>
>      v = visitor_input_test_init(data, "42");
> -    visit_type_AltStrBool(v, &asb, NULL, &err);
> -    g_assert(err);
> -    error_free(err);
> -    err = NULL;
> +    visit_type_AltStrBool(v, &asb, NULL, &data->err);
> +    g_assert(data->err);
>      qapi_free_AltStrBool(asb);

This leaves data->err non-null.

>
>      /* FIXME: Order of alternate should not affect semantics; asn should
>       * parse the same as ans */
>      v = visitor_input_test_init(data, "42");
> -    visit_type_AltStrNum(v, &asn, NULL, &err);
> +    visit_type_AltStrNum(v, &asn, NULL, &data->err);

If visit_type_AltStrNum() errors out, its error will be thrown away by
its error_propagate(), because data->err is already non-null.

If it fails to error out, its error_propagate() does nothing, and we
won't detect the test failure.

Your patch makes forgetting to reset err an even easier mistake to make,
because it removes most of the error_free() that serve as reminders.

Is it a good idea anyway?  Let's discuss before I check the remainder of
this patch.

>      /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
>      /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
> -    g_assert(err);
> -    error_free(err);
> -    err = NULL;
> +    g_assert(data->err);
>      qapi_free_AltStrNum(asn);
>
>      v = visitor_input_test_init(data, "42");
[...]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output Eric Blake
@ 2015-11-04  9:04   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04  9:04 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Suggest "qapi: Test alternate output visitor with boxed type"

Eric Blake <eblake@redhat.com> writes:

> The testsuite was only covering that we could output a built-in
> branch of an alternate; make sure that things still work even

Well, 'str' is built-in, too.  "'int' branch"?

> when a branch involves allocation, to ensure that we don't leak
> when run under valgrind.

More pedantry: we'd leak when not running under valgrind just as much.

> Update to modern style of g_new0() over g_malloc0() while
> touching it.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Patch looks good.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse Eric Blake
@ 2015-11-04  9:07   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04  9:07 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Our generated list visitors have the same problem as has been
> mentioned elsewhere (see commit 2f52e20): they allocate data
> even on failure. An upcoming patch will correct things to
> provide saner guarantees, but first we need to expose the
> behavior in the testsuite to ensure we aren't introducing any
> memory usage bugs.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

This commit documents the problem and adds test coverage.  Commit
2f52e20 only documented.  Do we have test coverage?

Patch looks good.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays Eric Blake
@ 2015-11-04  9:11   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04  9:11 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Our testsuite had no coverage of empty arrays, nor of what
> happens when the input does not match the expected type.
> Useful to have, especially if we start changing the visitor
> contracts.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: move earlier in series (was 16/17)
> v8: no change
> v7: no change
> v6: new patch
> ---
>  tests/test-qmp-input-visitor.c | 51 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)

Should we update test-qmp-input-strict.c as well?

Patch looks good.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting Eric Blake
@ 2015-11-04 10:09   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 10:09 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> qapi-code-gen.txt already claims that types, commands, and
> events share a common namespace; set this in stone by further
> documenting that our introspection output will never have
> collisions with the same name tied to more than one meta-type.
>
> Our largest QMP enum currently has 125 values, our largest
> object type has 27 members, and the mean for each is less than
> 10.  These sizes are small enough that the per-element overhead
> of O(log n) binary searching probably outweighs the speed
> possible with direct O(n) linear searching (a better algorithm
> with more overhead will only beat a leaner naive algorithm only
> as you scale to larger input sizes).
>
> Arguably, the overall SchemaInfo array could be sorted by name;
> there, we currently have 531 entities, large enough for a binary
> search to be faster than linear.  However, remember that we have
> mutually-recursive types, which means there is no topological
> ordering that will allow clients to learn all information about
> that type in a single linear pass; thus clients will want to do
> random access over the data, and they will probably read the
> introspection output into a hashtable for O(1) lookup rather
> than O(log n) binary searching, at which point, pre-sorting our
> introspection output doesn't help the client.
>
> Finally, I am not sure how to guarantee that python sorts strings
> for the C locale even if the generator is run under a different
> locale.

Python's "Sorting HOW TO" advises:

    For locale aware sorting, use locale.strxfrm() for a key function or
    locale.strcoll() for a comparison function.

https://docs.python.org/2.7/howto/sorting.html#odd-and-ends

Explicit, opt-in locale-dependence sure feels a lot cleaner and safer
than the historical mess we have in C.


>          Our current output order is deterministic (based on the
> order present in .json files, even if that order has no inherent
> bearing on how a client will present their QMP commands),

Actually no longer the case:

    def visit(self, visitor):
        visitor.visit_begin(self)
        for (name, entity) in sorted(self._entity_dict.items()):
            if visitor.visit_needed(entity):
                entity.visit(visitor)
        visitor.visit_end()

Dates back to commit 3f7dc21 "qapi: New QAPISchemaVisitor".  Without
sorting, we'd some unpredictable order.  I could've used OrderedDict
instead, preserving insertion order.

>                                                           while
> sorting data risks non-determinism if the generator is subject to
> any locale differences.
>
> For these reasons, we simply document that clients should not
> rely on any particular order of items in introspection output.
> Additionally, this gives us the freedom to later change our mind,
> so that we could rearrange output in a different order than the
> way it was listed in the .json file, without breaking any client
> that was already aware it had to do a linear search.
>
> Document these conventions, so that clients will know what can
> and cannot be relied on.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: retitle; and swing in the opposite direction: give the user
> no guarantee about order
> v8: no change
> v7: tweak commit wording
> v6: no change from v5
> ---
>  docs/qapi-code-gen.txt | 19 +++++++++++++++----
>  qapi/introspect.json   | 21 ++++++++++++++++-----
>  2 files changed, 31 insertions(+), 9 deletions(-)
>
> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
> index ba29bc6..20e6907 100644
> --- a/docs/qapi-code-gen.txt
> +++ b/docs/qapi-code-gen.txt
> @@ -516,6 +516,10 @@ query-qmp-schema.  QGA currently doesn't support introspection.
>
>  query-qmp-schema returns a JSON array of SchemaInfo objects.  These
>  objects together describe the wire ABI, as defined in the QAPI schema.
> +There is no specified order to the SchemaInfo objects returned; a
> +client must search for a particular name throughout the entire array
> +to learn more about that name, but is at least guaranteed that there
> +will be no collisions between type, command, and event names.

I would've omitted the "client must search" clause, but I habitually
write subtle contracts that need to be read slowly and carefully.  Feel
free to keep it.

>  However, the SchemaInfo can't reflect all the rules and restrictions
>  that apply to QMP.  It's interface introspection (figuring out what's
> @@ -596,7 +600,9 @@ any.  Each element is a JSON object with members "name" (the member's
>  name), "type" (the name of its type), and optionally "default".  The
>  member is optional if "default" is present.  Currently, "default" can
>  only have value null.  Other values are reserved for future
> -extensions.
> +extensions.  The "members" array is in no particular order; clients
> +must search every member when learning whether a particular member is
> +supported.

Nitpick: clients must search the object, not every member.

>  Example: the SchemaInfo for MyType from section Struct types
>
> @@ -610,7 +616,9 @@ Example: the SchemaInfo for MyType from section Struct types
>  "variants" is a JSON array describing the object's variant members.
>  Each element is a JSON object with members "case" (the value of type
>  tag this element applies to) and "type" (the name of an object type
> -that provides the variant members for this type tag value).
> +that provides the variant members for this type tag value).  The
> +"variants" array is in no particular order, and is not guaranteed to
> +list cases in the same order as the corresponding "tag" enum type.
>
>  Example: the SchemaInfo for flat union BlockdevOptions from section
>  Union types
> @@ -651,7 +659,8 @@ Union types
>  The SchemaInfo for an alternate type has meta-type "alternate", and
>  variant member "members".  "members" is a JSON array.  Each element is
>  a JSON object with member "type", which names a type.  Values of the
> -alternate type conform to exactly one of its member types.
> +alternate type conform to exactly one of its member types.  There is
> +no guarantee on the order in which "members" will be listed.
>
>  Example: the SchemaInfo for BlockRef from section Alternate types
>
> @@ -673,7 +682,9 @@ Example: the SchemaInfo for ['str']
>        "element-type": "str" }
>
>  The SchemaInfo for an enumeration type has meta-type "enum" and
> -variant member "values".
> +variant member "values".  The values are listed in no particular
> +order; clients must search every value when learning whether a
> +particular value is supported.

Similar nitpick.

>  Example: the SchemaInfo for MyEnum from section Enumeration types
>
> diff --git a/qapi/introspect.json b/qapi/introspect.json
> index cc50dc6..f86d552 100644
> --- a/qapi/introspect.json
> +++ b/qapi/introspect.json
> @@ -25,6 +25,10 @@
>  # Returns: array of @SchemaInfo, where each element describes an
>  # entity in the ABI: command, event, type, ...
>  #
> +# The order of the various SchemaInfo is unspecified; however, all
> +# names are guaranteed to be unique (no name will be duplicated with
> +# different meta-types).
> +#
>  # Note: the QAPI schema is also used to help define *internal*
>  # interfaces, by defining QAPI types.  These are not part of the QMP
>  # wire ABI, and therefore not returned by this command.
> @@ -78,7 +82,8 @@
>  #        Commands and events have the name defined in the QAPI schema.
>  #        Unlike command and event names, type names are not part of
>  #        the wire ABI.  Consequently, type names are meaningless
> -#        strings here.
> +#        strings here, although they are still guaranteed unique
> +#        regardless of @meta-type.
>  #
>  # All references to other SchemaInfo are by name.
>  #
> @@ -130,7 +135,9 @@
>  #
>  # Additional SchemaInfo members for meta-type 'enum'.
>  #
> -# @values: the enumeration type's values.
> +# @values: the enumeration type's values.  The values are in no particular
> +#          order, so clients must search every value when learning if a
> +#          particular value is present.

I'd drop the ", so clients must search" part as obvious.

>  #
>  # Values of this type are JSON string on the wire.
>  #
> @@ -158,14 +165,18 @@
>  #
>  # Additional SchemaInfo members for meta-type 'object'.
>  #
> -# @members: the object type's (non-variant) members.
> +# @members: the object type's (non-variant) members.  The members are
> +#           in no particular order, so clients must search every member
> +#           when learning if a particular member is present.

Likewise.

>  #
>  # @tag: #optional the name of the member serving as type tag.
>  #       An element of @members with this name must exist.
>  #
>  # @variants: #optional variant members, i.e. additional members that
>  #            depend on the type tag's value.  Present exactly when
> -#            @tag is present.
> +#            @tag is present.  The variants are in no particular order,
> +#            and may even differ from the order of the values of the
> +#            enum type of the @tag.
>  #
>  # Values of this type are JSON object on the wire.
>  #
> @@ -219,7 +230,7 @@
>  #
>  # Additional SchemaInfo members for meta-type 'alternate'.
>  #
> -# @members: the alternate type's members.
> +# @members: the alternate type's members, in no particular order.
>  #           The members' wire encoding is distinct, see
>  #           docs/qapi-code-gen.txt section Alternate types.
>  #

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C)
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (26 preceding siblings ...)
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 27/27] qapi: Simplify visits of optional fields Eric Blake
@ 2015-11-04 10:22 ` Markus Armbruster
  2015-11-04 15:06   ` Eric Blake
  2015-11-05 19:45 ` Markus Armbruster
  28 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 10:22 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

Eric Blake <eblake@redhat.com> writes:

> No pending prerequisites; based on qemu.git master
>
> Also available as a tag at this location:
> git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv9c
>
> and will soon be part of my branch with the rest of the v5 series, at:
> http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi
>
> v9 notes:
> More patches added, and several reorganized.  Lots of new patches
> from Markus, although not in the order originally proposed.
>
> The first 8 patches are fairly straightforward, and could probably
> be taken as-is. Patch 9 is a rewrite of v8 4/17, but in the opposite
> direction (document that no sorting is done, rather than attempting
> to sort), so it may need further fine-tuning.  Patches 12-21
> represents a fusion of Markus' and my attempts to rewrite v5 7/17
> into a more-reviewable set of patches, and caused further churn
> later in the series.

Hard freeze is next week.

PATCH 01-07+09 are simple cleanups, bug fixes tests and documentation,
which makes them obvious candidates for 2.5.

PATCH 08 is a feature, but harmless enough.  I still don't like it much,
but I said I'll take it.  Best before the hard freeze, though.

The remainder of the series doesn't feel like post hard freeze material.
What do you think?

I don't have the complete picture of your queue.  Please double-check
whether you got anything in it that affects introspection, because
changing introspection will become super awkward as soon as 2.5 is out.

> Patch 23 still uses tag_member.type == None; I ran out of time to
> work on Markus' idea of providing an instance of QAPISchemaBuiltinType
> to fill the role for 'qtype_code' without being exposed through .json
> files and without breaking the invariant of a valid member.type after
> check(), and wanted to get the rest of the series started under revew.
> So I may need a followup patch or even a v10 of the later half of
> this series after exploring that idea more.

I'll continue reviewing meanwhile.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members Eric Blake
@ 2015-11-04 11:02   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 11:02 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> We were previously creating all unions with an empty list for
> local_members.  However, it will make it easier to unify struct
> and union generation if we include the generated tag member in
> local_members.  That way, we can have a common code pattern:
> visit the base (if any), visit the local members (if any), visit
> the variants (if any).  The local_members of a flat union
> remains empty (because the discriminator is already visited as
> part of the base).  Then, by visiting tag_member.check() during
> AlternateType.check(), we no longer need to call it during
> Variants.check().

Moving tag_member.check() could perhaps be a separate patch.  But it's
okay as is.

> The various front end entities now exist as follows:
> struct: optional base, optional local_members, no variants
> simple union: no base, one-element local_members, variants with tag_member
>   from local_members
> flat union: base, no local_members, variants with tag_member from base
> alternate: no base, no local_members, variants

Ultimately, I'd like a single object type.  Then this becomes:

    object: optional base, optional local_members,
        optional variants with tag_member from base or local_members
    alternate: only variants

In both cases, I view the tag member as belonging to the outer
container, not variants:

    object stores it like any other member, and variants.tag_member
        merely identifies the member that serves as tag
    alternate doesn't store it member in self, but simply uses
        self.variants.tag_member instead.

Perhaps QAPISchemaObjectTypeVariants should be inlined.

Just rambling, the commit message is fine as is.

> With the new local members, we require a bit of finesse to
> avoid assertions in the clients.
>
> No change to generated code.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Patch looks good.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions Eric Blake
@ 2015-11-04 13:30   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 13:30 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> From: Markus Armbruster <armbru@redhat.com>
>
> Union tag values can't clash with member names in generated C anymore
> since commit e4ba22b, but QAPISchemaObjectTypeVariant.check() still
> asserts they don't.  Drop it.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Message-Id: <1446559499-26984-1-git-send-email-armbru@redhat.com>
> [A later patch will still need to pass vseen from Variants.check()
> to Variant.check(), so to avoid churn, change the cleanup to occur
> lower in Variant.check()]

Leaves QAPISchemaObjectTypeVariant.check() parameter seen temporarily
unused.  Okay, as long as we get in the patch that again uses it in the
same batch.

> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: new patch
> ---
>  scripts/qapi.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index a814e20..145dbfe 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1067,7 +1067,7 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>          QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
>
>      def check(self, schema, tag_type, seen):
> -        QAPISchemaObjectTypeMember.check(self, schema, [], seen)
> +        QAPISchemaObjectTypeMember.check(self, schema, [], {})
>          assert self.name in tag_type.values
>
>      # This function exists to support ugly simple union special cases

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
@ 2015-11-04 13:36   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 13:36 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> From: Markus Armbruster <armbru@redhat.com>
>
> This hunk
>
>     @@ -964,6 +965,7 @@ class QAPISchemaObjectType(QAPISchemaType):
>                  members = []
>              seen = {}
>              for m in members:
>     +            assert c_name(m.name) not in seen
>                  seen[m.name] = m
>              for m in self.local_members:
>                  m.check(schema, members, seen)
>
> is plainly broken.
>
> Asserting the members inherited from base don't clash is somewhat
> redundant, because self.base.check() just checked that.  But it
> doesn't hurt.
>
> The idea to use c_name(m.name) instead of m.name for collision
> checking is sound, because we need to catch clashes between the m.name
> and between the c_name(m.name), and when two m.name clash, then their
> c_name() also clash.
>
> However, using c_name(m.name) instead of m.name in one of several
> places doesn't work.  See the very next line.
>
> Keep the assertion, but drop the c_name() for now.  A future commit
> will bring it back.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Message-Id: <1446559499-26984-4-git-send-email-armbru@redhat.com>
> [change TAB to space]

In the commit message.  You had me wondering briefly whether my Emacs
configuration to avoid tabs in QEMU code failed :)

> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: new patch
> ---
>  scripts/qapi.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 145dbfe..c910715 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -987,7 +987,7 @@ class QAPISchemaObjectType(QAPISchemaType):
>              members = []
>          seen = {}
>          for m in members:
> -            assert c_name(m.name) not in seen
> +            assert m.name not in seen
>              seen[m.name] = m
>          for m in self.local_members:
>              m.check(schema, members, seen)

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit Eric Blake
@ 2015-11-04 13:43   ` Markus Armbruster
  2015-11-04 23:03     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 13:43 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> From: Markus Armbruster <armbru@redhat.com>
>
> QAPISchemaObjectTypeVariants.check() parameter members is no
> longer used, drop it.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Message-Id: <1446559499-26984-3-git-send-email-armbru@redhat.com>
> [Variant.check(seen) is used after all, so reword and reduce scope
> of this patch; rearrange later in the series]

Don't you need to update the subject?  My "previous commit" was "qapi:
Simplify QAPISchemaObjectTypeMember.check()", while yours is "qapi:
Eliminate QAPISchemaObjectType.check() variable members".

Not sure what moving my two patches apart buys you :)

> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: new patch
> ---
>  scripts/qapi.py | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 4019389..3af5edb 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -991,7 +991,7 @@ class QAPISchemaObjectType(QAPISchemaType):
>              assert m.name not in seen
>              seen[m.name] = m
>          if self.variants:
> -            self.variants.check(schema, [], seen)
> +            self.variants.check(schema, seen)
>          self.members = seen.values()
>
>      def is_implicit(self):
> @@ -1046,7 +1046,7 @@ class QAPISchemaObjectTypeVariants(object):
>          self.tag_member = tag_member
>          self.variants = variants
>
> -    def check(self, schema, members, seen):
> +    def check(self, schema, seen):
>          # seen is non-empty for unions, empty for alternates
>          if self.tag_name:    # flat union
>              self.tag_member = seen[self.tag_name]
> @@ -1086,7 +1086,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
>
>      def check(self, schema):
>          self.variants.tag_member.check(schema)
> -        self.variants.check(schema, [], {})
> +        self.variants.check(schema, {})
>
>      def json_type(self):
>          return 'value'

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C)
  2015-11-04 10:22 ` [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Markus Armbruster
@ 2015-11-04 15:06   ` Eric Blake
  2015-11-04 18:04     ` Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04 15:06 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 4395 bytes --]

On 11/04/2015 03:22 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> No pending prerequisites; based on qemu.git master
>>
>> Also available as a tag at this location:
>> git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv9c
>>
>> and will soon be part of my branch with the rest of the v5 series, at:
>> http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi
>>
>> v9 notes:
>> More patches added, and several reorganized.  Lots of new patches
>> from Markus, although not in the order originally proposed.
>>
>> The first 8 patches are fairly straightforward, and could probably
>> be taken as-is. Patch 9 is a rewrite of v8 4/17, but in the opposite
>> direction (document that no sorting is done, rather than attempting
>> to sort), so it may need further fine-tuning.  Patches 12-21
>> represents a fusion of Markus' and my attempts to rewrite v5 7/17
>> into a more-reviewable set of patches, and caused further churn
>> later in the series.
> 
> Hard freeze is next week.
> 
> PATCH 01-07+09 are simple cleanups, bug fixes tests and documentation,
> which makes them obvious candidates for 2.5.
> 
> PATCH 08 is a feature, but harmless enough.  I still don't like it much,
> but I said I'll take it.  Best before the hard freeze, though.
> 
> The remainder of the series doesn't feel like post hard freeze material.
> What do you think?

My patches _were_ posted prior to soft freeze, even if the initial
review did not happen then; so on that grounds, you can continue to take
as much as you want until hard freeze actually happens. But it gets
harder and harder to justify, and the process definitely changes when
hard freeze hits (no features, regardless of when they were first
posted, but only bug fixes).

So it sounds like we won't get all of my qapi queue in 2.5.  My goal had
originally been to get netdev_add to be fully introspectible, but that's
still more than 20 patches away; and the status quo of learning about
the netdev_add command being less than perfect isn't a regression per
se.  So you are right that the later patches in my series can probably
wait until 2.6.  I'm fine with your judgment on where you want to draw
the line of what will make soft freeze.

> 
> I don't have the complete picture of your queue.  Please double-check
> whether you got anything in it that affects introspection, because
> changing introspection will become super awkward as soon as 2.5 is out.

Patches 8 and 9 in this series have to make 2.5 (and we're in agreement
that while patch 9 is not quite baked in this v9 spin, we should still
have plenty of time to get it done before hard freeze).  The only other
pending patch I have previously posted from my queue that touches
qapi-introspect.py does not actually change introspection output:

http://repo.or.cz/qemu/ericb.git/commitdiff/5c25f6eb95, first posted at:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05441.html

so we should be fine on that front.  Introspection itself is fine, and
the bulk of my focus has been on cleanups to the internals and
extensions of the internals to allow netdev_add to be introspectible.

I can certainly browse through my pending queue to double-check if any
of the patches there qualify as bug fixes that are safe even during hard
freeze, and focus on hoisting them to the front of the review queue,
once we get 1-9 of this series ready for pull.  And obviously that
should mean user-triggerable bugs under existing .json files (patches
like 24/27 that fix design bugs in the generator, but which don't affect
any user besides the testsuite, aren't hard-freeze material - either it
makes soft freeze or it defers to 2.6).

> 
>> Patch 23 still uses tag_member.type == None; I ran out of time to
>> work on Markus' idea of providing an instance of QAPISchemaBuiltinType
>> to fill the role for 'qtype_code' without being exposed through .json
>> files and without breaking the invariant of a valid member.type after
>> check(), and wanted to get the rest of the series started under revew.
>> So I may need a followup patch or even a v10 of the later half of
>> this series after exploring that idea more.
> 
> I'll continue reviewing meanwhile.
> 

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-*
  2015-11-04  8:19   ` Markus Armbruster
@ 2015-11-04 17:24     ` Eric Blake
  2015-11-04 17:44       ` Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04 17:24 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 5730 bytes --]

On 11/04/2015 01:19 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> Make valgrind happy with the current state of the tests, so that
>> it is easier to see if future patches introduce new memory problems
>> without being drowned in noise.  Many of the leaks were due to
>> calling a second init without tearing down the data from an earlier
>> visit.  But since teardown is already idempotent, and we already
>> register teardown as part of input_visitor_test_add(), it is nicer
>> to just make init() safe to call multiple times than it is to have
>> to make all tests call teardown.
>>
>> Another common leak was forgetting to clean up an error object,
>> after testing that an error was raised.
>>
>> Another leak was in test_visitor_in_struct_nested(), failing to
>> clean the base member of UserDefTwo.  Cleaning that up left
>> check_and_free_str() as dead code (since using the qapi_free_*
>> takes care of recursion, and we don't want double frees).
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>
>> ---
>> v9: move earlier in series (was 13/17)
>> v8: no change
>> v7: no change
>> v6: make init repeatable rather than adding teardown everywhere,
>> fix additional leak with UserDefTwo base, plug additional files
>> ---
>>  tests/test-qmp-input-strict.c   | 10 ++++++++++
>>  tests/test-qmp-input-visitor.c  | 41 +++++++----------------------------------
>>  tests/test-qmp-output-visitor.c |  3 ++-
>>  3 files changed, 19 insertions(+), 35 deletions(-)
> 
> No leaks to plug in test/-qmp-commands.c and test-qmp-event.c?

Didn't check. I'll do that.

> 
>> diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
>> index b44184f..910e2f9 100644
>> --- a/tests/test-qmp-input-strict.c
>> +++ b/tests/test-qmp-input-strict.c
>> @@ -77,6 +77,8 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
>>  {
>>      Visitor *v;
>>
>> +    validate_teardown(data, NULL);
>> +
>>      data->obj = qobject_from_json(json_string);
>>      g_assert(data->obj != NULL);
>>
> 
> A test added with validate_test_add() may call validate_test_init_raw()
> any number of time.  Since validate_test_add() passes
> validate_teardown() as fixture teardown function, the last one will be
> cleaned up on test finalization.  The others will be cleaned up by the
> next validate_test_init_raw().  Okay.  Actually, the whole fixture
> business starts to make sense only now.
> 
> But why only validate_test_init_raw() and not validate_test_init()?
> 

Umm, because I didn't look, and just plugged holes? Will fix.

> The two duplicate code, by the way.

And the fix will probably be by having one call the other.

> 
>> @@ -193,6 +195,8 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
>>
>>      visit_type_TestStruct(v, &p, NULL, &err);
>>      g_assert(err);
>> +    error_free(err);
>> +    /* FIXME: visitor should not allocate p when returning error */
> 
> Indeed.
> 
> Recommend to always mention new FIXMEs in the commit message.

This fixme is part of the answer to your question about 6/27 - we do
have test coverage on non-arrays.


>> +++ b/tests/test-qmp-input-visitor.c
>> @@ -46,6 +46,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
>>      Visitor *v;
>>      va_list ap;
>>
>> +    visitor_input_teardown(data, NULL);
>> +
>>      va_start(ap, json_string);
>>      data->obj = qobject_from_jsonv(json_string, &ap);
>>      va_end(ap);
> 
> Here, you add it to visitor_input_test_init(), but not
> visitor_input_test_init_raw().
> 
> These two duplicate code, too.

Looks like I get to fix this too.


>> +++ b/tests/test-qmp-output-visitor.c
>> @@ -391,6 +391,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
>>      qobj = QOBJECT(qdict);

Here, qobj is an alias to qdict...

>>      visit_type_any(data->ov, &qobj, NULL, &err);
>>      g_assert(!err);
>> +    qobject_decref(qobj);
>>      obj = qmp_output_get_qobject(data->qov);
>>      g_assert(obj != NULL);
>>      qdict = qobject_to_qdict(obj);
>> @@ -411,7 +412,6 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
>        qobj = qdict_get(qdict, "string");

...but then we are reassigning it to instead be an alias within qdict.

>        g_assert(qobj);
>        qstring = qobject_to_qstring(qobj);
>>      g_assert(qstring);
>>      g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
>>      qobject_decref(obj);
>> -    qobject_decref(qobj);

Dereferencing a subset of the qdict leaks the overal qdict.

> 
> Hmm...  obj is an alias for qdict, qobj is a member of qdict, freeing
> obj frees qobj (unless there's another reference to qobj I can't see).
> The line you delete then is a use-after-free bug that underflows the
> reference counter.  Correct?

Valgrind complained about a leak, not a use-after-free. But there indeed
may be more than one issue that got solved by correctly dropping the
reference at the right point in time, prior to reassigning qobj for use
as pointing to a different portion of the qdict.

> 
> If yes, commit message should mention it briefly, because this isn't
> just a leak.  Actually, I'd make it a separate commit, to keep commit
> messages simple, particularly the headlines.

I'll have to refresh my memory what else is going on, but I can indeed
split this out if it is different than a simple memleak fix.

> 
> Aside: qobject_decref() neglects to assert(!obj || obj->refcnt > 0).

Sounds like a separate patch.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-*
  2015-11-04 17:24     ` Eric Blake
@ 2015-11-04 17:44       ` Markus Armbruster
  2015-11-05 13:09         ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 17:44 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> On 11/04/2015 01:19 AM, Markus Armbruster wrote:
>> Eric Blake <eblake@redhat.com> writes:
>> 
>>> Make valgrind happy with the current state of the tests, so that
>>> it is easier to see if future patches introduce new memory problems
>>> without being drowned in noise.  Many of the leaks were due to
>>> calling a second init without tearing down the data from an earlier
>>> visit.  But since teardown is already idempotent, and we already
>>> register teardown as part of input_visitor_test_add(), it is nicer
>>> to just make init() safe to call multiple times than it is to have
>>> to make all tests call teardown.
>>>
>>> Another common leak was forgetting to clean up an error object,
>>> after testing that an error was raised.
>>>
>>> Another leak was in test_visitor_in_struct_nested(), failing to
>>> clean the base member of UserDefTwo.  Cleaning that up left
>>> check_and_free_str() as dead code (since using the qapi_free_*
>>> takes care of recursion, and we don't want double frees).
>>>
>>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>>
>>> ---
>>> v9: move earlier in series (was 13/17)
>>> v8: no change
>>> v7: no change
>>> v6: make init repeatable rather than adding teardown everywhere,
>>> fix additional leak with UserDefTwo base, plug additional files
>>> ---
>>>  tests/test-qmp-input-strict.c   | 10 ++++++++++
>>>  tests/test-qmp-input-visitor.c | 41
>>> +++++++----------------------------------
>>>  tests/test-qmp-output-visitor.c |  3 ++-
>>>  3 files changed, 19 insertions(+), 35 deletions(-)
>> 
>> No leaks to plug in test/-qmp-commands.c and test-qmp-event.c?
>
> Didn't check. I'll do that.
>
>> 
>>> diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
>>> index b44184f..910e2f9 100644
>>> --- a/tests/test-qmp-input-strict.c
>>> +++ b/tests/test-qmp-input-strict.c
>>> @@ -77,6 +77,8 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
>>>  {
>>>      Visitor *v;
>>>
>>> +    validate_teardown(data, NULL);
>>> +
>>>      data->obj = qobject_from_json(json_string);
>>>      g_assert(data->obj != NULL);
>>>
>> 
>> A test added with validate_test_add() may call validate_test_init_raw()
>> any number of time.  Since validate_test_add() passes
>> validate_teardown() as fixture teardown function, the last one will be
>> cleaned up on test finalization.  The others will be cleaned up by the
>> next validate_test_init_raw().  Okay.  Actually, the whole fixture
>> business starts to make sense only now.
>> 
>> But why only validate_test_init_raw() and not validate_test_init()?
>> 
>
> Umm, because I didn't look, and just plugged holes? Will fix.
>
>> The two duplicate code, by the way.
>
> And the fix will probably be by having one call the other.
>
>> 
>>> @@ -193,6 +195,8 @@ static void
>>> test_validate_fail_struct(TestInputVisitorData *data,
>>>
>>>      visit_type_TestStruct(v, &p, NULL, &err);
>>>      g_assert(err);
>>> +    error_free(err);
>>> +    /* FIXME: visitor should not allocate p when returning error */
>> 
>> Indeed.
>> 
>> Recommend to always mention new FIXMEs in the commit message.
>
> This fixme is part of the answer to your question about 6/27 - we do
> have test coverage on non-arrays.

What we (royal we) don't have is memory going back from 06/27 to 03/27
%-}

>>> +++ b/tests/test-qmp-input-visitor.c
>>> @@ -46,6 +46,8 @@ Visitor
>>> *visitor_input_test_init(TestInputVisitorData *data,
>>>      Visitor *v;
>>>      va_list ap;
>>>
>>> +    visitor_input_teardown(data, NULL);
>>> +
>>>      va_start(ap, json_string);
>>>      data->obj = qobject_from_jsonv(json_string, &ap);
>>>      va_end(ap);
>> 
>> Here, you add it to visitor_input_test_init(), but not
>> visitor_input_test_init_raw().
>> 
>> These two duplicate code, too.
>
> Looks like I get to fix this too.
>
>
>>> +++ b/tests/test-qmp-output-visitor.c
>>> @@ -391,6 +391,7 @@ static void
>>> test_visitor_out_any(TestOutputVisitorData *data,
>>>      qobj = QOBJECT(qdict);
>
> Here, qobj is an alias to qdict...
>
>>>      visit_type_any(data->ov, &qobj, NULL, &err);
>>>      g_assert(!err);
>>> +    qobject_decref(qobj);
>>>      obj = qmp_output_get_qobject(data->qov);
>>>      g_assert(obj != NULL);
>>>      qdict = qobject_to_qdict(obj);
>>> @@ -411,7 +412,6 @@ static void
>>> test_visitor_out_any(TestOutputVisitorData *data,
>>        qobj = qdict_get(qdict, "string");
>
> ...but then we are reassigning it to instead be an alias within qdict.
>
>>        g_assert(qobj);
>>        qstring = qobject_to_qstring(qobj);
>>>      g_assert(qstring);
>>>      g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
>>>      qobject_decref(obj);
>>> -    qobject_decref(qobj);
>
> Dereferencing a subset of the qdict leaks the overal qdict.
>
>> 
>> Hmm...  obj is an alias for qdict, qobj is a member of qdict, freeing
>> obj frees qobj (unless there's another reference to qobj I can't see).
>> The line you delete then is a use-after-free bug that underflows the
>> reference counter.  Correct?
>
> Valgrind complained about a leak, not a use-after-free. But there indeed
> may be more than one issue that got solved by correctly dropping the
> reference at the right point in time, prior to reassigning qobj for use
> as pointing to a different portion of the qdict.
>
>> 
>> If yes, commit message should mention it briefly, because this isn't
>> just a leak.  Actually, I'd make it a separate commit, to keep commit
>> messages simple, particularly the headlines.
>
> I'll have to refresh my memory what else is going on, but I can indeed
> split this out if it is different than a simple memleak fix.

I really, really like bug fixes coming with an impact assessment.
However, since this is just *tests*, I recommend *not* to spend time on
figuring out what exactly was broken, and simply adjust the commit
messages claims a bit.

>> Aside: qobject_decref() neglects to assert(!obj || obj->refcnt > 0).
>
> Sounds like a separate patch.

Definitely.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C)
  2015-11-04 15:06   ` Eric Blake
@ 2015-11-04 18:04     ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 18:04 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

Eric Blake <eblake@redhat.com> writes:

> On 11/04/2015 03:22 AM, Markus Armbruster wrote:
>> Eric Blake <eblake@redhat.com> writes:
>> 
>>> No pending prerequisites; based on qemu.git master
>>>
>>> Also available as a tag at this location:
>>> git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv9c
>>>
>>> and will soon be part of my branch with the rest of the v5 series, at:
>>> http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi
>>>
>>> v9 notes:
>>> More patches added, and several reorganized.  Lots of new patches
>>> from Markus, although not in the order originally proposed.
>>>
>>> The first 8 patches are fairly straightforward, and could probably
>>> be taken as-is. Patch 9 is a rewrite of v8 4/17, but in the opposite
>>> direction (document that no sorting is done, rather than attempting
>>> to sort), so it may need further fine-tuning.  Patches 12-21
>>> represents a fusion of Markus' and my attempts to rewrite v5 7/17
>>> into a more-reviewable set of patches, and caused further churn
>>> later in the series.
>> 
>> Hard freeze is next week.
>> 
>> PATCH 01-07+09 are simple cleanups, bug fixes tests and documentation,
>> which makes them obvious candidates for 2.5.
>> 
>> PATCH 08 is a feature, but harmless enough.  I still don't like it much,
>> but I said I'll take it.  Best before the hard freeze, though.
>> 
>> The remainder of the series doesn't feel like post hard freeze material.
>> What do you think?
>
> My patches _were_ posted prior to soft freeze, even if the initial
> review did not happen then; so on that grounds, you can continue to take
> as much as you want until hard freeze actually happens. But it gets
> harder and harder to justify, and the process definitely changes when
> hard freeze hits (no features, regardless of when they were first
> posted, but only bug fixes).

We're on the same page.

> So it sounds like we won't get all of my qapi queue in 2.5.  My goal had
> originally been to get netdev_add to be fully introspectible, but that's
> still more than 20 patches away; and the status quo of learning about
> the netdev_add command being less than perfect isn't a regression per
> se.  So you are right that the later patches in my series can probably
> wait until 2.6.  I'm fine with your judgment on where you want to draw
> the line of what will make soft freeze.

It would've been nice to get through the complete queue, but I'm a
horribly picky reviewer.  On the plus side, it hasn't been just for
making patches prettier; we've found quite a few additional things to
improve.

>> I don't have the complete picture of your queue.  Please double-check
>> whether you got anything in it that affects introspection, because
>> changing introspection will become super awkward as soon as 2.5 is out.
>
> Patches 8 and 9 in this series have to make 2.5 (and we're in agreement
> that while patch 9 is not quite baked in this v9 spin, we should still
> have plenty of time to get it done before hard freeze).  The only other
> pending patch I have previously posted from my queue that touches
> qapi-introspect.py does not actually change introspection output:
>
> http://repo.or.cz/qemu/ericb.git/commitdiff/5c25f6eb95, first posted at:
> https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05441.html
>
> so we should be fine on that front.  Introspection itself is fine, and
> the bulk of my focus has been on cleanups to the internals and
> extensions of the internals to allow netdev_add to be introspectible.

That's reassuring.

> I can certainly browse through my pending queue to double-check if any
> of the patches there qualify as bug fixes that are safe even during hard
> freeze, and focus on hoisting them to the front of the review queue,
> once we get 1-9 of this series ready for pull.  And obviously that
> should mean user-triggerable bugs under existing .json files (patches
> like 24/27 that fix design bugs in the generator, but which don't affect
> any user besides the testsuite, aren't hard-freeze material - either it
> makes soft freeze or it defers to 2.6).

Your choice.  I probably wouldn't, because I figure that bug fixes that
impact users are pretty unlikely.  Fixes for stuff that breaks when you
do certain things in a schema we don't currently do are not critical,
and delaying them to the next cycle is just fine with me.

[...]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches Eric Blake
@ 2015-11-04 19:01   ` Markus Armbruster
  2015-11-04 23:11     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 19:01 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Right now, our ad hoc parser ensures that we cannot have a
> flat union that introduces any qapi member names that would
> conflict with the non-variant qapi members already present
> from the union's base type (see flat-union-clash-member.json).
> We want QAPISchema*.check() to make the same check, so we can
> later reduce some of the ad hoc checks.
>
> We already ensure that all branches of a flat union are qapi
> structs with no variants, at which point those members appear
> in the same JSON object as all non-variant members.  And we
> already have a map 'seen' of all non-variant members passed
> in to QAPISchemaObjectTypeVariants.check(), which we clone for
> each particular variant (since the members of one variant do
> not clash with another).  So all that is additionally needed
> is to actually check the each member of the variant type do
> not add any collisions.
>
> In general, a type used as a branch of a flat union cannot
> also be the base type of the flat union, so even though we are
> adding a call to variant.type.check() in order to populate
> variant.type.members, this is merely a case of gaining
> topological sorting of how types are visited (and type.check()
> is already set up to allow multiple calls due to base types).
>
> For simple unions, the same code happens to work by design,
> because of our synthesized wrapper classes (however, the
> wrapper has a single member 'data' which will never collide
> with the one non-variant member 'type', so it doesn't really
> matter).
>
> But for alternates, we do NOT want to check the type members
> for adding collisions (an alternate has no parent JSON object
> that is merging in member names, the way a flat union does), so
> we branch on whether seen is empty to distinguish whether we
> are checking a union or an alternate.
>
> No change to generated code.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: new patch, split off from v8 7/17
> ---
>  scripts/qapi.py | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index a20abda..3054628 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1057,8 +1057,9 @@ class QAPISchemaObjectTypeVariants(object):
>              assert self.tag_member in seen.itervalues()
>          assert isinstance(self.tag_member.type, QAPISchemaEnumType)
>          for v in self.variants:
> -            vseen = dict(seen)
> -            v.check(schema, self.tag_member.type, vseen)
> +            # Reset seen array for each variant, since qapi names from one
> +            # branch do not affect another branch
> +            v.check(schema, self.tag_member.type, dict(seen))
>
>
>  class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
> @@ -1068,6 +1069,14 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>      def check(self, schema, tag_type, seen):
>          QAPISchemaObjectTypeMember.check(self, schema)
>          assert self.name in tag_type.values
> +        if seen:
> +            # This variant is used within a union; ensure each qapi member
> +            # field does not collide with the union's non-variant members.
> +            assert isinstance(self.type, QAPISchemaObjectType)
> +            assert not self.type.variants       # not implemented
> +            self.type.check(schema)
> +            for m in self.type.members:
> +                m.check_clash(seen)
>
>      # This function exists to support ugly simple union special cases
>      # TODO get rid of them, and drop the function

Two call chains:

* QAPISchemaObjectType.check() via QAPISchemaObjectTypeVariants.check()

  In this case, the new conditional executes.

* QAPISchemaAlternateType.check() via same

  In this case, it doesn't.

Why can't we simply add the new code to QAPISchemaObjectType.check()?
The rest of the clash checking is already there...

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check()
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
@ 2015-11-04 19:02   ` Markus Armbruster
  2015-11-04 23:12     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-04 19:02 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> From: Markus Armbruster <armbru@redhat.com>
>
> Avoid the 'if seen' conditional by doing just the essential work
> here, namely setting self.tag_member for flat unions.
> Move the rest to callers.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> Message-Id: <1446559499-26984-7-git-send-email-armbru@redhat.com>
> [reword commit, rebase to earlier AlternateType.check() changes]
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: new patch
> ---
>  scripts/qapi.py | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 3054628..6653c70 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -988,9 +988,10 @@ class QAPISchemaObjectType(QAPISchemaType):
>          for m in self.local_members:
>              m.check(schema)
>              m.check_clash(seen)
> +        self.members = seen.values()
>          if self.variants:
>              self.variants.check(schema, seen)
> -        self.members = seen.values()
> +            assert self.variants.tag_member in self.members
>
>      def is_implicit(self):
>          # See QAPISchema._make_implicit_object_type()
> @@ -1053,8 +1054,6 @@ class QAPISchemaObjectTypeVariants(object):
>          # seen is non-empty for unions, empty for alternates

You added this comment in PATCH 10 to explain the conditional I'm
dropping here.  Let's drop the comment, too.

>          if self.tag_name:    # flat union
>              self.tag_member = seen[self.tag_name]
> -        if seen:
> -            assert self.tag_member in seen.itervalues()
>          assert isinstance(self.tag_member.type, QAPISchemaEnumType)
>          for v in self.variants:
>              # Reset seen array for each variant, since qapi names from one

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing in test-qmp-*
  2015-11-04  8:40   ` Markus Armbruster
@ 2015-11-04 21:05     ` Eric Blake
  2015-11-05  7:53       ` Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04 21:05 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 2342 bytes --]

On 11/04/2015 01:40 AM, Markus Armbruster wrote:

> 
>> By moving err into data, we can let test teardown take care
>> of cleaning up any collected error; it also gives us fewer
>> lines of code between repeated tests where init runs teardown
>> on our behalf.
> 
> This part isn't as obvious.
> 
> Having two parts of differing obviousness indicates patch splitting
> could make sense.  Especially when the parts are large and mechanical,
> because reviewing large mechanical changes is much easier when there's
> just one kind of it.

Will split.

>> @@ -364,21 +341,17 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>>      /* Parsing an int */
>>
>>      v = visitor_input_test_init(data, "42");
>> -    visit_type_AltStrBool(v, &asb, NULL, &err);
>> -    g_assert(err);
>> -    error_free(err);
>> -    err = NULL;
>> +    visit_type_AltStrBool(v, &asb, NULL, &data->err);
>> +    g_assert(data->err);
>>      qapi_free_AltStrBool(asb);
> 
> This leaves data->err non-null.
> 
>>
>>      /* FIXME: Order of alternate should not affect semantics; asn should
>>       * parse the same as ans */
>>      v = visitor_input_test_init(data, "42");

And this part wipes out data, so that data->err is once again NULL.

>> -    visit_type_AltStrNum(v, &asn, NULL, &err);
>> +    visit_type_AltStrNum(v, &asn, NULL, &data->err);
> 
> If visit_type_AltStrNum() errors out, its error will be thrown away by
> its error_propagate(), because data->err is already non-null.

No, you missed that this patch is relying on the magic in 3/27 that
wipes out data on every new test.

> 
> If it fails to error out, its error_propagate() does nothing, and we
> won't detect the test failure.
> 
> Your patch makes forgetting to reset err an even easier mistake to make,
> because it removes most of the error_free() that serve as reminders.
> 
> Is it a good idea anyway?  Let's discuss before I check the remainder of
> this patch.

The point was that by moving err _into_ data, then the resetting of err
becomes as simple as resetting data, rather than having to be verbose at
every use of data->err.  We just need a visitor_input_test_init() in
between.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit
  2015-11-04 13:43   ` Markus Armbruster
@ 2015-11-04 23:03     ` Eric Blake
  0 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04 23:03 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 2032 bytes --]

On 11/04/2015 06:43 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> From: Markus Armbruster <armbru@redhat.com>
>>
>> QAPISchemaObjectTypeVariants.check() parameter members is no
>> longer used, drop it.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> Message-Id: <1446559499-26984-3-git-send-email-armbru@redhat.com>
>> [Variant.check(seen) is used after all, so reword and reduce scope
>> of this patch; rearrange later in the series]
> 
> Don't you need to update the subject?  My "previous commit" was "qapi:
> Simplify QAPISchemaObjectTypeMember.check()", while yours is "qapi:
> Eliminate QAPISchemaObjectType.check() variable members".
> 
> Not sure what moving my two patches apart buys you :)

I'm not quite sure either.  [Can I blame late-night coding?]  For
reference, this was your 3/7 patch.  I was trying to get to the point of
my 'qapi: Check for qapi collisions of flat union branches' (ended up as
19/27) as soon as possible after my tweaks to your 'qapi: Drop obsolete
tag value collision assertions' (your 1/7), so that there was less of a
gap where avoiding churn on passing vseen(dict) to Variant.check()
looked like an unused variable.

In my first attempt, I tried floating my patch right after yours.  But I
quickly discovered that my patch worked better if I built it on top of
your 'qapi: Factor out QAPISchemaObjectTypeMember.check_clash()' (your
6/7), which in turn depended on several of your other patches.  So the
end result of what I posted happens to be whatever order worked for all
my cherry-picking, and I still ended up having to tweak both your 1/7
and 3/7 after all.

For v10, I may just go back to the order that you first supplied patches
in (if for no other reason than to make your commit message more
accurate about being a cleanup of the previous patch, with the meaning
that you had given it).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches
  2015-11-04 19:01   ` Markus Armbruster
@ 2015-11-04 23:11     ` Eric Blake
  2015-11-04 23:25       ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04 23:11 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 2305 bytes --]

On 11/04/2015 12:01 PM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> Right now, our ad hoc parser ensures that we cannot have a
>> flat union that introduces any qapi member names that would
>> conflict with the non-variant qapi members already present
>> from the union's base type (see flat-union-clash-member.json).
>> We want QAPISchema*.check() to make the same check, so we can
>> later reduce some of the ad hoc checks.
>>

>> @@ -1068,6 +1069,14 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>>      def check(self, schema, tag_type, seen):
>>          QAPISchemaObjectTypeMember.check(self, schema)
>>          assert self.name in tag_type.values
>> +        if seen:
>> +            # This variant is used within a union; ensure each qapi member
>> +            # field does not collide with the union's non-variant members.
>> +            assert isinstance(self.type, QAPISchemaObjectType)
>> +            assert not self.type.variants       # not implemented
>> +            self.type.check(schema)
>> +            for m in self.type.members:
>> +                m.check_clash(seen)
>>
>>      # This function exists to support ugly simple union special cases
>>      # TODO get rid of them, and drop the function
> 
> Two call chains:
> 
> * QAPISchemaObjectType.check() via QAPISchemaObjectTypeVariants.check()
> 
>   In this case, the new conditional executes.
> 
> * QAPISchemaAlternateType.check() via same
> 
>   In this case, it doesn't.
> 
> Why can't we simply add the new code to QAPISchemaObjectType.check()?

We could, but we'd need a nested for-loop:

for v in variants.variants:
    v.type.check(schema)
    assert not v.type.variants
    vseen = dict(seen)
    for m in v.type.members:
        m.check_clash(seen)

> The rest of the clash checking is already there...

You do have a point there.  I guess it wouldn't be the end of the world
to have the loop nesting be explicit rather than indirect through the
intermediate Variants.check().

I'll play with it; and depending on what I do, that may mean I don't
have to munge your other patches quite so heavily.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check()
  2015-11-04 19:02   ` Markus Armbruster
@ 2015-11-04 23:12     ` Eric Blake
  0 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-04 23:12 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 1798 bytes --]

On 11/04/2015 12:02 PM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> From: Markus Armbruster <armbru@redhat.com>
>>
>> Avoid the 'if seen' conditional by doing just the essential work
>> here, namely setting self.tag_member for flat unions.
>> Move the rest to callers.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> Message-Id: <1446559499-26984-7-git-send-email-armbru@redhat.com>
>> [reword commit, rebase to earlier AlternateType.check() changes]
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>
>> ---
>> v9: new patch
>> ---
>>  scripts/qapi.py | 5 ++---
>>  1 file changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 3054628..6653c70 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -988,9 +988,10 @@ class QAPISchemaObjectType(QAPISchemaType):
>>          for m in self.local_members:
>>              m.check(schema)
>>              m.check_clash(seen)
>> +        self.members = seen.values()
>>          if self.variants:
>>              self.variants.check(schema, seen)
>> -        self.members = seen.values()
>> +            assert self.variants.tag_member in self.members
>>
>>      def is_implicit(self):
>>          # See QAPISchema._make_implicit_object_type()
>> @@ -1053,8 +1054,6 @@ class QAPISchemaObjectTypeVariants(object):
>>          # seen is non-empty for unions, empty for alternates
> 
> You added this comment in PATCH 10 to explain the conditional I'm
> dropping here.  Let's drop the comment, too.

Except the comment becomes relevant again in 23/27.  Or maybe I just
move the comment to that point.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches
  2015-11-04 23:11     ` Eric Blake
@ 2015-11-04 23:25       ` Eric Blake
  2015-11-05  7:59         ` Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-04 23:25 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 1651 bytes --]

On 11/04/2015 04:11 PM, Eric Blake wrote:
> On 11/04/2015 12:01 PM, Markus Armbruster wrote:
>> Eric Blake <eblake@redhat.com> writes:
>>
>>> Right now, our ad hoc parser ensures that we cannot have a
>>> flat union that introduces any qapi member names that would
>>> conflict with the non-variant qapi members already present
>>> from the union's base type (see flat-union-clash-member.json).
>>> We want QAPISchema*.check() to make the same check, so we can
>>> later reduce some of the ad hoc checks.
>>>
> 

>> Why can't we simply add the new code to QAPISchemaObjectType.check()?
> 
> We could, but we'd need a nested for-loop:
> 
> for v in variants.variants:
>     v.type.check(schema)
>     assert not v.type.variants
>     vseen = dict(seen)
>     for m in v.type.members:
>         m.check_clash(seen)
> 
>> The rest of the clash checking is already there...
> 
> You do have a point there.  I guess it wouldn't be the end of the world
> to have the loop nesting be explicit rather than indirect through the
> intermediate Variants.check().
> 
> I'll play with it; and depending on what I do, that may mean I don't
> have to munge your other patches quite so heavily.

And of course, as soon as I hit send, I had another thought - your
patches already added Member.check_clash() called separately from the
.check() chain; maybe I am better off adding a Variants.check_clash()
separate from the .check() chain, rather than trying to cram the whole
nested loop directly in ObjectType.check().

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing in test-qmp-*
  2015-11-04 21:05     ` Eric Blake
@ 2015-11-05  7:53       ` Markus Armbruster
  2015-11-05 15:04         ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05  7:53 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> On 11/04/2015 01:40 AM, Markus Armbruster wrote:
>
>> 
>>> By moving err into data, we can let test teardown take care
>>> of cleaning up any collected error; it also gives us fewer
>>> lines of code between repeated tests where init runs teardown
>>> on our behalf.
>> 
>> This part isn't as obvious.
>> 
>> Having two parts of differing obviousness indicates patch splitting
>> could make sense.  Especially when the parts are large and mechanical,
>> because reviewing large mechanical changes is much easier when there's
>> just one kind of it.
>
> Will split.
>
>>> @@ -364,21 +341,17 @@ static void
>>> test_visitor_in_alternate_number(TestInputVisitorData *data,
>>>      /* Parsing an int */
>>>
>>>      v = visitor_input_test_init(data, "42");
>>> -    visit_type_AltStrBool(v, &asb, NULL, &err);
>>> -    g_assert(err);
>>> -    error_free(err);
>>> -    err = NULL;
>>> +    visit_type_AltStrBool(v, &asb, NULL, &data->err);
>>> +    g_assert(data->err);
>>>      qapi_free_AltStrBool(asb);
>> 
>> This leaves data->err non-null.
>> 
>>>
>>>      /* FIXME: Order of alternate should not affect semantics; asn should
>>>       * parse the same as ans */
>>>      v = visitor_input_test_init(data, "42");
>
> And this part wipes out data, so that data->err is once again NULL.
>
>>> -    visit_type_AltStrNum(v, &asn, NULL, &err);
>>> +    visit_type_AltStrNum(v, &asn, NULL, &data->err);
>> 
>> If visit_type_AltStrNum() errors out, its error will be thrown away by
>> its error_propagate(), because data->err is already non-null.
>
> No, you missed that this patch is relying on the magic in 3/27 that
> wipes out data on every new test.

You're right.

>> If it fails to error out, its error_propagate() does nothing, and we
>> won't detect the test failure.
>> 
>> Your patch makes forgetting to reset err an even easier mistake to make,
>> because it removes most of the error_free() that serve as reminders.
>> 
>> Is it a good idea anyway?  Let's discuss before I check the remainder of
>> this patch.
>
> The point was that by moving err _into_ data, then the resetting of err
> becomes as simple as resetting data, rather than having to be verbose at
> every use of data->err.  We just need a visitor_input_test_init() in
> between.

Reducing boilerplate is good.  However, I'm afraid hiding
error_free(err); err = NULL; like this sets an example that is easily
copied incorrectly.

Here's what error.h has to say about consuming an Error object:

 * Report an error to stderr:
 *     error_report_err(err);
 * This frees the error object.
 *
 * Report an error somewhere else:
 *     const char *msg = error_get_pretty(err);
 *     do with msg what needs to be done...
 *     error_free(err);
 *
 * Handle an error without reporting it (just for completeness):
 *     error_free(err);

Perhaps we want something like

 * Expect an error, abort() if there is none:
 *     error_free_or_abort(&err);
 * This frees the error object and clears err.  Convenient for tests.

Then the patch quoted above becomes

    @@ -364,21 +341,17 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
         /* Parsing an int */

         v = visitor_input_test_init(data, "42");
         visit_type_AltStrBool(v, &asb, NULL, &err);
    -    g_assert(err);
    -    error_free(err);
    -    err = NULL;
    +    error_free_or_abort(&err);
         qapi_free_AltStrBool(asb);

         /* FIXME: Order of alternate should not affect semantics; asn should
          * parse the same as ans */
         v = visitor_input_test_init(data, "42");
         visit_type_AltStrNum(v, &asn, NULL, &err);
         /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
         /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
    -    g_assert(err);
    -    error_free(err);
    -    err = NULL;
    +    error_free_or_abort(&err);
         qapi_free_AltStrNum(asn);

         v = visitor_input_test_init(data, "42");

Similar boilerplate reduction, but keeps the clearing of err more
visible.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches
  2015-11-04 23:25       ` Eric Blake
@ 2015-11-05  7:59         ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05  7:59 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> On 11/04/2015 04:11 PM, Eric Blake wrote:
>> On 11/04/2015 12:01 PM, Markus Armbruster wrote:
>>> Eric Blake <eblake@redhat.com> writes:
>>>
>>>> Right now, our ad hoc parser ensures that we cannot have a
>>>> flat union that introduces any qapi member names that would
>>>> conflict with the non-variant qapi members already present
>>>> from the union's base type (see flat-union-clash-member.json).
>>>> We want QAPISchema*.check() to make the same check, so we can
>>>> later reduce some of the ad hoc checks.
>>>>
>> 
>
>>> Why can't we simply add the new code to QAPISchemaObjectType.check()?
>> 
>> We could, but we'd need a nested for-loop:
>> 
>> for v in variants.variants:
>>     v.type.check(schema)
>>     assert not v.type.variants
>>     vseen = dict(seen)
>>     for m in v.type.members:
>>         m.check_clash(seen)

Looks clear enough to me.

>>> The rest of the clash checking is already there...
>> 
>> You do have a point there.  I guess it wouldn't be the end of the world
>> to have the loop nesting be explicit rather than indirect through the
>> intermediate Variants.check().

Hiding loop nesting behind method calls doesn't make code simpler :)

Methods help when they're useful abstractions.  For instance, hiding the
details of checking a member m behind m.check() is good.  But here,
we're checking relations between members.

>> I'll play with it; and depending on what I do, that may mean I don't
>> have to munge your other patches quite so heavily.
>
> And of course, as soon as I hit send, I had another thought - your
> patches already added Member.check_clash() called separately from the
> .check() chain; maybe I am better off adding a Variants.check_clash()
> separate from the .check() chain, rather than trying to cram the whole
> nested loop directly in ObjectType.check().

Matter of taste, can't tell without trying, use your judgement.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-*
  2015-11-04 17:44       ` Markus Armbruster
@ 2015-11-05 13:09         ` Eric Blake
  0 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-05 13:09 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 828 bytes --]

On 11/04/2015 10:44 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> On 11/04/2015 01:19 AM, Markus Armbruster wrote:
>>> Eric Blake <eblake@redhat.com> writes:
>>>
>>>> Make valgrind happy with the current state of the tests, so that

>>>>  tests/test-qmp-input-strict.c   | 10 ++++++++++
>>>>  tests/test-qmp-input-visitor.c | 41
>>>> +++++++----------------------------------
>>>>  tests/test-qmp-output-visitor.c |  3 ++-
>>>>  3 files changed, 19 insertions(+), 35 deletions(-)
>>>
>>> No leaks to plug in test/-qmp-commands.c and test-qmp-event.c?
>>
>> Didn't check. I'll do that.

Checked; no leaks to fix.  But they do include some 'err' fixes for 4/27
to add.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing in test-qmp-*
  2015-11-05  7:53       ` Markus Armbruster
@ 2015-11-05 15:04         ` Eric Blake
  0 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-05 15:04 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]

On 11/05/2015 12:53 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> On 11/04/2015 01:40 AM, Markus Armbruster wrote:
>>
>>>
>>>> By moving err into data, we can let test teardown take care
>>>> of cleaning up any collected error; it also gives us fewer
>>>> lines of code between repeated tests where init runs teardown
>>>> on our behalf.
>>>
>>> This part isn't as obvious.
>>>
>>> Having two parts of differing obviousness indicates patch splitting
>>> could make sense.  Especially when the parts are large and mechanical,
>>> because reviewing large mechanical changes is much easier when there's
>>> just one kind of it.
>>
>> Will split.

> Perhaps we want something like
> 
>  * Expect an error, abort() if there is none:
>  *     error_free_or_abort(&err);
>  * This frees the error object and clears err.  Convenient for tests.

Don't know if we'd want that directly in error.h, or just in the
affected tests, but I like the idea.  All the more reason for me to
split the patch into expected error vs. expected no error cases.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 21/27] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
@ 2015-11-05 15:29   ` Markus Armbruster
  2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 1/5] qapi: Generate a sed script to help eliminate camel_to_upper() Markus Armbruster
                       ` (4 more replies)
  0 siblings, 5 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

I really like the simplification.  The (one-time) churn is annoying.
Worthwhile?

See PATCH 3 for details.

Markus Armbruster (5):
  qapi: Generate a sed script to help eliminate camel_to_upper()
  Revert "qapi: Generate a sed script to help eliminate
    camel_to_upper()"
  qapi: Use common name mangling for enumeration constants
  crypto: Drop name mangling override
  Revert "qapi: allow override of default enum prefix naming"

 backends/baum.c                          |   2 +-
 backends/hostmem.c                       |  10 +-
 backends/msmouse.c                       |   2 +-
 backends/rng-egd.c                       |   2 +-
 backends/testdev.c                       |   2 +-
 balloon.c                                |   4 +-
 block.c                                  |  18 +-
 block/backup.c                           |  20 +-
 block/block-backend.c                    |  38 +--
 block/commit.c                           |  12 +-
 block/io.c                               |   4 +-
 block/mirror.c                           |  22 +-
 block/nbd.c                              |   6 +-
 block/qcow2.c                            |  10 +-
 block/quorum.c                           |  10 +-
 block/raw-posix.c                        |   8 +-
 block/stream.c                           |  10 +-
 block/vmdk.c                             |   2 +-
 blockdev-nbd.c                           |   2 +-
 blockdev.c                               | 134 ++++-----
 blockjob.c                               |  30 +-
 crypto/tlscredsanon.c                    |   6 +-
 crypto/tlscredsx509.c                    |   6 +-
 crypto/tlssession.c                      |   6 +-
 docs/qapi-code-gen.txt                   |  18 +-
 docs/writing-qmp-commands.txt            |   8 +-
 dump.c                                   |  28 +-
 gdbstub.c                                |  26 +-
 hmp.c                                    |  80 +++---
 hw/acpi/memory_hotplug.c                 |   2 +-
 hw/arm/musicpal.c                        |   2 +-
 hw/block/block.c                         |   2 +-
 hw/block/fdc.c                           |   4 +-
 hw/block/hd-geometry.c                   |  12 +-
 hw/block/virtio-blk.c                    |   8 +-
 hw/char/escc.c                           | 246 ++++++++--------
 hw/core/qdev-properties-system.c         |   2 +-
 hw/display/qxl.c                         |   4 +-
 hw/i386/kvm/i8254.c                      |   6 +-
 hw/i386/pc.c                             |  10 +-
 hw/i386/pc_piix.c                        |  10 +-
 hw/i386/pc_q35.c                         |  10 +-
 hw/ide/ahci.c                            |   4 +-
 hw/ide/core.c                            |   6 +-
 hw/ide/qdev.c                            |   2 +-
 hw/input/hid.c                           |  26 +-
 hw/input/ps2.c                           |  20 +-
 hw/input/virtio-input-hid.c              | 242 ++++++++--------
 hw/mem/pc-dimm.c                         |   2 +-
 hw/net/allwinner_emac.c                  |   2 +-
 hw/net/cadence_gem.c                     |   2 +-
 hw/net/dp8393x.c                         |   2 +-
 hw/net/e1000.c                           |   2 +-
 hw/net/eepro100.c                        |   2 +-
 hw/net/etraxfs_eth.c                     |   2 +-
 hw/net/fsl_etsec/etsec.c                 |   2 +-
 hw/net/imx_fec.c                         |   2 +-
 hw/net/lan9118.c                         |   2 +-
 hw/net/lance.c                           |   2 +-
 hw/net/mcf_fec.c                         |   2 +-
 hw/net/milkymist-minimac2.c              |   2 +-
 hw/net/mipsnet.c                         |   2 +-
 hw/net/ne2000-isa.c                      |   2 +-
 hw/net/ne2000.c                          |   2 +-
 hw/net/opencores_eth.c                   |   2 +-
 hw/net/pcnet-pci.c                       |   2 +-
 hw/net/rocker/rocker.c                   |   4 +-
 hw/net/rocker/rocker_fp.c                |   2 +-
 hw/net/rocker/rocker_of_dpa.c            |   8 +-
 hw/net/rtl8139.c                         |   2 +-
 hw/net/smc91c111.c                       |   2 +-
 hw/net/spapr_llan.c                      |   2 +-
 hw/net/stellaris_enet.c                  |   2 +-
 hw/net/vhost_net.c                       |  18 +-
 hw/net/virtio-net.c                      |  28 +-
 hw/net/vmxnet3.c                         |   2 +-
 hw/net/xen_nic.c                         |   2 +-
 hw/net/xgmac.c                           |   2 +-
 hw/net/xilinx_axienet.c                  |   2 +-
 hw/net/xilinx_ethlite.c                  |   2 +-
 hw/ppc/spapr_rtas.c                      |   2 +-
 hw/scsi/scsi-disk.c                      |   6 +-
 hw/scsi/scsi-generic.c                   |   4 +-
 hw/timer/mc146818rtc.c                   |  14 +-
 hw/tpm/tpm_passthrough.c                 |   2 +-
 hw/tpm/tpm_tis.c                         |   4 +-
 hw/usb/dev-network.c                     |   2 +-
 hw/usb/hcd-ehci.c                        |   4 +-
 hw/usb/redirect.c                        |   8 +-
 hw/vfio/pci.c                            |   2 +-
 hw/watchdog/watchdog.c                   |  16 +-
 include/block/block_int.h                |   2 +-
 include/crypto/tlssession.h              |   2 +-
 include/migration/migration.h            |   4 +-
 include/qapi/error.h                     |   6 +-
 include/ui/input.h                       |   8 +-
 include/ui/qemu-spice.h                  |   2 +-
 kvm-all.c                                |   2 +-
 migration/migration.c                    | 170 +++++------
 migration/ram.c                          |   4 +-
 migration/rdma.c                         |   2 +-
 migration/savevm.c                       |   4 +-
 monitor.c                                |  62 ++--
 net/dump.c                               |   4 +-
 net/filter.c                             |  10 +-
 net/hub.c                                |  20 +-
 net/l2tpv3.c                             |   4 +-
 net/net.c                                |  78 ++---
 net/netmap.c                             |   2 +-
 net/slirp.c                              |   4 +-
 net/socket.c                             |   6 +-
 net/tap-win32.c                          |   4 +-
 net/tap.c                                |  20 +-
 net/vde.c                                |   4 +-
 net/vhost-user.c                         |  16 +-
 numa.c                                   |   4 +-
 qapi/crypto.json                         |   1 -
 qapi/qmp-dispatch.c                      |   2 +-
 qdev-monitor.c                           |   4 +-
 qemu-char.c                              |  54 ++--
 qemu-img.c                               |   2 +-
 qemu-nbd.c                               |  12 +-
 qga/commands-posix.c                     |  34 +--
 qga/commands-win32.c                     |  44 +--
 qmp.c                                    |  16 +-
 qom/object.c                             |   6 +-
 scripts/qapi-introspect.py               |   2 +-
 scripts/qapi-types.py                    |   6 +-
 scripts/qapi-visit.py                    |   2 +-
 scripts/qapi.py                          |  85 ++----
 spice-qemu-char.c                        |   4 +-
 stubs/runstate-check.c                   |   2 +-
 target-i386/cpu.c                        |   2 +-
 target-lm32/op_helper.c                  |   2 +-
 tests/Makefile                           |   1 -
 tests/qapi-schema/enum-bad-prefix.err    |   1 -
 tests/qapi-schema/enum-bad-prefix.exit   |   1 -
 tests/qapi-schema/enum-bad-prefix.json   |   2 -
 tests/qapi-schema/enum-bad-prefix.out    |   0
 tests/qapi-schema/enum-clash-member.err  |   2 +-
 tests/qapi-schema/enum-clash-member.json |   2 +-
 tests/qapi-schema/enum-max-member.err    |   2 +-
 tests/qapi-schema/enum-max-member.json   |   4 +-
 tests/qapi-schema/qapi-schema-test.json  |   5 -
 tests/qapi-schema/qapi-schema-test.out   |   2 -
 tests/qapi-schema/test-qapi.py           |   4 +-
 tests/qapi-schema/union-bad-branch.err   |   2 +-
 tests/qapi-schema/union-bad-branch.json  |   4 +-
 tests/qapi-schema/union-max.err          |   2 +-
 tests/qapi-schema/union-max.json         |   2 +-
 tests/test-crypto-tlscredsx509.c         |   6 +-
 tests/test-crypto-tlssession.c           |  12 +-
 tests/test-qmp-commands.c                |   2 +-
 tests/test-qmp-event.c                   |   6 +-
 tests/test-qmp-input-visitor.c           |  66 ++---
 tests/test-qmp-output-visitor.c          |  84 +++---
 tests/test-string-output-visitor.c       |   4 +-
 tpm.c                                    |  14 +-
 trace/qmp.c                              |   6 +-
 ui/cocoa.m                               |  20 +-
 ui/console.c                             |  22 +-
 ui/gtk.c                                 |  20 +-
 ui/input-keymap.c                        | 274 +++++++++---------
 ui/input-legacy.c                        |  38 +--
 ui/input.c                               |  56 ++--
 ui/sdl.c                                 |  22 +-
 ui/sdl2-keymap.h                         | 480 +++++++++++++++----------------
 ui/sdl2.c                                |  20 +-
 ui/spice-core.c                          |   4 +-
 ui/spice-input.c                         |  20 +-
 ui/vnc-auth-vencrypt.c                   |   2 +-
 ui/vnc-ws.c                              |   2 +-
 ui/vnc.c                                 |  84 +++---
 util/error.c                             |   6 +-
 util/qemu-config.c                       |   8 +-
 util/qemu-sockets.c                      |  32 +--
 vl.c                                     | 166 +++++------
 xen-hvm.c                                |   4 +-
 178 files changed, 1746 insertions(+), 1816 deletions(-)
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.err
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.exit
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.json
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.out

-- 
2.4.3

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 1/5] qapi: Generate a sed script to help eliminate camel_to_upper()
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
@ 2015-11-05 15:29     ` Markus Armbruster
  2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 2/5] Revert "qapi: Generate a sed script to help eliminate camel_to_upper()" Markus Armbruster
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

Temporary patch, will be reverted right away.

Out of laziness, generate it right into the C code, in comments.

To generate the sed script, use

    $ make
    $ make check
    $ enum_gen_files='qapi-event.c qapi-types.c qga/qapi-generated/qga-qapi-types.c tests/test-qapi-event.c tests/test-qapi-types.c'
    $ sed -n 's,// @@@ ,,p' $enum_gen_files >enum-mangle.sed

To find the files to patch, use

    $ enum_mangle_regexp=`sed -n 's,// ### ,,p' $enum_gen_files | tr '\n' '|' | sed 's/|$//'`
    $ git-grep -El "$enum_mangle_regexp" $srcdir >enum-mangle-files

where $srcdir is the root of your source tree.

To patch them, use

    $ xargs sed -ri --file enum-mangle.sed <enum-mangle-files

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 843e364..c2e3057 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1517,20 +1517,26 @@ def gen_enum_lookup(name, values, prefix=None):
     ret = mcgen('''
 
 const char *const %(c_name)s_lookup[] = {
+// ### %(prefix)s
 ''',
+                prefix=camel_to_upper(prefix or name),
                 c_name=c_name(name))
     for value in values:
         index = c_enum_const(name, value, prefix)
         ret += mcgen('''
     [%(index)s] = "%(value)s",
+// @@@ s/(^|[^A-Za-z0-9_])%(index)s($|[^A-Za-z0-9_])/\\1%(new)s\\2/g
 ''',
+                     new=c_name((prefix or name) + '_' + value),
                      index=index, value=value)
 
     max_index = c_enum_const(name, 'MAX', prefix)
     ret += mcgen('''
     [%(max_index)s] = NULL,
+// @@@ s/(^|[^A-Za-z0-9_])%(max_index)s($|[^A-Za-z0-9_])/\\1%(new)s\\2/g
 };
 ''',
+                 new=c_name((prefix or name) + '_' + 'MAX'),
                  max_index=max_index)
     return ret
 
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 2/5] Revert "qapi: Generate a sed script to help eliminate camel_to_upper()"
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
  2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 1/5] qapi: Generate a sed script to help eliminate camel_to_upper() Markus Armbruster
@ 2015-11-05 15:29     ` Markus Armbruster
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

This reverts commit a1827a5b53f9749a8b062a1927e11daab6df98ce.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi.py | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index c2e3057..843e364 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1517,26 +1517,20 @@ def gen_enum_lookup(name, values, prefix=None):
     ret = mcgen('''
 
 const char *const %(c_name)s_lookup[] = {
-// ### %(prefix)s
 ''',
-                prefix=camel_to_upper(prefix or name),
                 c_name=c_name(name))
     for value in values:
         index = c_enum_const(name, value, prefix)
         ret += mcgen('''
     [%(index)s] = "%(value)s",
-// @@@ s/(^|[^A-Za-z0-9_])%(index)s($|[^A-Za-z0-9_])/\\1%(new)s\\2/g
 ''',
-                     new=c_name((prefix or name) + '_' + value),
                      index=index, value=value)
 
     max_index = c_enum_const(name, 'MAX', prefix)
     ret += mcgen('''
     [%(max_index)s] = NULL,
-// @@@ s/(^|[^A-Za-z0-9_])%(max_index)s($|[^A-Za-z0-9_])/\\1%(new)s\\2/g
 };
 ''',
-                 new=c_name((prefix or name) + '_' + 'MAX'),
                  max_index=max_index)
     return ret
 
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
  2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 1/5] qapi: Generate a sed script to help eliminate camel_to_upper() Markus Armbruster
  2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 2/5] Revert "qapi: Generate a sed script to help eliminate camel_to_upper()" Markus Armbruster
@ 2015-11-05 15:30     ` Markus Armbruster
  2015-11-05 16:01       ` Daniel P. Berrange
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 4/5] crypto: Drop name mangling override Markus Armbruster
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 5/5] Revert "qapi: allow override of default enum prefix naming" Markus Armbruster
  4 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

QAPI names needn't be valid C identifiers, so we mangle them with
c_name().  Except for enumeration constants, which we mangle with
camel_to_upper().

c_name() is easy enough to understand: replace '.' and '-' by '_',
prefix certain ticklish identifiers with 'q_'.

camel_to_upper() is a hairball of heuristics, and guessing how it'll
mangle interesting input could serve as a (nerdy) game.  Despite some
tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
(commit 351d36e).

Example: QAPI definition

    { 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }

generates

    typedef enum BlockDeviceIoStatus {
        BLOCK_DEVICE_IO_STATUS_OK = 0,
        BLOCK_DEVICE_IO_STATUS_FAILED = 1,
        BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
        BLOCK_DEVICE_IO_STATUS_MAX = 3,
    } BlockDeviceIoStatus;

Observe that c_name() maps BlockDeviceIoStatus to itself, and
camel_to_upper() maps it to BLOCK_DEVICE_IO_STATUS, i.e. the
enumeration constants are shouted, the enumeration type isn't.

Because mangled names must not clash, name mangling restricts the
names you can use.  For example, you can't have member 'a-b' and
'a_b'.

Having two separate manglings complicates this.  Enumeration constants
must be distinct after mangling with camel_to_upper().  But as soon as
you use the enumeration as union tag, they must *also* be distinct
after mangling with c_name().

Having shouted enumeration constants isn't worth the complexity cost.
Mangle them with c_name() instead, and drop camel_to_upper() along
with its helper camel_case().  The example above becomes

    typedef enum BlockDeviceIoStatus {
        BlockDeviceIoStatus_ok = 0,
        BlockDeviceIoStatus_failed = 1,
        BlockDeviceIoStatus_nospace = 2,
        BlockDeviceIoStatus_MAX = 3,
    } BlockDeviceIoStatus;

Use the sed script generated with the help of the commit just reverted
to update the code using QAPI-generated enumeration constants.

The sed script misses an occurence in target-i386/cpu.c, because we
construct enumeration constants with the ## operator there.  Updated
manually.

The sed script misses commented out occurences in ui/sdl2-keymap.h
that show possible future extensions, i.e. enumeration constants that
aren't defined, yet.  Update them like this:

    $ sed -r -i 's/Q_KEY_CODE(_[A-Za-z0-9_]*)/QKeyCode\L\1/' ui/sdl2-keymap.h

The changed mangling affects a few tests.  Fix them up.

Examples in docs/qapi-code-gen.txt updated manually.  The paragraph
explaining enumeration type name mangling is now obsolete.  I'll fix
it shortly, mark it FIXME until then.

"git-grep -E $enum_mangle_regexp" with enum_mangle_regexp from the
commit just reverted shows possible missed occurences.  Most of them
are QCRYPTO_TLS_CREDS_ENDPOINT, which is not to be replaced now,
because it uses the name mangling override from commit 351d36e.  The
rest are all false positives.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 backends/baum.c                          |   2 +-
 backends/hostmem.c                       |  10 +-
 backends/msmouse.c                       |   2 +-
 backends/rng-egd.c                       |   2 +-
 backends/testdev.c                       |   2 +-
 balloon.c                                |   4 +-
 block.c                                  |  18 +-
 block/backup.c                           |  20 +-
 block/block-backend.c                    |  38 +--
 block/commit.c                           |  12 +-
 block/io.c                               |   4 +-
 block/mirror.c                           |  22 +-
 block/nbd.c                              |   6 +-
 block/qcow2.c                            |  10 +-
 block/quorum.c                           |  10 +-
 block/raw-posix.c                        |   8 +-
 block/stream.c                           |  10 +-
 block/vmdk.c                             |   2 +-
 blockdev-nbd.c                           |   2 +-
 blockdev.c                               | 134 ++++-----
 blockjob.c                               |  30 +-
 crypto/tlscredsanon.c                    |   6 +-
 crypto/tlscredsx509.c                    |   6 +-
 crypto/tlssession.c                      |   6 +-
 docs/qapi-code-gen.txt                   |  11 +-
 docs/writing-qmp-commands.txt            |   8 +-
 dump.c                                   |  28 +-
 gdbstub.c                                |  26 +-
 hmp.c                                    |  80 +++---
 hw/acpi/memory_hotplug.c                 |   2 +-
 hw/arm/musicpal.c                        |   2 +-
 hw/block/block.c                         |   2 +-
 hw/block/fdc.c                           |   4 +-
 hw/block/hd-geometry.c                   |  12 +-
 hw/block/virtio-blk.c                    |   8 +-
 hw/char/escc.c                           | 246 ++++++++--------
 hw/core/qdev-properties-system.c         |   2 +-
 hw/display/qxl.c                         |   4 +-
 hw/i386/kvm/i8254.c                      |   6 +-
 hw/i386/pc.c                             |  10 +-
 hw/i386/pc_piix.c                        |  10 +-
 hw/i386/pc_q35.c                         |  10 +-
 hw/ide/ahci.c                            |   4 +-
 hw/ide/core.c                            |   6 +-
 hw/ide/qdev.c                            |   2 +-
 hw/input/hid.c                           |  26 +-
 hw/input/ps2.c                           |  20 +-
 hw/input/virtio-input-hid.c              | 242 ++++++++--------
 hw/mem/pc-dimm.c                         |   2 +-
 hw/net/allwinner_emac.c                  |   2 +-
 hw/net/cadence_gem.c                     |   2 +-
 hw/net/dp8393x.c                         |   2 +-
 hw/net/e1000.c                           |   2 +-
 hw/net/eepro100.c                        |   2 +-
 hw/net/etraxfs_eth.c                     |   2 +-
 hw/net/fsl_etsec/etsec.c                 |   2 +-
 hw/net/imx_fec.c                         |   2 +-
 hw/net/lan9118.c                         |   2 +-
 hw/net/lance.c                           |   2 +-
 hw/net/mcf_fec.c                         |   2 +-
 hw/net/milkymist-minimac2.c              |   2 +-
 hw/net/mipsnet.c                         |   2 +-
 hw/net/ne2000-isa.c                      |   2 +-
 hw/net/ne2000.c                          |   2 +-
 hw/net/opencores_eth.c                   |   2 +-
 hw/net/pcnet-pci.c                       |   2 +-
 hw/net/rocker/rocker.c                   |   4 +-
 hw/net/rocker/rocker_fp.c                |   2 +-
 hw/net/rocker/rocker_of_dpa.c            |   8 +-
 hw/net/rtl8139.c                         |   2 +-
 hw/net/smc91c111.c                       |   2 +-
 hw/net/spapr_llan.c                      |   2 +-
 hw/net/stellaris_enet.c                  |   2 +-
 hw/net/vhost_net.c                       |  18 +-
 hw/net/virtio-net.c                      |  28 +-
 hw/net/vmxnet3.c                         |   2 +-
 hw/net/xen_nic.c                         |   2 +-
 hw/net/xgmac.c                           |   2 +-
 hw/net/xilinx_axienet.c                  |   2 +-
 hw/net/xilinx_ethlite.c                  |   2 +-
 hw/ppc/spapr_rtas.c                      |   2 +-
 hw/scsi/scsi-disk.c                      |   6 +-
 hw/scsi/scsi-generic.c                   |   4 +-
 hw/timer/mc146818rtc.c                   |  14 +-
 hw/tpm/tpm_passthrough.c                 |   2 +-
 hw/tpm/tpm_tis.c                         |   4 +-
 hw/usb/dev-network.c                     |   2 +-
 hw/usb/hcd-ehci.c                        |   4 +-
 hw/usb/redirect.c                        |   8 +-
 hw/vfio/pci.c                            |   2 +-
 hw/watchdog/watchdog.c                   |  16 +-
 include/block/block_int.h                |   2 +-
 include/crypto/tlssession.h              |   2 +-
 include/migration/migration.h            |   4 +-
 include/qapi/error.h                     |   6 +-
 include/ui/input.h                       |   8 +-
 include/ui/qemu-spice.h                  |   2 +-
 kvm-all.c                                |   2 +-
 migration/migration.c                    | 170 +++++------
 migration/ram.c                          |   4 +-
 migration/rdma.c                         |   2 +-
 migration/savevm.c                       |   4 +-
 monitor.c                                |  62 ++--
 net/dump.c                               |   4 +-
 net/filter.c                             |  10 +-
 net/hub.c                                |  20 +-
 net/l2tpv3.c                             |   4 +-
 net/net.c                                |  78 ++---
 net/netmap.c                             |   2 +-
 net/slirp.c                              |   4 +-
 net/socket.c                             |   6 +-
 net/tap-win32.c                          |   4 +-
 net/tap.c                                |  20 +-
 net/vde.c                                |   4 +-
 net/vhost-user.c                         |  16 +-
 numa.c                                   |   4 +-
 qapi/qmp-dispatch.c                      |   2 +-
 qdev-monitor.c                           |   4 +-
 qemu-char.c                              |  54 ++--
 qemu-img.c                               |   2 +-
 qemu-nbd.c                               |  12 +-
 qga/commands-posix.c                     |  34 +--
 qga/commands-win32.c                     |  44 +--
 qmp.c                                    |  16 +-
 qom/object.c                             |   6 +-
 scripts/qapi.py                          |  48 +---
 spice-qemu-char.c                        |   4 +-
 stubs/runstate-check.c                   |   2 +-
 target-i386/cpu.c                        |   2 +-
 target-lm32/op_helper.c                  |   2 +-
 tests/qapi-schema/enum-clash-member.err  |   2 +-
 tests/qapi-schema/enum-clash-member.json |   2 +-
 tests/qapi-schema/enum-max-member.err    |   2 +-
 tests/qapi-schema/enum-max-member.json   |   4 +-
 tests/qapi-schema/union-bad-branch.err   |   2 +-
 tests/qapi-schema/union-bad-branch.json  |   4 +-
 tests/qapi-schema/union-max.err          |   2 +-
 tests/qapi-schema/union-max.json         |   2 +-
 tests/test-crypto-tlscredsx509.c         |   6 +-
 tests/test-crypto-tlssession.c           |  12 +-
 tests/test-qmp-commands.c                |   2 +-
 tests/test-qmp-event.c                   |   6 +-
 tests/test-qmp-input-visitor.c           |  66 ++---
 tests/test-qmp-output-visitor.c          |  84 +++---
 tests/test-string-output-visitor.c       |   4 +-
 tpm.c                                    |  14 +-
 trace/qmp.c                              |   6 +-
 ui/cocoa.m                               |  20 +-
 ui/console.c                             |  22 +-
 ui/gtk.c                                 |  20 +-
 ui/input-keymap.c                        | 274 +++++++++---------
 ui/input-legacy.c                        |  38 +--
 ui/input.c                               |  56 ++--
 ui/sdl.c                                 |  22 +-
 ui/sdl2-keymap.h                         | 480 +++++++++++++++----------------
 ui/sdl2.c                                |  20 +-
 ui/spice-core.c                          |   4 +-
 ui/spice-input.c                         |  20 +-
 ui/vnc-auth-vencrypt.c                   |   2 +-
 ui/vnc-ws.c                              |   2 +-
 ui/vnc.c                                 |  84 +++---
 util/error.c                             |   6 +-
 util/qemu-config.c                       |   8 +-
 util/qemu-sockets.c                      |  32 +--
 vl.c                                     | 166 +++++------
 xen-hvm.c                                |   4 +-
 166 files changed, 1728 insertions(+), 1763 deletions(-)

diff --git a/backends/baum.c b/backends/baum.c
index 723c658..b4f58f2 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -635,7 +635,7 @@ fail_handle:
 
 static void register_types(void)
 {
-    register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL,
+    register_char_driver("braille", ChardevBackendKind_braille, NULL,
                          chr_baum_init);
 }
 
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 41ba2af..d3fb769 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -19,10 +19,10 @@
 
 #ifdef CONFIG_NUMA
 #include <numaif.h>
-QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_DEFAULT != MPOL_DEFAULT);
-QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_PREFERRED != MPOL_PREFERRED);
-QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_BIND != MPOL_BIND);
-QEMU_BUILD_BUG_ON(HOST_MEM_POLICY_INTERLEAVE != MPOL_INTERLEAVE);
+QEMU_BUILD_BUG_ON(HostMemPolicy_default != MPOL_DEFAULT);
+QEMU_BUILD_BUG_ON(HostMemPolicy_preferred != MPOL_PREFERRED);
+QEMU_BUILD_BUG_ON(HostMemPolicy_bind != MPOL_BIND);
+QEMU_BUILD_BUG_ON(HostMemPolicy_interleave != MPOL_INTERLEAVE);
 #endif
 
 static void
@@ -127,7 +127,7 @@ host_memory_backend_set_policy(Object *obj, int policy, Error **errp)
     backend->policy = policy;
 
 #ifndef CONFIG_NUMA
-    if (policy != HOST_MEM_POLICY_DEFAULT) {
+    if (policy != HostMemPolicy_default) {
         error_setg(errp, "NUMA policies are not supported by this QEMU");
     }
 #endif
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 0126fa0..3c36f80 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -82,7 +82,7 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
 
 static void register_types(void)
 {
-    register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL,
+    register_char_driver("msmouse", ChardevBackendKind_msmouse, NULL,
                          qemu_chr_open_msmouse);
 }
 
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 6c13409..b5bd641 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -147,7 +147,7 @@ static void rng_egd_opened(RngBackend *b, Error **errp)
 
     s->chr = qemu_chr_find(s->chr_name);
     if (s->chr == NULL) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", s->chr_name);
         return;
     }
diff --git a/backends/testdev.c b/backends/testdev.c
index 26d5c73..c416d9e 100644
--- a/backends/testdev.c
+++ b/backends/testdev.c
@@ -128,7 +128,7 @@ static CharDriverState *chr_testdev_init(const char *id,
 
 static void register_types(void)
 {
-    register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL,
+    register_char_driver("testdev", ChardevBackendKind_testdev, NULL,
                          chr_testdev_init);
 }
 
diff --git a/balloon.c b/balloon.c
index 5d69e8a..f1a1fa4 100644
--- a/balloon.c
+++ b/balloon.c
@@ -40,12 +40,12 @@ static void *balloon_opaque;
 static bool have_balloon(Error **errp)
 {
     if (kvm_enabled() && !kvm_has_sync_mmu()) {
-        error_set(errp, ERROR_CLASS_KVM_MISSING_CAP,
+        error_set(errp, ErrorClass_KVMMissingCap,
                   "Using KVM without synchronous MMU, balloon unavailable");
         return false;
     }
     if (!balloon_event_fn) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+        error_set(errp, ErrorClass_DeviceNotActive,
                   "No balloon device has been activated");
         return false;
     }
diff --git a/block.c b/block.c
index e9f40dc..5be623d 100644
--- a/block.c
+++ b/block.c
@@ -1079,7 +1079,7 @@ static int bdrv_fill_options(QDict **options, const char **pfilename,
         }
     }
 
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         *flags |= BDRV_O_INCOMING;
     }
 
@@ -1548,9 +1548,9 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename,
         if (bs->blk) {
             blk_dev_change_media_cb(bs->blk, true);
         }
-    } else if (!runstate_check(RUN_STATE_PRELAUNCH)
-               && !runstate_check(RUN_STATE_INMIGRATE)
-               && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
+    } else if (!runstate_check(RunState_prelaunch)
+               && !runstate_check(RunState_inmigrate)
+               && !runstate_check(RunState_paused)) { /* HACK */
         error_setg(errp,
                    "Guest must be stopped for opening of encrypted image");
         ret = -EBUSY;
@@ -1795,7 +1795,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
 
     ret = bdrv_flush(reopen_state->bs);
     if (ret) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error (%s) flushing drive",
+        error_set(errp, ErrorClass_GenericError, "Error (%s) flushing drive",
                   strerror(-ret));
         goto error;
     }
@@ -2585,7 +2585,7 @@ void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp)
         }
     } else {
         if (bdrv_key_required(bs)) {
-            error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED,
+            error_set(errp, ErrorClass_DeviceEncrypted,
                       "'%s' (%s) is encrypted",
                       bdrv_get_device_or_node_name(bs),
                       bdrv_get_encrypted_filename(bs));
@@ -3190,11 +3190,11 @@ bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
 {
     if (bdrv_dirty_bitmap_frozen(bitmap)) {
-        return DIRTY_BITMAP_STATUS_FROZEN;
+        return DirtyBitmapStatus_frozen;
     } else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
-        return DIRTY_BITMAP_STATUS_DISABLED;
+        return DirtyBitmapStatus_disabled;
     } else {
-        return DIRTY_BITMAP_STATUS_ACTIVE;
+        return DirtyBitmapStatus_active;
     }
 }
 
diff --git a/block/backup.c b/block/backup.c
index ec01db8..e60a08d 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -223,7 +223,7 @@ static void backup_iostatus_reset(BlockJob *job)
 
 static const BlockJobDriver backup_job_driver = {
     .instance_size  = sizeof(BackupBlockJob),
-    .job_type       = BLOCK_JOB_TYPE_BACKUP,
+    .job_type       = BlockJobType_backup,
     .set_speed      = backup_set_speed,
     .iostatus_reset = backup_iostatus_reset,
 };
@@ -317,7 +317,7 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
                                     false);
                 if ((ret < 0) &&
                     backup_error_action(job, error_is_read, -ret) ==
-                    BLOCK_ERROR_ACTION_REPORT) {
+                    BlockErrorAction_report) {
                     return ret;
                 }
             } while (ret < 0);
@@ -370,7 +370,7 @@ static void coroutine_fn backup_run(void *opaque)
 
     bdrv_add_before_write_notifier(bs, &before_write);
 
-    if (job->sync_mode == MIRROR_SYNC_MODE_NONE) {
+    if (job->sync_mode == MirrorSyncMode_none) {
         while (!block_job_is_cancelled(&job->common)) {
             /* Yield until the job is cancelled.  We just let our before_write
              * notify callback service CoW requests. */
@@ -378,7 +378,7 @@ static void coroutine_fn backup_run(void *opaque)
             qemu_coroutine_yield();
             job->common.busy = true;
         }
-    } else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
+    } else if (job->sync_mode == MirrorSyncMode_incremental) {
         ret = backup_run_incremental(job);
     } else {
         /* Both FULL and TOP SYNC_MODE's require copying.. */
@@ -388,7 +388,7 @@ static void coroutine_fn backup_run(void *opaque)
                 break;
             }
 
-            if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
+            if (job->sync_mode == MirrorSyncMode_top) {
                 int i, n;
                 int alloced = 0;
 
@@ -426,7 +426,7 @@ static void coroutine_fn backup_run(void *opaque)
                 /* Depending on error action, fail now or retry cluster */
                 BlockErrorAction action =
                     backup_error_action(job, error_is_read, -ret);
-                if (action == BLOCK_ERROR_ACTION_REPORT) {
+                if (action == BlockErrorAction_report) {
                     break;
                 } else {
                     start--;
@@ -485,8 +485,8 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
         return;
     }
 
-    if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
-         on_source_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+    if ((on_source_error == BlockdevOnError_stop ||
+         on_source_error == BlockdevOnError_enospc) &&
         (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
         error_setg(errp, QERR_INVALID_PARAMETER, "on-source-error");
         return;
@@ -512,7 +512,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
         return;
     }
 
-    if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
+    if (sync_mode == MirrorSyncMode_incremental) {
         if (!sync_bitmap) {
             error_setg(errp, "must provide a valid bitmap name for "
                              "\"incremental\" sync mode");
@@ -550,7 +550,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
     job->on_target_error = on_target_error;
     job->target = target;
     job->sync_mode = sync_mode;
-    job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
+    job->sync_bitmap = sync_mode == MirrorSyncMode_incremental ?
                        sync_bitmap : NULL;
     job->common.len = len;
     job->common.co = qemu_coroutine_create(backup_run);
diff --git a/block/block-backend.c b/block/block-backend.c
index 19fdaae..827a5dc 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -489,7 +489,7 @@ void blk_dev_resize_cb(BlockBackend *blk)
 void blk_iostatus_enable(BlockBackend *blk)
 {
     blk->iostatus_enabled = true;
-    blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
+    blk->iostatus = BlockDeviceIoStatus_ok;
 }
 
 /* The I/O status is only enabled if the drive explicitly
@@ -497,9 +497,9 @@ void blk_iostatus_enable(BlockBackend *blk)
 bool blk_iostatus_is_enabled(const BlockBackend *blk)
 {
     return (blk->iostatus_enabled &&
-           (blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
-            blk->on_write_error == BLOCKDEV_ON_ERROR_STOP   ||
-            blk->on_read_error == BLOCKDEV_ON_ERROR_STOP));
+           (blk->on_write_error == BlockdevOnError_enospc ||
+            blk->on_write_error == BlockdevOnError_stop   ||
+            blk->on_read_error == BlockdevOnError_stop));
 }
 
 BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk)
@@ -515,7 +515,7 @@ void blk_iostatus_disable(BlockBackend *blk)
 void blk_iostatus_reset(BlockBackend *blk)
 {
     if (blk_iostatus_is_enabled(blk)) {
-        blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
+        blk->iostatus = BlockDeviceIoStatus_ok;
         if (blk->bs && blk->bs->job) {
             block_job_iostatus_reset(blk->bs->job);
         }
@@ -525,9 +525,9 @@ void blk_iostatus_reset(BlockBackend *blk)
 void blk_iostatus_set_err(BlockBackend *blk, int error)
 {
     assert(blk_iostatus_is_enabled(blk));
-    if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
-        blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
-                                          BLOCK_DEVICE_IO_STATUS_FAILED;
+    if (blk->iostatus == BlockDeviceIoStatus_ok) {
+        blk->iostatus = error == ENOSPC ? BlockDeviceIoStatus_nospace :
+                                          BlockDeviceIoStatus_failed;
     }
 }
 
@@ -856,15 +856,15 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
     BlockdevOnError on_err = blk_get_on_error(blk, is_read);
 
     switch (on_err) {
-    case BLOCKDEV_ON_ERROR_ENOSPC:
+    case BlockdevOnError_enospc:
         return (error == ENOSPC) ?
-               BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
-    case BLOCKDEV_ON_ERROR_STOP:
-        return BLOCK_ERROR_ACTION_STOP;
-    case BLOCKDEV_ON_ERROR_REPORT:
-        return BLOCK_ERROR_ACTION_REPORT;
-    case BLOCKDEV_ON_ERROR_IGNORE:
-        return BLOCK_ERROR_ACTION_IGNORE;
+               BlockErrorAction_stop : BlockErrorAction_report;
+    case BlockdevOnError_stop:
+        return BlockErrorAction_stop;
+    case BlockdevOnError_report:
+        return BlockErrorAction_report;
+    case BlockdevOnError_ignore:
+        return BlockErrorAction_ignore;
     default:
         abort();
     }
@@ -876,7 +876,7 @@ static void send_qmp_error_event(BlockBackend *blk,
 {
     IoOperationType optype;
 
-    optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
+    optype = is_read ? IoOperationType_read : IoOperationType_write;
     qapi_event_send_block_io_error(blk_name(blk), optype, action,
                                    blk_iostatus_is_enabled(blk),
                                    error == ENOSPC, strerror(error),
@@ -892,7 +892,7 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
 {
     assert(error >= 0);
 
-    if (action == BLOCK_ERROR_ACTION_STOP) {
+    if (action == BlockErrorAction_stop) {
         /* First set the iostatus, so that "info block" returns an iostatus
          * that matches the events raised so far (an additional error iostatus
          * is fine, but not a lost one).
@@ -909,7 +909,7 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
          */
         qemu_system_vmstop_request_prepare();
         send_qmp_error_event(blk, action, is_read, error);
-        qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
+        qemu_system_vmstop_request(RunState_io_error);
     } else {
         send_qmp_error_event(blk, action, is_read, error);
     }
diff --git a/block/commit.c b/block/commit.c
index fdebe87..7173832 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -160,9 +160,9 @@ wait:
             bytes_written += n * BDRV_SECTOR_SIZE;
         }
         if (ret < 0) {
-            if (s->on_error == BLOCKDEV_ON_ERROR_STOP ||
-                s->on_error == BLOCKDEV_ON_ERROR_REPORT||
-                (s->on_error == BLOCKDEV_ON_ERROR_ENOSPC && ret == -ENOSPC)) {
+            if (s->on_error == BlockdevOnError_stop ||
+                s->on_error == BlockdevOnError_report||
+                (s->on_error == BlockdevOnError_enospc && ret == -ENOSPC)) {
                 goto out;
             } else {
                 n = 0;
@@ -196,7 +196,7 @@ static void commit_set_speed(BlockJob *job, int64_t speed, Error **errp)
 
 static const BlockJobDriver commit_job_driver = {
     .instance_size = sizeof(CommitBlockJob),
-    .job_type      = BLOCK_JOB_TYPE_COMMIT,
+    .job_type      = BlockJobType_commit,
     .set_speed     = commit_set_speed,
 };
 
@@ -212,8 +212,8 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
     BlockDriverState *overlay_bs;
     Error *local_err = NULL;
 
-    if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
-         on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+    if ((on_error == BlockdevOnError_stop ||
+         on_error == BlockdevOnError_enospc) &&
         (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
         error_setg(errp, "Invalid parameter combination");
         return;
diff --git a/block/io.c b/block/io.c
index 8dcad3b..f32ee63 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1129,11 +1129,11 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
 
     ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
 
-    if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF &&
+    if (!ret && bs->detect_zeroes != BlockdevDetectZeroesOptions_off &&
         !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_write_zeroes &&
         qemu_iovec_is_zero(qiov)) {
         flags |= BDRV_REQ_ZERO_WRITE;
-        if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) {
+        if (bs->detect_zeroes == BlockdevDetectZeroesOptions_unmap) {
             flags |= BDRV_REQ_MAY_UNMAP;
         }
     }
diff --git a/block/mirror.c b/block/mirror.c
index b1252a1..80cacd0 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -130,7 +130,7 @@ static void mirror_write_complete(void *opaque, int ret)
 
         bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
         action = mirror_error_action(s, false, -ret);
-        if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
+        if (action == BlockErrorAction_report && s->ret >= 0) {
             s->ret = ret;
         }
     }
@@ -146,7 +146,7 @@ static void mirror_read_complete(void *opaque, int ret)
 
         bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
         action = mirror_error_action(s, true, -ret);
-        if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
+        if (action == BlockErrorAction_report && s->ret >= 0) {
             s->ret = ret;
         }
 
@@ -511,7 +511,7 @@ static void coroutine_fn mirror_run(void *opaque)
          * or when the source is clean, whichever comes first.
          */
         if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - last_pause_ns < SLICE_TIME &&
-            s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
+            s->common.iostatus == BlockDeviceIoStatus_ok) {
             if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
                 (cnt == 0 && s->in_flight > 0)) {
                 trace_mirror_yield(s, s->in_flight, s->buf_free_count, cnt);
@@ -530,7 +530,7 @@ static void coroutine_fn mirror_run(void *opaque)
             ret = bdrv_flush(s->target);
             if (ret < 0) {
                 if (mirror_error_action(s, false, -ret) ==
-                    BLOCK_ERROR_ACTION_REPORT) {
+                    BlockErrorAction_report) {
                     goto immediate_exit;
                 }
             } else {
@@ -672,7 +672,7 @@ static void mirror_complete(BlockJob *job, Error **errp)
 
 static const BlockJobDriver mirror_job_driver = {
     .instance_size = sizeof(MirrorBlockJob),
-    .job_type      = BLOCK_JOB_TYPE_MIRROR,
+    .job_type      = BlockJobType_mirror,
     .set_speed     = mirror_set_speed,
     .iostatus_reset= mirror_iostatus_reset,
     .complete      = mirror_complete,
@@ -680,7 +680,7 @@ static const BlockJobDriver mirror_job_driver = {
 
 static const BlockJobDriver commit_active_job_driver = {
     .instance_size = sizeof(MirrorBlockJob),
-    .job_type      = BLOCK_JOB_TYPE_COMMIT,
+    .job_type      = BlockJobType_commit,
     .set_speed     = mirror_set_speed,
     .iostatus_reset
                    = mirror_iostatus_reset,
@@ -707,8 +707,8 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
 
     assert ((granularity & (granularity - 1)) == 0);
 
-    if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
-         on_source_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+    if ((on_source_error == BlockdevOnError_stop ||
+         on_source_error == BlockdevOnError_enospc) &&
         (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
         error_setg(errp, QERR_INVALID_PARAMETER, "on-source-error");
         return;
@@ -766,12 +766,12 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
     bool is_none_mode;
     BlockDriverState *base;
 
-    if (mode == MIRROR_SYNC_MODE_INCREMENTAL) {
+    if (mode == MirrorSyncMode_incremental) {
         error_setg(errp, "Sync mode 'incremental' not supported");
         return;
     }
-    is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
-    base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
+    is_none_mode = mode == MirrorSyncMode_none;
+    base = mode == MirrorSyncMode_top ? backing_bs(bs) : NULL;
     mirror_start_job(bs, target, replaces,
                      speed, granularity, buf_size,
                      on_source_error, on_target_error, unmap, cb, opaque, errp,
diff --git a/block/nbd.c b/block/nbd.c
index cd6a587..281799a 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -206,12 +206,12 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
     saddr = g_new0(SocketAddress, 1);
 
     if (qdict_haskey(options, "path")) {
-        saddr->type = SOCKET_ADDRESS_KIND_UNIX;
+        saddr->type = SocketAddressKind_unix;
         saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
         saddr->u.q_unix->path = g_strdup(qdict_get_str(options, "path"));
         qdict_del(options, "path");
     } else {
-        saddr->type = SOCKET_ADDRESS_KIND_INET;
+        saddr->type = SocketAddressKind_inet;
         saddr->u.inet = g_new0(InetSocketAddress, 1);
         saddr->u.inet->host = g_strdup(qdict_get_str(options, "host"));
         if (!qdict_get_try_str(options, "port")) {
@@ -223,7 +223,7 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
         qdict_del(options, "port");
     }
 
-    s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+    s->client.is_unix = saddr->type == SocketAddressKind_unix;
 
     *export = g_strdup(qdict_get_try_str(options, "export"));
     if (*export) {
diff --git a/block/qcow2.c b/block/qcow2.c
index 88f56c8..49a3cfe 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2040,7 +2040,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     Error *local_err = NULL;
     int ret;
 
-    if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
+    if (prealloc == PreallocMode_full || prealloc == PreallocMode_falloc) {
         /* Note: The following calculation does not need to be exact; if it is a
          * bit off, either some bytes will be "leaked" (which is fine) or we
          * will need to increase the file size by some bytes (which is fine,
@@ -2209,7 +2209,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     }
 
     /* And if we're supposed to preallocate metadata, do that now */
-    if (prealloc != PREALLOC_MODE_OFF) {
+    if (prealloc != PreallocMode_off) {
         BDRVQcow2State *s = bs->opaque;
         qemu_co_mutex_lock(&s->lock);
         ret = preallocate(bs);
@@ -2269,7 +2269,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
                                          DEFAULT_CLUSTER_SIZE);
     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
     prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
-                               PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+                               PreallocMode_MAX, PreallocMode_off,
                                &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -2294,7 +2294,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
         flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
     }
 
-    if (backing_file && prealloc != PREALLOC_MODE_OFF) {
+    if (backing_file && prealloc != PreallocMode_off) {
         error_setg(errp, "Backing file and preallocation cannot be used at "
                    "the same time");
         ret = -EINVAL;
@@ -2738,7 +2738,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
     ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
 
     *spec_info = (ImageInfoSpecific){
-        .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
+        .type  = ImageInfoSpecificKind_qcow2,
         .u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
     };
     if (s->qcow_version == 2) {
diff --git a/block/quorum.c b/block/quorum.c
index b9ba028..f9de3a6 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -283,7 +283,7 @@ static void quorum_aio_cb(void *opaque, int ret)
     BDRVQuorumState *s = acb->common.bs->opaque;
     bool rewrite = false;
 
-    if (acb->is_read && s->read_pattern == QUORUM_READ_PATTERN_FIFO) {
+    if (acb->is_read && s->read_pattern == QuorumReadPattern_fifo) {
         /* We try to read next child in FIFO order if we fail to read */
         if (ret < 0 && ++acb->child_iter < s->num_children) {
             read_fifo_child(acb);
@@ -681,7 +681,7 @@ static BlockAIOCB *quorum_aio_readv(BlockDriverState *bs,
                                       nb_sectors, cb, opaque);
     acb->is_read = true;
 
-    if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
+    if (s->read_pattern == QuorumReadPattern_quorum) {
         acb->child_iter = s->num_children - 1;
         return read_quorum_children(acb);
     }
@@ -844,10 +844,10 @@ static int parse_read_pattern(const char *opt)
 
     if (!opt) {
         /* Set quorum as default */
-        return QUORUM_READ_PATTERN_QUORUM;
+        return QuorumReadPattern_quorum;
     }
 
-    for (i = 0; i < QUORUM_READ_PATTERN_MAX; i++) {
+    for (i = 0; i < QuorumReadPattern_MAX; i++) {
         if (!strcmp(opt, QuorumReadPattern_lookup[i])) {
             return i;
         }
@@ -903,7 +903,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
     }
     s->read_pattern = ret;
 
-    if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
+    if (s->read_pattern == QuorumReadPattern_quorum) {
         /* is the driver in blkverify mode */
         if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
             s->num_children == 2 && s->threshold == 2) {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 918c756..d825003 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1636,7 +1636,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,
+                               PreallocMode_MAX, PreallocMode_off,
                                &local_err);
     g_free(buf);
     if (local_err) {
@@ -1676,7 +1676,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
 
     switch (prealloc) {
 #ifdef CONFIG_POSIX_FALLOCATE
-    case PREALLOC_MODE_FALLOC:
+    case PreallocMode_falloc:
         /* posix_fallocate() doesn't set errno. */
         result = -posix_fallocate(fd, 0, total_size);
         if (result != 0) {
@@ -1685,7 +1685,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
         }
         break;
 #endif
-    case PREALLOC_MODE_FULL:
+    case PreallocMode_full:
     {
         int64_t num = 0, left = total_size;
         buf = g_malloc0(65536);
@@ -1712,7 +1712,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
         g_free(buf);
         break;
     }
-    case PREALLOC_MODE_OFF:
+    case PreallocMode_off:
         break;
     default:
         result = -EINVAL;
diff --git a/block/stream.c b/block/stream.c
index 25af7ef..268c09f 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -163,14 +163,14 @@ wait:
             BlockErrorAction action =
                 block_job_error_action(&s->common, s->common.bs, s->on_error,
                                        true, -ret);
-            if (action == BLOCK_ERROR_ACTION_STOP) {
+            if (action == BlockErrorAction_stop) {
                 n = 0;
                 continue;
             }
             if (error == 0) {
                 error = ret;
             }
-            if (action == BLOCK_ERROR_ACTION_REPORT) {
+            if (action == BlockErrorAction_report) {
                 break;
             }
         }
@@ -209,7 +209,7 @@ static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
 
 static const BlockJobDriver stream_job_driver = {
     .instance_size = sizeof(StreamBlockJob),
-    .job_type      = BLOCK_JOB_TYPE_STREAM,
+    .job_type      = BlockJobType_stream,
     .set_speed     = stream_set_speed,
 };
 
@@ -221,8 +221,8 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
 {
     StreamBlockJob *s;
 
-    if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
-         on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
+    if ((on_error == BlockdevOnError_stop ||
+         on_error == BlockdevOnError_enospc) &&
         (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
         error_setg(errp, QERR_INVALID_PARAMETER, "on-error");
         return;
diff --git a/block/vmdk.c b/block/vmdk.c
index 6f819e4..6c029c0 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -2161,7 +2161,7 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
     ImageInfoList **next;
 
     *spec_info = (ImageInfoSpecific){
-        .type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
+        .type = ImageInfoSpecificKind_vmdk,
         {
             .vmdk = g_new0(ImageInfoSpecificVmdk, 1),
         },
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index bcdd18b..491aba5 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -90,7 +90,7 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
diff --git a/blockdev.c b/blockdev.c
index 8b8bfa9..1ffd6b1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -312,13 +312,13 @@ static void bdrv_put_ref_bh_schedule(BlockDriverState *bs)
 static int parse_block_error_action(const char *buf, bool is_read, Error **errp)
 {
     if (!strcmp(buf, "ignore")) {
-        return BLOCKDEV_ON_ERROR_IGNORE;
+        return BlockdevOnError_ignore;
     } else if (!is_read && !strcmp(buf, "enospc")) {
-        return BLOCKDEV_ON_ERROR_ENOSPC;
+        return BlockdevOnError_enospc;
     } else if (!strcmp(buf, "stop")) {
-        return BLOCKDEV_ON_ERROR_STOP;
+        return BlockdevOnError_stop;
     } else if (!strcmp(buf, "report")) {
-        return BLOCKDEV_ON_ERROR_REPORT;
+        return BlockdevOnError_report;
     } else {
         error_setg(errp, "'%s' invalid %s error action",
                    buf, is_read ? "read" : "write");
@@ -441,8 +441,8 @@ 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,
+                            BlockdevDetectZeroesOptions_MAX,
+                            BlockdevDetectZeroesOptions_off,
                             &local_error);
         if (local_error) {
             error_propagate(errp, local_error);
@@ -450,7 +450,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
         }
 
         if (bdrv_flags &&
-            *detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
+            *detect_zeroes == BlockdevDetectZeroesOptions_unmap &&
             !(*bdrv_flags & BDRV_O_UNMAP))
         {
             error_setg(errp, "setting detect-zeroes to unmap is not allowed "
@@ -476,7 +476,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
     const char *id;
     bool has_driver_specific_opts;
     BlockdevDetectZeroesOptions detect_zeroes =
-        BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+        BlockdevDetectZeroesOptions_off;
     const char *throttling_group = NULL;
 
     /* Check common options by copying from bs_opts to opts, all other options
@@ -525,7 +525,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
         qdict_put(bs_opts, "driver", qstring_from_str(buf));
     }
 
-    on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
+    on_write_error = BlockdevOnError_enospc;
     if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
         on_write_error = parse_block_error_action(buf, 0, &error);
         if (error) {
@@ -534,7 +534,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
         }
     }
 
-    on_read_error = BLOCKDEV_ON_ERROR_REPORT;
+    on_read_error = BlockdevOnError_report;
     if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
         on_read_error = parse_block_error_action(buf, 1, &error);
         if (error) {
@@ -928,7 +928,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
         }
     }
 
-    translation = BIOS_ATA_TRANSLATION_AUTO;
+    translation = BiosAtaTranslation_auto;
     value = qemu_opt_get(legacy_opts, "trans");
     if (value != NULL) {
         if (!cyls) {
@@ -937,15 +937,15 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
             goto fail;
         }
         if (!strcmp(value, "none")) {
-            translation = BIOS_ATA_TRANSLATION_NONE;
+            translation = BiosAtaTranslation_none;
         } else if (!strcmp(value, "lba")) {
-            translation = BIOS_ATA_TRANSLATION_LBA;
+            translation = BiosAtaTranslation_lba;
         } else if (!strcmp(value, "large")) {
-            translation = BIOS_ATA_TRANSLATION_LARGE;
+            translation = BiosAtaTranslation_large;
         } else if (!strcmp(value, "rechs")) {
-            translation = BIOS_ATA_TRANSLATION_RECHS;
+            translation = BiosAtaTranslation_rechs;
         } else if (!strcmp(value, "auto")) {
-            translation = BIOS_ATA_TRANSLATION_AUTO;
+            translation = BiosAtaTranslation_auto;
         } else {
             error_report("'%s' invalid translation type", value);
             goto fail;
@@ -1171,7 +1171,7 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,
         .has_mode = has_mode,
         .mode = mode,
     };
-    blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
+    blockdev_do_action(TransactionActionKind_blockdev_snapshot_sync,
                        &snapshot, errp);
 }
 
@@ -1184,7 +1184,7 @@ void qmp_blockdev_snapshot_internal_sync(const char *device,
         .name = (char *) name
     };
 
-    blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,
+    blockdev_do_action(TransactionActionKind_blockdev_snapshot_internal_sync,
                        &snapshot, errp);
 }
 
@@ -1205,7 +1205,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return NULL;
     }
@@ -1390,7 +1390,7 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
     int ret1;
 
     g_assert(common->action->type ==
-             TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC);
+             TransactionActionKind_blockdev_snapshot_internal_sync);
     internal = common->action->u.blockdev_snapshot_internal_sync;
     state = DO_UPCAST(InternalSnapshotState, common, common);
 
@@ -1401,7 +1401,7 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
     /* 2. check for validation */
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -1531,13 +1531,13 @@ static void external_snapshot_prepare(BlkTransactionState *common,
     const char *snapshot_node_name;
     const char *new_image_file;
     const char *format = "qcow2";
-    enum NewImageMode mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    enum NewImageMode mode = NewImageMode_absolute_paths;
     ExternalSnapshotState *state =
                              DO_UPCAST(ExternalSnapshotState, common, common);
     TransactionAction *action = common->action;
 
     /* get parameters */
-    g_assert(action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
+    g_assert(action->type == TransactionActionKind_blockdev_snapshot_sync);
 
     has_device = action->u.blockdev_snapshot_sync->has_device;
     device = action->u.blockdev_snapshot_sync->device;
@@ -1604,7 +1604,7 @@ static void external_snapshot_prepare(BlkTransactionState *common,
     flags = state->old_bs->open_flags;
 
     /* create new image w/backing file */
-    if (mode != NEW_IMAGE_MODE_EXISTING) {
+    if (mode != NewImageMode_existing) {
         bdrv_img_create(new_image_file, format,
                         state->old_bs->filename,
                         state->old_bs->drv->format_name,
@@ -1682,12 +1682,12 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
     DriveBackup *backup;
     Error *local_err = NULL;
 
-    assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
+    assert(common->action->type == TransactionActionKind_drive_backup);
     backup = common->action->u.drive_backup;
 
     blk = blk_by_name(backup->device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", backup->device);
         return;
     }
@@ -1755,7 +1755,7 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
     BlockBackend *blk, *target;
     Error *local_err = NULL;
 
-    assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
+    assert(common->action->type == TransactionActionKind_blockdev_backup);
     backup = common->action->u.blockdev_backup;
 
     blk = blk_by_name(backup->device);
@@ -1832,31 +1832,31 @@ static void abort_commit(BlkTransactionState *common)
 }
 
 static const BdrvActionOps actions[] = {
-    [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC] = {
+    [TransactionActionKind_blockdev_snapshot_sync] = {
         .instance_size = sizeof(ExternalSnapshotState),
         .prepare  = external_snapshot_prepare,
         .commit   = external_snapshot_commit,
         .abort = external_snapshot_abort,
         .clean = external_snapshot_clean,
     },
-    [TRANSACTION_ACTION_KIND_DRIVE_BACKUP] = {
+    [TransactionActionKind_drive_backup] = {
         .instance_size = sizeof(DriveBackupState),
         .prepare = drive_backup_prepare,
         .abort = drive_backup_abort,
         .clean = drive_backup_clean,
     },
-    [TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP] = {
+    [TransactionActionKind_blockdev_backup] = {
         .instance_size = sizeof(BlockdevBackupState),
         .prepare = blockdev_backup_prepare,
         .abort = blockdev_backup_abort,
         .clean = blockdev_backup_clean,
     },
-    [TRANSACTION_ACTION_KIND_ABORT] = {
+    [TransactionActionKind_abort] = {
         .instance_size = sizeof(BlkTransactionState),
         .prepare = abort_prepare,
         .commit = abort_commit,
     },
-    [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC] = {
+    [TransactionActionKind_blockdev_snapshot_internal_sync] = {
         .instance_size = sizeof(InternalSnapshotState),
         .prepare  = internal_snapshot_prepare,
         .abort = internal_snapshot_abort,
@@ -1974,7 +1974,7 @@ void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2042,7 +2042,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2108,7 +2108,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2315,8 +2315,8 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
     if (blk_get_attached_dev(blk)) {
         blk_hide_on_behalf_of_hmp_drive_del(blk);
         /* Further I/O must not pause the guest */
-        blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
-                         BLOCKDEV_ON_ERROR_REPORT);
+        blk_set_on_error(blk, BlockdevOnError_report,
+                         BlockdevOnError_report);
     } else {
         blk_unref(blk);
     }
@@ -2429,12 +2429,12 @@ void qmp_block_stream(const char *device,
     const char *base_name = NULL;
 
     if (!has_on_error) {
-        on_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_error = BlockdevOnError_report;
     }
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2501,7 +2501,7 @@ void qmp_block_commit(const char *device,
     /* This will be part of the QMP command, if/when the
      * BlockdevOnError change for blkmirror makes it in
      */
-    BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;
+    BlockdevOnError on_error = BlockdevOnError_report;
 
     if (!has_speed) {
         speed = 0;
@@ -2514,7 +2514,7 @@ void qmp_block_commit(const char *device,
      *  scenario in which all optional arguments are omitted. */
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2618,18 +2618,18 @@ void qmp_drive_backup(const char *device, const char *target,
         speed = 0;
     }
     if (!has_on_source_error) {
-        on_source_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_source_error = BlockdevOnError_report;
     }
     if (!has_on_target_error) {
-        on_target_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_target_error = BlockdevOnError_report;
     }
     if (!has_mode) {
-        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+        mode = NewImageMode_absolute_paths;
     }
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2646,7 +2646,7 @@ void qmp_drive_backup(const char *device, const char *target,
     bs = blk_bs(blk);
 
     if (!has_format) {
-        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
+        format = mode == NewImageMode_existing ? NULL : bs->drv->format_name;
     }
 
     /* Early check to avoid creating target */
@@ -2658,13 +2658,13 @@ void qmp_drive_backup(const char *device, const char *target,
 
     /* See if we have a backing HD we can use to create our new image
      * on top of. */
-    if (sync == MIRROR_SYNC_MODE_TOP) {
+    if (sync == MirrorSyncMode_top) {
         source = backing_bs(bs);
         if (!source) {
-            sync = MIRROR_SYNC_MODE_FULL;
+            sync = MirrorSyncMode_full;
         }
     }
-    if (sync == MIRROR_SYNC_MODE_NONE) {
+    if (sync == MirrorSyncMode_none) {
         source = bs;
     }
 
@@ -2674,7 +2674,7 @@ void qmp_drive_backup(const char *device, const char *target,
         goto out;
     }
 
-    if (mode != NEW_IMAGE_MODE_EXISTING) {
+    if (mode != NewImageMode_existing) {
         assert(format);
         if (source) {
             bdrv_img_create(target, format, source->filename,
@@ -2750,10 +2750,10 @@ void qmp_blockdev_backup(const char *device, const char *target,
         speed = 0;
     }
     if (!has_on_source_error) {
-        on_source_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_source_error = BlockdevOnError_report;
     }
     if (!has_on_target_error) {
-        on_target_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_target_error = BlockdevOnError_report;
     }
 
     blk = blk_by_name(device);
@@ -2823,13 +2823,13 @@ void qmp_drive_mirror(const char *device, const char *target,
         speed = 0;
     }
     if (!has_on_source_error) {
-        on_source_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_source_error = BlockdevOnError_report;
     }
     if (!has_on_target_error) {
-        on_target_error = BLOCKDEV_ON_ERROR_REPORT;
+        on_target_error = BlockdevOnError_report;
     }
     if (!has_mode) {
-        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+        mode = NewImageMode_absolute_paths;
     }
     if (!has_granularity) {
         granularity = 0;
@@ -2854,7 +2854,7 @@ void qmp_drive_mirror(const char *device, const char *target,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -2869,7 +2869,7 @@ void qmp_drive_mirror(const char *device, const char *target,
     bs = blk_bs(blk);
 
     if (!has_format) {
-        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
+        format = mode == NewImageMode_existing ? NULL : bs->drv->format_name;
     }
 
     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_MIRROR, errp)) {
@@ -2878,10 +2878,10 @@ void qmp_drive_mirror(const char *device, const char *target,
 
     flags = bs->open_flags | BDRV_O_RDWR;
     source = backing_bs(bs);
-    if (!source && sync == MIRROR_SYNC_MODE_TOP) {
-        sync = MIRROR_SYNC_MODE_FULL;
+    if (!source && sync == MirrorSyncMode_top) {
+        sync = MirrorSyncMode_full;
     }
-    if (sync == MIRROR_SYNC_MODE_NONE) {
+    if (sync == MirrorSyncMode_none) {
         source = bs;
     }
 
@@ -2921,8 +2921,8 @@ void qmp_drive_mirror(const char *device, const char *target,
         }
     }
 
-    if ((sync == MIRROR_SYNC_MODE_FULL || !source)
-        && mode != NEW_IMAGE_MODE_EXISTING)
+    if ((sync == MirrorSyncMode_full || !source)
+        && mode != NewImageMode_existing)
     {
         /* create new image w/o backing file */
         assert(format);
@@ -2930,9 +2930,9 @@ void qmp_drive_mirror(const char *device, const char *target,
                         NULL, NULL, NULL, size, flags, &local_err, false);
     } else {
         switch (mode) {
-        case NEW_IMAGE_MODE_EXISTING:
+        case NewImageMode_existing:
             break;
-        case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
+        case NewImageMode_absolute_paths:
             /* create new image with backing file */
             bdrv_img_create(target, format,
                             source->filename,
@@ -3018,7 +3018,7 @@ static BlockJob *find_block_job(const char *device, AioContext **aio_context,
     return bs->job;
 
 notfound:
-    error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+    error_set(errp, ErrorClass_DeviceNotActive,
               "No active block job on device '%s'", device);
     if (*aio_context) {
         aio_context_release(*aio_context);
@@ -3126,7 +3126,7 @@ void qmp_change_backing_file(const char *device,
 
     blk = blk_by_name(device);
     if (!blk) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
         return;
     }
@@ -3217,7 +3217,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
      * when called from drive_new().
      *
      * For now, simply forbidding the combination for all drivers will do. */
-    if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {
+    if (options->has_aio && options->aio == BlockdevAioOptions_native) {
         bool direct = options->has_cache &&
                       options->cache->has_direct &&
                       options->cache->direct;
diff --git a/blockjob.c b/blockjob.c
index c02fe59..c0e2824 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -164,7 +164,7 @@ bool block_job_is_cancelled(BlockJob *job)
 
 void block_job_iostatus_reset(BlockJob *job)
 {
-    job->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
+    job->iostatus = BlockDeviceIoStatus_ok;
     if (job->driver->iostatus_reset) {
         job->driver->iostatus_reset(job);
     }
@@ -284,9 +284,9 @@ BlockJobInfo *block_job_query(BlockJob *job)
 
 static void block_job_iostatus_set_err(BlockJob *job, int error)
 {
-    if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
-        job->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
-                                          BLOCK_DEVICE_IO_STATUS_FAILED;
+    if (job->iostatus == BlockDeviceIoStatus_ok) {
+        job->iostatus = error == ENOSPC ? BlockDeviceIoStatus_nospace :
+                                          BlockDeviceIoStatus_failed;
     }
 }
 
@@ -330,27 +330,27 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
     BlockErrorAction action;
 
     switch (on_err) {
-    case BLOCKDEV_ON_ERROR_ENOSPC:
+    case BlockdevOnError_enospc:
         action = (error == ENOSPC) ?
-                 BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
+                 BlockErrorAction_stop : BlockErrorAction_report;
         break;
-    case BLOCKDEV_ON_ERROR_STOP:
-        action = BLOCK_ERROR_ACTION_STOP;
+    case BlockdevOnError_stop:
+        action = BlockErrorAction_stop;
         break;
-    case BLOCKDEV_ON_ERROR_REPORT:
-        action = BLOCK_ERROR_ACTION_REPORT;
+    case BlockdevOnError_report:
+        action = BlockErrorAction_report;
         break;
-    case BLOCKDEV_ON_ERROR_IGNORE:
-        action = BLOCK_ERROR_ACTION_IGNORE;
+    case BlockdevOnError_ignore:
+        action = BlockErrorAction_ignore;
         break;
     default:
         abort();
     }
     qapi_event_send_block_job_error(job->id,
-                                    is_read ? IO_OPERATION_TYPE_READ :
-                                    IO_OPERATION_TYPE_WRITE,
+                                    is_read ? IoOperationType_read :
+                                    IoOperationType_write,
                                     action, &error_abort);
-    if (action == BLOCK_ERROR_ACTION_STOP) {
+    if (action == BlockErrorAction_stop) {
         /* make the pause user visible, which will be resumed from QMP. */
         job->user_paused = true;
         block_job_pause(job);
diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c
index c3fcdaf..3f03c70 100644
--- a/crypto/tlscredsanon.c
+++ b/crypto/tlscredsanon.c
@@ -38,7 +38,7 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds,
     trace_qcrypto_tls_creds_anon_load(creds,
             creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>");
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
         if (qcrypto_tls_creds_get_path(&creds->parent_obj,
                                        QCRYPTO_TLS_CREDS_DH_PARAMS,
                                        false, &dhparams, errp) < 0) {
@@ -79,7 +79,7 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds,
 static void
 qcrypto_tls_creds_anon_unload(QCryptoTLSCredsAnon *creds)
 {
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
+    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_client) {
         if (creds->data.client) {
             gnutls_anon_free_client_credentials(creds->data.client);
             creds->data.client = NULL;
@@ -141,7 +141,7 @@ qcrypto_tls_creds_anon_prop_get_loaded(Object *obj,
 {
     QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj);
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
         return creds->data.server != NULL;
     } else {
         return creds->data.client != NULL;
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index dc46bc4..9137da3 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -549,7 +549,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
     trace_qcrypto_tls_creds_x509_load(creds,
             creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>");
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
         if (qcrypto_tls_creds_get_path(&creds->parent_obj,
                                        QCRYPTO_TLS_CREDS_X509_CA_CERT,
                                        true, &cacert, errp) < 0 ||
@@ -583,7 +583,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
 
     if (creds->sanityCheck &&
         qcrypto_tls_creds_x509_sanity_check(creds,
-            creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
+            creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server,
             cacert, cert, errp) < 0) {
         goto cleanup;
     }
@@ -626,7 +626,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
         }
     }
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
         if (qcrypto_tls_creds_get_dh_params_file(&creds->parent_obj, dhparams,
                                                  &creds->parent_obj.dh_params,
                                                  errp) < 0) {
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index ffc5c47..bd0bac4 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -116,7 +116,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
         goto error;
     }
 
-    if (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+    if (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
         ret = gnutls_init(&session->handle, GNUTLS_SERVER);
     } else {
         ret = gnutls_init(&session->handle, GNUTLS_CLIENT);
@@ -138,7 +138,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
                        gnutls_strerror(ret));
             goto error;
         }
-        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
             ret = gnutls_credentials_set(session->handle,
                                          GNUTLS_CRD_ANON,
                                          acreds->data.server);
@@ -171,7 +171,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
             goto error;
         }
 
-        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
             /* This requests, but does not enforce a client cert.
              * The cert checking code later does enforcement */
             gnutls_certificate_server_set_request(session->handle,
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 20e6907..24ab324 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -257,6 +257,7 @@ useful.  The list of strings should be lower case; if an enum name
 represents multiple words, use '-' between words.  The string 'max' is
 not allowed as an enum value, and values should not be repeated.
 
+FIXME obsolete, rewrite
 The enum constants will be named by using a heuristic to turn the
 type name into a set of underscore separated words. For the example
 above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name
@@ -1034,15 +1035,15 @@ Example:
 
         qmp = qmp_event_build_dict("MY_EVENT");
 
-        emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp, &err);
+        emit(example_QAPIEvent_MY_EVENT, qmp, &err);
 
         error_propagate(errp, err);
         QDECREF(qmp);
     }
 
     const char *const example_QAPIEvent_lookup[] = {
-        [EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT",
-        [EXAMPLE_QAPI_EVENT_MAX] = NULL,
+        [example_QAPIEvent_MY_EVENT] = "MY_EVENT",
+        [example_QAPIEvent_MAX] = NULL,
     };
     $ cat qapi-generated/example-qapi-event.h
 [Uninteresting stuff omitted...]
@@ -1058,8 +1059,8 @@ Example:
     void qapi_event_send_my_event(Error **errp);
 
     typedef enum example_QAPIEvent {
-        EXAMPLE_QAPI_EVENT_MY_EVENT = 0,
-        EXAMPLE_QAPI_EVENT_MAX = 1,
+        example_QAPIEvent_MY_EVENT = 0,
+        example_QAPIEvent_MAX = 1,
     } example_QAPIEvent;
 
     extern const char *const example_QAPIEvent_lookup[];
diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt
index 8647cac..fb0f42a 100644
--- a/docs/writing-qmp-commands.txt
+++ b/docs/writing-qmp-commands.txt
@@ -219,7 +219,7 @@ void qmp_hello_world(bool has_message, const char *message, Error **errp)
 {
     if (has_message) {
         if (strstr(message, "love")) {
-            error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+            error_set(errp, ErrorClass_GenericError,
                       "the word 'love' is not allowed");
             return;
         }
@@ -231,7 +231,7 @@ void qmp_hello_world(bool has_message, const char *message, Error **errp)
 
 The first argument to the error_set() function is the Error pointer to pointer,
 which is passed to all QMP functions. The second argument is a ErrorClass
-value, which should be ERROR_CLASS_GENERIC_ERROR most of the time (more
+value, which should be ErrorClass_GenericError most of the time (more
 details about error classes are given below). The third argument is a human
 description of the error, this is a free-form printf-like string.
 
@@ -249,7 +249,7 @@ The QMP server's response should be:
     }
 }
 
-As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR. There
+As a general rule, all QMP errors should use ErrorClass_GenericError. There
 are two exceptions to this rule:
 
  1. A non-generic ErrorClass value exists* for the failure you want to report
@@ -260,7 +260,7 @@ are two exceptions to this rule:
     can check for it
 
 If the failure you want to report doesn't fall in one of the two cases above,
-just report ERROR_CLASS_GENERIC_ERROR.
+just report ErrorClass_GenericError.
 
  * All existing ErrorClass values are defined in the qapi-schema.json file
 
diff --git a/dump.c b/dump.c
index 78b7d84..f0c87a8 100644
--- a/dump.c
+++ b/dump.c
@@ -1443,12 +1443,12 @@ static void dump_init(DumpState *s, int fd, bool has_format,
     int ret;
 
     /* kdump-compressed is conflict with paging and filter */
-    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+    if (has_format && format != DumpGuestMemoryFormat_elf) {
         assert(!paging && !has_filter);
     }
 
     if (runstate_is_running()) {
-        vm_stop(RUN_STATE_SAVE_VM);
+        vm_stop(RunState_save_vm);
         s->resume = true;
     } else {
         s->resume = false;
@@ -1516,13 +1516,13 @@ static void dump_init(DumpState *s, int fd, bool has_format,
     s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;
 
     /* init for kdump-compressed format */
-    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+    if (has_format && format != DumpGuestMemoryFormat_elf) {
         switch (format) {
-        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
+        case DumpGuestMemoryFormat_kdump_zlib:
             s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
             break;
 
-        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
+        case DumpGuestMemoryFormat_kdump_lzo:
 #ifdef CONFIG_LZO
             if (lzo_init() != LZO_E_OK) {
                 error_setg(errp, "failed to initialize the LZO library");
@@ -1532,7 +1532,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
             s->flag_compress = DUMP_DH_COMPRESSED_LZO;
             break;
 
-        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
+        case DumpGuestMemoryFormat_kdump_snappy:
             s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
             break;
 
@@ -1609,7 +1609,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
      * kdump-compressed format need the whole memory dumped, so paging or
      * filter is not supported here.
      */
-    if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
+    if ((has_format && format != DumpGuestMemoryFormat_elf) &&
         (paging || has_begin || has_length)) {
         error_setg(errp, "kdump-compressed format doesn't support paging or "
                          "filter");
@@ -1626,14 +1626,14 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
 
     /* check whether lzo/snappy is supported */
 #ifndef CONFIG_LZO
-    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
+    if (has_format && format == DumpGuestMemoryFormat_kdump_lzo) {
         error_setg(errp, "kdump-lzo is not available now");
         return;
     }
 #endif
 
 #ifndef CONFIG_SNAPPY
-    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
+    if (has_format && format == DumpGuestMemoryFormat_kdump_snappy) {
         error_setg(errp, "kdump-snappy is not available now");
         return;
     }
@@ -1671,7 +1671,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
         return;
     }
 
-    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+    if (has_format && format != DumpGuestMemoryFormat_elf) {
         create_kdump_vmcore(s, errp);
     } else {
         create_vmcore(s, errp);
@@ -1689,25 +1689,25 @@ DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
     /* elf is always available */
     item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
     cap->formats = item;
-    item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
+    item->value = DumpGuestMemoryFormat_elf;
 
     /* kdump-zlib is always available */
     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
     item = item->next;
-    item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+    item->value = DumpGuestMemoryFormat_kdump_zlib;
 
     /* add new item if kdump-lzo is available */
 #ifdef CONFIG_LZO
     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
     item = item->next;
-    item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+    item->value = DumpGuestMemoryFormat_kdump_lzo;
 #endif
 
     /* add new item if kdump-snappy is available */
 #ifdef CONFIG_SNAPPY
     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
     item = item->next;
-    item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+    item->value = DumpGuestMemoryFormat_kdump_snappy;
 #endif
 
     return cap;
diff --git a/gdbstub.c b/gdbstub.c
index d2c95b5..34c20e1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1237,7 +1237,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
         return;
     }
     switch (state) {
-    case RUN_STATE_DEBUG:
+    case RunState_debug:
         if (cpu->watchpoint_hit) {
             switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
             case BP_MEM_READ:
@@ -1260,25 +1260,25 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
         tb_flush(cpu);
         ret = GDB_SIGNAL_TRAP;
         break;
-    case RUN_STATE_PAUSED:
+    case RunState_paused:
         ret = GDB_SIGNAL_INT;
         break;
-    case RUN_STATE_SHUTDOWN:
+    case RunState_shutdown:
         ret = GDB_SIGNAL_QUIT;
         break;
-    case RUN_STATE_IO_ERROR:
+    case RunState_io_error:
         ret = GDB_SIGNAL_IO;
         break;
-    case RUN_STATE_WATCHDOG:
+    case RunState_watchdog:
         ret = GDB_SIGNAL_ALRM;
         break;
-    case RUN_STATE_INTERNAL_ERROR:
+    case RunState_internal_error:
         ret = GDB_SIGNAL_ABRT;
         break;
-    case RUN_STATE_SAVE_VM:
-    case RUN_STATE_RESTORE_VM:
+    case RunState_save_vm:
+    case RunState_restore_vm:
         return;
-    case RUN_STATE_FINISH_MIGRATE:
+    case RunState_finish_migrate:
         ret = GDB_SIGNAL_XCPU;
         break;
     default:
@@ -1314,7 +1314,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
         return;
     s->current_syscall_cb = cb;
 #ifndef CONFIG_USER_ONLY
-    vm_stop(RUN_STATE_DEBUG);
+    vm_stop(RunState_debug);
 #endif
     p = s->syscall_buf;
     p_end = &s->syscall_buf[sizeof(s->syscall_buf)];
@@ -1401,7 +1401,7 @@ static void gdb_read_byte(GDBState *s, int ch)
     if (runstate_is_running()) {
         /* when the CPU is running, we cannot do anything except stop
            it when receiving a char */
-        vm_stop(RUN_STATE_PAUSED);
+        vm_stop(RunState_paused);
     } else
 #endif
     {
@@ -1666,7 +1666,7 @@ static void gdb_chr_event(void *opaque, int event)
 {
     switch (event) {
     case CHR_EVENT_OPENED:
-        vm_stop(RUN_STATE_PAUSED);
+        vm_stop(RunState_paused);
         gdb_has_xml = false;
         break;
     default:
@@ -1707,7 +1707,7 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
 static void gdb_sigterm_handler(int signal)
 {
     if (runstate_is_running()) {
-        vm_stop(RUN_STATE_PAUSED);
+        vm_stop(RunState_paused);
     }
 }
 #endif
diff --git a/hmp.c b/hmp.c
index a15d00c..6a7a779 100644
--- a/hmp.c
+++ b/hmp.c
@@ -94,7 +94,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
                    info->running ? "running" : "paused",
                    info->singlestep ? " (single step mode)" : "");
 
-    if (!info->running && info->status != RUN_STATE_PAUSED) {
+    if (!info->running && info->status != RunState_paused) {
         monitor_printf(mon, " (%s)", RunState_lookup[info->status]);
     }
 
@@ -269,19 +269,19 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
     if (params) {
         monitor_printf(mon, "parameters:");
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_LEVEL],
+            MigrationParameter_lookup[MigrationParameter_compress_level],
             params->compress_level);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_THREADS],
+            MigrationParameter_lookup[MigrationParameter_compress_threads],
             params->compress_threads);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS],
+            MigrationParameter_lookup[MigrationParameter_decompress_threads],
             params->decompress_threads);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL],
+            MigrationParameter_lookup[MigrationParameter_x_cpu_throttle_initial],
             params->x_cpu_throttle_initial);
         monitor_printf(mon, " %s: %" PRId64,
-            MigrationParameter_lookup[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT],
+            MigrationParameter_lookup[MigrationParameter_x_cpu_throttle_increment],
             params->x_cpu_throttle_increment);
         monitor_printf(mon, "\n");
     }
@@ -364,7 +364,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     }
 
     if (info) {
-        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
+        if (info->has_io_status && info->io_status != BlockDeviceIoStatus_ok) {
             monitor_printf(mon, "    I/O status:       %s\n",
                            BlockDeviceIoStatus_lookup[info->io_status]);
         }
@@ -394,7 +394,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
                        inserted->backing_file_depth);
     }
 
-    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
+    if (inserted->detect_zeroes != BlockdevDetectZeroesOptions_off) {
         monitor_printf(mon, "    Detect zeroes:    %s\n",
                        BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
     }
@@ -844,7 +844,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
                        ti->id, TpmTypeOptionsKind_lookup[ti->options->type]);
 
         switch (ti->options->type) {
-        case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
+        case TpmTypeOptionsKind_passthrough:
             tpo = ti->options->u.passthrough;
             monitor_printf(mon, "%s%s%s%s",
                            tpo->has_path ? ",path=" : "",
@@ -852,7 +852,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
                            tpo->has_cancel_path ? ",cancel-path=" : "",
                            tpo->has_cancel_path ? tpo->cancel_path : "");
             break;
-        case TPM_TYPE_OPTIONS_KIND_MAX:
+        case TpmTypeOptionsKind_MAX:
             break;
         }
         monitor_printf(mon, "\n");
@@ -1063,14 +1063,14 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
     }
 
     if (reuse) {
-        mode = NEW_IMAGE_MODE_EXISTING;
+        mode = NewImageMode_existing;
     } else {
-        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+        mode = NewImageMode_absolute_paths;
     }
 
     qmp_drive_mirror(device, filename, !!format, format,
                      false, NULL, false, NULL,
-                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+                     full ? MirrorSyncMode_full : MirrorSyncMode_top,
                      true, mode, false, 0, false, 0, false, 0,
                      false, 0, false, 0, false, true, &err);
     hmp_handle_error(mon, &err);
@@ -1093,13 +1093,13 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
     }
 
     if (reuse) {
-        mode = NEW_IMAGE_MODE_EXISTING;
+        mode = NewImageMode_existing;
     } else {
-        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+        mode = NewImageMode_absolute_paths;
     }
 
     qmp_drive_backup(device, filename, !!format, format,
-                     full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+                     full ? MirrorSyncMode_full : MirrorSyncMode_top,
                      true, mode, false, 0, false, NULL,
                      false, 0, false, 0, &err);
     hmp_handle_error(mon, &err);
@@ -1122,7 +1122,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
         return;
     }
 
-    mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+    mode = reuse ? NewImageMode_existing : NewImageMode_absolute_paths;
     qmp_blockdev_snapshot_sync(true, device, false, NULL,
                                filename, false, NULL,
                                !!format, format,
@@ -1200,7 +1200,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
     MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
     int i;
 
-    for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+    for (i = 0; i < MigrationCapability_MAX; i++) {
         if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
             caps->value = g_malloc0(sizeof(*caps->value));
             caps->value->capability = i;
@@ -1211,7 +1211,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
         }
     }
 
-    if (i == MIGRATION_CAPABILITY_MAX) {
+    if (i == MigrationCapability_MAX) {
         error_setg(&err, QERR_INVALID_PARAMETER, cap);
     }
 
@@ -1236,22 +1236,22 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
     bool has_x_cpu_throttle_increment = false;
     int i;
 
-    for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
+    for (i = 0; i < MigrationParameter_MAX; i++) {
         if (strcmp(param, MigrationParameter_lookup[i]) == 0) {
             switch (i) {
-            case MIGRATION_PARAMETER_COMPRESS_LEVEL:
+            case MigrationParameter_compress_level:
                 has_compress_level = true;
                 break;
-            case MIGRATION_PARAMETER_COMPRESS_THREADS:
+            case MigrationParameter_compress_threads:
                 has_compress_threads = true;
                 break;
-            case MIGRATION_PARAMETER_DECOMPRESS_THREADS:
+            case MigrationParameter_decompress_threads:
                 has_decompress_threads = true;
                 break;
-            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL:
+            case MigrationParameter_x_cpu_throttle_initial:
                 has_x_cpu_throttle_initial = true;
                 break;
-            case MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT:
+            case MigrationParameter_x_cpu_throttle_increment:
                 has_x_cpu_throttle_increment = true;
                 break;
             }
@@ -1265,7 +1265,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
         }
     }
 
-    if (i == MIGRATION_PARAMETER_MAX) {
+    if (i == MigrationParameter_MAX) {
         error_setg(&err, QERR_INVALID_PARAMETER, param);
     }
 
@@ -1349,7 +1349,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 
     qmp_change(device, target, !!arg, arg, &err);
     if (err &&
-        error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
+        error_get_class(err) == ErrorClass_DeviceEncrypted) {
         error_free(err);
         monitor_read_block_device_key(mon, device, NULL, NULL);
         return;
@@ -1396,7 +1396,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
 
     qmp_block_stream(device, base != NULL, base, false, NULL,
                      qdict_haskey(qdict, "speed"), speed,
-                     true, BLOCKDEV_ON_ERROR_REPORT, &error);
+                     true, BlockdevOnError_report, &error);
 
     hmp_handle_error(mon, &error);
 }
@@ -1466,8 +1466,8 @@ static void hmp_migrate_status_cb(void *opaque)
     MigrationInfo *info;
 
     info = qmp_query_migrate(NULL);
-    if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
-        info->status == MIGRATION_STATUS_SETUP) {
+    if (!info->has_status || info->status == MigrationStatus_active ||
+        info->status == MigrationStatus_setup) {
         if (info->has_disk) {
             int progress;
 
@@ -1556,7 +1556,7 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
     bool has_length = qdict_haskey(qdict, "length");
     int64_t begin = 0;
     int64_t length = 0;
-    enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
+    enum DumpGuestMemoryFormat dump_format = DumpGuestMemoryFormat_elf;
     char *prot;
 
     if (zlib + lzo + snappy > 1) {
@@ -1566,15 +1566,15 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
     }
 
     if (zlib) {
-        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+        dump_format = DumpGuestMemoryFormat_kdump_zlib;
     }
 
     if (lzo) {
-        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+        dump_format = DumpGuestMemoryFormat_kdump_lzo;
     }
 
     if (snappy) {
-        dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+        dump_format = DumpGuestMemoryFormat_kdump_snappy;
     }
 
     if (has_begin) {
@@ -1735,14 +1735,14 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
             if (*endp != '\0') {
                 goto err_out;
             }
-            keylist->value->type = KEY_VALUE_KIND_NUMBER;
+            keylist->value->type = KeyValueKind_number;
             keylist->value->u.number = value;
         } else {
             int idx = index_from_key(keyname_buf);
-            if (idx == Q_KEY_CODE_MAX) {
+            if (idx == QKeyCode_MAX) {
                 goto err_out;
             }
-            keylist->value->type = KEY_VALUE_KIND_QCODE;
+            keylist->value->type = KeyValueKind_qcode;
             keylist->value->u.qcode = idx;
         }
 
@@ -1892,7 +1892,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
     if (blk) {
         qemuio_command(blk, command);
     } else {
-        error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(&err, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device);
     }
 
@@ -1959,7 +1959,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
 
         if (value) {
             switch (value->type) {
-            case MEMORY_DEVICE_INFO_KIND_DIMM:
+            case MemoryDeviceInfoKind_dimm:
                 di = value->u.dimm;
 
                 monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
@@ -2034,7 +2034,7 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
 
     obj = object_resolve_path(path, &ambiguous);
     if (obj == NULL) {
-        error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(&err, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", path);
     } else {
         if (ambiguous) {
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index ce428df..20caa31 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -10,7 +10,7 @@ static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev)
 {
     ACPIOSTInfo *info = g_new0(ACPIOSTInfo, 1);
 
-    info->slot_type = ACPI_SLOT_TYPE_DIMM;
+    info->slot_type = ACPISlotType_DIMM;
     info->slot = g_strdup_printf("%d", slot);
     info->source = mdev->ost_event;
     info->status = mdev->ost_status;
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index b534bb9..127dae9 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -374,7 +374,7 @@ static void eth_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_mv88w8618_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = eth_receive,
     .cleanup = eth_cleanup,
diff --git a/hw/block/block.c b/hw/block/block.c
index f7243e5..2a458a4 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -71,7 +71,7 @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
         hd_geometry_guess(conf->blk,
                           &conf->cyls, &conf->heads, &conf->secs,
                           ptrans);
-    } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) {
+    } else if (ptrans && *ptrans == BiosAtaTranslation_auto) {
         *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs);
     }
     if (conf->cyls || conf->heads || conf->secs) {
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 4292ece..145f2ad 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2214,11 +2214,11 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
         drive->fdctrl = fdctrl;
 
         if (drive->blk) {
-            if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
+            if (blk_get_on_error(drive->blk, 0) != BlockdevOnError_enospc) {
                 error_setg(errp, "fdc doesn't support drive option werror");
                 return;
             }
-            if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+            if (blk_get_on_error(drive->blk, 1) != BlockdevOnError_report) {
                 error_setg(errp, "fdc doesn't support drive option rerror");
                 return;
             }
diff --git a/hw/block/hd-geometry.c b/hw/block/hd-geometry.c
index b187878..5479359 100644
--- a/hw/block/hd-geometry.c
+++ b/hw/block/hd-geometry.c
@@ -129,7 +129,7 @@ void hd_geometry_guess(BlockBackend *blk,
         *pcyls = geo.cylinders;
         *psecs = geo.sectors;
         *pheads = geo.heads;
-        translation = BIOS_ATA_TRANSLATION_NONE;
+        translation = BiosAtaTranslation_none;
     } else if (guess_disk_lchs(blk, &cylinders, &heads, &secs) < 0) {
         /* no LCHS guess: use a standard physical disk geometry  */
         guess_chs_for_size(blk, pcyls, pheads, psecs);
@@ -140,8 +140,8 @@ void hd_geometry_guess(BlockBackend *blk,
            geometry is OK */
         guess_chs_for_size(blk, pcyls, pheads, psecs);
         translation = *pcyls * *pheads <= 131072
-            ? BIOS_ATA_TRANSLATION_LARGE
-            : BIOS_ATA_TRANSLATION_LBA;
+            ? BiosAtaTranslation_large
+            : BiosAtaTranslation_lba;
     } else {
         /* LCHS guess with heads <= 16: use as physical geometry */
         *pcyls = cylinders;
@@ -149,7 +149,7 @@ void hd_geometry_guess(BlockBackend *blk,
         *psecs = secs;
         /* disable any translation to be in sync with
            the logical geometry */
-        translation = BIOS_ATA_TRANSLATION_NONE;
+        translation = BiosAtaTranslation_none;
     }
     if (ptrans) {
         *ptrans = translation;
@@ -160,6 +160,6 @@ void hd_geometry_guess(BlockBackend *blk,
 int hd_bios_chs_auto_trans(uint32_t cyls, uint32_t heads, uint32_t secs)
 {
     return cyls <= 1024 && heads <= 16 && secs <= 63
-        ? BIOS_ATA_TRANSLATION_NONE
-        : BIOS_ATA_TRANSLATION_LBA;
+        ? BiosAtaTranslation_none
+        : BiosAtaTranslation_lba;
 }
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 093e475..988868f 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -71,17 +71,17 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
                                                    is_read, error);
     VirtIOBlock *s = req->dev;
 
-    if (action == BLOCK_ERROR_ACTION_STOP) {
+    if (action == BlockErrorAction_stop) {
         req->next = s->rq;
         s->rq = req;
-    } else if (action == BLOCK_ERROR_ACTION_REPORT) {
+    } else if (action == BlockErrorAction_report) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
         block_acct_done(blk_get_stats(s->blk), &req->acct);
         virtio_blk_free_request(req);
     }
 
     blk_error_action(s->blk, action, is_read, error);
-    return action != BLOCK_ERROR_ACTION_IGNORE;
+    return action != BlockErrorAction_ignore;
 }
 
 static void virtio_blk_rw_complete(void *opaque, int ret)
@@ -105,7 +105,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
             bool is_read = !(p & VIRTIO_BLK_T_OUT);
             /* Note that memory may be dirtied on read failure.  If the
              * virtio request is not completed here, as is the case for
-             * BLOCK_ERROR_ACTION_STOP, the memory may not be copied
+             * BlockErrorAction_stop, the memory may not be copied
              * correctly during live migration.  While this is ugly,
              * it is acceptable because the device is free to write to
              * the memory until the request is completed (which will
diff --git a/hw/char/escc.c b/hw/char/escc.c
index c9840e1..d1c6e7b 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -714,126 +714,126 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
     return &d->mmio;
 }
 
-static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = {
-    [Q_KEY_CODE_SHIFT]         = 99,
-    [Q_KEY_CODE_SHIFT_R]       = 110,
-    [Q_KEY_CODE_ALT]           = 19,
-    [Q_KEY_CODE_ALT_R]         = 13,
-    [Q_KEY_CODE_ALTGR]         = 13,
-    [Q_KEY_CODE_CTRL]          = 76,
-    [Q_KEY_CODE_CTRL_R]        = 76,
-    [Q_KEY_CODE_ESC]           = 29,
-    [Q_KEY_CODE_1]             = 30,
-    [Q_KEY_CODE_2]             = 31,
-    [Q_KEY_CODE_3]             = 32,
-    [Q_KEY_CODE_4]             = 33,
-    [Q_KEY_CODE_5]             = 34,
-    [Q_KEY_CODE_6]             = 35,
-    [Q_KEY_CODE_7]             = 36,
-    [Q_KEY_CODE_8]             = 37,
-    [Q_KEY_CODE_9]             = 38,
-    [Q_KEY_CODE_0]             = 39,
-    [Q_KEY_CODE_MINUS]         = 40,
-    [Q_KEY_CODE_EQUAL]         = 41,
-    [Q_KEY_CODE_BACKSPACE]     = 43,
-    [Q_KEY_CODE_TAB]           = 53,
-    [Q_KEY_CODE_Q]             = 54,
-    [Q_KEY_CODE_W]             = 55,
-    [Q_KEY_CODE_E]             = 56,
-    [Q_KEY_CODE_R]             = 57,
-    [Q_KEY_CODE_T]             = 58,
-    [Q_KEY_CODE_Y]             = 59,
-    [Q_KEY_CODE_U]             = 60,
-    [Q_KEY_CODE_I]             = 61,
-    [Q_KEY_CODE_O]             = 62,
-    [Q_KEY_CODE_P]             = 63,
-    [Q_KEY_CODE_BRACKET_LEFT]  = 64,
-    [Q_KEY_CODE_BRACKET_RIGHT] = 65,
-    [Q_KEY_CODE_RET]           = 89,
-    [Q_KEY_CODE_A]             = 77,
-    [Q_KEY_CODE_S]             = 78,
-    [Q_KEY_CODE_D]             = 79,
-    [Q_KEY_CODE_F]             = 80,
-    [Q_KEY_CODE_G]             = 81,
-    [Q_KEY_CODE_H]             = 82,
-    [Q_KEY_CODE_J]             = 83,
-    [Q_KEY_CODE_K]             = 84,
-    [Q_KEY_CODE_L]             = 85,
-    [Q_KEY_CODE_SEMICOLON]     = 86,
-    [Q_KEY_CODE_APOSTROPHE]    = 87,
-    [Q_KEY_CODE_GRAVE_ACCENT]  = 42,
-    [Q_KEY_CODE_BACKSLASH]     = 88,
-    [Q_KEY_CODE_Z]             = 100,
-    [Q_KEY_CODE_X]             = 101,
-    [Q_KEY_CODE_C]             = 102,
-    [Q_KEY_CODE_V]             = 103,
-    [Q_KEY_CODE_B]             = 104,
-    [Q_KEY_CODE_N]             = 105,
-    [Q_KEY_CODE_M]             = 106,
-    [Q_KEY_CODE_COMMA]         = 107,
-    [Q_KEY_CODE_DOT]           = 108,
-    [Q_KEY_CODE_SLASH]         = 109,
-    [Q_KEY_CODE_ASTERISK]      = 47,
-    [Q_KEY_CODE_SPC]           = 121,
-    [Q_KEY_CODE_CAPS_LOCK]     = 119,
-    [Q_KEY_CODE_F1]            = 5,
-    [Q_KEY_CODE_F2]            = 6,
-    [Q_KEY_CODE_F3]            = 8,
-    [Q_KEY_CODE_F4]            = 10,
-    [Q_KEY_CODE_F5]            = 12,
-    [Q_KEY_CODE_F6]            = 14,
-    [Q_KEY_CODE_F7]            = 16,
-    [Q_KEY_CODE_F8]            = 17,
-    [Q_KEY_CODE_F9]            = 18,
-    [Q_KEY_CODE_F10]           = 7,
-    [Q_KEY_CODE_NUM_LOCK]      = 98,
-    [Q_KEY_CODE_SCROLL_LOCK]   = 23,
-    [Q_KEY_CODE_KP_DIVIDE]     = 46,
-    [Q_KEY_CODE_KP_MULTIPLY]   = 47,
-    [Q_KEY_CODE_KP_SUBTRACT]   = 71,
-    [Q_KEY_CODE_KP_ADD]        = 125,
-    [Q_KEY_CODE_KP_ENTER]      = 90,
-    [Q_KEY_CODE_KP_DECIMAL]    = 50,
-    [Q_KEY_CODE_KP_0]          = 94,
-    [Q_KEY_CODE_KP_1]          = 112,
-    [Q_KEY_CODE_KP_2]          = 113,
-    [Q_KEY_CODE_KP_3]          = 114,
-    [Q_KEY_CODE_KP_4]          = 91,
-    [Q_KEY_CODE_KP_5]          = 92,
-    [Q_KEY_CODE_KP_6]          = 93,
-    [Q_KEY_CODE_KP_7]          = 68,
-    [Q_KEY_CODE_KP_8]          = 69,
-    [Q_KEY_CODE_KP_9]          = 70,
-    [Q_KEY_CODE_LESS]          = 124,
-    [Q_KEY_CODE_F11]           = 9,
-    [Q_KEY_CODE_F12]           = 11,
-    [Q_KEY_CODE_HOME]          = 52,
-    [Q_KEY_CODE_PGUP]          = 96,
-    [Q_KEY_CODE_PGDN]          = 123,
-    [Q_KEY_CODE_END]           = 74,
-    [Q_KEY_CODE_LEFT]          = 24,
-    [Q_KEY_CODE_UP]            = 20,
-    [Q_KEY_CODE_DOWN]          = 27,
-    [Q_KEY_CODE_RIGHT]         = 28,
-    [Q_KEY_CODE_INSERT]        = 44,
-    [Q_KEY_CODE_DELETE]        = 66,
-    [Q_KEY_CODE_STOP]          = 1,
-    [Q_KEY_CODE_AGAIN]         = 3,
-    [Q_KEY_CODE_PROPS]         = 25,
-    [Q_KEY_CODE_UNDO]          = 26,
-    [Q_KEY_CODE_FRONT]         = 49,
-    [Q_KEY_CODE_COPY]          = 51,
-    [Q_KEY_CODE_OPEN]          = 72,
-    [Q_KEY_CODE_PASTE]         = 73,
-    [Q_KEY_CODE_FIND]          = 95,
-    [Q_KEY_CODE_CUT]           = 97,
-    [Q_KEY_CODE_LF]            = 111,
-    [Q_KEY_CODE_HELP]          = 118,
-    [Q_KEY_CODE_META_L]        = 120,
-    [Q_KEY_CODE_META_R]        = 122,
-    [Q_KEY_CODE_COMPOSE]       = 67,
-    [Q_KEY_CODE_PRINT]         = 22,
-    [Q_KEY_CODE_SYSRQ]         = 21,
+static const uint8_t qcode_to_keycode[QKeyCode_MAX] = {
+    [QKeyCode_shift]         = 99,
+    [QKeyCode_shift_r]       = 110,
+    [QKeyCode_alt]           = 19,
+    [QKeyCode_alt_r]         = 13,
+    [QKeyCode_altgr]         = 13,
+    [QKeyCode_ctrl]          = 76,
+    [QKeyCode_ctrl_r]        = 76,
+    [QKeyCode_esc]           = 29,
+    [QKeyCode_1]             = 30,
+    [QKeyCode_2]             = 31,
+    [QKeyCode_3]             = 32,
+    [QKeyCode_4]             = 33,
+    [QKeyCode_5]             = 34,
+    [QKeyCode_6]             = 35,
+    [QKeyCode_7]             = 36,
+    [QKeyCode_8]             = 37,
+    [QKeyCode_9]             = 38,
+    [QKeyCode_0]             = 39,
+    [QKeyCode_minus]         = 40,
+    [QKeyCode_equal]         = 41,
+    [QKeyCode_backspace]     = 43,
+    [QKeyCode_tab]           = 53,
+    [QKeyCode_q]             = 54,
+    [QKeyCode_w]             = 55,
+    [QKeyCode_e]             = 56,
+    [QKeyCode_r]             = 57,
+    [QKeyCode_t]             = 58,
+    [QKeyCode_y]             = 59,
+    [QKeyCode_u]             = 60,
+    [QKeyCode_i]             = 61,
+    [QKeyCode_o]             = 62,
+    [QKeyCode_p]             = 63,
+    [QKeyCode_bracket_left]  = 64,
+    [QKeyCode_bracket_right] = 65,
+    [QKeyCode_ret]           = 89,
+    [QKeyCode_a]             = 77,
+    [QKeyCode_s]             = 78,
+    [QKeyCode_d]             = 79,
+    [QKeyCode_f]             = 80,
+    [QKeyCode_g]             = 81,
+    [QKeyCode_h]             = 82,
+    [QKeyCode_j]             = 83,
+    [QKeyCode_k]             = 84,
+    [QKeyCode_l]             = 85,
+    [QKeyCode_semicolon]     = 86,
+    [QKeyCode_apostrophe]    = 87,
+    [QKeyCode_grave_accent]  = 42,
+    [QKeyCode_backslash]     = 88,
+    [QKeyCode_z]             = 100,
+    [QKeyCode_x]             = 101,
+    [QKeyCode_c]             = 102,
+    [QKeyCode_v]             = 103,
+    [QKeyCode_b]             = 104,
+    [QKeyCode_n]             = 105,
+    [QKeyCode_m]             = 106,
+    [QKeyCode_comma]         = 107,
+    [QKeyCode_dot]           = 108,
+    [QKeyCode_slash]         = 109,
+    [QKeyCode_asterisk]      = 47,
+    [QKeyCode_spc]           = 121,
+    [QKeyCode_caps_lock]     = 119,
+    [QKeyCode_f1]            = 5,
+    [QKeyCode_f2]            = 6,
+    [QKeyCode_f3]            = 8,
+    [QKeyCode_f4]            = 10,
+    [QKeyCode_f5]            = 12,
+    [QKeyCode_f6]            = 14,
+    [QKeyCode_f7]            = 16,
+    [QKeyCode_f8]            = 17,
+    [QKeyCode_f9]            = 18,
+    [QKeyCode_f10]           = 7,
+    [QKeyCode_num_lock]      = 98,
+    [QKeyCode_scroll_lock]   = 23,
+    [QKeyCode_kp_divide]     = 46,
+    [QKeyCode_kp_multiply]   = 47,
+    [QKeyCode_kp_subtract]   = 71,
+    [QKeyCode_kp_add]        = 125,
+    [QKeyCode_kp_enter]      = 90,
+    [QKeyCode_kp_decimal]    = 50,
+    [QKeyCode_kp_0]          = 94,
+    [QKeyCode_kp_1]          = 112,
+    [QKeyCode_kp_2]          = 113,
+    [QKeyCode_kp_3]          = 114,
+    [QKeyCode_kp_4]          = 91,
+    [QKeyCode_kp_5]          = 92,
+    [QKeyCode_kp_6]          = 93,
+    [QKeyCode_kp_7]          = 68,
+    [QKeyCode_kp_8]          = 69,
+    [QKeyCode_kp_9]          = 70,
+    [QKeyCode_less]          = 124,
+    [QKeyCode_f11]           = 9,
+    [QKeyCode_f12]           = 11,
+    [QKeyCode_home]          = 52,
+    [QKeyCode_pgup]          = 96,
+    [QKeyCode_pgdn]          = 123,
+    [QKeyCode_end]           = 74,
+    [QKeyCode_left]          = 24,
+    [QKeyCode_up]            = 20,
+    [QKeyCode_down]          = 27,
+    [QKeyCode_right]         = 28,
+    [QKeyCode_insert]        = 44,
+    [QKeyCode_delete]        = 66,
+    [QKeyCode_stop]          = 1,
+    [QKeyCode_again]         = 3,
+    [QKeyCode_props]         = 25,
+    [QKeyCode_undo]          = 26,
+    [QKeyCode_front]         = 49,
+    [QKeyCode_copy]          = 51,
+    [QKeyCode_open]          = 72,
+    [QKeyCode_paste]         = 73,
+    [QKeyCode_find]          = 95,
+    [QKeyCode_cut]           = 97,
+    [QKeyCode_lf]            = 111,
+    [QKeyCode_help]          = 118,
+    [QKeyCode_meta_l]        = 120,
+    [QKeyCode_meta_r]        = 122,
+    [QKeyCode_compose]       = 67,
+    [QKeyCode_print]         = 22,
+    [QKeyCode_sysrq]         = 21,
 };
 
 static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
@@ -842,12 +842,12 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
     ChannelState *s = (ChannelState *)dev;
     int qcode, keycode;
 
-    assert(evt->type == INPUT_EVENT_KIND_KEY);
+    assert(evt->type == InputEventKind_key);
     qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
     trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
                                evt->u.key->down);
 
-    if (qcode == Q_KEY_CODE_CAPS_LOCK) {
+    if (qcode == QKeyCode_caps_lock) {
         if (evt->u.key->down) {
             s->caps_lock_mode ^= 1;
             if (s->caps_lock_mode == 2) {
@@ -861,7 +861,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
         }
     }
 
-    if (qcode == Q_KEY_CODE_NUM_LOCK) {
+    if (qcode == QKeyCode_num_lock) {
         if (evt->u.key->down) {
             s->num_lock_mode ^= 1;
             if (s->num_lock_mode == 2) {
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 921e799..e0ddedb 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -229,7 +229,7 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque,
     }
 
     queues = qemu_find_net_clients_except(str, peers,
-                                          NET_CLIENT_OPTIONS_KIND_NIC,
+                                          NetClientOptionsKind_nic,
                                           MAX_QUEUE_NUM);
     if (queues == 0) {
         err = -ENOENT;
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 9c961da..64c76ba 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -963,8 +963,8 @@ static void interface_set_client_capabilities(QXLInstance *sin,
         return;
     }
 
-    if (runstate_check(RUN_STATE_INMIGRATE) ||
-        runstate_check(RUN_STATE_POSTMIGRATE)) {
+    if (runstate_check(RunState_inmigrate) ||
+        runstate_check(RunState_postmigrate)) {
         return;
     }
 
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 90eea10..2b613d7 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -269,9 +269,9 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
         return;
     }
     switch (s->lost_tick_policy) {
-    case LOST_TICK_POLICY_DELAY:
+    case LostTickPolicy_delay:
         break; /* enabled by default */
-    case LOST_TICK_POLICY_DISCARD:
+    case LostTickPolicy_discard:
         if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
             struct kvm_reinject_control control = { .pit_reinject = 0 };
 
@@ -301,7 +301,7 @@ static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
 static Property kvm_pit_properties[] = {
     DEFINE_PROP_UINT32("iobase", PITCommonState, iobase,  -1),
     DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
-                               lost_tick_policy, LOST_TICK_POLICY_DELAY),
+                               lost_tick_policy, LostTickPolicy_delay),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0cb8afd..f360988 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1795,7 +1795,7 @@ static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
         return;
     }
     if (value > (1ULL << 32)) {
-        error_set(&error, ERROR_CLASS_GENERIC_ERROR,
+        error_set(&error, ErrorClass_GenericError,
                   "Machine option 'max-ram-below-4g=%"PRIu64
                   "' expects size less than or equal to 4G", value);
         error_propagate(errp, error);
@@ -1832,7 +1832,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)
 {
     bool smm_available = false;
 
-    if (pcms->smm == ON_OFF_AUTO_OFF) {
+    if (pcms->smm == OnOffAuto_off) {
         return false;
     }
 
@@ -1846,7 +1846,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)
         return true;
     }
 
-    if (pcms->smm == ON_OFF_AUTO_ON) {
+    if (pcms->smm == OnOffAuto_on) {
         error_report("System Management Mode not supported by this hypervisor.");
         exit(1);
     }
@@ -1894,7 +1894,7 @@ static void pc_machine_initfn(Object *obj)
                                     "Maximum ram below the 4G boundary (32bit boundary)",
                                     &error_abort);
 
-    pcms->smm = ON_OFF_AUTO_AUTO;
+    pcms->smm = OnOffAuto_auto;
     object_property_add(obj, PC_MACHINE_SMM, "OnOffAuto",
                         pc_machine_get_smm,
                         pc_machine_set_smm,
@@ -1903,7 +1903,7 @@ static void pc_machine_initfn(Object *obj)
                                     "Enable SMM (pc & q35)",
                                     &error_abort);
 
-    pcms->vmport = ON_OFF_AUTO_AUTO;
+    pcms->vmport = OnOffAuto_auto;
     object_property_add(obj, PC_MACHINE_VMPORT, "OnOffAuto",
                         pc_machine_get_vmport,
                         pc_machine_set_vmport,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 393dcc4..8e0544e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -225,14 +225,14 @@ static void pc_init1(MachineState *machine,
 
     pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
 
-    assert(pcms->vmport != ON_OFF_AUTO_MAX);
-    if (pcms->vmport == ON_OFF_AUTO_AUTO) {
-        pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
+    assert(pcms->vmport != OnOffAuto_MAX);
+    if (pcms->vmport == OnOffAuto_auto) {
+        pcms->vmport = xen_enabled() ? OnOffAuto_off : OnOffAuto_on;
     }
 
     /* init basic PC hardware */
     pc_basic_device_init(isa_bus, gsi, &rtc_state, true,
-                         (pcms->vmport != ON_OFF_AUTO_ON), 0x4);
+                         (pcms->vmport != OnOffAuto_on), 0x4);
 
     pc_nic_init(isa_bus, pci_bus);
 
@@ -306,7 +306,7 @@ static void pc_compat_2_3(MachineState *machine)
     PCMachineState *pcms = PC_MACHINE(machine);
     savevm_skip_section_footers();
     if (kvm_enabled()) {
-        pcms->smm = ON_OFF_AUTO_OFF;
+        pcms->smm = OnOffAuto_off;
     }
     global_state_set_optional();
     savevm_skip_configuration();
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2f8f396..23796fd 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -233,14 +233,14 @@ static void pc_q35_init(MachineState *machine)
 
     pc_register_ferr_irq(gsi[13]);
 
-    assert(pcms->vmport != ON_OFF_AUTO_MAX);
-    if (pcms->vmport == ON_OFF_AUTO_AUTO) {
-        pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
+    assert(pcms->vmport != OnOffAuto_MAX);
+    if (pcms->vmport == OnOffAuto_auto) {
+        pcms->vmport = xen_enabled() ? OnOffAuto_off : OnOffAuto_on;
     }
 
     /* init basic PC hardware */
     pc_basic_device_init(isa_bus, gsi, &rtc_state, !mc->no_floppy,
-                         (pcms->vmport != ON_OFF_AUTO_ON), 0xff0104);
+                         (pcms->vmport != OnOffAuto_on), 0xff0104);
 
     /* connect pm stuff to lpc */
     ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms), !mc->no_tco);
@@ -289,7 +289,7 @@ static void pc_compat_2_3(MachineState *machine)
     PCMachineState *pcms = PC_MACHINE(machine);
     savevm_skip_section_footers();
     if (kvm_enabled()) {
-        pcms->smm = ON_OFF_AUTO_OFF;
+        pcms->smm = OnOffAuto_off;
     }
     global_state_set_optional();
     savevm_skip_configuration();
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 21f76ed..76bb87c 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -938,10 +938,10 @@ static void ncq_cb(void *opaque, int ret)
         bool is_read = ncq_tfs->cmd == READ_FPDMA_QUEUED;
         BlockErrorAction action = blk_get_error_action(ide_state->blk,
                                                        is_read, -ret);
-        if (action == BLOCK_ERROR_ACTION_STOP) {
+        if (action == BlockErrorAction_stop) {
             ncq_tfs->halt = true;
             ide_state->bus->error_status = IDE_RETRY_HBA;
-        } else if (action == BLOCK_ERROR_ACTION_REPORT) {
+        } else if (action == BlockErrorAction_report) {
             ncq_err(ncq_tfs);
         }
         blk_error_action(ide_state->blk, action, is_read, -ret);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 317406d..e1a08e7 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -668,10 +668,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
     bool is_read = (op & IDE_RETRY_READ) != 0;
     BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
 
-    if (action == BLOCK_ERROR_ACTION_STOP) {
+    if (action == BlockErrorAction_stop) {
         assert(s->bus->retry_unit == s->unit);
         s->bus->error_status = op;
-    } else if (action == BLOCK_ERROR_ACTION_REPORT) {
+    } else if (action == BlockErrorAction_report) {
         if (op & IDE_RETRY_DMA) {
             ide_dma_error(s);
         } else {
@@ -679,7 +679,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
         }
     }
     blk_error_action(s->blk, action, is_read, error);
-    return action != BLOCK_ERROR_ACTION_IGNORE;
+    return action != BlockErrorAction_ignore;
 }
 
 static void ide_dma_cb(void *opaque, int ret)
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 788b361..9ac3290 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -271,7 +271,7 @@ static Property ide_hd_properties[] = {
     DEFINE_IDE_DEV_PROPERTIES(),
     DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf),
     DEFINE_PROP_BIOS_CHS_TRANS("bios-chs-trans",
-                IDEDrive, dev.chs_trans, BIOS_ATA_TRANSLATION_AUTO),
+                IDEDrive, dev.chs_trans, BiosAtaTranslation_auto),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/input/hid.c b/hw/input/hid.c
index e39269f..0d23912 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -108,10 +108,10 @@ void hid_set_next_idle(HIDState *hs)
 static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
                               InputEvent *evt)
 {
-    static const int bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]   = 0x01,
-        [INPUT_BUTTON_RIGHT]  = 0x02,
-        [INPUT_BUTTON_MIDDLE] = 0x04,
+    static const int bmap[InputButton_MAX] = {
+        [InputButton_Left]   = 0x01,
+        [InputButton_Right]  = 0x02,
+        [InputButton_Middle] = 0x04,
     };
     HIDState *hs = (HIDState *)dev;
     HIDPointerEvent *e;
@@ -120,28 +120,28 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
     e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
 
     switch (evt->type) {
-    case INPUT_EVENT_KIND_REL:
-        if (evt->u.rel->axis == INPUT_AXIS_X) {
+    case InputEventKind_rel:
+        if (evt->u.rel->axis == InputAxis_X) {
             e->xdx += evt->u.rel->value;
-        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
+        } else if (evt->u.rel->axis == InputAxis_Y) {
             e->ydy += evt->u.rel->value;
         }
         break;
 
-    case INPUT_EVENT_KIND_ABS:
-        if (evt->u.rel->axis == INPUT_AXIS_X) {
+    case InputEventKind_abs:
+        if (evt->u.rel->axis == InputAxis_X) {
             e->xdx = evt->u.rel->value;
-        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
+        } else if (evt->u.rel->axis == InputAxis_Y) {
             e->ydy = evt->u.rel->value;
         }
         break;
 
-    case INPUT_EVENT_KIND_BTN:
+    case InputEventKind_btn:
         if (evt->u.btn->down) {
             e->buttons_state |= bmap[evt->u.btn->button];
-            if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
+            if (evt->u.btn->button == InputButton_WheelUp) {
                 e->dz--;
-            } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
+            } else if (evt->u.btn->button == InputButton_WheelDown) {
                 e->dz++;
             }
         } else {
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 3d6d496..0bfbbdc 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -382,10 +382,10 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
                             InputEvent *evt)
 {
-    static const int bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
-        [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
-        [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
+    static const int bmap[InputButton_MAX] = {
+        [InputButton_Left]   = MOUSE_EVENT_LBUTTON,
+        [InputButton_Middle] = MOUSE_EVENT_MBUTTON,
+        [InputButton_Right]  = MOUSE_EVENT_RBUTTON,
     };
     PS2MouseState *s = (PS2MouseState *)dev;
 
@@ -394,20 +394,20 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
         return;
 
     switch (evt->type) {
-    case INPUT_EVENT_KIND_REL:
-        if (evt->u.rel->axis == INPUT_AXIS_X) {
+    case InputEventKind_rel:
+        if (evt->u.rel->axis == InputAxis_X) {
             s->mouse_dx += evt->u.rel->value;
-        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
+        } else if (evt->u.rel->axis == InputAxis_Y) {
             s->mouse_dy -= evt->u.rel->value;
         }
         break;
 
-    case INPUT_EVENT_KIND_BTN:
+    case InputEventKind_btn:
         if (evt->u.btn->down) {
             s->mouse_buttons |= bmap[evt->u.btn->button];
-            if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
+            if (evt->u.btn->button == InputButton_WheelUp) {
                 s->mouse_dz--;
-            } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
+            } else if (evt->u.btn->button == InputButton_WheelDown) {
                 s->mouse_dz++;
             }
         } else {
diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index bdd479c..ce8c2c1 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -21,139 +21,139 @@
 
 /* ----------------------------------------------------------------- */
 
-static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = {
-    [Q_KEY_CODE_ESC]                 = KEY_ESC,
-    [Q_KEY_CODE_1]                   = KEY_1,
-    [Q_KEY_CODE_2]                   = KEY_2,
-    [Q_KEY_CODE_3]                   = KEY_3,
-    [Q_KEY_CODE_4]                   = KEY_4,
-    [Q_KEY_CODE_5]                   = KEY_5,
-    [Q_KEY_CODE_6]                   = KEY_6,
-    [Q_KEY_CODE_7]                   = KEY_7,
-    [Q_KEY_CODE_8]                   = KEY_8,
-    [Q_KEY_CODE_9]                   = KEY_9,
-    [Q_KEY_CODE_0]                   = KEY_0,
-    [Q_KEY_CODE_MINUS]               = KEY_MINUS,
-    [Q_KEY_CODE_EQUAL]               = KEY_EQUAL,
-    [Q_KEY_CODE_BACKSPACE]           = KEY_BACKSPACE,
+static const unsigned int keymap_qcode[QKeyCode_MAX] = {
+    [QKeyCode_esc]                 = KEY_ESC,
+    [QKeyCode_1]                   = KEY_1,
+    [QKeyCode_2]                   = KEY_2,
+    [QKeyCode_3]                   = KEY_3,
+    [QKeyCode_4]                   = KEY_4,
+    [QKeyCode_5]                   = KEY_5,
+    [QKeyCode_6]                   = KEY_6,
+    [QKeyCode_7]                   = KEY_7,
+    [QKeyCode_8]                   = KEY_8,
+    [QKeyCode_9]                   = KEY_9,
+    [QKeyCode_0]                   = KEY_0,
+    [QKeyCode_minus]               = KEY_MINUS,
+    [QKeyCode_equal]               = KEY_EQUAL,
+    [QKeyCode_backspace]           = KEY_BACKSPACE,
 
-    [Q_KEY_CODE_TAB]                 = KEY_TAB,
-    [Q_KEY_CODE_Q]                   = KEY_Q,
-    [Q_KEY_CODE_W]                   = KEY_W,
-    [Q_KEY_CODE_E]                   = KEY_E,
-    [Q_KEY_CODE_R]                   = KEY_R,
-    [Q_KEY_CODE_T]                   = KEY_T,
-    [Q_KEY_CODE_Y]                   = KEY_Y,
-    [Q_KEY_CODE_U]                   = KEY_U,
-    [Q_KEY_CODE_I]                   = KEY_I,
-    [Q_KEY_CODE_O]                   = KEY_O,
-    [Q_KEY_CODE_P]                   = KEY_P,
-    [Q_KEY_CODE_BRACKET_LEFT]        = KEY_LEFTBRACE,
-    [Q_KEY_CODE_BRACKET_RIGHT]       = KEY_RIGHTBRACE,
-    [Q_KEY_CODE_RET]                 = KEY_ENTER,
+    [QKeyCode_tab]                 = KEY_TAB,
+    [QKeyCode_q]                   = KEY_Q,
+    [QKeyCode_w]                   = KEY_W,
+    [QKeyCode_e]                   = KEY_E,
+    [QKeyCode_r]                   = KEY_R,
+    [QKeyCode_t]                   = KEY_T,
+    [QKeyCode_y]                   = KEY_Y,
+    [QKeyCode_u]                   = KEY_U,
+    [QKeyCode_i]                   = KEY_I,
+    [QKeyCode_o]                   = KEY_O,
+    [QKeyCode_p]                   = KEY_P,
+    [QKeyCode_bracket_left]        = KEY_LEFTBRACE,
+    [QKeyCode_bracket_right]       = KEY_RIGHTBRACE,
+    [QKeyCode_ret]                 = KEY_ENTER,
 
-    [Q_KEY_CODE_CTRL]                = KEY_LEFTCTRL,
-    [Q_KEY_CODE_A]                   = KEY_A,
-    [Q_KEY_CODE_S]                   = KEY_S,
-    [Q_KEY_CODE_D]                   = KEY_D,
-    [Q_KEY_CODE_F]                   = KEY_F,
-    [Q_KEY_CODE_G]                   = KEY_G,
-    [Q_KEY_CODE_H]                   = KEY_H,
-    [Q_KEY_CODE_J]                   = KEY_J,
-    [Q_KEY_CODE_K]                   = KEY_K,
-    [Q_KEY_CODE_L]                   = KEY_L,
-    [Q_KEY_CODE_SEMICOLON]           = KEY_SEMICOLON,
-    [Q_KEY_CODE_APOSTROPHE]          = KEY_APOSTROPHE,
-    [Q_KEY_CODE_GRAVE_ACCENT]        = KEY_GRAVE,
+    [QKeyCode_ctrl]                = KEY_LEFTCTRL,
+    [QKeyCode_a]                   = KEY_A,
+    [QKeyCode_s]                   = KEY_S,
+    [QKeyCode_d]                   = KEY_D,
+    [QKeyCode_f]                   = KEY_F,
+    [QKeyCode_g]                   = KEY_G,
+    [QKeyCode_h]                   = KEY_H,
+    [QKeyCode_j]                   = KEY_J,
+    [QKeyCode_k]                   = KEY_K,
+    [QKeyCode_l]                   = KEY_L,
+    [QKeyCode_semicolon]           = KEY_SEMICOLON,
+    [QKeyCode_apostrophe]          = KEY_APOSTROPHE,
+    [QKeyCode_grave_accent]        = KEY_GRAVE,
 
-    [Q_KEY_CODE_SHIFT]               = KEY_LEFTSHIFT,
-    [Q_KEY_CODE_BACKSLASH]           = KEY_BACKSLASH,
-    [Q_KEY_CODE_LESS]                = KEY_102ND,
-    [Q_KEY_CODE_Z]                   = KEY_Z,
-    [Q_KEY_CODE_X]                   = KEY_X,
-    [Q_KEY_CODE_C]                   = KEY_C,
-    [Q_KEY_CODE_V]                   = KEY_V,
-    [Q_KEY_CODE_B]                   = KEY_B,
-    [Q_KEY_CODE_N]                   = KEY_N,
-    [Q_KEY_CODE_M]                   = KEY_M,
-    [Q_KEY_CODE_COMMA]               = KEY_COMMA,
-    [Q_KEY_CODE_DOT]                 = KEY_DOT,
-    [Q_KEY_CODE_SLASH]               = KEY_SLASH,
-    [Q_KEY_CODE_SHIFT_R]             = KEY_RIGHTSHIFT,
+    [QKeyCode_shift]               = KEY_LEFTSHIFT,
+    [QKeyCode_backslash]           = KEY_BACKSLASH,
+    [QKeyCode_less]                = KEY_102ND,
+    [QKeyCode_z]                   = KEY_Z,
+    [QKeyCode_x]                   = KEY_X,
+    [QKeyCode_c]                   = KEY_C,
+    [QKeyCode_v]                   = KEY_V,
+    [QKeyCode_b]                   = KEY_B,
+    [QKeyCode_n]                   = KEY_N,
+    [QKeyCode_m]                   = KEY_M,
+    [QKeyCode_comma]               = KEY_COMMA,
+    [QKeyCode_dot]                 = KEY_DOT,
+    [QKeyCode_slash]               = KEY_SLASH,
+    [QKeyCode_shift_r]             = KEY_RIGHTSHIFT,
 
-    [Q_KEY_CODE_ALT]                 = KEY_LEFTALT,
-    [Q_KEY_CODE_SPC]                 = KEY_SPACE,
-    [Q_KEY_CODE_CAPS_LOCK]           = KEY_CAPSLOCK,
+    [QKeyCode_alt]                 = KEY_LEFTALT,
+    [QKeyCode_spc]                 = KEY_SPACE,
+    [QKeyCode_caps_lock]           = KEY_CAPSLOCK,
 
-    [Q_KEY_CODE_F1]                  = KEY_F1,
-    [Q_KEY_CODE_F2]                  = KEY_F2,
-    [Q_KEY_CODE_F3]                  = KEY_F3,
-    [Q_KEY_CODE_F4]                  = KEY_F4,
-    [Q_KEY_CODE_F5]                  = KEY_F5,
-    [Q_KEY_CODE_F6]                  = KEY_F6,
-    [Q_KEY_CODE_F7]                  = KEY_F7,
-    [Q_KEY_CODE_F8]                  = KEY_F8,
-    [Q_KEY_CODE_F9]                  = KEY_F9,
-    [Q_KEY_CODE_F10]                 = KEY_F10,
-    [Q_KEY_CODE_NUM_LOCK]            = KEY_NUMLOCK,
-    [Q_KEY_CODE_SCROLL_LOCK]         = KEY_SCROLLLOCK,
+    [QKeyCode_f1]                  = KEY_F1,
+    [QKeyCode_f2]                  = KEY_F2,
+    [QKeyCode_f3]                  = KEY_F3,
+    [QKeyCode_f4]                  = KEY_F4,
+    [QKeyCode_f5]                  = KEY_F5,
+    [QKeyCode_f6]                  = KEY_F6,
+    [QKeyCode_f7]                  = KEY_F7,
+    [QKeyCode_f8]                  = KEY_F8,
+    [QKeyCode_f9]                  = KEY_F9,
+    [QKeyCode_f10]                 = KEY_F10,
+    [QKeyCode_num_lock]            = KEY_NUMLOCK,
+    [QKeyCode_scroll_lock]         = KEY_SCROLLLOCK,
 
-    [Q_KEY_CODE_KP_0]                = KEY_KP0,
-    [Q_KEY_CODE_KP_1]                = KEY_KP1,
-    [Q_KEY_CODE_KP_2]                = KEY_KP2,
-    [Q_KEY_CODE_KP_3]                = KEY_KP3,
-    [Q_KEY_CODE_KP_4]                = KEY_KP4,
-    [Q_KEY_CODE_KP_5]                = KEY_KP5,
-    [Q_KEY_CODE_KP_6]                = KEY_KP6,
-    [Q_KEY_CODE_KP_7]                = KEY_KP7,
-    [Q_KEY_CODE_KP_8]                = KEY_KP8,
-    [Q_KEY_CODE_KP_9]                = KEY_KP9,
-    [Q_KEY_CODE_KP_SUBTRACT]         = KEY_KPMINUS,
-    [Q_KEY_CODE_KP_ADD]              = KEY_KPPLUS,
-    [Q_KEY_CODE_KP_DECIMAL]          = KEY_KPDOT,
-    [Q_KEY_CODE_KP_ENTER]            = KEY_KPENTER,
-    [Q_KEY_CODE_KP_DIVIDE]           = KEY_KPSLASH,
-    [Q_KEY_CODE_KP_MULTIPLY]         = KEY_KPASTERISK,
+    [QKeyCode_kp_0]                = KEY_KP0,
+    [QKeyCode_kp_1]                = KEY_KP1,
+    [QKeyCode_kp_2]                = KEY_KP2,
+    [QKeyCode_kp_3]                = KEY_KP3,
+    [QKeyCode_kp_4]                = KEY_KP4,
+    [QKeyCode_kp_5]                = KEY_KP5,
+    [QKeyCode_kp_6]                = KEY_KP6,
+    [QKeyCode_kp_7]                = KEY_KP7,
+    [QKeyCode_kp_8]                = KEY_KP8,
+    [QKeyCode_kp_9]                = KEY_KP9,
+    [QKeyCode_kp_subtract]         = KEY_KPMINUS,
+    [QKeyCode_kp_add]              = KEY_KPPLUS,
+    [QKeyCode_kp_decimal]          = KEY_KPDOT,
+    [QKeyCode_kp_enter]            = KEY_KPENTER,
+    [QKeyCode_kp_divide]           = KEY_KPSLASH,
+    [QKeyCode_kp_multiply]         = KEY_KPASTERISK,
 
-    [Q_KEY_CODE_F11]                 = KEY_F11,
-    [Q_KEY_CODE_F12]                 = KEY_F12,
+    [QKeyCode_f11]                 = KEY_F11,
+    [QKeyCode_f12]                 = KEY_F12,
 
-    [Q_KEY_CODE_CTRL_R]              = KEY_RIGHTCTRL,
-    [Q_KEY_CODE_SYSRQ]               = KEY_SYSRQ,
-    [Q_KEY_CODE_ALT_R]               = KEY_RIGHTALT,
+    [QKeyCode_ctrl_r]              = KEY_RIGHTCTRL,
+    [QKeyCode_sysrq]               = KEY_SYSRQ,
+    [QKeyCode_alt_r]               = KEY_RIGHTALT,
 
-    [Q_KEY_CODE_HOME]                = KEY_HOME,
-    [Q_KEY_CODE_UP]                  = KEY_UP,
-    [Q_KEY_CODE_PGUP]                = KEY_PAGEUP,
-    [Q_KEY_CODE_LEFT]                = KEY_LEFT,
-    [Q_KEY_CODE_RIGHT]               = KEY_RIGHT,
-    [Q_KEY_CODE_END]                 = KEY_END,
-    [Q_KEY_CODE_DOWN]                = KEY_DOWN,
-    [Q_KEY_CODE_PGDN]                = KEY_PAGEDOWN,
-    [Q_KEY_CODE_INSERT]              = KEY_INSERT,
-    [Q_KEY_CODE_DELETE]              = KEY_DELETE,
+    [QKeyCode_home]                = KEY_HOME,
+    [QKeyCode_up]                  = KEY_UP,
+    [QKeyCode_pgup]                = KEY_PAGEUP,
+    [QKeyCode_left]                = KEY_LEFT,
+    [QKeyCode_right]               = KEY_RIGHT,
+    [QKeyCode_end]                 = KEY_END,
+    [QKeyCode_down]                = KEY_DOWN,
+    [QKeyCode_pgdn]                = KEY_PAGEDOWN,
+    [QKeyCode_insert]              = KEY_INSERT,
+    [QKeyCode_delete]              = KEY_DELETE,
 
-    [Q_KEY_CODE_META_L]              = KEY_LEFTMETA,
-    [Q_KEY_CODE_META_R]              = KEY_RIGHTMETA,
-    [Q_KEY_CODE_MENU]                = KEY_MENU,
+    [QKeyCode_meta_l]              = KEY_LEFTMETA,
+    [QKeyCode_meta_r]              = KEY_RIGHTMETA,
+    [QKeyCode_menu]                = KEY_MENU,
 };
 
-static const unsigned int keymap_button[INPUT_BUTTON_MAX] = {
-    [INPUT_BUTTON_LEFT]              = BTN_LEFT,
-    [INPUT_BUTTON_RIGHT]             = BTN_RIGHT,
-    [INPUT_BUTTON_MIDDLE]            = BTN_MIDDLE,
-    [INPUT_BUTTON_WHEEL_UP]          = BTN_GEAR_UP,
-    [INPUT_BUTTON_WHEEL_DOWN]        = BTN_GEAR_DOWN,
+static const unsigned int keymap_button[InputButton_MAX] = {
+    [InputButton_Left]              = BTN_LEFT,
+    [InputButton_Right]             = BTN_RIGHT,
+    [InputButton_Middle]            = BTN_MIDDLE,
+    [InputButton_WheelUp]          = BTN_GEAR_UP,
+    [InputButton_WheelDown]        = BTN_GEAR_DOWN,
 };
 
-static const unsigned int axismap_rel[INPUT_AXIS_MAX] = {
-    [INPUT_AXIS_X]                   = REL_X,
-    [INPUT_AXIS_Y]                   = REL_Y,
+static const unsigned int axismap_rel[InputAxis_MAX] = {
+    [InputAxis_X]                   = REL_X,
+    [InputAxis_Y]                   = REL_Y,
 };
 
-static const unsigned int axismap_abs[INPUT_AXIS_MAX] = {
-    [INPUT_AXIS_X]                   = ABS_X,
-    [INPUT_AXIS_Y]                   = ABS_Y,
+static const unsigned int axismap_abs[InputAxis_MAX] = {
+    [InputAxis_X]                   = ABS_X,
+    [InputAxis_Y]                   = ABS_Y,
 };
 
 /* ----------------------------------------------------------------- */
@@ -192,7 +192,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
     int qcode;
 
     switch (evt->type) {
-    case INPUT_EVENT_KIND_KEY:
+    case InputEventKind_key:
         qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
         if (qcode && keymap_qcode[qcode]) {
             event.type  = cpu_to_le16(EV_KEY);
@@ -206,7 +206,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
             }
         }
         break;
-    case INPUT_EVENT_KIND_BTN:
+    case InputEventKind_btn:
         if (keymap_button[evt->u.btn->button]) {
             event.type  = cpu_to_le16(EV_KEY);
             event.code  = cpu_to_le16(keymap_button[evt->u.btn->button]);
@@ -220,13 +220,13 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
             }
         }
         break;
-    case INPUT_EVENT_KIND_REL:
+    case InputEventKind_rel:
         event.type  = cpu_to_le16(EV_REL);
         event.code  = cpu_to_le16(axismap_rel[evt->u.rel->axis]);
         event.value = cpu_to_le32(evt->u.rel->value);
         virtio_input_send(vinput, &event);
         break;
-    case INPUT_EVENT_KIND_ABS:
+    case InputEventKind_abs:
         event.type  = cpu_to_le16(EV_ABS);
         event.code  = cpu_to_le16(axismap_abs[evt->u.abs->axis]);
         event.value = cpu_to_le32(evt->u.abs->value);
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index d5cdab2..16c1a84 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -204,7 +204,7 @@ ram_addr_t get_current_ram_size(void)
 
         if (value) {
             switch (value->type) {
-            case MEMORY_DEVICE_INFO_KIND_DIMM:
+            case MemoryDeviceInfoKind_dimm:
                 size += value->u.dimm->size;
                 break;
             default:
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index 0407dee..2569e14 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -422,7 +422,7 @@ static const MemoryRegionOps aw_emac_mem_ops = {
 };
 
 static NetClientInfo net_aw_emac_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = aw_emac_can_receive,
     .receive = aw_emac_receive,
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 3639fc1..902d988 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1181,7 +1181,7 @@ static void gem_set_link(NetClientState *nc)
 }
 
 static NetClientInfo net_gem_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = gem_can_receive,
     .receive = gem_receive,
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index ab607e4..3ab8f0a 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -810,7 +810,7 @@ static void dp8393x_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_dp83932_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = dp8393x_can_receive,
     .receive = dp8393x_receive,
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 910de3a..a1ccb95 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1516,7 +1516,7 @@ pci_e1000_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_e1000_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = e1000_can_receive,
     .receive = e1000_receive,
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 60333b7..db5d41f 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1832,7 +1832,7 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
 }
 
 static NetClientInfo net_eepro100_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = nic_receive,
 };
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index d600275..fc629a5 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -577,7 +577,7 @@ static const MemoryRegionOps eth_ops = {
 };
 
 static NetClientInfo net_etraxfs_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = eth_receive,
     .link_status_changed = eth_set_link,
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index 04bb41d..f0dfa07 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -369,7 +369,7 @@ static void etsec_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_etsec_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = etsec_receive,
     .link_status_changed = etsec_set_link_status,
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index c50bf7f..cf5985a 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -651,7 +651,7 @@ static void imx_fec_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_imx_fec_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = imx_fec_can_receive,
     .receive = imx_fec_receive,
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 4f0e840..47747c0 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1305,7 +1305,7 @@ static const MemoryRegionOps lan9118_16bit_mem_ops = {
 };
 
 static NetClientInfo net_lan9118_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = lan9118_receive,
     .link_status_changed = lan9118_set_link,
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 780b39d..72be9d1 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -92,7 +92,7 @@ static const MemoryRegionOps lance_mem_ops = {
 };
 
 static NetClientInfo net_lance_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = pcnet_receive,
     .link_status_changed = pcnet_set_link_status,
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index 21928f9..cf6c642 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -506,7 +506,7 @@ static const MemoryRegionOps mcf_fec_ops = {
 };
 
 static NetClientInfo net_mcf_fec_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = mcf_fec_receive,
 };
diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c
index 6302b8b..5dd73ef 100644
--- a/hw/net/milkymist-minimac2.c
+++ b/hw/net/milkymist-minimac2.c
@@ -443,7 +443,7 @@ static void milkymist_minimac2_reset(DeviceState *d)
 }
 
 static NetClientInfo net_milkymist_minimac2_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = minimac2_rx,
 };
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index f261011..d664294 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -218,7 +218,7 @@ static const VMStateDescription vmstate_mipsnet = {
 };
 
 static NetClientInfo net_mipsnet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = mipsnet_receive,
 };
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 18b0644..6e893f7 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -42,7 +42,7 @@ typedef struct ISANE2000State {
 } ISANE2000State;
 
 static NetClientInfo net_ne2000_isa_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = ne2000_receive,
 };
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 010f9ef..e17d871 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -705,7 +705,7 @@ void ne2000_setup_io(NE2000State *s, DeviceState *dev, unsigned size)
 }
 
 static NetClientInfo net_ne2000_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = ne2000_receive,
 };
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 3642046..145da70 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -473,7 +473,7 @@ static ssize_t open_eth_receive(NetClientState *nc,
 }
 
 static NetClientInfo net_open_eth_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = open_eth_can_receive,
     .receive = open_eth_receive,
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index b4d60b8..536e3a9 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -271,7 +271,7 @@ static void pci_pcnet_uninit(PCIDevice *dev)
 }
 
 static NetClientInfo net_pci_pcnet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = pcnet_receive,
     .link_status_changed = pcnet_set_link_status,
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index bb6fdc3..32aa2a8 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -101,7 +101,7 @@ RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
 
     r = rocker_find(name);
     if (!r) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s not found", name);
         return NULL;
     }
@@ -122,7 +122,7 @@ RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
 
     r = rocker_find(name);
     if (!r) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s not found", name);
         return NULL;
     }
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 5906396..7acbe7c 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -166,7 +166,7 @@ static void fp_port_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo fp_port_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = fp_port_receive,
     .receive_iov = fp_port_receive_iov,
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 1ad2791..b5d096d 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2462,14 +2462,14 @@ RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
 
     r = rocker_find(name);
     if (!r) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s not found", name);
         return NULL;
     }
 
     w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
     if (!w) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s doesn't have OF-DPA world", name);
         return NULL;
     }
@@ -2597,14 +2597,14 @@ RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
 
     r = rocker_find(name);
     if (!r) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s not found", name);
         return NULL;
     }
 
     w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
     if (!w) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "rocker %s doesn't have OF-DPA world", name);
         return NULL;
     }
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 68e43f3..3c7640f 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3411,7 +3411,7 @@ static void rtl8139_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_rtl8139_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = rtl8139_can_receive,
     .receive = rtl8139_receive,
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index c19cdd1..7f8c3b8 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -754,7 +754,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
 };
 
 static NetClientInfo net_smc91c111_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = smc91c111_can_receive_nc,
     .receive = smc91c111_receive,
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 1ca5e9c..2f20381 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -188,7 +188,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
 }
 
 static NetClientInfo net_spapr_vlan_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = spapr_vlan_can_receive,
     .receive = spapr_vlan_receive,
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 21a4773..25b6496 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -449,7 +449,7 @@ static void stellaris_enet_reset(stellaris_enet_state *s)
 }
 
 static NetClientInfo net_stellaris_enet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = stellaris_enet_receive,
 };
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index d91b7b1..704c398 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -97,10 +97,10 @@ static const int *vhost_net_get_feature_bits(struct vhost_net *net)
     const int *feature_bits = 0;
 
     switch (net->nc->info->type) {
-    case NET_CLIENT_OPTIONS_KIND_TAP:
+    case NetClientOptionsKind_tap:
         feature_bits = kernel_feature_bits;
         break;
-    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
+    case NetClientOptionsKind_vhost_user:
         feature_bits = user_feature_bits;
         break;
     default:
@@ -132,7 +132,7 @@ uint64_t vhost_net_get_max_queues(VHostNetState *net)
 static int vhost_net_get_fd(NetClientState *backend)
 {
     switch (backend->info->type) {
-    case NET_CLIENT_OPTIONS_KIND_TAP:
+    case NetClientOptionsKind_tap:
         return tap_get_fd(backend);
     default:
         fprintf(stderr, "vhost-net requires tap backend\n");
@@ -249,7 +249,7 @@ static int vhost_net_start_one(struct vhost_net *net,
         net->nc->info->poll(net->nc, false);
     }
 
-    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
+    if (net->nc->info->type == NetClientOptionsKind_tap) {
         qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
         file.fd = net->backend;
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
@@ -264,7 +264,7 @@ static int vhost_net_start_one(struct vhost_net *net,
     return 0;
 fail:
     file.fd = -1;
-    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
+    if (net->nc->info->type == NetClientOptionsKind_tap) {
         while (file.index-- > 0) {
             const VhostOps *vhost_ops = net->dev.vhost_ops;
             int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
@@ -286,13 +286,13 @@ static void vhost_net_stop_one(struct vhost_net *net,
 {
     struct vhost_vring_file file = { .fd = -1 };
 
-    if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
+    if (net->nc->info->type == NetClientOptionsKind_tap) {
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
             const VhostOps *vhost_ops = net->dev.vhost_ops;
             int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
             assert(r >= 0);
         }
-    } else if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
+    } else if (net->nc->info->type == NetClientOptionsKind_vhost_user) {
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
             const VhostOps *vhost_ops = net->dev.vhost_ops;
             int r = vhost_ops->vhost_reset_device(&net->dev);
@@ -420,10 +420,10 @@ VHostNetState *get_vhost_net(NetClientState *nc)
     }
 
     switch (nc->info->type) {
-    case NET_CLIENT_OPTIONS_KIND_TAP:
+    case NetClientOptionsKind_tap:
         vhost_net = tap_get_vhost_net(nc);
         break;
-    case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
+    case NetClientOptionsKind_vhost_user:
         vhost_net = vhost_user_get_vhost_net(nc);
         break;
     default:
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index a877614..0ee732b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -264,19 +264,19 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
     info->promiscuous = n->promisc;
 
     if (n->nouni) {
-        info->unicast = RX_STATE_NONE;
+        info->unicast = RxState_none;
     } else if (n->alluni) {
-        info->unicast = RX_STATE_ALL;
+        info->unicast = RxState_all;
     } else {
-        info->unicast = RX_STATE_NORMAL;
+        info->unicast = RxState_normal;
     }
 
     if (n->nomulti) {
-        info->multicast = RX_STATE_NONE;
+        info->multicast = RxState_none;
     } else if (n->allmulti) {
-        info->multicast = RX_STATE_ALL;
+        info->multicast = RxState_all;
     } else {
-        info->multicast = RX_STATE_NORMAL;
+        info->multicast = RxState_normal;
     }
 
     info->broadcast_allowed = n->nobcast;
@@ -305,11 +305,11 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
     info->vlan_table = get_vlan_table(n);
 
     if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
-        info->vlan = RX_STATE_ALL;
+        info->vlan = RxState_all;
     } else if (!info->vlan_table) {
-        info->vlan = RX_STATE_NONE;
+        info->vlan = RxState_none;
     } else {
-        info->vlan = RX_STATE_NORMAL;
+        info->vlan = RxState_normal;
     }
 
     /* enable event notification after query */
@@ -406,11 +406,11 @@ static int peer_attach(VirtIONet *n, int index)
         return 0;
     }
 
-    if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
+    if (nc->peer->info->type == NetClientOptionsKind_vhost_user) {
         vhost_set_vring_enable(nc->peer, 1);
     }
 
-    if (nc->peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP) {
+    if (nc->peer->info->type != NetClientOptionsKind_tap) {
         return 0;
     }
 
@@ -425,11 +425,11 @@ static int peer_detach(VirtIONet *n, int index)
         return 0;
     }
 
-    if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
+    if (nc->peer->info->type == NetClientOptionsKind_vhost_user) {
         vhost_set_vring_enable(nc->peer, 0);
     }
 
-    if (nc->peer->info->type !=  NET_CLIENT_OPTIONS_KIND_TAP) {
+    if (nc->peer->info->type !=  NetClientOptionsKind_tap) {
         return 0;
     }
 
@@ -1604,7 +1604,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
 }
 
 static NetClientInfo net_virtio_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = virtio_net_can_receive,
     .receive = virtio_net_receive,
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 5e3a233..0d27056 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2001,7 +2001,7 @@ static void vmxnet3_set_link_status(NetClientState *nc)
 }
 
 static NetClientInfo net_vmxnet3_info = {
-        .type = NET_CLIENT_OPTIONS_KIND_NIC,
+        .type = NetClientOptionsKind_nic,
         .size = sizeof(NICState),
         .receive = vmxnet3_receive,
         .link_status_changed = vmxnet3_set_link_status,
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 0da16b4..994c163 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -279,7 +279,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
 /* ------------------------------------------------------------- */
 
 static NetClientInfo net_xen_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = net_rx_packet,
 };
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index 15fb681..bf08312 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -370,7 +370,7 @@ out:
 }
 
 static NetClientInfo net_xgmac_enet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = eth_rx,
 };
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index d63c423..11a199b 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -933,7 +933,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
 }
 
 static NetClientInfo net_xilinx_enet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = eth_rx,
 };
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index ad6b553..a738306 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -214,7 +214,7 @@ static void xilinx_ethlite_reset(DeviceState *dev)
 }
 
 static NetClientInfo net_xilinx_ethlite_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .can_receive = eth_can_rx,
     .receive = eth_rx,
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 34b12a3..aaed8d7 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -297,7 +297,7 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
 {
     target_ulong ret = 0;
 
-    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
+    qapi_event_send_guest_panicked(GuestPanicAction_pause, &error_abort);
 
     rtas_st(rets, 0, ret);
 }
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index bada9a7..c070447 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -414,7 +414,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
     BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
                                                    is_read, error);
 
-    if (action == BLOCK_ERROR_ACTION_REPORT) {
+    if (action == BlockErrorAction_report) {
         switch (error) {
         case ENOMEDIUM:
             scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
@@ -434,10 +434,10 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
         }
     }
     blk_error_action(s->qdev.conf.blk, action, is_read, error);
-    if (action == BLOCK_ERROR_ACTION_STOP) {
+    if (action == BlockErrorAction_stop) {
         scsi_req_retry(&r->req);
     }
-    return action != BLOCK_ERROR_ACTION_IGNORE;
+    return action != BlockErrorAction_ignore;
 }
 
 static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index a4626f7..674d62f 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -407,11 +407,11 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
         return;
     }
 
-    if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
+    if (blk_get_on_error(s->conf.blk, 0) != BlockdevOnError_enospc) {
         error_setg(errp, "Device doesn't support drive option werror");
         return;
     }
-    if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+    if (blk_get_on_error(s->conf.blk, 1) != BlockdevOnError_report) {
         error_setg(errp, "Device doesn't support drive option rerror");
         return;
     }
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index a9f0efd..9e11d20 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -187,7 +187,7 @@ static void rtc_periodic_timer(void *opaque)
     if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
         s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
 #ifdef TARGET_I386
-        if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
+        if (s->lost_tick_policy == LostTickPolicy_slew) {
             if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                 s->irq_reinject_on_ack_count = 0;		
             apic_reset_irq_delivered();
@@ -732,7 +732,7 @@ static int rtc_post_load(void *opaque, int version_id)
 
 #ifdef TARGET_I386
     if (version_id >= 2) {
-        if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
+        if (s->lost_tick_policy == LostTickPolicy_slew) {
             rtc_coalesced_timer_update(s);
         }
     }
@@ -793,7 +793,7 @@ static void rtc_notify_clock_reset(Notifier *notifier, void *data)
     periodic_timer_update(s, now);
     check_update_timer(s);
 #ifdef TARGET_I386
-    if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
+    if (s->lost_tick_policy == LostTickPolicy_slew) {
         rtc_coalesced_timer_update(s);
     }
 #endif
@@ -818,7 +818,7 @@ static void rtc_reset(void *opaque)
     qemu_irq_lower(s->irq);
 
 #ifdef TARGET_I386
-    if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
+    if (s->lost_tick_policy == LostTickPolicy_slew) {
         s->irq_coalesced = 0;
         s->irq_reinject_on_ack_count = 0;		
     }
@@ -870,11 +870,11 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
 
 #ifdef TARGET_I386
     switch (s->lost_tick_policy) {
-    case LOST_TICK_POLICY_SLEW:
+    case LostTickPolicy_slew:
         s->coalesced_timer =
             timer_new_ns(rtc_clock, rtc_coalesced_timer, s);
         break;
-    case LOST_TICK_POLICY_DISCARD:
+    case LostTickPolicy_discard:
         break;
     default:
         error_setg(errp, "Invalid lost tick policy.");
@@ -929,7 +929,7 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
 static Property mc146818rtc_properties[] = {
     DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
     DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
-                               lost_tick_policy, LOST_TICK_POLICY_DISCARD),
+                               lost_tick_policy, LostTickPolicy_discard),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index be160c1..46d6612 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -491,7 +491,7 @@ static const QemuOptDesc tpm_passthrough_cmdline_opts[] = {
 };
 
 static const TPMDriverOps tpm_passthrough_driver = {
-    .type                     = TPM_TYPE_PASSTHROUGH,
+    .type                     = TpmType_passthrough,
     .opts                     = tpm_passthrough_cmdline_opts,
     .desc                     = tpm_passthrough_create_desc,
     .create                   = tpm_passthrough_create,
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 0806b5f..96d1db3 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -1041,7 +1041,7 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    s->be_driver->fe_model = TPM_MODEL_TPM_TIS;
+    s->be_driver->fe_model = TpmModel_tpm_tis;
 
     if (tpm_backend_init(s->be_driver, s, tpm_tis_receive_cb)) {
         error_setg(errp, "tpm_tis: backend driver with id %s could not be "
@@ -1093,7 +1093,7 @@ static const TypeInfo tpm_tis_info = {
 static void tpm_tis_register(void)
 {
     type_register_static(&tpm_tis_info);
-    tpm_register_model(TPM_MODEL_TPM_TIS);
+    tpm_register_model(TpmModel_tpm_tis);
 }
 
 type_init(tpm_tis_register)
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 7800cee..10b35f7 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1330,7 +1330,7 @@ static void usb_net_handle_destroy(USBDevice *dev)
 }
 
 static NetClientInfo net_usbnet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NetClientOptionsKind_nic,
     .size = sizeof(NICState),
     .receive = usbnet_receive,
     .cleanup = usbnet_cleanup,
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 64a54c6..29c2f5a 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2390,7 +2390,7 @@ static void usb_ehci_vm_state_change(void *opaque, int running, RunState state)
      * USB-devices which have async handled packages have a packet in the
      * ep queue to match the completion with.
      */
-    if (state == RUN_STATE_RUNNING) {
+    if (state == RunState_running) {
         ehci_advance_async_state(ehci);
     }
 
@@ -2400,7 +2400,7 @@ static void usb_ehci_vm_state_change(void *opaque, int running, RunState state)
      * will never have existed on the destination. Therefor we must flush the
      * async schedule on savevm to catch any not yet noticed unlinks.
      */
-    if (state == RUN_STATE_SAVE_VM) {
+    if (state == RunState_save_vm) {
         ehci_advance_async_state(ehci);
         ehci_queues_rip_unseen(ehci, 1);
     }
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 38086cd..5b42858 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -285,7 +285,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
     }
 
     /* Don't send new data to the chardev until our state is fully synced */
-    if (!runstate_check(RUN_STATE_RUNNING)) {
+    if (!runstate_check(RunState_running)) {
         return 0;
     }
 
@@ -1227,7 +1227,7 @@ static void usbredir_create_parser(USBRedirDevice *dev)
     usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams);
 #endif
 
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         flags |= usbredirparser_fl_no_hello;
     }
     usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE,
@@ -1295,7 +1295,7 @@ static int usbredir_chardev_can_read(void *opaque)
     }
 
     /* Don't read new data from the chardev until our state is fully synced */
-    if (!runstate_check(RUN_STATE_RUNNING)) {
+    if (!runstate_check(RunState_running)) {
         return 0;
     }
 
@@ -1345,7 +1345,7 @@ static void usbredir_vm_state_change(void *priv, int running, RunState state)
 {
     USBRedirDevice *dev = priv;
 
-    if (state == RUN_STATE_RUNNING && dev->parser != NULL) {
+    if (state == RunState_running && dev->parser != NULL) {
         usbredirparser_do_write(dev->parser); /* Flush any pending writes */
     }
 }
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 8fadbcf..b507671 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2139,7 +2139,7 @@ static void vfio_err_notifier_handler(void *opaque)
                  __func__, vdev->host.domain, vdev->host.bus,
                  vdev->host.slot, vdev->host.function);
 
-    vm_stop(RUN_STATE_INTERNAL_ERROR);
+    vm_stop(RunState_internal_error);
 }
 
 /*
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 8d4b0ee..bdbda9d 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -112,17 +112,17 @@ void watchdog_perform_action(void)
 {
     switch (watchdog_action) {
     case WDT_RESET:             /* same as 'system_reset' in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, &error_abort);
+        qapi_event_send_watchdog(WatchdogExpirationAction_reset, &error_abort);
         qemu_system_reset_request();
         break;
 
     case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, &error_abort);
+        qapi_event_send_watchdog(WatchdogExpirationAction_shutdown, &error_abort);
         qemu_system_powerdown_request();
         break;
 
     case WDT_POWEROFF:          /* same as 'quit' command in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, &error_abort);
+        qapi_event_send_watchdog(WatchdogExpirationAction_poweroff, &error_abort);
         exit(0);
 
     case WDT_PAUSE:             /* same as 'stop' command in monitor */
@@ -130,21 +130,21 @@ void watchdog_perform_action(void)
          * you would get a deadlock.  Bypass the problem.
          */
         qemu_system_vmstop_request_prepare();
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, &error_abort);
-        qemu_system_vmstop_request(RUN_STATE_WATCHDOG);
+        qapi_event_send_watchdog(WatchdogExpirationAction_pause, &error_abort);
+        qemu_system_vmstop_request(RunState_watchdog);
         break;
 
     case WDT_DEBUG:
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, &error_abort);
+        qapi_event_send_watchdog(WatchdogExpirationAction_debug, &error_abort);
         fprintf(stderr, "watchdog: timer fired\n");
         break;
 
     case WDT_NONE:
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, &error_abort);
+        qapi_event_send_watchdog(WatchdogExpirationAction_none, &error_abort);
         break;
 
     case WDT_NMI:
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI,
+        qapi_event_send_watchdog(WatchdogExpirationAction_inject_nmi,
                                  &error_abort);
         inject_nmi();
         break;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 3ceeb5a..9f8481b 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -646,7 +646,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
  * @target: Block device to write to.
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
  * @sync_mode: What parts of the disk image should be copied to the destination.
- * @sync_bitmap: The dirty bitmap if sync_mode is MIRROR_SYNC_MODE_INCREMENTAL.
+ * @sync_bitmap: The dirty bitmap if sync_mode is MirrorSyncMode_incremental.
  * @on_source_error: The action to take upon error reading from the source.
  * @on_target_error: The action to take upon error writing to the target.
  * @cb: Completion function for the job.
diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
index b38fe69..1d9c7aa 100644
--- a/include/crypto/tlssession.h
+++ b/include/crypto/tlssession.h
@@ -63,7 +63,7 @@
  *    sess = qcrypto_tls_session_new(creds,
  *                                   "vnc.example.com",
  *                                   NULL,
- *                                   QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
+ *                                   QCRYPTO_TLS_CREDS_ENDPOINT_client,
  *                                   errp);
  *    if (sess == NULL) {
  *       return -1;
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 8334621..729d8cd 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -66,7 +66,7 @@ struct MigrationState
     QemuThread thread;
     QEMUBH *cleanup_bh;
     QEMUFile *file;
-    int parameters[MIGRATION_PARAMETER_MAX];
+    int parameters[MigrationParameter_MAX];
 
     int state;
     MigrationParams params;
@@ -76,7 +76,7 @@ struct MigrationState
     int64_t expected_downtime;
     int64_t dirty_pages_rate;
     int64_t dirty_bytes_rate;
-    bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
+    bool enabled_capabilities[MigrationCapability_MAX];
     int64_t xbzrle_cache_size;
     int64_t setup_time;
     int64_t dirty_sync_count;
diff --git a/include/qapi/error.h b/include/qapi/error.h
index c69dddb..4e34dfe 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -93,7 +93,7 @@ const char *error_get_pretty(Error *err);
 
 /*
  * Get @err's error class.
- * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
+ * Note: use of error classes other than ErrorClass_GenericError is
  * strongly discouraged.
  */
 ErrorClass error_get_class(const Error *err);
@@ -105,7 +105,7 @@ ErrorClass error_get_class(const Error *err);
  * If @errp is &error_abort, print a suitable message and abort().
  * If @errp is &error_fatal, print a suitable message and exit(1).
  * If @errp is anything else, *@errp must be NULL.
- * The new error's class is ERROR_CLASS_GENERIC_ERROR, and its
+ * The new error's class is ErrorClass_GenericError, and its
  * human-readable error message is made from printf-style @fmt, ...
  */
 #define error_setg(errp, fmt, ...)                              \
@@ -196,7 +196,7 @@ void error_report_err(Error *);
 
 /*
  * Just like error_setg(), except you get to specify the error class.
- * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
+ * Note: use of error classes other than ErrorClass_GenericError is
  * strongly discouraged.
  */
 #define error_set(errp, err_class, fmt, ...)                    \
diff --git a/include/ui/input.h b/include/ui/input.h
index 5d5ac00..b459eae 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -3,10 +3,10 @@
 
 #include "qapi-types.h"
 
-#define INPUT_EVENT_MASK_KEY   (1<<INPUT_EVENT_KIND_KEY)
-#define INPUT_EVENT_MASK_BTN   (1<<INPUT_EVENT_KIND_BTN)
-#define INPUT_EVENT_MASK_REL   (1<<INPUT_EVENT_KIND_REL)
-#define INPUT_EVENT_MASK_ABS   (1<<INPUT_EVENT_KIND_ABS)
+#define INPUT_EVENT_MASK_KEY   (1<<InputEventKind_key)
+#define INPUT_EVENT_MASK_BTN   (1<<InputEventKind_btn)
+#define INPUT_EVENT_MASK_REL   (1<<InputEventKind_rel)
+#define INPUT_EVENT_MASK_ABS   (1<<InputEventKind_abs)
 
 #define INPUT_EVENT_ABS_SIZE   0x8000
 
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index f9ce357..2e5a3d0 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -81,7 +81,7 @@ static inline int qemu_spice_display_add_client(int csock, int skipauth,
 static inline bool qemu_using_spice(Error **errp)
 {
     if (!using_spice) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+        error_set(errp, ErrorClass_DeviceNotActive,
                   "SPICE is not in use");
         return false;
     }
diff --git a/kvm-all.c b/kvm-all.c
index c442838..e8a3fae 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1900,7 +1900,7 @@ int kvm_cpu_exec(CPUState *cpu)
 
     if (ret < 0) {
         cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
-        vm_stop(RUN_STATE_INTERNAL_ERROR);
+        vm_stop(RunState_internal_error);
     }
 
     cpu->exit_request = 0;
diff --git a/migration/migration.c b/migration/migration.c
index b092f38..c2f77a0 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -65,19 +65,19 @@ static bool deferred_incoming;
 MigrationState *migrate_get_current(void)
 {
     static MigrationState current_migration = {
-        .state = MIGRATION_STATUS_NONE,
+        .state = MigrationStatus_none,
         .bandwidth_limit = MAX_THROTTLE,
         .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
         .mbps = -1,
-        .parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] =
+        .parameters[MigrationParameter_compress_level] =
                 DEFAULT_MIGRATE_COMPRESS_LEVEL,
-        .parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] =
+        .parameters[MigrationParameter_compress_threads] =
                 DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
-        .parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+        .parameters[MigrationParameter_decompress_threads] =
                 DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
-        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
+        .parameters[MigrationParameter_x_cpu_throttle_initial] =
                 DEFAULT_MIGRATE_X_CPU_THROTTLE_INITIAL,
-        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
+        .parameters[MigrationParameter_x_cpu_throttle_increment] =
                 DEFAULT_MIGRATE_X_CPU_THROTTLE_INCREMENT,
     };
 
@@ -132,7 +132,7 @@ int global_state_store(void)
 
 void global_state_store_running(void)
 {
-    const char *state = RunState_lookup[RUN_STATE_RUNNING];
+    const char *state = RunState_lookup[RunState_running];
     strncpy((char *)global_state.runstate,
            state, sizeof(global_state.runstate));
 }
@@ -184,7 +184,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,
+    r = qapi_enum_parse(RunState_lookup, runstate, RunState_MAX,
                                 -1, &local_err);
 
     if (r == -1) {
@@ -252,7 +252,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp)
 {
     const char *p;
 
-    qapi_event_send_migration(MIGRATION_STATUS_SETUP, &error_abort);
+    qapi_event_send_migration(MigrationStatus_setup, &error_abort);
     if (!strcmp(uri, "defer")) {
         deferred_incoming_migration(errp);
     } else if (strstart(uri, "tcp:", &p)) {
@@ -281,7 +281,7 @@ static void process_incoming_migration_co(void *opaque)
     int ret;
 
     migration_incoming_state_new(f);
-    migrate_generate_event(MIGRATION_STATUS_ACTIVE);
+    migrate_generate_event(MigrationStatus_active);
     ret = qemu_loadvm_state(f);
 
     qemu_fclose(f);
@@ -289,7 +289,7 @@ static void process_incoming_migration_co(void *opaque)
     migration_incoming_state_destroy();
 
     if (ret < 0) {
-        migrate_generate_event(MIGRATION_STATUS_FAILED);
+        migrate_generate_event(MigrationStatus_failed);
         error_report("load of migration failed: %s", strerror(-ret));
         migrate_decompress_threads_join();
         exit(EXIT_FAILURE);
@@ -298,7 +298,7 @@ static void process_incoming_migration_co(void *opaque)
     /* Make sure all file formats flush their mutable metadata */
     bdrv_invalidate_cache_all(&local_err);
     if (local_err) {
-        migrate_generate_event(MIGRATION_STATUS_FAILED);
+        migrate_generate_event(MigrationStatus_failed);
         error_report_err(local_err);
         migrate_decompress_threads_join();
         exit(EXIT_FAILURE);
@@ -315,11 +315,11 @@ static void process_incoming_migration_co(void *opaque)
        runstate_set. */
 
     if (!global_state_received() ||
-        global_state_get_runstate() == RUN_STATE_RUNNING) {
+        global_state_get_runstate() == RunState_running) {
         if (autostart) {
             vm_start();
         } else {
-            runstate_set(RUN_STATE_PAUSED);
+            runstate_set(RunState_paused);
         }
     } else {
         runstate_set(global_state_get_runstate());
@@ -330,7 +330,7 @@ static void process_incoming_migration_co(void *opaque)
      * observer sees this event they might start to prod at the VM assuming
      * it's ready to use.
      */
-    migrate_generate_event(MIGRATION_STATUS_COMPLETED);
+    migrate_generate_event(MigrationStatus_completed);
 }
 
 void process_incoming_migration(QEMUFile *f)
@@ -363,7 +363,7 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
     int i;
 
     caps = NULL; /* silence compiler warning */
-    for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+    for (i = 0; i < MigrationCapability_MAX; i++) {
         if (head == NULL) {
             head = g_malloc0(sizeof(*caps));
             caps = head;
@@ -386,15 +386,15 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
     MigrationState *s = migrate_get_current();
 
     params = g_malloc0(sizeof(*params));
-    params->compress_level = s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
+    params->compress_level = s->parameters[MigrationParameter_compress_level];
     params->compress_threads =
-            s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
+            s->parameters[MigrationParameter_compress_threads];
     params->decompress_threads =
-            s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
+            s->parameters[MigrationParameter_decompress_threads];
     params->x_cpu_throttle_initial =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+            s->parameters[MigrationParameter_x_cpu_throttle_initial];
     params->x_cpu_throttle_increment =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
+            s->parameters[MigrationParameter_x_cpu_throttle_increment];
 
     return params;
 }
@@ -419,15 +419,15 @@ MigrationInfo *qmp_query_migrate(Error **errp)
     MigrationState *s = migrate_get_current();
 
     switch (s->state) {
-    case MIGRATION_STATUS_NONE:
+    case MigrationStatus_none:
         /* no migration has happened ever */
         break;
-    case MIGRATION_STATUS_SETUP:
+    case MigrationStatus_setup:
         info->has_status = true;
         info->has_total_time = false;
         break;
-    case MIGRATION_STATUS_ACTIVE:
-    case MIGRATION_STATUS_CANCELLING:
+    case MigrationStatus_active:
+    case MigrationStatus_cancelling:
         info->has_status = true;
         info->has_total_time = true;
         info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
@@ -465,7 +465,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 
         get_xbzrle_cache_stats(info);
         break;
-    case MIGRATION_STATUS_COMPLETED:
+    case MigrationStatus_completed:
         get_xbzrle_cache_stats(info);
 
         info->has_status = true;
@@ -488,10 +488,10 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->ram->mbps = s->mbps;
         info->ram->dirty_sync_count = s->dirty_sync_count;
         break;
-    case MIGRATION_STATUS_FAILED:
+    case MigrationStatus_failed:
         info->has_status = true;
         break;
-    case MIGRATION_STATUS_CANCELLED:
+    case MigrationStatus_cancelled:
         info->has_status = true;
         break;
     }
@@ -506,8 +506,8 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
     MigrationState *s = migrate_get_current();
     MigrationCapabilityStatusList *cap;
 
-    if (s->state == MIGRATION_STATUS_ACTIVE ||
-        s->state == MIGRATION_STATUS_SETUP) {
+    if (s->state == MigrationStatus_active ||
+        s->state == MigrationStatus_setup) {
         error_setg(errp, QERR_MIGRATION_ACTIVE);
         return;
     }
@@ -563,22 +563,22 @@ void qmp_migrate_set_parameters(bool has_compress_level,
     }
 
     if (has_compress_level) {
-        s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] = compress_level;
+        s->parameters[MigrationParameter_compress_level] = compress_level;
     }
     if (has_compress_threads) {
-        s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] = compress_threads;
+        s->parameters[MigrationParameter_compress_threads] = compress_threads;
     }
     if (has_decompress_threads) {
-        s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+        s->parameters[MigrationParameter_decompress_threads] =
                                                     decompress_threads;
     }
     if (has_x_cpu_throttle_initial) {
-        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
+        s->parameters[MigrationParameter_x_cpu_throttle_initial] =
                                                     x_cpu_throttle_initial;
     }
 
     if (has_x_cpu_throttle_increment) {
-        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
+        s->parameters[MigrationParameter_x_cpu_throttle_increment] =
                                                     x_cpu_throttle_increment;
     }
 }
@@ -611,13 +611,13 @@ static void migrate_fd_cleanup(void *opaque)
         s->file = NULL;
     }
 
-    assert(s->state != MIGRATION_STATUS_ACTIVE);
+    assert(s->state != MigrationStatus_active);
 
-    if (s->state != MIGRATION_STATUS_COMPLETED) {
+    if (s->state != MigrationStatus_completed) {
         qemu_savevm_state_cancel();
-        if (s->state == MIGRATION_STATUS_CANCELLING) {
-            migrate_set_state(s, MIGRATION_STATUS_CANCELLING,
-                              MIGRATION_STATUS_CANCELLED);
+        if (s->state == MigrationStatus_cancelling) {
+            migrate_set_state(s, MigrationStatus_cancelling,
+                              MigrationStatus_cancelled);
         }
     }
 
@@ -628,7 +628,7 @@ void migrate_fd_error(MigrationState *s)
 {
     trace_migrate_fd_error();
     assert(s->file == NULL);
-    migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED);
+    migrate_set_state(s, MigrationStatus_setup, MigrationStatus_failed);
     notifier_list_notify(&migration_state_notifiers, s);
 }
 
@@ -640,12 +640,12 @@ static void migrate_fd_cancel(MigrationState *s)
 
     do {
         old_state = s->state;
-        if (old_state != MIGRATION_STATUS_SETUP &&
-            old_state != MIGRATION_STATUS_ACTIVE) {
+        if (old_state != MigrationStatus_setup &&
+            old_state != MigrationStatus_active) {
             break;
         }
-        migrate_set_state(s, old_state, MIGRATION_STATUS_CANCELLING);
-    } while (s->state != MIGRATION_STATUS_CANCELLING);
+        migrate_set_state(s, old_state, MigrationStatus_cancelling);
+    } while (s->state != MigrationStatus_cancelling);
 
     /*
      * If we're unlucky the migration code might be stuck somewhere in a
@@ -654,7 +654,7 @@ static void migrate_fd_cancel(MigrationState *s)
      * The outgoing qemu file gets closed in migrate_fd_cleanup that is
      * called in a bh, so there is no race against this cancel.
      */
-    if (s->state == MIGRATION_STATUS_CANCELLING && f) {
+    if (s->state == MigrationStatus_cancelling && f) {
         qemu_file_shutdown(f);
     }
 }
@@ -671,35 +671,35 @@ void remove_migration_state_change_notifier(Notifier *notify)
 
 bool migration_in_setup(MigrationState *s)
 {
-    return s->state == MIGRATION_STATUS_SETUP;
+    return s->state == MigrationStatus_setup;
 }
 
 bool migration_has_finished(MigrationState *s)
 {
-    return s->state == MIGRATION_STATUS_COMPLETED;
+    return s->state == MigrationStatus_completed;
 }
 
 bool migration_has_failed(MigrationState *s)
 {
-    return (s->state == MIGRATION_STATUS_CANCELLED ||
-            s->state == MIGRATION_STATUS_FAILED);
+    return (s->state == MigrationStatus_cancelled ||
+            s->state == MigrationStatus_failed);
 }
 
 static MigrationState *migrate_init(const MigrationParams *params)
 {
     MigrationState *s = migrate_get_current();
     int64_t bandwidth_limit = s->bandwidth_limit;
-    bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
+    bool enabled_capabilities[MigrationCapability_MAX];
     int64_t xbzrle_cache_size = s->xbzrle_cache_size;
-    int compress_level = s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
+    int compress_level = s->parameters[MigrationParameter_compress_level];
     int compress_thread_count =
-            s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
+            s->parameters[MigrationParameter_compress_threads];
     int decompress_thread_count =
-            s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
+            s->parameters[MigrationParameter_decompress_threads];
     int x_cpu_throttle_initial =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+            s->parameters[MigrationParameter_x_cpu_throttle_initial];
     int x_cpu_throttle_increment =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
+            s->parameters[MigrationParameter_x_cpu_throttle_increment];
 
     memcpy(enabled_capabilities, s->enabled_capabilities,
            sizeof(enabled_capabilities));
@@ -710,17 +710,17 @@ static MigrationState *migrate_init(const MigrationParams *params)
            sizeof(enabled_capabilities));
     s->xbzrle_cache_size = xbzrle_cache_size;
 
-    s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] = compress_level;
-    s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] =
+    s->parameters[MigrationParameter_compress_level] = compress_level;
+    s->parameters[MigrationParameter_compress_threads] =
                compress_thread_count;
-    s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
+    s->parameters[MigrationParameter_decompress_threads] =
                decompress_thread_count;
-    s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
+    s->parameters[MigrationParameter_x_cpu_throttle_initial] =
                 x_cpu_throttle_initial;
-    s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
+    s->parameters[MigrationParameter_x_cpu_throttle_increment] =
                 x_cpu_throttle_increment;
     s->bandwidth_limit = bandwidth_limit;
-    migrate_set_state(s, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
+    migrate_set_state(s, MigrationStatus_none, MigrationStatus_setup);
 
     s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     return s;
@@ -773,13 +773,13 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
     params.blk = has_blk && blk;
     params.shared = has_inc && inc;
 
-    if (s->state == MIGRATION_STATUS_ACTIVE ||
-        s->state == MIGRATION_STATUS_SETUP ||
-        s->state == MIGRATION_STATUS_CANCELLING) {
+    if (s->state == MigrationStatus_active ||
+        s->state == MigrationStatus_setup ||
+        s->state == MigrationStatus_cancelling) {
         error_setg(errp, QERR_MIGRATION_ACTIVE);
         return;
     }
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         error_setg(errp, "Guest is waiting for an incoming migration");
         return;
     }
@@ -797,7 +797,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
        state.  This change is only needed if previous migration
        failed/was cancelled.  We don't use migrate_set_state() because
        we are setting the initial state, not changing it. */
-    s->state = MIGRATION_STATUS_NONE;
+    s->state = MigrationStatus_none;
 
     s = migrate_init(&params);
 
@@ -818,7 +818,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
     } else {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "uri",
                    "a valid migration protocol");
-        migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_FAILED);
+        migrate_set_state(s, MigrationStatus_setup, MigrationStatus_failed);
         return;
     }
 
@@ -899,7 +899,7 @@ bool migrate_auto_converge(void)
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
+    return s->enabled_capabilities[MigrationCapability_auto_converge];
 }
 
 bool migrate_zero_blocks(void)
@@ -908,7 +908,7 @@ bool migrate_zero_blocks(void)
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_ZERO_BLOCKS];
+    return s->enabled_capabilities[MigrationCapability_zero_blocks];
 }
 
 bool migrate_use_compression(void)
@@ -917,7 +917,7 @@ bool migrate_use_compression(void)
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_COMPRESS];
+    return s->enabled_capabilities[MigrationCapability_compress];
 }
 
 int migrate_compress_level(void)
@@ -926,7 +926,7 @@ int migrate_compress_level(void)
 
     s = migrate_get_current();
 
-    return s->parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL];
+    return s->parameters[MigrationParameter_compress_level];
 }
 
 int migrate_compress_threads(void)
@@ -935,7 +935,7 @@ int migrate_compress_threads(void)
 
     s = migrate_get_current();
 
-    return s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
+    return s->parameters[MigrationParameter_compress_threads];
 }
 
 int migrate_decompress_threads(void)
@@ -944,7 +944,7 @@ int migrate_decompress_threads(void)
 
     s = migrate_get_current();
 
-    return s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
+    return s->parameters[MigrationParameter_decompress_threads];
 }
 
 bool migrate_use_events(void)
@@ -953,7 +953,7 @@ bool migrate_use_events(void)
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_EVENTS];
+    return s->enabled_capabilities[MigrationCapability_events];
 }
 
 int migrate_use_xbzrle(void)
@@ -962,7 +962,7 @@ int migrate_use_xbzrle(void)
 
     s = migrate_get_current();
 
-    return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];
+    return s->enabled_capabilities[MigrationCapability_xbzrle];
 }
 
 int64_t migrate_xbzrle_cache_size(void)
@@ -994,7 +994,7 @@ static void migration_completion(MigrationState *s, bool *old_vm_running,
 
     ret = global_state_store();
     if (!ret) {
-        ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+        ret = vm_stop_force_state(RunState_finish_migrate);
         if (ret >= 0) {
             qemu_file_set_rate_limit(s->file, INT64_MAX);
             qemu_savevm_state_complete(s->file);
@@ -1011,11 +1011,11 @@ static void migration_completion(MigrationState *s, bool *old_vm_running,
         goto fail;
     }
 
-    migrate_set_state(s, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_COMPLETED);
+    migrate_set_state(s, MigrationStatus_active, MigrationStatus_completed);
     return;
 
 fail:
-    migrate_set_state(s, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_FAILED);
+    migrate_set_state(s, MigrationStatus_active, MigrationStatus_failed);
 }
 
 /* migration thread support */
@@ -1036,9 +1036,9 @@ static void *migration_thread(void *opaque)
     qemu_savevm_state_begin(s->file, &s->params);
 
     s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
-    migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE);
+    migrate_set_state(s, MigrationStatus_setup, MigrationStatus_active);
 
-    while (s->state == MIGRATION_STATUS_ACTIVE) {
+    while (s->state == MigrationStatus_active) {
         int64_t current_time;
         uint64_t pending_size;
 
@@ -1055,8 +1055,8 @@ static void *migration_thread(void *opaque)
         }
 
         if (qemu_file_get_error(s->file)) {
-            migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
-                              MIGRATION_STATUS_FAILED);
+            migrate_set_state(s, MigrationStatus_active,
+                              MigrationStatus_failed);
             break;
         }
         current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
@@ -1091,7 +1091,7 @@ static void *migration_thread(void *opaque)
     cpu_throttle_stop();
 
     qemu_mutex_lock_iothread();
-    if (s->state == MIGRATION_STATUS_COMPLETED) {
+    if (s->state == MigrationStatus_completed) {
         int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
         uint64_t transferred_bytes = qemu_ftell(s->file);
         s->total_time = end_time - s->total_time;
@@ -1100,7 +1100,7 @@ static void *migration_thread(void *opaque)
             s->mbps = (((double) transferred_bytes * 8.0) /
                        ((double) s->total_time)) / 1000;
         }
-        runstate_set(RUN_STATE_POSTMIGRATE);
+        runstate_set(RunState_postmigrate);
     } else {
         if (old_vm_running) {
             vm_start();
diff --git a/migration/ram.c b/migration/ram.c
index a25bcc7..1d6fb68 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -419,9 +419,9 @@ static void mig_throttle_guest_down(void)
 {
     MigrationState *s = migrate_get_current();
     uint64_t pct_initial =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+            s->parameters[MigrationParameter_x_cpu_throttle_initial];
     uint64_t pct_icrement =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
+            s->parameters[MigrationParameter_x_cpu_throttle_increment];
 
     /* We have not started throttling yet. Let's start it. */
     if (!cpu_throttle_active()) {
diff --git a/migration/rdma.c b/migration/rdma.c
index 553fbd7..ed34279 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3491,7 +3491,7 @@ void rdma_start_outgoing_migration(void *opaque,
     }
 
     ret = qemu_rdma_source_init(rdma, &local_err,
-        s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL]);
+        s->enabled_capabilities[MigrationCapability_rdma_pin_all]);
 
     if (ret) {
         goto err;
diff --git a/migration/savevm.c b/migration/savevm.c
index dbcc39a..199b687 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1318,7 +1318,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, "Error saving global state\n");
         return;
     }
-    vm_stop(RUN_STATE_SAVE_VM);
+    vm_stop(RunState_save_vm);
 
     memset(sn, 0, sizeof(*sn));
 
@@ -1390,7 +1390,7 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
     int ret;
 
     saved_vm_running = runstate_is_running();
-    vm_stop(RUN_STATE_SAVE_VM);
+    vm_stop(RunState_save_vm);
     global_state_store_running();
 
     f = qemu_fopen(filename, "wb");
diff --git a/monitor.c b/monitor.c
index 6cd747f..c10cd41 100644
--- a/monitor.c
+++ b/monitor.c
@@ -441,14 +441,14 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data,
 }
 
 
-static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT_MAX] = {
+static MonitorQAPIEventConf monitor_qapi_event_conf[QAPIEvent_MAX] = {
     /* Limit guest-triggerable events to 1 per second */
-    [QAPI_EVENT_RTC_CHANGE]        = { 1000 * SCALE_MS },
-    [QAPI_EVENT_WATCHDOG]          = { 1000 * SCALE_MS },
-    [QAPI_EVENT_BALLOON_CHANGE]    = { 1000 * SCALE_MS },
-    [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
-    [QAPI_EVENT_QUORUM_FAILURE]    = { 1000 * SCALE_MS },
-    [QAPI_EVENT_VSERPORT_CHANGE]   = { 1000 * SCALE_MS },
+    [QAPIEvent_RTC_CHANGE]        = { 1000 * SCALE_MS },
+    [QAPIEvent_WATCHDOG]          = { 1000 * SCALE_MS },
+    [QAPIEvent_BALLOON_CHANGE]    = { 1000 * SCALE_MS },
+    [QAPIEvent_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
+    [QAPIEvent_QUORUM_FAILURE]    = { 1000 * SCALE_MS },
+    [QAPIEvent_VSERPORT_CHANGE]   = { 1000 * SCALE_MS },
 };
 
 GHashTable *monitor_qapi_event_state;
@@ -481,7 +481,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
     MonitorQAPIEventConf *evconf;
     MonitorQAPIEventState *evstate;
 
-    assert(event < QAPI_EVENT_MAX);
+    assert(event < QAPIEvent_MAX);
     evconf = &monitor_qapi_event_conf[event];
     trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
 
@@ -568,7 +568,7 @@ static unsigned int qapi_event_throttle_hash(const void *key)
     const MonitorQAPIEventState *evstate = key;
     unsigned int hash = evstate->event * 255;
 
-    if (evstate->event == QAPI_EVENT_VSERPORT_CHANGE) {
+    if (evstate->event == QAPIEvent_VSERPORT_CHANGE) {
         hash += g_str_hash(qdict_get_str(evstate->data, "id"));
     }
 
@@ -584,7 +584,7 @@ static gboolean qapi_event_throttle_equal(const void *a, const void *b)
         return FALSE;
     }
 
-    if (eva->event == QAPI_EVENT_VSERPORT_CHANGE) {
+    if (eva->event == QAPIEvent_VSERPORT_CHANGE) {
         return !strcmp(qdict_get_str(eva->data, "id"),
                        qdict_get_str(evb->data, "id"));
     }
@@ -946,7 +946,7 @@ EventInfoList *qmp_query_events(Error **errp)
     EventInfoList *info, *ev_list = NULL;
     QAPIEvent e;
 
-    for (e = 0 ; e < QAPI_EVENT_MAX ; e++) {
+    for (e = 0 ; e < QAPIEvent_MAX ; e++) {
         const char *event_name = QAPIEvent_lookup[e];
         assert(event_name != NULL);
         info = g_malloc0(sizeof(*info));
@@ -1053,7 +1053,7 @@ static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
     for (elem = events; elem != NULL; elem = elem->next) {
         monitor_printf(mon, "%s : state %u\n",
                        elem->value->name,
-                       elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0);
+                       elem->value->state == TraceEventState_enabled ? 1 : 0);
     }
     qapi_free_TraceEventInfoList(events);
 }
@@ -1369,13 +1369,13 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
 
     dx = strtol(dx_str, NULL, 0);
     dy = strtol(dy_str, NULL, 0);
-    qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
-    qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
+    qemu_input_queue_rel(NULL, InputAxis_X, dx);
+    qemu_input_queue_rel(NULL, InputAxis_Y, dy);
 
     if (dz_str) {
         dz = strtol(dz_str, NULL, 0);
         if (dz != 0) {
-            button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
+            button = (dz > 0) ? InputButton_WheelUp : InputButton_WheelDown;
             qemu_input_queue_btn(NULL, button, true);
             qemu_input_event_sync();
             qemu_input_queue_btn(NULL, button, false);
@@ -1386,10 +1386,10 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
 
 static void hmp_mouse_button(Monitor *mon, const QDict *qdict)
 {
-    static uint32_t bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]       = MOUSE_EVENT_LBUTTON,
-        [INPUT_BUTTON_MIDDLE]     = MOUSE_EVENT_MBUTTON,
-        [INPUT_BUTTON_RIGHT]      = MOUSE_EVENT_RBUTTON,
+    static uint32_t bmap[InputButton_MAX] = {
+        [InputButton_Left]       = MOUSE_EVENT_LBUTTON,
+        [InputButton_Middle]     = MOUSE_EVENT_MBUTTON,
+        [InputButton_Right]      = MOUSE_EVENT_RBUTTON,
     };
     int button_state = qdict_get_int(qdict, "button_state");
 
@@ -1740,7 +1740,7 @@ static void hmp_loadvm(Monitor *mon, const QDict *qdict)
     int saved_vm_running  = runstate_is_running();
     const char *name = qdict_get_str(qdict, "name");
 
-    vm_stop(RUN_STATE_RESTORE_VM);
+    vm_stop(RunState_restore_vm);
 
     if (load_vmstate(name) == 0 && saved_vm_running) {
         vm_start();
@@ -3209,7 +3209,7 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
     }
     len = strlen(str);
     readline_set_completion_index(rs, len);
-    for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+    for (i = 0; i < QKeyCode_MAX; i++) {
         if (!strncmp(str, QKeyCode_lookup[i], len)) {
             readline_add_completion(rs, QKeyCode_lookup[i]);
         }
@@ -3226,7 +3226,7 @@ void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
         NetClientState *ncs[MAX_QUEUE_NUM];
         int count, i;
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_OPTIONS_KIND_NONE,
+                                             NetClientOptionsKind_none,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             const char *name = ncs[i]->name;
@@ -3251,7 +3251,7 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
 
     len = strlen(str);
     readline_set_completion_index(rs, len);
-    count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC,
+    count = qemu_find_net_clients_except(NULL, ncs, NetClientOptionsKind_nic,
                                          MAX_QUEUE_NUM);
     for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
         QemuOpts *opts;
@@ -3308,7 +3308,7 @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
     readline_set_completion_index(rs, len);
     if (nb_args == 2) {
         int i;
-        for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+        for (i = 0; i < MigrationCapability_MAX; i++) {
             const char *name = MigrationCapability_lookup[i];
             if (!strncmp(str, name, len)) {
                 readline_add_completion(rs, name);
@@ -3329,7 +3329,7 @@ void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
     readline_set_completion_index(rs, len);
     if (nb_args == 2) {
         int i;
-        for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
+        for (i = 0; i < MigrationParameter_MAX; i++) {
             const char *name = MigrationParameter_lookup[i];
             if (!strncmp(str, name, len)) {
                 readline_add_completion(rs, name);
@@ -3363,7 +3363,7 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
     readline_set_completion_index(rs, len);
     if (nb_args == 2) {
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_OPTIONS_KIND_NONE,
+                                             NetClientOptionsKind_none,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             int id;
@@ -3380,13 +3380,13 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
         return;
     } else if (nb_args == 3) {
         count = qemu_find_net_clients_except(NULL, ncs,
-                                             NET_CLIENT_OPTIONS_KIND_NIC,
+                                             NetClientOptionsKind_nic,
                                              MAX_QUEUE_NUM);
         for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
             int id;
             const char *name;
 
-            if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT ||
+            if (ncs[i]->info->type == NetClientOptionsKind_hubport ||
                 net_hub_id_for_client(ncs[i], &id)) {
                 continue;
             }
@@ -3573,13 +3573,13 @@ static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
     bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities;
 
     if (is_cap && mon->qmp.in_command_mode) {
-        error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+        error_set(errp, ErrorClass_CommandNotFound,
                   "Capabilities negotiation is already complete, command "
                   "'%s' ignored", cmd->name);
         return true;
     }
     if (!is_cap && !mon->qmp.in_command_mode) {
-        error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+        error_set(errp, ErrorClass_CommandNotFound,
                   "Expecting capabilities negotiation with "
                   "'qmp_capabilities' before command '%s'", cmd->name);
         return true;
@@ -3868,7 +3868,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
     trace_handle_qmp_command(mon, cmd_name);
     cmd = qmp_find_cmd(cmd_name);
     if (!cmd) {
-        error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
+        error_set(&local_err, ErrorClass_CommandNotFound,
                   "The command %s has not been found", cmd_name);
         goto err_out;
     }
diff --git a/net/dump.c b/net/dump.c
index ce16a4b..be6d487 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -170,7 +170,7 @@ static void dumpclient_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_dump_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_DUMP,
+    .type = NetClientOptionsKind_dump,
     .size = sizeof(DumpNetClient),
     .receive = dumpclient_receive,
     .receive_iov = dumpclient_receive_iov,
@@ -187,7 +187,7 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
     NetClientState *nc;
     DumpNetClient *dnc;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_DUMP);
+    assert(opts->type == NetClientOptionsKind_dump);
     dump = opts->u.dump;
 
     assert(peer);
diff --git a/net/filter.c b/net/filter.c
index 326f2b5..8303c0f 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -26,7 +26,7 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
                                NetPacketSent *sent_cb)
 {
     if (nf->direction == direction ||
-        nf->direction == NET_FILTER_DIRECTION_ALL) {
+        nf->direction == NetFilterDirection_all) {
         return NETFILTER_GET_CLASS(OBJECT(nf))->receive_iov(
                                    nf, sender, flags, iov, iovcnt, sent_cb);
     }
@@ -50,12 +50,12 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
         goto out;
     }
 
-    if (nf->direction == NET_FILTER_DIRECTION_ALL) {
+    if (nf->direction == NetFilterDirection_all) {
         if (sender == nf->netdev) {
             /* This packet is sent by netdev itself */
-            direction = NET_FILTER_DIRECTION_TX;
+            direction = NetFilterDirection_tx;
         } else {
-            direction = NET_FILTER_DIRECTION_RX;
+            direction = NetFilterDirection_rx;
         }
     } else {
         direction = nf->direction;
@@ -145,7 +145,7 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
     }
 
     queues = qemu_find_net_clients_except(nf->netdev_id, ncs,
-                                          NET_CLIENT_OPTIONS_KIND_NIC,
+                                          NetClientOptionsKind_nic,
                                           MAX_QUEUE_NUM);
     if (queues < 1) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "netdev",
diff --git a/net/hub.c b/net/hub.c
index 9ae9f01..7ad1e36 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -130,7 +130,7 @@ static void net_hub_port_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_hub_port_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_HUBPORT,
+    .type = NetClientOptionsKind_hubport,
     .size = sizeof(NetHubPort),
     .can_receive = net_hub_port_can_receive,
     .receive = net_hub_port_receive,
@@ -265,10 +265,10 @@ int net_hub_id_for_client(NetClientState *nc, int *id)
 {
     NetHubPort *port;
 
-    if (nc->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+    if (nc->info->type == NetClientOptionsKind_hubport) {
         port = DO_UPCAST(NetHubPort, nc, nc);
     } else if (nc->peer != NULL && nc->peer->info->type ==
-            NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+            NetClientOptionsKind_hubport) {
         port = DO_UPCAST(NetHubPort, nc, nc->peer);
     } else {
         return -ENOENT;
@@ -285,7 +285,7 @@ int net_init_hubport(const NetClientOptions *opts, const char *name,
 {
     const NetdevHubPortOptions *hubport;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT);
+    assert(opts->type == NetClientOptionsKind_hubport);
     assert(!peer);
     hubport = opts->u.hubport;
 
@@ -314,14 +314,14 @@ void net_hub_check_clients(void)
             }
 
             switch (peer->info->type) {
-            case NET_CLIENT_OPTIONS_KIND_NIC:
+            case NetClientOptionsKind_nic:
                 has_nic = 1;
                 break;
-            case NET_CLIENT_OPTIONS_KIND_USER:
-            case NET_CLIENT_OPTIONS_KIND_TAP:
-            case NET_CLIENT_OPTIONS_KIND_SOCKET:
-            case NET_CLIENT_OPTIONS_KIND_VDE:
-            case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
+            case NetClientOptionsKind_user:
+            case NetClientOptionsKind_tap:
+            case NetClientOptionsKind_socket:
+            case NetClientOptionsKind_vde:
+            case NetClientOptionsKind_vhost_user:
                 has_host_dev = 1;
                 break;
             default:
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 8e68e54..05303f5 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -516,7 +516,7 @@ static void net_l2tpv3_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_l2tpv3_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_L2TPV3,
+    .type = NetClientOptionsKind_l2tpv3,
     .size = sizeof(NetL2TPV3State),
     .receive = net_l2tpv3_receive_dgram,
     .receive_iov = net_l2tpv3_receive_dgram_iov,
@@ -545,7 +545,7 @@ int net_init_l2tpv3(const NetClientOptions *opts,
     s->queue_tail = 0;
     s->header_mismatch = false;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_L2TPV3);
+    assert(opts->type == NetClientOptionsKind_l2tpv3);
     l2tpv3 = opts->u.l2tpv3;
 
     if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {
diff --git a/net/net.c b/net/net.c
index ade6051..f972c55 100644
--- a/net/net.c
+++ b/net/net.c
@@ -317,7 +317,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
     NICState *nic;
     int i, queues = MAX(1, conf->peers.queues);
 
-    assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
+    assert(info->type == NetClientOptionsKind_nic);
     assert(info->size >= sizeof(NICState));
 
     nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
@@ -388,13 +388,13 @@ void qemu_del_net_client(NetClientState *nc)
     int queues, i;
     NetFilterState *nf, *next;
 
-    assert(nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC);
+    assert(nc->info->type != NetClientOptionsKind_nic);
 
     /* If the NetClientState belongs to a multiqueue backend, we will change all
      * other NetClientStates also.
      */
     queues = qemu_find_net_clients_except(nc->name, ncs,
-                                          NET_CLIENT_OPTIONS_KIND_NIC,
+                                          NetClientOptionsKind_nic,
                                           MAX_QUEUE_NUM);
     assert(queues != 0);
 
@@ -403,7 +403,7 @@ void qemu_del_net_client(NetClientState *nc)
     }
 
     /* If there is a peer NIC, delete and cleanup client, but do not free. */
-    if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+    if (nc->peer && nc->peer->info->type == NetClientOptionsKind_nic) {
         NICState *nic = qemu_get_nic(nc->peer);
         if (nic->peer_deleted) {
             return;
@@ -459,7 +459,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
     NetClientState *nc;
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
-        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (nc->info->type == NetClientOptionsKind_nic) {
             if (nc->queue_index == 0) {
                 func(qemu_get_nic(nc), opaque);
             }
@@ -621,7 +621,7 @@ void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge)
 {
     nc->receive_disabled = 0;
 
-    if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+    if (nc->peer && nc->peer->info->type == NetClientOptionsKind_hubport) {
         if (net_hub_flush(nc->peer)) {
             qemu_notify_event();
         }
@@ -660,13 +660,13 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
     }
 
     /* Let filters handle the packet first */
-    ret = filter_receive(sender, NET_FILTER_DIRECTION_TX,
+    ret = filter_receive(sender, NetFilterDirection_tx,
                          sender, flags, buf, size, sent_cb);
     if (ret) {
         return ret;
     }
 
-    ret = filter_receive(sender->peer, NET_FILTER_DIRECTION_RX,
+    ret = filter_receive(sender->peer, NetFilterDirection_rx,
                          sender, flags, buf, size, sent_cb);
     if (ret) {
         return ret;
@@ -760,13 +760,13 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
     }
 
     /* Let filters handle the packet first */
-    ret = filter_receive_iov(sender, NET_FILTER_DIRECTION_TX, sender,
+    ret = filter_receive_iov(sender, NetFilterDirection_tx, sender,
                              QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt, sent_cb);
     if (ret) {
         return ret;
     }
 
-    ret = filter_receive_iov(sender->peer, NET_FILTER_DIRECTION_RX, sender,
+    ret = filter_receive_iov(sender->peer, NetFilterDirection_rx, sender,
                              QEMU_NET_PACKET_FLAG_NONE, iov, iovcnt, sent_cb);
     if (ret) {
         return ret;
@@ -790,7 +790,7 @@ NetClientState *qemu_find_netdev(const char *id)
     NetClientState *nc;
 
     QTAILQ_FOREACH(nc, &net_clients, next) {
-        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
+        if (nc->info->type == NetClientOptionsKind_nic)
             continue;
         if (!strcmp(nc->name, id)) {
             return nc;
@@ -882,7 +882,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
     NICInfo *nd;
     const NetLegacyNicOptions *nic;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_NIC);
+    assert(opts->type == NetClientOptionsKind_nic);
     nic = opts->u.nic;
 
     idx = nic_get_free_idx();
@@ -943,32 +943,32 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
 }
 
 
-static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
+static int (* const net_client_init_fun[NetClientOptionsKind_MAX])(
     const NetClientOptions *opts,
     const char *name,
     NetClientState *peer, Error **errp) = {
-        [NET_CLIENT_OPTIONS_KIND_NIC]       = net_init_nic,
+        [NetClientOptionsKind_nic]       = net_init_nic,
 #ifdef CONFIG_SLIRP
-        [NET_CLIENT_OPTIONS_KIND_USER]      = net_init_slirp,
+        [NetClientOptionsKind_user]      = net_init_slirp,
 #endif
-        [NET_CLIENT_OPTIONS_KIND_TAP]       = net_init_tap,
-        [NET_CLIENT_OPTIONS_KIND_SOCKET]    = net_init_socket,
+        [NetClientOptionsKind_tap]       = net_init_tap,
+        [NetClientOptionsKind_socket]    = net_init_socket,
 #ifdef CONFIG_VDE
-        [NET_CLIENT_OPTIONS_KIND_VDE]       = net_init_vde,
+        [NetClientOptionsKind_vde]       = net_init_vde,
 #endif
 #ifdef CONFIG_NETMAP
-        [NET_CLIENT_OPTIONS_KIND_NETMAP]    = net_init_netmap,
+        [NetClientOptionsKind_netmap]    = net_init_netmap,
 #endif
-        [NET_CLIENT_OPTIONS_KIND_DUMP]      = net_init_dump,
+        [NetClientOptionsKind_dump]      = net_init_dump,
 #ifdef CONFIG_NET_BRIDGE
-        [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
+        [NetClientOptionsKind_bridge]    = net_init_bridge,
 #endif
-        [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
+        [NetClientOptionsKind_hubport]   = net_init_hubport,
 #ifdef CONFIG_VHOST_NET_USED
-        [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
+        [NetClientOptionsKind_vhost_user] = net_init_vhost_user,
 #endif
 #ifdef CONFIG_L2TPV3
-        [NET_CLIENT_OPTIONS_KIND_L2TPV3]    = net_init_l2tpv3,
+        [NetClientOptionsKind_l2tpv3]    = net_init_l2tpv3,
 #endif
 };
 
@@ -984,8 +984,8 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
         opts = netdev->opts;
         name = netdev->id;
 
-        if (opts->type == NET_CLIENT_OPTIONS_KIND_DUMP ||
-            opts->type == NET_CLIENT_OPTIONS_KIND_NIC ||
+        if (opts->type == NetClientOptionsKind_dump ||
+            opts->type == NetClientOptionsKind_nic ||
             !net_client_init_fun[opts->type]) {
             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
                        "a netdev backend type");
@@ -997,10 +997,10 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
         /* missing optional values have been initialized to "all bits zero" */
         name = net->has_id ? net->id : net->name;
 
-        if (opts->type == NET_CLIENT_OPTIONS_KIND_NONE) {
+        if (opts->type == NetClientOptionsKind_none) {
             return 0; /* nothing to do */
         }
-        if (opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
+        if (opts->type == NetClientOptionsKind_hubport) {
             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
                        "a net type");
             return -1;
@@ -1014,7 +1014,7 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
         }
 
         /* Do not add to a vlan if it's a nic with a netdev= parameter. */
-        if (opts->type != NET_CLIENT_OPTIONS_KIND_NIC ||
+        if (opts->type != NetClientOptionsKind_nic ||
             !opts->u.nic->has_netdev) {
             peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
         }
@@ -1123,7 +1123,7 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict)
                      device, vlan_id);
         return;
     }
-    if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+    if (nc->info->type == NetClientOptionsKind_nic) {
         error_report("invalid host network device '%s'", device);
         return;
     }
@@ -1170,7 +1170,7 @@ void qmp_netdev_del(const char *id, Error **errp)
 
     nc = qemu_find_netdev(id);
     if (!nc) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", id);
         return;
     }
@@ -1220,7 +1220,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name,
         }
 
         /* only query rx-filter information of NIC */
-        if (nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (nc->info->type != NetClientOptionsKind_nic) {
             if (has_name) {
                 error_setg(errp, "net client(%s) isn't a NIC", name);
                 return NULL;
@@ -1279,10 +1279,10 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
             continue;
         }
 
-        if (!peer || type == NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (!peer || type == NetClientOptionsKind_nic) {
             print_net_client(mon, nc);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
-        if (peer && type == NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (peer && type == NetClientOptionsKind_nic) {
             monitor_printf(mon, " \\ ");
             print_net_client(mon, peer);
         }
@@ -1296,11 +1296,11 @@ void qmp_set_link(const char *name, bool up, Error **errp)
     int queues, i;
 
     queues = qemu_find_net_clients_except(name, ncs,
-                                          NET_CLIENT_OPTIONS_KIND_MAX,
+                                          NetClientOptionsKind_MAX,
                                           MAX_QUEUE_NUM);
 
     if (queues == 0) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", name);
         return;
     }
@@ -1323,7 +1323,7 @@ void qmp_set_link(const char *name, bool up, Error **errp)
          * multiple clients that can still communicate with each other in
          * disconnected mode. For now maintain this compatibility.
          */
-        if (nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (nc->peer->info->type == NetClientOptionsKind_nic) {
             for (i = 0; i < queues; i++) {
                 ncs[i]->peer->link_down = !up;
             }
@@ -1364,7 +1364,7 @@ void net_cleanup(void)
      */
     while (!QTAILQ_EMPTY(&net_clients)) {
         nc = QTAILQ_FIRST(&net_clients);
-        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
+        if (nc->info->type == NetClientOptionsKind_nic) {
             qemu_del_nic(qemu_get_nic(nc));
         } else {
             qemu_del_net_client(nc);
@@ -1396,7 +1396,7 @@ void net_check_clients(void)
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (!nc->peer) {
             fprintf(stderr, "Warning: %s %s has no peer\n",
-                    nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ?
+                    nc->info->type == NetClientOptionsKind_nic ?
                     "nic" : "netdev", nc->name);
         }
     }
diff --git a/net/netmap.c b/net/netmap.c
index 508b829..381d3d0 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -417,7 +417,7 @@ static void netmap_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
 
 /* NetClientInfo methods */
 static NetClientInfo net_netmap_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NETMAP,
+    .type = NetClientOptionsKind_netmap,
     .size = sizeof(NetmapState),
     .receive = netmap_receive,
     .receive_iov = netmap_receive_iov,
diff --git a/net/slirp.c b/net/slirp.c
index f505570..d912756 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -126,7 +126,7 @@ static void net_slirp_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_slirp_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_USER,
+    .type = NetClientOptionsKind_user,
     .size = sizeof(SlirpState),
     .receive = net_slirp_receive,
     .cleanup = net_slirp_cleanup,
@@ -746,7 +746,7 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
     const NetdevUserOptions *user;
     const char **dnssearch;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
+    assert(opts->type == NetClientOptionsKind_user);
     user = opts->u.user;
 
     vnet = user->has_net ? g_strdup(user->net) :
diff --git a/net/socket.c b/net/socket.c
index e8605d4..ef9cfea 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -346,7 +346,7 @@ static void net_socket_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_dgram_socket_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
+    .type = NetClientOptionsKind_socket,
     .size = sizeof(NetSocketState),
     .receive = net_socket_receive_dgram,
     .cleanup = net_socket_cleanup,
@@ -429,7 +429,7 @@ static void net_socket_connect(void *opaque)
 }
 
 static NetClientInfo net_socket_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_SOCKET,
+    .type = NetClientOptionsKind_socket,
     .size = sizeof(NetSocketState),
     .receive = net_socket_receive,
     .cleanup = net_socket_cleanup,
@@ -706,7 +706,7 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
     Error *err = NULL;
     const NetdevSocketOptions *sock;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_SOCKET);
+    assert(opts->type == NetClientOptionsKind_socket);
     sock = opts->u.socket;
 
     if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 4e2fa55..803ff4e 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -723,7 +723,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 }
 
 static NetClientInfo net_tap_win32_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_TAP,
+    .type = NetClientOptionsKind_tap,
     .size = sizeof(TAPState),
     .receive = tap_receive,
     .cleanup = tap_cleanup,
@@ -767,7 +767,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
     /* FIXME error_setg(errp, ...) on failure */
     const NetdevTapOptions *tap;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(opts->type == NetClientOptionsKind_tap);
     tap = opts->u.tap;
 
     if (!tap->has_ifname) {
diff --git a/net/tap.c b/net/tap.c
index 85c4142..50aaf65 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -221,7 +221,7 @@ static bool tap_has_ufo(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
 
     return s->has_ufo;
 }
@@ -230,7 +230,7 @@ static bool tap_has_vnet_hdr(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
 
     return !!s->host_vnet_hdr_len;
 }
@@ -239,7 +239,7 @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
 
     return !!tap_probe_vnet_hdr_len(s->fd, len);
 }
@@ -248,7 +248,7 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
     assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) ||
            len == sizeof(struct virtio_net_hdr));
 
@@ -260,7 +260,7 @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
 
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
     assert(!!s->host_vnet_hdr_len == using_vnet_hdr);
 
     s->using_vnet_hdr = using_vnet_hdr;
@@ -326,14 +326,14 @@ static void tap_poll(NetClientState *nc, bool enable)
 int tap_get_fd(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
     return s->fd;
 }
 
 /* fd support */
 
 static NetClientInfo net_tap_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_TAP,
+    .type = NetClientOptionsKind_tap,
     .size = sizeof(TAPState),
     .receive = tap_receive,
     .receive_raw = tap_receive_raw,
@@ -565,7 +565,7 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
     TAPState *s;
     int fd, vnet_hdr;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_BRIDGE);
+    assert(opts->type == NetClientOptionsKind_bridge);
     bridge = opts->u.bridge;
 
     helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;
@@ -728,7 +728,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
     const char *vhostfdname;
     char ifname[128];
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(opts->type == NetClientOptionsKind_tap);
     tap = opts->u.tap;
     queues = tap->has_queues ? tap->queues : 1;
     vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
@@ -890,7 +890,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
 VHostNetState *tap_get_vhost_net(NetClientState *nc)
 {
     TAPState *s = DO_UPCAST(TAPState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP);
+    assert(nc->info->type == NetClientOptionsKind_tap);
     return s->vhost_net;
 }
 
diff --git a/net/vde.c b/net/vde.c
index 4475d92..9c508bb 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -68,7 +68,7 @@ static void vde_cleanup(NetClientState *nc)
 }
 
 static NetClientInfo net_vde_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_VDE,
+    .type = NetClientOptionsKind_vde,
     .size = sizeof(VDEState),
     .receive = vde_receive,
     .cleanup = vde_cleanup,
@@ -115,7 +115,7 @@ int net_init_vde(const NetClientOptions *opts, const char *name,
     /* FIXME error_setg(errp, ...) on failure */
     const NetdevVdeOptions *vde;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VDE);
+    assert(opts->type == NetClientOptionsKind_vde);
     vde = opts->u.vde;
 
     /* missing optional values have been initialized to "all bits zero" */
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 0ebd7df..51d96bd 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -32,7 +32,7 @@ typedef struct VhostUserChardevProps {
 VHostNetState *vhost_user_get_vhost_net(NetClientState *nc)
 {
     VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+    assert(nc->info->type == NetClientOptionsKind_vhost_user);
     return s->vhost_net;
 }
 
@@ -47,7 +47,7 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
     int i;
 
     for (i = 0; i < queues; i++) {
-        assert (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+        assert (ncs[i]->info->type == NetClientOptionsKind_vhost_user);
 
         s = DO_UPCAST(VhostUserState, nc, ncs[i]);
         if (!vhost_user_running(s)) {
@@ -71,7 +71,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[])
     options.backend_type = VHOST_BACKEND_TYPE_USER;
 
     for (i = 0; i < queues; i++) {
-        assert (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+        assert (ncs[i]->info->type == NetClientOptionsKind_vhost_user);
 
         s = DO_UPCAST(VhostUserState, nc, ncs[i]);
         if (vhost_user_running(s)) {
@@ -146,20 +146,20 @@ static void vhost_user_cleanup(NetClientState *nc)
 
 static bool vhost_user_has_vnet_hdr(NetClientState *nc)
 {
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+    assert(nc->info->type == NetClientOptionsKind_vhost_user);
 
     return true;
 }
 
 static bool vhost_user_has_ufo(NetClientState *nc)
 {
-    assert(nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+    assert(nc->info->type == NetClientOptionsKind_vhost_user);
 
     return true;
 }
 
 static NetClientInfo net_vhost_user_info = {
-        .type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
+        .type = NetClientOptionsKind_vhost_user,
         .size = sizeof(VhostUserState),
         .receive = vhost_user_receive,
         .cleanup = vhost_user_cleanup,
@@ -176,7 +176,7 @@ static void net_vhost_user_event(void *opaque, int event)
     int queues;
 
     queues = qemu_find_net_clients_except(name, ncs,
-                                          NET_CLIENT_OPTIONS_KIND_NIC,
+                                          NetClientOptionsKind_nic,
                                           MAX_QUEUE_NUM);
     s = DO_UPCAST(VhostUserState, nc, ncs[0]);
     trace_vhost_user_event(s->chr->label, event);
@@ -301,7 +301,7 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name,
     const NetdevVhostUserOptions *vhost_user_opts;
     CharDriverState *chr;
 
-    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
+    assert(opts->type == NetClientOptionsKind_vhost_user);
     vhost_user_opts = opts->u.vhost_user;
 
     chr = net_vhost_parse_chardev(vhost_user_opts, errp);
diff --git a/numa.c b/numa.c
index fdfe294..17ba4cb 100644
--- a/numa.c
+++ b/numa.c
@@ -227,7 +227,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
     }
 
     switch (object->type) {
-    case NUMA_OPTIONS_KIND_NODE:
+    case NumaOptionsKind_node:
         numa_node_parse(object->u.node, opts, &err);
         if (err) {
             goto error;
@@ -488,7 +488,7 @@ static void numa_stat_memory_devices(uint64_t node_mem[])
 
         if (value) {
             switch (value->type) {
-            case MEMORY_DEVICE_INFO_KIND_DIMM:
+            case MemoryDeviceInfoKind_dimm:
                 node_mem[value->u.dimm->node] += value->u.dimm->size;
                 break;
             default:
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 7bcc860..77d9990 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -76,7 +76,7 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
     command = qdict_get_str(dict, "execute");
     cmd = qmp_find_command(command);
     if (cmd == NULL) {
-        error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+        error_set(errp, ErrorClass_CommandNotFound,
                   "The command %s has not been found", command);
         return NULL;
     }
diff --git a/qdev-monitor.c b/qdev-monitor.c
index a35098f..ecc0818 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -461,7 +461,7 @@ static BusState *qbus_find(const char *path, Error **errp)
         pos += len;
         dev = qbus_find_dev(bus, elem);
         if (!dev) {
-            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+            error_set(errp, ErrorClass_DeviceNotFound,
                       "Device '%s' not found", elem);
             qbus_list_dev(bus, errp);
             return NULL;
@@ -788,7 +788,7 @@ void qmp_device_del(const char *id, Error **errp)
     }
 
     if (!obj) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", id);
         return;
     }
diff --git a/qemu-char.c b/qemu-char.c
index 5448b0f..9fe4935 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -98,16 +98,16 @@ static int SocketAddress_to_str(char *dest, int max_len,
                                 bool is_listen, bool is_telnet)
 {
     switch (addr->type) {
-    case SOCKET_ADDRESS_KIND_INET:
+    case SocketAddressKind_inet:
         return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix,
                         is_telnet ? "telnet" : "tcp", addr->u.inet->host,
                         addr->u.inet->port, is_listen ? ",server" : "");
         break;
-    case SOCKET_ADDRESS_KIND_UNIX:
+    case SocketAddressKind_unix:
         return snprintf(dest, max_len, "%sunix:%s%s", prefix,
                         addr->u.q_unix->path, is_listen ? ",server" : "");
         break;
-    case SOCKET_ADDRESS_KIND_FD:
+    case SocketAddressKind_fd:
         return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str,
                         is_listen ? ",server" : "");
         break;
@@ -3258,7 +3258,7 @@ void qmp_ringbuf_write(const char *device, const char *data,
         return;
     }
 
-    if (has_format && (format == DATA_FORMAT_BASE64)) {
+    if (has_format && (format == DataFormat_base64)) {
         write_data = g_base64_decode(data, &write_count);
     } else {
         write_data = (uint8_t *)data;
@@ -3308,7 +3308,7 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
 
     ringbuf_chr_read(chr, read_data, size);
 
-    if (has_format && (format == DATA_FORMAT_BASE64)) {
+    if (has_format && (format == DataFormat_base64)) {
         data = g_base64_encode(read_data, size);
         g_free(read_data);
     } else {
@@ -3598,11 +3598,11 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
 
     addr = g_new0(SocketAddress, 1);
     if (path) {
-        addr->type = SOCKET_ADDRESS_KIND_UNIX;
+        addr->type = SocketAddressKind_unix;
         addr->u.q_unix = g_new0(UnixSocketAddress, 1);
         addr->u.q_unix->path = g_strdup(path);
     } else {
-        addr->type = SOCKET_ADDRESS_KIND_INET;
+        addr->type = SocketAddressKind_inet;
         addr->u.inet = g_new0(InetSocketAddress, 1);
         addr->u.inet->host = g_strdup(host);
         addr->u.inet->port = g_strdup(port);
@@ -3647,7 +3647,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
     backend->u.udp = g_new0(ChardevUdp, 1);
 
     addr = g_new0(SocketAddress, 1);
-    addr->type = SOCKET_ADDRESS_KIND_INET;
+    addr->type = SocketAddressKind_inet;
     addr->u.inet = g_new0(InetSocketAddress, 1);
     addr->u.inet->host = g_strdup(host);
     addr->u.inet->port = g_strdup(port);
@@ -3660,7 +3660,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
     if (has_local) {
         backend->u.udp->has_local = true;
         addr = g_new0(SocketAddress, 1);
-        addr->type = SOCKET_ADDRESS_KIND_INET;
+        addr->type = SocketAddressKind_inet;
         addr->u.inet = g_new0(InetSocketAddress, 1);
         addr->u.inet->host = g_strdup(localaddr);
         addr->u.inet->port = g_strdup(localport);
@@ -3755,7 +3755,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
         qapi_free_ChardevReturn(ret);
         backend = g_new0(ChardevBackend, 1);
         backend->u.mux = g_new0(ChardevMux, 1);
-        backend->type = CHARDEV_BACKEND_KIND_MUX;
+        backend->type = ChardevBackendKind_mux;
         backend->u.mux->chardev = g_strdup(bid);
         ret = qmp_chardev_add(id, backend, errp);
         if (!ret) {
@@ -4196,7 +4196,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
 
     s->fd = -1;
     s->listen_fd = -1;
-    s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
+    s->is_unix = addr->type == SocketAddressKind_unix;
     s->is_listen = is_listen;
     s->is_telnet = is_telnet;
     s->do_nodelay = do_nodelay;
@@ -4297,7 +4297,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
 
     chr->label = g_strdup(id);
     chr->avail_connections =
-        (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
+        (backend->type == ChardevBackendKind_mux) ? MAX_MUX : 1;
     if (!chr->filename) {
         chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]);
     }
@@ -4331,44 +4331,44 @@ void qmp_chardev_remove(const char *id, Error **errp)
 
 static void register_types(void)
 {
-    register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL,
+    register_char_driver("null", ChardevBackendKind_null, NULL,
                          qemu_chr_open_null);
-    register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET,
+    register_char_driver("socket", ChardevBackendKind_socket,
                          qemu_chr_parse_socket, qmp_chardev_open_socket);
-    register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp,
+    register_char_driver("udp", ChardevBackendKind_udp, qemu_chr_parse_udp,
                          qmp_chardev_open_udp);
-    register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF,
+    register_char_driver("ringbuf", ChardevBackendKind_ringbuf,
                          qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
-    register_char_driver("file", CHARDEV_BACKEND_KIND_FILE,
+    register_char_driver("file", ChardevBackendKind_file,
                          qemu_chr_parse_file_out, qmp_chardev_open_file);
-    register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO,
+    register_char_driver("stdio", ChardevBackendKind_stdio,
                          qemu_chr_parse_stdio, qemu_chr_open_stdio);
 #if defined HAVE_CHARDEV_SERIAL
-    register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL,
+    register_char_driver("serial", ChardevBackendKind_serial,
                          qemu_chr_parse_serial, qmp_chardev_open_serial);
-    register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL,
+    register_char_driver("tty", ChardevBackendKind_serial,
                          qemu_chr_parse_serial, qmp_chardev_open_serial);
 #endif
 #ifdef HAVE_CHARDEV_PARPORT
-    register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL,
+    register_char_driver("parallel", ChardevBackendKind_parallel,
                          qemu_chr_parse_parallel, qmp_chardev_open_parallel);
-    register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL,
+    register_char_driver("parport", ChardevBackendKind_parallel,
                          qemu_chr_parse_parallel, qmp_chardev_open_parallel);
 #endif
 #ifdef HAVE_CHARDEV_PTY
-    register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL,
+    register_char_driver("pty", ChardevBackendKind_pty, NULL,
                          qemu_chr_open_pty);
 #endif
 #ifdef _WIN32
-    register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL,
+    register_char_driver("console", ChardevBackendKind_console, NULL,
                          qemu_chr_open_win_con);
 #endif
-    register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE,
+    register_char_driver("pipe", ChardevBackendKind_pipe,
                          qemu_chr_parse_pipe, qemu_chr_open_pipe);
-    register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux,
+    register_char_driver("mux", ChardevBackendKind_mux, qemu_chr_parse_mux,
                          qemu_chr_open_mux);
     /* Bug-compatibility: */
-    register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY,
+    register_char_driver("memory", ChardevBackendKind_memory,
                          qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf);
     /* this must be done after machine init, since we register FEs with muxes
      * as part of realize functions like serial_isa_realizefn when -nographic
diff --git a/qemu-img.c b/qemu-img.c
index 3025776..0358a49 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -760,7 +760,7 @@ static int img_commit(int argc, char **argv)
         .bs   = bs,
     };
 
-    commit_active_start(bs, base_bs, 0, BLOCKDEV_ON_ERROR_REPORT,
+    commit_active_start(bs, base_bs, 0, BlockdevOnError_report,
                         common_block_job_cb, &cbi, &local_err);
     if (local_err) {
         goto done;
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 3afec76..10407ac 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -362,11 +362,11 @@ static SocketAddress *nbd_build_socket_address(const char *sockpath,
 
     saddr = g_new0(SocketAddress, 1);
     if (sockpath) {
-        saddr->type = SOCKET_ADDRESS_KIND_UNIX;
+        saddr->type = SocketAddressKind_unix;
         saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
         saddr->u.q_unix->path = g_strdup(sockpath);
     } else {
-        saddr->type = SOCKET_ADDRESS_KIND_INET;
+        saddr->type = SocketAddressKind_inet;
         saddr->u.inet = g_new0(InetSocketAddress, 1);
         saddr->u.inet->host = g_strdup(bindto);
         if (port) {
@@ -432,7 +432,7 @@ int main(int argc, char **argv)
     pthread_t client_thread;
     const char *fmt = NULL;
     Error *local_err = NULL;
-    BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+    BlockdevDetectZeroesOptions detect_zeroes = BlockdevDetectZeroesOptions_off;
     QDict *options = NULL;
 
     /* The client thread uses SIGTERM to interrupt the server.  A signal
@@ -487,14 +487,14 @@ int main(int argc, char **argv)
             detect_zeroes =
                 qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
                                 optarg,
-                                BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
-                                BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
+                                BlockdevDetectZeroesOptions_MAX,
+                                BlockdevDetectZeroesOptions_off,
                                 &local_err);
             if (local_err) {
                 errx(EXIT_FAILURE, "Failed to parse detect_zeroes mode: %s", 
                      error_get_pretty(local_err));
             }
-            if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
+            if (detect_zeroes == BlockdevDetectZeroesOptions_unmap &&
                 !(flags & BDRV_O_UNMAP)) {
                 errx(EXIT_FAILURE, "setting detect-zeroes to unmap is not allowed "
                                    "without setting discard operation to unmap"); 
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 67a173a..73a2f32 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -902,7 +902,7 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
         }
         for (i = 0; i < nhosts; i++) {
             if (host == hosts[i]) {
-                disk->bus_type = GUEST_DISK_BUS_TYPE_IDE;
+                disk->bus_type = GuestDiskBusType_ide;
                 disk->bus = i;
                 disk->unit = tgt[1];
                 break;
@@ -918,16 +918,16 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
             g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
             goto cleanup;
         }
-        disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
+        disk->bus_type = GuestDiskBusType_scsi;
         disk->unit = tgt[1];
     } else if (strcmp(driver, "virtio-pci") == 0) {
         if (has_tgt) {
             /* virtio-scsi: target*:0:0:<unit> */
-            disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
+            disk->bus_type = GuestDiskBusType_scsi;
             disk->unit = tgt[2];
         } else {
             /* virtio-blk: 1 disk per 1 device */
-            disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO;
+            disk->bus_type = GuestDiskBusType_virtio;
         }
     } else if (strcmp(driver, "ahci") == 0) {
         /* ahci: 1 host per 1 unit */
@@ -938,7 +938,7 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
         for (i = 0; i < nhosts; i++) {
             if (host == hosts[i]) {
                 disk->unit = i;
-                disk->bus_type = GUEST_DISK_BUS_TYPE_SATA;
+                disk->bus_type = GuestDiskBusType_sata;
                 break;
             }
         }
@@ -1156,10 +1156,10 @@ static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp)
 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
 {
     if (ga_is_frozen(ga_state)) {
-        return GUEST_FSFREEZE_STATUS_FROZEN;
+        return GuestFsfreezeStatus_frozen;
     }
 
-    return GUEST_FSFREEZE_STATUS_THAWED;
+    return GuestFsfreezeStatus_thawed;
 }
 
 int64_t qmp_guest_fsfreeze_freeze(Error **errp)
@@ -1314,7 +1314,7 @@ static void guest_fsfreeze_cleanup(void)
 {
     Error *err = NULL;
 
-    if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
+    if (ga_is_frozen(ga_state) == GuestFsfreezeStatus_frozen) {
         qmp_guest_fsfreeze_thaw(&err);
         if (err) {
             slog("failed to clean up frozen filesystems: %s",
@@ -1697,7 +1697,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
             address_item = g_malloc0(sizeof(*address_item));
             address_item->value = g_malloc0(sizeof(*address_item->value));
             address_item->value->ip_address = g_strdup(addr4);
-            address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
+            address_item->value->ip_address_type = GuestIpAddressType_ipv4;
 
             if (ifa->ifa_netmask) {
                 /* Count the number of set bits in netmask.
@@ -1717,7 +1717,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
             address_item = g_malloc0(sizeof(*address_item));
             address_item->value = g_malloc0(sizeof(*address_item->value));
             address_item->value->ip_address = g_strdup(addr6);
-            address_item->value->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
+            address_item->value->ip_address_type = GuestIpAddressType_ipv6;
 
             if (ifa->ifa_netmask) {
                 /* Count the number of set bits in netmask.
@@ -2099,7 +2099,7 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
          */
         if (!dp && errno == ENOENT) {
             result->response =
-                GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
+                GuestMemoryBlockResponseType_operation_not_supported;
             goto out1;
         }
         closedir(dp);
@@ -2113,10 +2113,10 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
             error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
         } else {
             if (errno == ENOENT) {
-                result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_NOT_FOUND;
+                result->response = GuestMemoryBlockResponseType_not_found;
             } else {
                 result->response =
-                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+                    GuestMemoryBlockResponseType_operation_failed;
             }
         }
         g_free(dirpath);
@@ -2135,14 +2135,14 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
                 mem_blk->can_offline = false;
             } else if (!mem_blk->online) {
                 result->response =
-                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
+                    GuestMemoryBlockResponseType_operation_not_supported;
             }
         } else {
             if (sys2memblk) {
                 error_propagate(errp, local_err);
             } else {
                 result->response =
-                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+                    GuestMemoryBlockResponseType_operation_failed;
             }
         }
         goto out2;
@@ -2176,11 +2176,11 @@ static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
             if (local_err) {
                 error_free(local_err);
                 result->response =
-                    GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
+                    GuestMemoryBlockResponseType_operation_failed;
                 goto out2;
             }
 
-            result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_SUCCESS;
+            result->response = GuestMemoryBlockResponseType_success;
             result->has_error_code = false;
         } /* otherwise pretend successful re-(on|off)-lining */
     }
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index d9de23b..2990ee7 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -395,32 +395,32 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
 #ifdef CONFIG_QGA_NTDDSCSI
 
 static STORAGE_BUS_TYPE win2qemu[] = {
-    [BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
-    [BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
-    [BusTypeAtapi] = GUEST_DISK_BUS_TYPE_IDE,
-    [BusTypeAta] = GUEST_DISK_BUS_TYPE_IDE,
-    [BusType1394] = GUEST_DISK_BUS_TYPE_IEEE1394,
-    [BusTypeSsa] = GUEST_DISK_BUS_TYPE_SSA,
-    [BusTypeFibre] = GUEST_DISK_BUS_TYPE_SSA,
-    [BusTypeUsb] = GUEST_DISK_BUS_TYPE_USB,
-    [BusTypeRAID] = GUEST_DISK_BUS_TYPE_RAID,
+    [BusTypeUnknown] = GuestDiskBusType_unknown,
+    [BusTypeScsi] = GuestDiskBusType_scsi,
+    [BusTypeAtapi] = GuestDiskBusType_ide,
+    [BusTypeAta] = GuestDiskBusType_ide,
+    [BusType1394] = GuestDiskBusType_ieee1394,
+    [BusTypeSsa] = GuestDiskBusType_ssa,
+    [BusTypeFibre] = GuestDiskBusType_ssa,
+    [BusTypeUsb] = GuestDiskBusType_usb,
+    [BusTypeRAID] = GuestDiskBusType_raid,
 #if (_WIN32_WINNT >= 0x0600)
-    [BusTypeiScsi] = GUEST_DISK_BUS_TYPE_ISCSI,
-    [BusTypeSas] = GUEST_DISK_BUS_TYPE_SAS,
-    [BusTypeSata] = GUEST_DISK_BUS_TYPE_SATA,
-    [BusTypeSd] =  GUEST_DISK_BUS_TYPE_SD,
-    [BusTypeMmc] = GUEST_DISK_BUS_TYPE_MMC,
+    [BusTypeiScsi] = GuestDiskBusType_iscsi,
+    [BusTypeSas] = GuestDiskBusType_sas,
+    [BusTypeSata] = GuestDiskBusType_sata,
+    [BusTypeSd] =  GuestDiskBusType_sd,
+    [BusTypeMmc] = GuestDiskBusType_mmc,
 #endif
 #if (_WIN32_WINNT >= 0x0601)
-    [BusTypeVirtual] = GUEST_DISK_BUS_TYPE_VIRTUAL,
-    [BusTypeFileBackedVirtual] = GUEST_DISK_BUS_TYPE_FILE_BACKED_VIRTUAL,
+    [BusTypeVirtual] = GuestDiskBusType_virtual,
+    [BusTypeFileBackedVirtual] = GuestDiskBusType_file_backed_virtual,
 #endif
 };
 
 static GuestDiskBusType find_bus_type(STORAGE_BUS_TYPE bus)
 {
     if (bus > ARRAY_SIZE(win2qemu) || (int)bus < 0) {
-        return GUEST_DISK_BUS_TYPE_UNKNOWN;
+        return GuestDiskBusType_unknown;
     }
     return win2qemu[(int)bus];
 }
@@ -704,10 +704,10 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
     }
 
     if (ga_is_frozen(ga_state)) {
-        return GUEST_FSFREEZE_STATUS_FROZEN;
+        return GuestFsfreezeStatus_frozen;
     }
 
-    return GUEST_FSFREEZE_STATUS_THAWED;
+    return GuestFsfreezeStatus_thawed;
 }
 
 /*
@@ -782,7 +782,7 @@ static void guest_fsfreeze_cleanup(void)
         return;
     }
 
-    if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
+    if (ga_is_frozen(ga_state) == GuestFsfreezeStatus_frozen) {
         qmp_guest_fsfreeze_thaw(&err);
         if (err) {
             slog("failed to clean up frozen filesystems: %s",
@@ -1093,10 +1093,10 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
             address_item->value->prefix = guest_ip_prefix(ip_addr);
             if (ip_addr->Address.lpSockaddr->sa_family == AF_INET) {
                 address_item->value->ip_address_type =
-                    GUEST_IP_ADDRESS_TYPE_IPV4;
+                    GuestIpAddressType_ipv4;
             } else if (ip_addr->Address.lpSockaddr->sa_family == AF_INET6) {
                 address_item->value->ip_address_type =
-                    GUEST_IP_ADDRESS_TYPE_IPV6;
+                    GuestIpAddressType_ipv6;
             }
         }
         if (head_addr) {
diff --git a/qmp.c b/qmp.c
index ff54e5a..6982d2e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -102,10 +102,10 @@ void qmp_quit(Error **errp)
 
 void qmp_stop(Error **errp)
 {
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         autostart = 0;
     } else {
-        vm_stop(RUN_STATE_PAUSED);
+        vm_stop(RunState_paused);
     }
 }
 
@@ -177,7 +177,7 @@ void qmp_cont(Error **errp)
     if (runstate_needs_reset()) {
         error_setg(errp, "Resetting the Virtual Machine is required");
         return;
-    } else if (runstate_check(RUN_STATE_SUSPENDED)) {
+    } else if (runstate_check(RunState_suspended)) {
         return;
     }
 
@@ -192,7 +192,7 @@ void qmp_cont(Error **errp)
         }
     }
 
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         autostart = 1;
     } else {
         vm_start();
@@ -216,7 +216,7 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
         if (ambiguous) {
             error_setg(errp, "Path '%s' is ambiguous", path);
         } else {
-            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+            error_set(errp, ErrorClass_DeviceNotFound,
                       "Device '%s' not found", path);
         }
         return NULL;
@@ -243,7 +243,7 @@ void qmp_qom_set(const char *path, const char *property, QObject *value,
 
     obj = object_resolve_path(path, NULL);
     if (!obj) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", path);
         return;
     }
@@ -257,7 +257,7 @@ QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
 
     obj = object_resolve_path(path, NULL);
     if (!obj) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", path);
         return NULL;
     }
@@ -506,7 +506,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
 
     klass = object_class_by_name(typename);
     if (klass == NULL) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", typename);
         return NULL;
     }
diff --git a/qom/object.c b/qom/object.c
index 11cd86b..9aa4f41 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1018,7 +1018,7 @@ Object *object_property_get_link(Object *obj, const char *name,
     if (str && *str) {
         target = object_resolve_path(str, NULL);
         if (!target) {
-            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+            error_set(errp, ErrorClass_DeviceNotFound,
                       "Device '%s' not found", str);
         }
     }
@@ -1330,14 +1330,14 @@ static Object *object_resolve_link(Object *obj, const char *name,
     target = object_resolve_path_type(path, target_type, &ambiguous);
 
     if (ambiguous) {
-        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+        error_set(errp, ErrorClass_GenericError,
                   "Path '%s' does not uniquely identify an object", path);
     } else if (!target) {
         target = object_resolve_path(path, &ambiguous);
         if (target || ambiguous) {
             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
         } else {
-            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+            error_set(errp, ErrorClass_DeviceNotFound,
                       "Device '%s' not found", path);
         }
         target = NULL;
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 843e364..8e935d7 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -548,8 +548,8 @@ def check_union(expr, expr_info):
     base = expr.get('base')
     discriminator = expr.get('discriminator')
     members = expr['data']
-    values = {'MAX': '(automatic)', 'KIND': '(automatic)',
-              'TYPE': '(automatic)'}
+    values = {'MAX': '(automatic)', 'kind': '(automatic)',
+              'type': '(automatic)'}
 
     # Two types of unions, determined by discriminator.
 
@@ -623,7 +623,7 @@ def check_union(expr, expr_info):
 
         # Otherwise, check for conflicts in the generated enum
         else:
-            c_key = camel_to_upper(key)
+            c_key = c_name(key)
             if c_key in values:
                 raise QAPIExprError(expr_info,
                                     "Union '%s' member '%s' clashes with '%s'"
@@ -642,7 +642,7 @@ def check_alternate(expr, expr_info):
         check_name(expr_info, "Member of alternate '%s'" % name, key)
 
         # Check for conflicts in the generated enum
-        c_key = camel_to_upper(key)
+        c_key = c_name(key)
         if c_key in values:
             raise QAPIExprError(expr_info,
                                 "Alternate '%s' member '%s' clashes with '%s'"
@@ -678,7 +678,7 @@ def check_enum(expr, expr_info):
     for member in members:
         check_name(expr_info, "Member of enum '%s'" % name, member,
                    enum_member=True)
-        key = camel_to_upper(member)
+        key = c_name(member)
         if key in values:
             raise QAPIExprError(expr_info,
                                 "Enum '%s' member '%s' clashes with '%s'"
@@ -1362,46 +1362,10 @@ class QAPISchema(object):
 # Code generation helpers
 #
 
-def camel_case(name):
-    new_name = ''
-    first = True
-    for ch in name:
-        if ch in ['_', '-']:
-            first = True
-        elif first:
-            new_name += ch.upper()
-            first = False
-        else:
-            new_name += ch.lower()
-    return new_name
-
-
-# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
-# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
-# ENUM24_Name -> ENUM24_NAME
-def camel_to_upper(value):
-    c_fun_str = c_name(value, False)
-    if value.isupper():
-        return c_fun_str
-
-    new_name = ''
-    l = len(c_fun_str)
-    for i in range(l):
-        c = c_fun_str[i]
-        # When c is upper and no "_" appears before, do more checks
-        if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
-            if i < l - 1 and c_fun_str[i + 1].islower():
-                new_name += '_'
-            elif c_fun_str[i - 1].isdigit():
-                new_name += '_'
-        new_name += c
-    return new_name.lstrip('_').upper()
-
-
 def c_enum_const(type_name, const_name, prefix=None):
     if prefix is not None:
         type_name = prefix
-    return camel_to_upper(type_name + '_' + const_name)
+    return c_name(type_name + '_' + const_name)
 
 c_name_trans = string.maketrans('.-', '__')
 
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index e70e0f7..b8dea83 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -381,9 +381,9 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
 
 static void register_types(void)
 {
-    register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC,
+    register_char_driver("spicevmc", ChardevBackendKind_spicevmc,
                          qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc);
-    register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT,
+    register_char_driver("spiceport", ChardevBackendKind_spiceport,
                          qemu_chr_parse_spice_port, qemu_chr_open_spice_port);
 }
 
diff --git a/stubs/runstate-check.c b/stubs/runstate-check.c
index bd2e375..efc02ab 100644
--- a/stubs/runstate-check.c
+++ b/stubs/runstate-check.c
@@ -2,5 +2,5 @@
 
 bool runstate_check(RunState state)
 {
-    return state == RUN_STATE_PRELAUNCH;
+    return state == RunState_prelaunch;
 }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9280bfc..5e4f8e3 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -436,7 +436,7 @@ typedef struct X86RegisterInfo32 {
 } X86RegisterInfo32;
 
 #define REGISTER(reg) \
-    [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
+    [R_##reg] = { .name = #reg, .qapi_enum = X86CPURegister32_##reg }
 static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
     REGISTER(EAX),
     REGISTER(ECX),
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 61209c1..afe9de1 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -42,7 +42,7 @@ void HELPER(ill)(CPULM32State *env)
     fprintf(stderr, "VM paused due to illegal instruction. "
             "Connect a debugger or switch to the monitor console "
             "to find out more.\n");
-    vm_stop(RUN_STATE_PAUSED);
+    vm_stop(RunState_paused);
     cs->halted = 1;
     raise_exception(env, EXCP_HALTED);
 #endif
diff --git a/tests/qapi-schema/enum-clash-member.err b/tests/qapi-schema/enum-clash-member.err
index 48bd136..d012611 100644
--- a/tests/qapi-schema/enum-clash-member.err
+++ b/tests/qapi-schema/enum-clash-member.err
@@ -1 +1 @@
-tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'ONE' clashes with 'one'
+tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'a_b' clashes with 'a-b'
diff --git a/tests/qapi-schema/enum-clash-member.json b/tests/qapi-schema/enum-clash-member.json
index b7dc02a..7342991 100644
--- a/tests/qapi-schema/enum-clash-member.json
+++ b/tests/qapi-schema/enum-clash-member.json
@@ -1,2 +1,2 @@
 # we reject enums where members will clash when mapped to C enum
-{ 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] }
+{ 'enum': 'MyEnum', 'data': [ 'a-b', 'a_b' ] }
diff --git a/tests/qapi-schema/enum-max-member.err b/tests/qapi-schema/enum-max-member.err
index f77837f..06468f3 100644
--- a/tests/qapi-schema/enum-max-member.err
+++ b/tests/qapi-schema/enum-max-member.err
@@ -1 +1 @@
-tests/qapi-schema/enum-max-member.json:3: Enum 'MyEnum' member 'max' clashes with '(automatic)'
+tests/qapi-schema/enum-max-member.json:3: Enum 'MyEnum' member 'MAX' clashes with '(automatic)'
diff --git a/tests/qapi-schema/enum-max-member.json b/tests/qapi-schema/enum-max-member.json
index 4bcda0b..9b16e39 100644
--- a/tests/qapi-schema/enum-max-member.json
+++ b/tests/qapi-schema/enum-max-member.json
@@ -1,3 +1,3 @@
-# we reject user-supplied 'max' for clashing with implicit enum end
+# we reject user-supplied 'MAX' for clashing with implicit enum end
 # TODO: should we instead munge the implicit value to avoid the clash?
-{ 'enum': 'MyEnum', 'data': [ 'max' ] }
+{ 'enum': 'MyEnum', 'data': [ 'MAX' ] }
diff --git a/tests/qapi-schema/union-bad-branch.err b/tests/qapi-schema/union-bad-branch.err
index 8822735..923aa51 100644
--- a/tests/qapi-schema/union-bad-branch.err
+++ b/tests/qapi-schema/union-bad-branch.err
@@ -1 +1 @@
-tests/qapi-schema/union-bad-branch.json:6: Union 'MyUnion' member 'ONE' clashes with 'one'
+tests/qapi-schema/union-bad-branch.json:6: Union 'MyUnion' member 'a_b' clashes with 'a-b'
diff --git a/tests/qapi-schema/union-bad-branch.json b/tests/qapi-schema/union-bad-branch.json
index 913aa38..615dee5 100644
--- a/tests/qapi-schema/union-bad-branch.json
+++ b/tests/qapi-schema/union-bad-branch.json
@@ -4,5 +4,5 @@
 { 'struct': 'Two',
   'data': { 'number': 'int' } }
 { 'union': 'MyUnion',
-  'data': { 'one': 'One',
-            'ONE': 'Two' } }
+  'data': { 'a-b': 'One',
+            'a_b': 'Two' } }
diff --git a/tests/qapi-schema/union-max.err b/tests/qapi-schema/union-max.err
index 55ce439..d4f28e7 100644
--- a/tests/qapi-schema/union-max.err
+++ b/tests/qapi-schema/union-max.err
@@ -1 +1 @@
-tests/qapi-schema/union-max.json:2: Union 'Union' member 'max' clashes with '(automatic)'
+tests/qapi-schema/union-max.json:2: Union 'Union' member 'MAX' clashes with '(automatic)'
diff --git a/tests/qapi-schema/union-max.json b/tests/qapi-schema/union-max.json
index d6ad986..989030e 100644
--- a/tests/qapi-schema/union-max.json
+++ b/tests/qapi-schema/union-max.json
@@ -1,3 +1,3 @@
 # we reject 'max' branch in a union, for collision with C enum
 { 'union': 'Union',
-  'data': { 'max': 'int' } }
+  'data': { 'MAX': 'int' } }
diff --git a/tests/test-crypto-tlscredsx509.c b/tests/test-crypto-tlscredsx509.c
index c70aa55..a1e2d51 100644
--- a/tests/test-crypto-tlscredsx509.c
+++ b/tests/test-crypto-tlscredsx509.c
@@ -48,7 +48,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
         parent,
         "testtlscreds",
         errp,
-        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ?
+        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
@@ -111,8 +111,8 @@ static void test_tls_creds(const void *opaque)
 
     creds = test_tls_creds_create(
         (data->isServer ?
-         QCRYPTO_TLS_CREDS_ENDPOINT_SERVER :
-         QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT),
+         QCRYPTO_TLS_CREDS_ENDPOINT_server :
+         QCRYPTO_TLS_CREDS_ENDPOINT_client),
         CERT_DIR,
         &err);
 
diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c
index 4524128..4620086 100644
--- a/tests/test-crypto-tlssession.c
+++ b/tests/test-crypto-tlssession.c
@@ -69,10 +69,10 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
     Object *creds = object_new_with_props(
         TYPE_QCRYPTO_TLS_CREDS_X509,
         parent,
-        (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ?
+        (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
          "testtlscredsserver" : "testtlscredsclient"),
         &err,
-        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ?
+        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
@@ -160,13 +160,13 @@ static void test_crypto_tls_session(const void *opaque)
                   CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY) == 0);
 
     clientCreds = test_tls_creds_create(
-        QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
+        QCRYPTO_TLS_CREDS_ENDPOINT_client,
         CLIENT_CERT_DIR,
         &err);
     g_assert(clientCreds != NULL);
 
     serverCreds = test_tls_creds_create(
-        QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
+        QCRYPTO_TLS_CREDS_ENDPOINT_server,
         SERVER_CERT_DIR,
         &err);
     g_assert(serverCreds != NULL);
@@ -182,11 +182,11 @@ static void test_crypto_tls_session(const void *opaque)
     /* Now the real part of the test, setup the sessions */
     clientSess = qcrypto_tls_session_new(
         clientCreds, data->hostname, NULL,
-        QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, &err);
+        QCRYPTO_TLS_CREDS_ENDPOINT_client, &err);
     serverSess = qcrypto_tls_session_new(
         serverCreds, NULL,
         data->wildcards ? "tlssessionacl" : NULL,
-        QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, &err);
+        QCRYPTO_TLS_CREDS_ENDPOINT_server, &err);
 
     g_assert(clientSess != NULL);
     g_assert(serverSess != NULL);
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index f23d8ea..af5984e 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -62,7 +62,7 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
 {
     __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
 
-    ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
+    ret->type = __org_qemu_x_Union1Kind___org_qemu_x_branch;
     ret->u.__org_qemu_x_branch = strdup("blah1");
 
     return ret;
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 035c65c..394938b 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -212,12 +212,12 @@ static void test_event_d(TestEventData *data,
     struct1.integer = 2;
     struct1.string = g_strdup("test1");
     struct1.has_enum1 = true;
-    struct1.enum1 = ENUM_ONE_VALUE1;
+    struct1.enum1 = EnumOne_value1;
 
     a.struct1 = &struct1;
     a.string = g_strdup("test2");
     a.has_enum2 = true;
-    a.enum2 = ENUM_ONE_VALUE2;
+    a.enum2 = EnumOne_value2;
 
     d_struct1 = qdict_new();
     qdict_put(d_struct1, "integer", qint_from_int(2));
@@ -238,7 +238,7 @@ static void test_event_d(TestEventData *data,
     qdict_put(d, "event", qstring_from_str("EVENT_D"));
     qdict_put(d, "data", d_data);
 
-    qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3,
+    qapi_event_send_event_d(&a, "test3", false, NULL, true, EnumOne_value3,
                            &error_abort);
 
     g_free(struct1.string);
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index e9a66a7..86b825f 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -298,7 +298,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
                                 "'boolean': true }");
 
     visit_type_UserDefFlatUnion(v, &tmp, NULL, &error_abort);
-    g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
+    g_assert_cmpint(tmp->enum1, ==, EnumOne_value1);
     g_assert_cmpstr(tmp->string, ==, "str");
     g_assert_cmpint(tmp->integer, ==, 41);
     g_assert_cmpint(tmp->u.value1->boolean, ==, true);
@@ -317,13 +317,13 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42");
     visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
-    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
+    g_assert_cmpint(tmp->type, ==, UserDefAlternateKind_i);
     g_assert_cmpint(tmp->u.i, ==, 42);
     qapi_free_UserDefAlternate(tmp);
 
     v = visitor_input_test_init(data, "'string'");
     visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
-    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
+    g_assert_cmpint(tmp->type, ==, UserDefAlternateKind_s);
     g_assert_cmpstr(tmp->u.s, ==, "string");
     qapi_free_UserDefAlternate(tmp);
 
@@ -355,32 +355,32 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
      * parse the same as ans */
     v = visitor_input_test_init(data, "42");
     visit_type_AltStrNum(v, &asn, NULL, &data->err);
-    /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
+    /* FIXME g_assert_cmpint(asn->type, == AltStrNumKind_n); */
     /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
     g_assert(data->err);
     qapi_free_AltStrNum(asn);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltNumStr(v, &ans, NULL, &error_abort);
-    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
+    g_assert_cmpint(ans->type, ==, AltNumStrKind_n);
     g_assert_cmpfloat(ans->u.n, ==, 42);
     qapi_free_AltNumStr(ans);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltStrInt(v, &asi, NULL, &error_abort);
-    g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
+    g_assert_cmpint(asi->type, ==, AltStrIntKind_i);
     g_assert_cmpint(asi->u.i, ==, 42);
     qapi_free_AltStrInt(asi);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
-    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
+    g_assert_cmpint(ain->type, ==, AltIntNumKind_i);
     g_assert_cmpint(ain->u.i, ==, 42);
     qapi_free_AltIntNum(ain);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
-    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
+    g_assert_cmpint(ani->type, ==, AltNumIntKind_i);
     g_assert_cmpint(ani->u.i, ==, 42);
     qapi_free_AltNumInt(ani);
 
@@ -393,13 +393,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltStrNum(v, &asn, NULL, &error_abort);
-    g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
+    g_assert_cmpint(asn->type, ==, AltStrNumKind_n);
     g_assert_cmpfloat(asn->u.n, ==, 42.5);
     qapi_free_AltStrNum(asn);
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumStr(v, &ans, NULL, &error_abort);
-    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
+    g_assert_cmpint(ans->type, ==, AltNumStrKind_n);
     g_assert_cmpfloat(ans->u.n, ==, 42.5);
     qapi_free_AltNumStr(ans);
 
@@ -410,13 +410,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltIntNum(v, &ain, NULL, &error_abort);
-    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
+    g_assert_cmpint(ain->type, ==, AltIntNumKind_n);
     g_assert_cmpfloat(ain->u.n, ==, 42.5);
     qapi_free_AltIntNum(ain);
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumInt(v, &ani, NULL, &error_abort);
-    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
+    g_assert_cmpint(ani->type, ==, AltNumIntKind_n);
     g_assert_cmpfloat(ani->u.n, ==, 42.5);
     qapi_free_AltNumInt(ani);
 }
@@ -447,63 +447,63 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
     g_assert_cmpint(cvalue->type, ==, kind);
 
     switch (kind) {
-    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+    case UserDefNativeListUnionKind_integer: {
         intList *elem = NULL;
         for (i = 0, elem = cvalue->u.integer; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+    case UserDefNativeListUnionKind_s8: {
         int8List *elem = NULL;
         for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+    case UserDefNativeListUnionKind_s16: {
         int16List *elem = NULL;
         for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+    case UserDefNativeListUnionKind_s32: {
         int32List *elem = NULL;
         for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+    case UserDefNativeListUnionKind_s64: {
         int64List *elem = NULL;
         for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+    case UserDefNativeListUnionKind_u8: {
         uint8List *elem = NULL;
         for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+    case UserDefNativeListUnionKind_u16: {
         uint16List *elem = NULL;
         for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+    case UserDefNativeListUnionKind_u32: {
         uint32List *elem = NULL;
         for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+    case UserDefNativeListUnionKind_u64: {
         uint64List *elem = NULL;
         for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) {
             g_assert_cmpint(elem->value, ==, i);
@@ -523,63 +523,63 @@ static void test_visitor_in_native_list_int(TestInputVisitorData *data,
                                             const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+                                    UserDefNativeListUnionKind_integer);
 }
 
 static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
                                              const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+                                    UserDefNativeListUnionKind_s8);
 }
 
 static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
                                               const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+                                    UserDefNativeListUnionKind_s16);
 }
 
 static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
                                               const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+                                    UserDefNativeListUnionKind_s32);
 }
 
 static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
                                               const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+                                    UserDefNativeListUnionKind_s64);
 }
 
 static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
                                              const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+                                    UserDefNativeListUnionKind_u8);
 }
 
 static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
                                                const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+                                    UserDefNativeListUnionKind_u16);
 }
 
 static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
                                                const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+                                    UserDefNativeListUnionKind_u32);
 }
 
 static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
                                                const void *unused)
 {
     test_native_list_integer_helper(data, unused,
-                                    USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+                                    UserDefNativeListUnionKind_u64);
 }
 
 static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
@@ -605,7 +605,7 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
 
     visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
-    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+    g_assert_cmpint(cvalue->type, ==, UserDefNativeListUnionKind_boolean);
 
     for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) {
         g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
@@ -638,7 +638,7 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
 
     visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
-    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+    g_assert_cmpint(cvalue->type, ==, UserDefNativeListUnionKind_string);
 
     for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) {
         gchar str[8];
@@ -675,7 +675,7 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
 
     visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
     g_assert(cvalue != NULL);
-    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+    g_assert_cmpint(cvalue->type, ==, UserDefNativeListUnionKind_number);
 
     for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {
         GString *double_expected = g_string_new("");
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 0d0c859..bd33977 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -128,7 +128,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
     QObject *obj;
     EnumOne i;
 
-    for (i = 0; i < ENUM_ONE_MAX; i++) {
+    for (i = 0; i < EnumOne_MAX; i++) {
         visit_type_EnumOne(data->ov, &i, "unused", &error_abort);
 
         obj = qmp_output_get_qobject(data->qov);
@@ -143,7 +143,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
 static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
                                          const void *unused)
 {
-    EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
+    EnumOne i, bad_values[] = { EnumOne_MAX, -1 };
     Error *err;
 
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
@@ -247,7 +247,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
 static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
                                            const void *unused)
 {
-    EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
+    EnumOne bad_values[] = { EnumOne_MAX, -1 };
     UserDefOne u = {0};
     UserDefOne *pu = &u;
     Error *err;
@@ -400,7 +400,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
     QDict *qdict;
 
     UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
-    tmp->enum1 = ENUM_ONE_VALUE1;
+    tmp->enum1 = EnumOne_value1;
     tmp->string = g_strdup("str");
     tmp->u.value1 = g_malloc0(sizeof(UserDefA));
     tmp->integer = 41;
@@ -428,7 +428,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     UserDefAlternate *tmp;
 
     tmp = g_new0(UserDefAlternate, 1);
-    tmp->type = USER_DEF_ALTERNATE_KIND_I;
+    tmp->type = UserDefAlternateKind_i;
     tmp->u.i = 42;
 
     visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
@@ -441,7 +441,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     qobject_decref(arg);
 
     tmp = g_new0(UserDefAlternate, 1);
-    tmp->type = USER_DEF_ALTERNATE_KIND_S;
+    tmp->type = UserDefAlternateKind_s;
     tmp->u.s = g_strdup("hello");
 
     visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort);
@@ -468,7 +468,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 {
     int i;
     switch (cvalue->type) {
-    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
+    case UserDefNativeListUnionKind_integer: {
         intList **list = &cvalue->u.integer;
         for (i = 0; i < 32; i++) {
             *list = g_new0(intList, 1);
@@ -478,7 +478,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
+    case UserDefNativeListUnionKind_s8: {
         int8List **list = &cvalue->u.s8;
         for (i = 0; i < 32; i++) {
             *list = g_new0(int8List, 1);
@@ -488,7 +488,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
+    case UserDefNativeListUnionKind_s16: {
         int16List **list = &cvalue->u.s16;
         for (i = 0; i < 32; i++) {
             *list = g_new0(int16List, 1);
@@ -498,7 +498,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
+    case UserDefNativeListUnionKind_s32: {
         int32List **list = &cvalue->u.s32;
         for (i = 0; i < 32; i++) {
             *list = g_new0(int32List, 1);
@@ -508,7 +508,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
+    case UserDefNativeListUnionKind_s64: {
         int64List **list = &cvalue->u.s64;
         for (i = 0; i < 32; i++) {
             *list = g_new0(int64List, 1);
@@ -518,7 +518,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
+    case UserDefNativeListUnionKind_u8: {
         uint8List **list = &cvalue->u.u8;
         for (i = 0; i < 32; i++) {
             *list = g_new0(uint8List, 1);
@@ -528,7 +528,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
+    case UserDefNativeListUnionKind_u16: {
         uint16List **list = &cvalue->u.u16;
         for (i = 0; i < 32; i++) {
             *list = g_new0(uint16List, 1);
@@ -538,7 +538,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
+    case UserDefNativeListUnionKind_u32: {
         uint32List **list = &cvalue->u.u32;
         for (i = 0; i < 32; i++) {
             *list = g_new0(uint32List, 1);
@@ -548,7 +548,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
+    case UserDefNativeListUnionKind_u64: {
         uint64List **list = &cvalue->u.u64;
         for (i = 0; i < 32; i++) {
             *list = g_new0(uint64List, 1);
@@ -558,7 +558,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
+    case UserDefNativeListUnionKind_boolean: {
         boolList **list = &cvalue->u.boolean;
         for (i = 0; i < 32; i++) {
             *list = g_new0(boolList, 1);
@@ -568,7 +568,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
+    case UserDefNativeListUnionKind_string: {
         strList **list = &cvalue->u.string;
         for (i = 0; i < 32; i++) {
             *list = g_new0(strList, 1);
@@ -578,7 +578,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
         }
         break;
     }
-    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
+    case UserDefNativeListUnionKind_number: {
         numberList **list = &cvalue->u.number;
         for (i = 0; i < 32; i++) {
             *list = g_new0(numberList, 1);
@@ -608,19 +608,19 @@ static void check_native_list(QObject *qobj,
     qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
 
     switch (kind) {
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
+    case UserDefNativeListUnionKind_s8:
+    case UserDefNativeListUnionKind_s16:
+    case UserDefNativeListUnionKind_s32:
+    case UserDefNativeListUnionKind_s64:
+    case UserDefNativeListUnionKind_u8:
+    case UserDefNativeListUnionKind_u16:
+    case UserDefNativeListUnionKind_u32:
+    case UserDefNativeListUnionKind_u64:
         /* all integer elements in JSON arrays get stored into QInts when
          * we convert to QObjects, so we can check them all in the same
          * fashion, so simply fall through here
          */
-    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
+    case UserDefNativeListUnionKind_integer:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
             QInt *qvalue;
@@ -631,7 +631,7 @@ static void check_native_list(QObject *qobj,
             qobject_decref(qlist_pop(qlist));
         }
         break;
-    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
+    case UserDefNativeListUnionKind_boolean:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
             QBool *qvalue;
@@ -642,7 +642,7 @@ static void check_native_list(QObject *qobj,
             qobject_decref(qlist_pop(qlist));
         }
         break;
-    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
+    case UserDefNativeListUnionKind_string:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
             QString *qvalue;
@@ -655,7 +655,7 @@ static void check_native_list(QObject *qobj,
             qobject_decref(qlist_pop(qlist));
         }
         break;
-    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
+    case UserDefNativeListUnionKind_number:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
             QFloat *qvalue;
@@ -701,73 +701,73 @@ static void test_native_list(TestOutputVisitorData *data,
 static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
                                              const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
+    test_native_list(data, unused, UserDefNativeListUnionKind_integer);
 }
 
 static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
                                               const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
+    test_native_list(data, unused, UserDefNativeListUnionKind_s8);
 }
 
 static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
                                                const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
+    test_native_list(data, unused, UserDefNativeListUnionKind_s16);
 }
 
 static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
                                                const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
+    test_native_list(data, unused, UserDefNativeListUnionKind_s32);
 }
 
 static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
                                                const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
+    test_native_list(data, unused, UserDefNativeListUnionKind_s64);
 }
 
 static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
                                                const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
+    test_native_list(data, unused, UserDefNativeListUnionKind_u8);
 }
 
 static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
                                                 const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
+    test_native_list(data, unused, UserDefNativeListUnionKind_u16);
 }
 
 static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
                                                 const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
+    test_native_list(data, unused, UserDefNativeListUnionKind_u32);
 }
 
 static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
                                                 const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
+    test_native_list(data, unused, UserDefNativeListUnionKind_u64);
 }
 
 static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
                                               const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
+    test_native_list(data, unused, UserDefNativeListUnionKind_boolean);
 }
 
 static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
                                               const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
+    test_native_list(data, unused, UserDefNativeListUnionKind_string);
 }
 
 static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
                                                 const void *unused)
 {
-    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
+    test_native_list(data, unused, UserDefNativeListUnionKind_number);
 }
 
 static void output_visitor_test_add(const char *testpath,
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index fd5e67b..66a31ba 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -194,7 +194,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
     char *str;
     EnumOne i;
 
-    for (i = 0; i < ENUM_ONE_MAX; i++) {
+    for (i = 0; i < EnumOne_MAX; i++) {
         char *str_human;
 
         visit_type_EnumOne(data->ov, &i, "unused", &err);
@@ -217,7 +217,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data,
 static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
                                          const void *unused)
 {
-    EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
+    EnumOne i, bad_values[] = { EnumOne_MAX, -1 };
     Error *err;
 
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
diff --git a/tpm.c b/tpm.c
index f2c59d1..1c77712 100644
--- a/tpm.c
+++ b/tpm.c
@@ -32,7 +32,7 @@ static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = {
 };
 
 static enum TpmModel tpm_models[TPM_MAX_MODELS] = {
-    TPM_MODEL_MAX,
+    TpmModel_MAX,
 };
 
 int tpm_register_model(enum TpmModel model)
@@ -40,7 +40,7 @@ int tpm_register_model(enum TpmModel model)
     int i;
 
     for (i = 0; i < TPM_MAX_MODELS; i++) {
-        if (tpm_models[i] == TPM_MODEL_MAX) {
+        if (tpm_models[i] == TpmModel_MAX) {
             tpm_models[i] = model;
             return 0;
         }
@@ -259,8 +259,8 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
     res->options = g_new0(TpmTypeOptions, 1);
 
     switch (drv->ops->type) {
-    case TPM_TYPE_PASSTHROUGH:
-        res->options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
+    case TpmType_passthrough:
+        res->options->type = TpmTypeOptionsKind_passthrough;
         tpo = g_new0(TPMPassthroughOptions, 1);
         res->options->u.passthrough = tpo;
         if (drv->path) {
@@ -272,7 +272,7 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
             tpo->has_cancel_path = true;
         }
         break;
-    case TPM_TYPE_MAX:
+    case TpmType_MAX:
         break;
     }
 
@@ -311,7 +311,7 @@ TpmTypeList *qmp_query_tpm_types(Error **errp)
     unsigned int i = 0;
     TpmTypeList *head = NULL, *prev = NULL, *cur_item;
 
-    for (i = 0; i < TPM_TYPE_MAX; i++) {
+    for (i = 0; i < TpmType_MAX; i++) {
         if (!tpm_driver_find_by_type(i)) {
             continue;
         }
@@ -335,7 +335,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp)
     unsigned int i = 0;
     TpmModelList *head = NULL, *prev = NULL, *cur_item;
 
-    for (i = 0; i < TPM_MODEL_MAX; i++) {
+    for (i = 0; i < TpmModel_MAX; i++) {
         if (!tpm_model_is_registered(i)) {
             continue;
         }
diff --git a/trace/qmp.c b/trace/qmp.c
index 0b19489..9b836b5 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -24,11 +24,11 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp)
         elem->value = g_new(TraceEventInfo, 1);
         elem->value->name = g_strdup(trace_event_get_name(ev));
         if (!trace_event_get_state_static(ev)) {
-            elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;
+            elem->value->state = TraceEventState_unavailable;
         } else if (!trace_event_get_state_dynamic(ev)) {
-            elem->value->state = TRACE_EVENT_STATE_DISABLED;
+            elem->value->state = TraceEventState_disabled;
         } else {
-            elem->value->state = TRACE_EVENT_STATE_ENABLED;
+            elem->value->state = TraceEventState_enabled;
         }
         elem->next = events;
         events = elem;
diff --git a/ui/cocoa.m b/ui/cocoa.m
index c0d6bb2..8830e78 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -725,12 +725,12 @@ QemuCocoaView *cocoaView;
 
     if (mouse_event) {
         if (last_buttons != buttons) {
-            static uint32_t bmap[INPUT_BUTTON_MAX] = {
-                [INPUT_BUTTON_LEFT]       = MOUSE_EVENT_LBUTTON,
-                [INPUT_BUTTON_MIDDLE]     = MOUSE_EVENT_MBUTTON,
-                [INPUT_BUTTON_RIGHT]      = MOUSE_EVENT_RBUTTON,
-                [INPUT_BUTTON_WHEEL_UP]   = MOUSE_EVENT_WHEELUP,
-                [INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN,
+            static uint32_t bmap[InputButton_MAX] = {
+                [InputButton_Left]       = MOUSE_EVENT_LBUTTON,
+                [InputButton_Middle]     = MOUSE_EVENT_MBUTTON,
+                [InputButton_Right]      = MOUSE_EVENT_RBUTTON,
+                [InputButton_WheelUp]   = MOUSE_EVENT_WHEELUP,
+                [InputButton_WheelDown] = MOUSE_EVENT_WHEELDN,
             };
             qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
             last_buttons = buttons;
@@ -742,12 +742,12 @@ QemuCocoaView *cocoaView;
                  * clicks in the titlebar.
                  */
                 if ([self screenContainsPoint:p]) {
-                    qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width);
-                    qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, screen.height);
+                    qemu_input_queue_abs(dcl->con, InputAxis_X, p.x, screen.width);
+                    qemu_input_queue_abs(dcl->con, InputAxis_Y, screen.height - p.y, screen.height);
                 }
             } else {
-                qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
-                qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]);
+                qemu_input_queue_rel(dcl->con, InputAxis_X, (int)[event deltaX]);
+                qemu_input_queue_rel(dcl->con, InputAxis_Y, (int)[event deltaY]);
             }
         } else {
             [NSApp sendEvent:event];
diff --git a/ui/console.c b/ui/console.c
index f26544e..e183e46 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1108,16 +1108,16 @@ void kbd_put_keysym_console(QemuConsole *s, int keysym)
     }
 }
 
-static const int qcode_to_keysym[Q_KEY_CODE_MAX] = {
-    [Q_KEY_CODE_UP]     = QEMU_KEY_UP,
-    [Q_KEY_CODE_DOWN]   = QEMU_KEY_DOWN,
-    [Q_KEY_CODE_RIGHT]  = QEMU_KEY_RIGHT,
-    [Q_KEY_CODE_LEFT]   = QEMU_KEY_LEFT,
-    [Q_KEY_CODE_HOME]   = QEMU_KEY_HOME,
-    [Q_KEY_CODE_END]    = QEMU_KEY_END,
-    [Q_KEY_CODE_PGUP]   = QEMU_KEY_PAGEUP,
-    [Q_KEY_CODE_PGDN]   = QEMU_KEY_PAGEDOWN,
-    [Q_KEY_CODE_DELETE] = QEMU_KEY_DELETE,
+static const int qcode_to_keysym[QKeyCode_MAX] = {
+    [QKeyCode_up]     = QEMU_KEY_UP,
+    [QKeyCode_down]   = QEMU_KEY_DOWN,
+    [QKeyCode_right]  = QEMU_KEY_RIGHT,
+    [QKeyCode_left]   = QEMU_KEY_LEFT,
+    [QKeyCode_home]   = QEMU_KEY_HOME,
+    [QKeyCode_end]    = QEMU_KEY_END,
+    [QKeyCode_pgup]   = QEMU_KEY_PAGEUP,
+    [QKeyCode_pgdn]   = QEMU_KEY_PAGEDOWN,
+    [QKeyCode_delete] = QEMU_KEY_DELETE,
 };
 
 bool kbd_put_qcode_console(QemuConsole *s, int qcode)
@@ -2095,7 +2095,7 @@ static const TypeInfo qemu_console_info = {
 static void register_types(void)
 {
     type_register_static(&qemu_console_info);
-    register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc,
+    register_char_driver("vc", ChardevBackendKind_vc, qemu_chr_parse_vc,
                          vc_init);
 }
 
diff --git a/ui/gtk.c b/ui/gtk.c
index 47b37e1..556af4b 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -869,14 +869,14 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
             y >= surface_height(vc->gfx.ds)) {
             return TRUE;
         }
-        qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
+        qemu_input_queue_abs(vc->gfx.dcl.con, InputAxis_X, x,
                              surface_width(vc->gfx.ds));
-        qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
+        qemu_input_queue_abs(vc->gfx.dcl.con, InputAxis_Y, y,
                              surface_height(vc->gfx.ds));
         qemu_input_event_sync();
     } else if (s->last_set && s->ptr_owner == vc) {
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, y - s->last_y);
+        qemu_input_queue_rel(vc->gfx.dcl.con, InputAxis_X, x - s->last_x);
+        qemu_input_queue_rel(vc->gfx.dcl.con, InputAxis_Y, y - s->last_y);
         qemu_input_event_sync();
     }
     s->last_x = x;
@@ -943,11 +943,11 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
     }
 
     if (button->button == 1) {
-        btn = INPUT_BUTTON_LEFT;
+        btn = InputButton_Left;
     } else if (button->button == 2) {
-        btn = INPUT_BUTTON_MIDDLE;
+        btn = InputButton_Middle;
     } else if (button->button == 3) {
-        btn = INPUT_BUTTON_RIGHT;
+        btn = InputButton_Right;
     } else {
         return TRUE;
     }
@@ -965,9 +965,9 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
     InputButton btn;
 
     if (scroll->direction == GDK_SCROLL_UP) {
-        btn = INPUT_BUTTON_WHEEL_UP;
+        btn = InputButton_WheelUp;
     } else if (scroll->direction == GDK_SCROLL_DOWN) {
-        btn = INPUT_BUTTON_WHEEL_DOWN;
+        btn = InputButton_WheelDown;
     } else {
         return TRUE;
     }
@@ -1049,7 +1049,7 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
     }
 
     if (key->keyval == GDK_KEY_Pause) {
-        qemu_input_event_send_key_qcode(vc->gfx.dcl.con, Q_KEY_CODE_PAUSE,
+        qemu_input_event_send_key_qcode(vc->gfx.dcl.con, QKeyCode_pause,
                                         key->type == GDK_KEY_PRESS);
         return TRUE;
     }
diff --git a/ui/input-keymap.c b/ui/input-keymap.c
index d36be4b..624df17 100644
--- a/ui/input-keymap.c
+++ b/ui/input-keymap.c
@@ -3,146 +3,146 @@
 #include "ui/input.h"
 
 static const int qcode_to_number[] = {
-    [Q_KEY_CODE_SHIFT] = 0x2a,
-    [Q_KEY_CODE_SHIFT_R] = 0x36,
-
-    [Q_KEY_CODE_ALT] = 0x38,
-    [Q_KEY_CODE_ALT_R] = 0xb8,
-    [Q_KEY_CODE_ALTGR] = 0x64,
-    [Q_KEY_CODE_ALTGR_R] = 0xe4,
-    [Q_KEY_CODE_CTRL] = 0x1d,
-    [Q_KEY_CODE_CTRL_R] = 0x9d,
-
-    [Q_KEY_CODE_META_L] = 0xdb,
-    [Q_KEY_CODE_META_R] = 0xdc,
-    [Q_KEY_CODE_MENU] = 0xdd,
-
-    [Q_KEY_CODE_ESC] = 0x01,
-
-    [Q_KEY_CODE_1] = 0x02,
-    [Q_KEY_CODE_2] = 0x03,
-    [Q_KEY_CODE_3] = 0x04,
-    [Q_KEY_CODE_4] = 0x05,
-    [Q_KEY_CODE_5] = 0x06,
-    [Q_KEY_CODE_6] = 0x07,
-    [Q_KEY_CODE_7] = 0x08,
-    [Q_KEY_CODE_8] = 0x09,
-    [Q_KEY_CODE_9] = 0x0a,
-    [Q_KEY_CODE_0] = 0x0b,
-    [Q_KEY_CODE_MINUS] = 0x0c,
-    [Q_KEY_CODE_EQUAL] = 0x0d,
-    [Q_KEY_CODE_BACKSPACE] = 0x0e,
-
-    [Q_KEY_CODE_TAB] = 0x0f,
-    [Q_KEY_CODE_Q] = 0x10,
-    [Q_KEY_CODE_W] = 0x11,
-    [Q_KEY_CODE_E] = 0x12,
-    [Q_KEY_CODE_R] = 0x13,
-    [Q_KEY_CODE_T] = 0x14,
-    [Q_KEY_CODE_Y] = 0x15,
-    [Q_KEY_CODE_U] = 0x16,
-    [Q_KEY_CODE_I] = 0x17,
-    [Q_KEY_CODE_O] = 0x18,
-    [Q_KEY_CODE_P] = 0x19,
-    [Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
-    [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
-    [Q_KEY_CODE_RET] = 0x1c,
-
-    [Q_KEY_CODE_A] = 0x1e,
-    [Q_KEY_CODE_S] = 0x1f,
-    [Q_KEY_CODE_D] = 0x20,
-    [Q_KEY_CODE_F] = 0x21,
-    [Q_KEY_CODE_G] = 0x22,
-    [Q_KEY_CODE_H] = 0x23,
-    [Q_KEY_CODE_J] = 0x24,
-    [Q_KEY_CODE_K] = 0x25,
-    [Q_KEY_CODE_L] = 0x26,
-    [Q_KEY_CODE_SEMICOLON] = 0x27,
-    [Q_KEY_CODE_APOSTROPHE] = 0x28,
-    [Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
-
-    [Q_KEY_CODE_BACKSLASH] = 0x2b,
-    [Q_KEY_CODE_Z] = 0x2c,
-    [Q_KEY_CODE_X] = 0x2d,
-    [Q_KEY_CODE_C] = 0x2e,
-    [Q_KEY_CODE_V] = 0x2f,
-    [Q_KEY_CODE_B] = 0x30,
-    [Q_KEY_CODE_N] = 0x31,
-    [Q_KEY_CODE_M] = 0x32,
-    [Q_KEY_CODE_COMMA] = 0x33,
-    [Q_KEY_CODE_DOT] = 0x34,
-    [Q_KEY_CODE_SLASH] = 0x35,
-
-    [Q_KEY_CODE_ASTERISK] = 0x37,
-
-    [Q_KEY_CODE_SPC] = 0x39,
-    [Q_KEY_CODE_CAPS_LOCK] = 0x3a,
-    [Q_KEY_CODE_F1] = 0x3b,
-    [Q_KEY_CODE_F2] = 0x3c,
-    [Q_KEY_CODE_F3] = 0x3d,
-    [Q_KEY_CODE_F4] = 0x3e,
-    [Q_KEY_CODE_F5] = 0x3f,
-    [Q_KEY_CODE_F6] = 0x40,
-    [Q_KEY_CODE_F7] = 0x41,
-    [Q_KEY_CODE_F8] = 0x42,
-    [Q_KEY_CODE_F9] = 0x43,
-    [Q_KEY_CODE_F10] = 0x44,
-    [Q_KEY_CODE_NUM_LOCK] = 0x45,
-    [Q_KEY_CODE_SCROLL_LOCK] = 0x46,
-
-    [Q_KEY_CODE_KP_DIVIDE] = 0xb5,
-    [Q_KEY_CODE_KP_MULTIPLY] = 0x37,
-    [Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
-    [Q_KEY_CODE_KP_ADD] = 0x4e,
-    [Q_KEY_CODE_KP_ENTER] = 0x9c,
-    [Q_KEY_CODE_KP_DECIMAL] = 0x53,
-    [Q_KEY_CODE_SYSRQ] = 0x54,
-
-    [Q_KEY_CODE_KP_0] = 0x52,
-    [Q_KEY_CODE_KP_1] = 0x4f,
-    [Q_KEY_CODE_KP_2] = 0x50,
-    [Q_KEY_CODE_KP_3] = 0x51,
-    [Q_KEY_CODE_KP_4] = 0x4b,
-    [Q_KEY_CODE_KP_5] = 0x4c,
-    [Q_KEY_CODE_KP_6] = 0x4d,
-    [Q_KEY_CODE_KP_7] = 0x47,
-    [Q_KEY_CODE_KP_8] = 0x48,
-    [Q_KEY_CODE_KP_9] = 0x49,
-
-    [Q_KEY_CODE_LESS] = 0x56,
-
-    [Q_KEY_CODE_F11] = 0x57,
-    [Q_KEY_CODE_F12] = 0x58,
-
-    [Q_KEY_CODE_PRINT] = 0xb7,
-
-    [Q_KEY_CODE_HOME] = 0xc7,
-    [Q_KEY_CODE_PGUP] = 0xc9,
-    [Q_KEY_CODE_PGDN] = 0xd1,
-    [Q_KEY_CODE_END] = 0xcf,
-
-    [Q_KEY_CODE_LEFT] = 0xcb,
-    [Q_KEY_CODE_UP] = 0xc8,
-    [Q_KEY_CODE_DOWN] = 0xd0,
-    [Q_KEY_CODE_RIGHT] = 0xcd,
-
-    [Q_KEY_CODE_INSERT] = 0xd2,
-    [Q_KEY_CODE_DELETE] = 0xd3,
-
-    [Q_KEY_CODE_RO] = 0x73,
-    [Q_KEY_CODE_KP_COMMA] = 0x7e,
-
-    [Q_KEY_CODE_MAX] = 0,
+    [QKeyCode_shift] = 0x2a,
+    [QKeyCode_shift_r] = 0x36,
+
+    [QKeyCode_alt] = 0x38,
+    [QKeyCode_alt_r] = 0xb8,
+    [QKeyCode_altgr] = 0x64,
+    [QKeyCode_altgr_r] = 0xe4,
+    [QKeyCode_ctrl] = 0x1d,
+    [QKeyCode_ctrl_r] = 0x9d,
+
+    [QKeyCode_meta_l] = 0xdb,
+    [QKeyCode_meta_r] = 0xdc,
+    [QKeyCode_menu] = 0xdd,
+
+    [QKeyCode_esc] = 0x01,
+
+    [QKeyCode_1] = 0x02,
+    [QKeyCode_2] = 0x03,
+    [QKeyCode_3] = 0x04,
+    [QKeyCode_4] = 0x05,
+    [QKeyCode_5] = 0x06,
+    [QKeyCode_6] = 0x07,
+    [QKeyCode_7] = 0x08,
+    [QKeyCode_8] = 0x09,
+    [QKeyCode_9] = 0x0a,
+    [QKeyCode_0] = 0x0b,
+    [QKeyCode_minus] = 0x0c,
+    [QKeyCode_equal] = 0x0d,
+    [QKeyCode_backspace] = 0x0e,
+
+    [QKeyCode_tab] = 0x0f,
+    [QKeyCode_q] = 0x10,
+    [QKeyCode_w] = 0x11,
+    [QKeyCode_e] = 0x12,
+    [QKeyCode_r] = 0x13,
+    [QKeyCode_t] = 0x14,
+    [QKeyCode_y] = 0x15,
+    [QKeyCode_u] = 0x16,
+    [QKeyCode_i] = 0x17,
+    [QKeyCode_o] = 0x18,
+    [QKeyCode_p] = 0x19,
+    [QKeyCode_bracket_left] = 0x1a,
+    [QKeyCode_bracket_right] = 0x1b,
+    [QKeyCode_ret] = 0x1c,
+
+    [QKeyCode_a] = 0x1e,
+    [QKeyCode_s] = 0x1f,
+    [QKeyCode_d] = 0x20,
+    [QKeyCode_f] = 0x21,
+    [QKeyCode_g] = 0x22,
+    [QKeyCode_h] = 0x23,
+    [QKeyCode_j] = 0x24,
+    [QKeyCode_k] = 0x25,
+    [QKeyCode_l] = 0x26,
+    [QKeyCode_semicolon] = 0x27,
+    [QKeyCode_apostrophe] = 0x28,
+    [QKeyCode_grave_accent] = 0x29,
+
+    [QKeyCode_backslash] = 0x2b,
+    [QKeyCode_z] = 0x2c,
+    [QKeyCode_x] = 0x2d,
+    [QKeyCode_c] = 0x2e,
+    [QKeyCode_v] = 0x2f,
+    [QKeyCode_b] = 0x30,
+    [QKeyCode_n] = 0x31,
+    [QKeyCode_m] = 0x32,
+    [QKeyCode_comma] = 0x33,
+    [QKeyCode_dot] = 0x34,
+    [QKeyCode_slash] = 0x35,
+
+    [QKeyCode_asterisk] = 0x37,
+
+    [QKeyCode_spc] = 0x39,
+    [QKeyCode_caps_lock] = 0x3a,
+    [QKeyCode_f1] = 0x3b,
+    [QKeyCode_f2] = 0x3c,
+    [QKeyCode_f3] = 0x3d,
+    [QKeyCode_f4] = 0x3e,
+    [QKeyCode_f5] = 0x3f,
+    [QKeyCode_f6] = 0x40,
+    [QKeyCode_f7] = 0x41,
+    [QKeyCode_f8] = 0x42,
+    [QKeyCode_f9] = 0x43,
+    [QKeyCode_f10] = 0x44,
+    [QKeyCode_num_lock] = 0x45,
+    [QKeyCode_scroll_lock] = 0x46,
+
+    [QKeyCode_kp_divide] = 0xb5,
+    [QKeyCode_kp_multiply] = 0x37,
+    [QKeyCode_kp_subtract] = 0x4a,
+    [QKeyCode_kp_add] = 0x4e,
+    [QKeyCode_kp_enter] = 0x9c,
+    [QKeyCode_kp_decimal] = 0x53,
+    [QKeyCode_sysrq] = 0x54,
+
+    [QKeyCode_kp_0] = 0x52,
+    [QKeyCode_kp_1] = 0x4f,
+    [QKeyCode_kp_2] = 0x50,
+    [QKeyCode_kp_3] = 0x51,
+    [QKeyCode_kp_4] = 0x4b,
+    [QKeyCode_kp_5] = 0x4c,
+    [QKeyCode_kp_6] = 0x4d,
+    [QKeyCode_kp_7] = 0x47,
+    [QKeyCode_kp_8] = 0x48,
+    [QKeyCode_kp_9] = 0x49,
+
+    [QKeyCode_less] = 0x56,
+
+    [QKeyCode_f11] = 0x57,
+    [QKeyCode_f12] = 0x58,
+
+    [QKeyCode_print] = 0xb7,
+
+    [QKeyCode_home] = 0xc7,
+    [QKeyCode_pgup] = 0xc9,
+    [QKeyCode_pgdn] = 0xd1,
+    [QKeyCode_end] = 0xcf,
+
+    [QKeyCode_left] = 0xcb,
+    [QKeyCode_up] = 0xc8,
+    [QKeyCode_down] = 0xd0,
+    [QKeyCode_right] = 0xcd,
+
+    [QKeyCode_insert] = 0xd2,
+    [QKeyCode_delete] = 0xd3,
+
+    [QKeyCode_ro] = 0x73,
+    [QKeyCode_kp_comma] = 0x7e,
+
+    [QKeyCode_MAX] = 0,
 };
 
 static int number_to_qcode[0x100];
 
 int qemu_input_key_value_to_number(const KeyValue *value)
 {
-    if (value->type == KEY_VALUE_KIND_QCODE) {
+    if (value->type == KeyValueKind_qcode) {
         return qcode_to_number[value->u.qcode];
     } else {
-        assert(value->type == KEY_VALUE_KIND_NUMBER);
+        assert(value->type == KeyValueKind_number);
         return value->u.number;
     }
 }
@@ -154,7 +154,7 @@ int qemu_input_key_number_to_qcode(uint8_t nr)
     if (first) {
         int qcode, number;
         first = false;
-        for (qcode = 0; qcode < Q_KEY_CODE_MAX; qcode++) {
+        for (qcode = 0; qcode < QKeyCode_MAX; qcode++) {
             number = qcode_to_number[qcode];
             assert(number < ARRAY_SIZE(number_to_qcode));
             number_to_qcode[number] = qcode;
@@ -166,10 +166,10 @@ int qemu_input_key_number_to_qcode(uint8_t nr)
 
 int qemu_input_key_value_to_qcode(const KeyValue *value)
 {
-    if (value->type == KEY_VALUE_KIND_QCODE) {
+    if (value->type == KeyValueKind_qcode) {
         return value->u.qcode;
     } else {
-        assert(value->type == KEY_VALUE_KIND_NUMBER);
+        assert(value->type == KeyValueKind_number);
         return qemu_input_key_number_to_qcode(value->u.number);
     }
 }
@@ -180,8 +180,8 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
     int keycode = qemu_input_key_value_to_number(value);
     int count = 0;
 
-    if (value->type == KEY_VALUE_KIND_QCODE &&
-        value->u.qcode == Q_KEY_CODE_PAUSE) {
+    if (value->type == KeyValueKind_qcode &&
+        value->u.qcode == QKeyCode_pause) {
         /* specific case */
         int v = down ? 0 : 0x80;
         codes[count++] = 0xe1;
diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index a67ed32..661faf0 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -38,7 +38,7 @@ struct QEMUPutMouseEntry {
     /* new input core */
     QemuInputHandler h;
     QemuInputHandlerState *s;
-    int axis[INPUT_AXIS_MAX];
+    int axis[InputAxis_MAX];
     int buttons;
 };
 
@@ -67,7 +67,7 @@ int index_from_key(const char *key)
         }
     }
 
-    /* Return Q_KEY_CODE_MAX if the key is invalid */
+    /* Return QKeyCode_MAX if the key is invalid */
     return i;
 }
 
@@ -143,40 +143,40 @@ QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
                                InputEvent *evt)
 {
-    static const int bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
-        [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
-        [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
+    static const int bmap[InputButton_MAX] = {
+        [InputButton_Left]   = MOUSE_EVENT_LBUTTON,
+        [InputButton_Middle] = MOUSE_EVENT_MBUTTON,
+        [InputButton_Right]  = MOUSE_EVENT_RBUTTON,
     };
     QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
 
     switch (evt->type) {
-    case INPUT_EVENT_KIND_BTN:
+    case InputEventKind_btn:
         if (evt->u.btn->down) {
             s->buttons |= bmap[evt->u.btn->button];
         } else {
             s->buttons &= ~bmap[evt->u.btn->button];
         }
-        if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
+        if (evt->u.btn->down && evt->u.btn->button == InputButton_WheelUp) {
             s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
-                                    s->axis[INPUT_AXIS_X],
-                                    s->axis[INPUT_AXIS_Y],
+                                    s->axis[InputAxis_X],
+                                    s->axis[InputAxis_Y],
                                     -1,
                                     s->buttons);
         }
         if (evt->u.btn->down &&
-            evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
+            evt->u.btn->button == InputButton_WheelDown) {
             s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
-                                    s->axis[INPUT_AXIS_X],
-                                    s->axis[INPUT_AXIS_Y],
+                                    s->axis[InputAxis_X],
+                                    s->axis[InputAxis_Y],
                                     1,
                                     s->buttons);
         }
         break;
-    case INPUT_EVENT_KIND_ABS:
+    case InputEventKind_abs:
         s->axis[evt->u.abs->axis] = evt->u.abs->value;
         break;
-    case INPUT_EVENT_KIND_REL:
+    case InputEventKind_rel:
         s->axis[evt->u.rel->axis] += evt->u.rel->value;
         break;
     default:
@@ -189,14 +189,14 @@ static void legacy_mouse_sync(DeviceState *dev)
     QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
 
     s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
-                            s->axis[INPUT_AXIS_X],
-                            s->axis[INPUT_AXIS_Y],
+                            s->axis[InputAxis_X],
+                            s->axis[InputAxis_Y],
                             0,
                             s->buttons);
 
     if (!s->qemu_put_mouse_event_absolute) {
-        s->axis[INPUT_AXIS_X] = 0;
-        s->axis[INPUT_AXIS_Y] = 0;
+        s->axis[InputAxis_X] = 0;
+        s->axis[InputAxis_Y] = 0;
     }
 }
 
diff --git a/ui/input.c b/ui/input.c
index 643f885..28af744 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -85,7 +85,7 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
 
     dev = qdev_find_recursive(sysbus_get_default(), device_id);
     if (dev == NULL) {
-        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+        error_set(errp, ErrorClass_DeviceNotFound,
                   "Device '%s' not found", device_id);
         return;
     }
@@ -139,7 +139,7 @@ void qmp_x_input_send_event(bool has_console, int64_t console,
         }
     }
 
-    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
+    if (!runstate_is_running() && !runstate_check(RunState_suspended)) {
         error_setg(errp, "VM not running");
         return;
     }
@@ -168,10 +168,10 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
 {
     switch (graphic_rotate) {
     case 90:
-        if (evt->u.abs->axis == INPUT_AXIS_X) {
-            evt->u.abs->axis = INPUT_AXIS_Y;
-        } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
-            evt->u.abs->axis = INPUT_AXIS_X;
+        if (evt->u.abs->axis == InputAxis_X) {
+            evt->u.abs->axis = InputAxis_Y;
+        } else if (evt->u.abs->axis == InputAxis_Y) {
+            evt->u.abs->axis = InputAxis_X;
             evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
         }
         break;
@@ -179,11 +179,11 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
         evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
         break;
     case 270:
-        if (evt->u.abs->axis == INPUT_AXIS_X) {
-            evt->u.abs->axis = INPUT_AXIS_Y;
+        if (evt->u.abs->axis == InputAxis_X) {
+            evt->u.abs->axis = InputAxis_Y;
             evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
-        } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
-            evt->u.abs->axis = INPUT_AXIS_X;
+        } else if (evt->u.abs->axis == InputAxis_Y) {
+            evt->u.abs->axis = InputAxis_X;
         }
         break;
     }
@@ -198,36 +198,36 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
         idx = qemu_console_get_index(src);
     }
     switch (evt->type) {
-    case INPUT_EVENT_KIND_KEY:
+    case InputEventKind_key:
         switch (evt->u.key->key->type) {
-        case KEY_VALUE_KIND_NUMBER:
+        case KeyValueKind_number:
             qcode = qemu_input_key_number_to_qcode(evt->u.key->key->u.number);
             name = QKeyCode_lookup[qcode];
             trace_input_event_key_number(idx, evt->u.key->key->u.number,
                                          name, evt->u.key->down);
             break;
-        case KEY_VALUE_KIND_QCODE:
+        case KeyValueKind_qcode:
             name = QKeyCode_lookup[evt->u.key->key->u.qcode];
             trace_input_event_key_qcode(idx, name, evt->u.key->down);
             break;
-        case KEY_VALUE_KIND_MAX:
+        case KeyValueKind_MAX:
             /* keep gcc happy */
             break;
         }
         break;
-    case INPUT_EVENT_KIND_BTN:
+    case InputEventKind_btn:
         name = InputButton_lookup[evt->u.btn->button];
         trace_input_event_btn(idx, name, evt->u.btn->down);
         break;
-    case INPUT_EVENT_KIND_REL:
+    case InputEventKind_rel:
         name = InputAxis_lookup[evt->u.rel->axis];
         trace_input_event_rel(idx, name, evt->u.rel->value);
         break;
-    case INPUT_EVENT_KIND_ABS:
+    case InputEventKind_abs:
         name = InputAxis_lookup[evt->u.abs->axis];
         trace_input_event_abs(idx, name, evt->u.abs->value);
         break;
-    case INPUT_EVENT_KIND_MAX:
+    case InputEventKind_MAX:
         /* keep gcc happy */
         break;
     }
@@ -304,14 +304,14 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
 {
     QemuInputHandlerState *s;
 
-    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
+    if (!runstate_is_running() && !runstate_check(RunState_suspended)) {
         return;
     }
 
     qemu_input_event_trace(src, evt);
 
     /* pre processing */
-    if (graphic_rotate && (evt->type == INPUT_EVENT_KIND_ABS)) {
+    if (graphic_rotate && (evt->type == InputEventKind_abs)) {
             qemu_input_transform_abs_rotate(evt);
     }
 
@@ -328,7 +328,7 @@ void qemu_input_event_sync(void)
 {
     QemuInputHandlerState *s;
 
-    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
+    if (!runstate_is_running() && !runstate_check(RunState_suspended)) {
         return;
     }
 
@@ -349,7 +349,7 @@ InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
 {
     InputEvent *evt = g_new0(InputEvent, 1);
     evt->u.key = g_new0(InputKeyEvent, 1);
-    evt->type = INPUT_EVENT_KIND_KEY;
+    evt->type = InputEventKind_key;
     evt->u.key->key = key;
     evt->u.key->down = down;
     return evt;
@@ -372,7 +372,7 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
 void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
 {
     KeyValue *key = g_new0(KeyValue, 1);
-    key->type = KEY_VALUE_KIND_NUMBER;
+    key->type = KeyValueKind_number;
     key->u.number = num;
     qemu_input_event_send_key(src, key, down);
 }
@@ -380,7 +380,7 @@ void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
 void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
 {
     KeyValue *key = g_new0(KeyValue, 1);
-    key->type = KEY_VALUE_KIND_QCODE;
+    key->type = KeyValueKind_qcode;
     key->u.qcode = q;
     qemu_input_event_send_key(src, key, down);
 }
@@ -399,7 +399,7 @@ InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
 {
     InputEvent *evt = g_new0(InputEvent, 1);
     evt->u.btn = g_new0(InputBtnEvent, 1);
-    evt->type = INPUT_EVENT_KIND_BTN;
+    evt->type = InputEventKind_btn;
     evt->u.btn->button = btn;
     evt->u.btn->down = down;
     return evt;
@@ -419,7 +419,7 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
     InputButton btn;
     uint32_t mask;
 
-    for (btn = 0; btn < INPUT_BUTTON_MAX; btn++) {
+    for (btn = 0; btn < InputButton_MAX; btn++) {
         mask = button_map[btn];
         if ((button_old & mask) == (button_new & mask)) {
             continue;
@@ -461,7 +461,7 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind,
 void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
 {
     InputEvent *evt;
-    evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value);
+    evt = qemu_input_event_new_move(InputEventKind_rel, axis, value);
     qemu_input_event_send(src, evt);
     qapi_free_InputEvent(evt);
 }
@@ -470,7 +470,7 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
 {
     InputEvent *evt;
     int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
-    evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
+    evt = qemu_input_event_new_move(InputEventKind_abs, axis, scaled);
     qemu_input_event_send(src, evt);
     qapi_free_InputEvent(evt);
 }
diff --git a/ui/sdl.c b/ui/sdl.c
index 3be2910..d038b62 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -305,7 +305,7 @@ static void sdl_process_key(SDL_KeyboardEvent *ev)
 
     if (ev->keysym.sym == SDLK_PAUSE) {
         /* specific case */
-        qemu_input_event_send_key_qcode(dcl->con, Q_KEY_CODE_PAUSE,
+        qemu_input_event_send_key_qcode(dcl->con, QKeyCode_pause,
                                         ev->type == SDL_KEYDOWN);
         return;
     }
@@ -465,12 +465,12 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
 
 static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
 {
-    static uint32_t bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]       = SDL_BUTTON(SDL_BUTTON_LEFT),
-        [INPUT_BUTTON_MIDDLE]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),
-        [INPUT_BUTTON_RIGHT]      = SDL_BUTTON(SDL_BUTTON_RIGHT),
-        [INPUT_BUTTON_WHEEL_UP]   = SDL_BUTTON(SDL_BUTTON_WHEELUP),
-        [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
+    static uint32_t bmap[InputButton_MAX] = {
+        [InputButton_Left]       = SDL_BUTTON(SDL_BUTTON_LEFT),
+        [InputButton_Middle]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),
+        [InputButton_Right]      = SDL_BUTTON(SDL_BUTTON_RIGHT),
+        [InputButton_WheelUp]   = SDL_BUTTON(SDL_BUTTON_WHEELUP),
+        [InputButton_WheelDown] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
     };
     static uint32_t prev_state;
 
@@ -480,9 +480,9 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
     }
 
     if (qemu_input_is_absolute()) {
-        qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,
+        qemu_input_queue_abs(dcl->con, InputAxis_X, x,
                              real_screen->w);
-        qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,
+        qemu_input_queue_abs(dcl->con, InputAxis_Y, y,
                              real_screen->h);
     } else {
         if (guest_cursor) {
@@ -493,8 +493,8 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
             dx = x;
             dy = y;
         }
-        qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, dx);
-        qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, dy);
+        qemu_input_queue_rel(dcl->con, InputAxis_X, dx);
+        qemu_input_queue_rel(dcl->con, InputAxis_Y, dy);
     }
     qemu_input_event_sync();
 }
diff --git a/ui/sdl2-keymap.h b/ui/sdl2-keymap.h
index cbedaa4..b34a26c 100644
--- a/ui/sdl2-keymap.h
+++ b/ui/sdl2-keymap.h
@@ -2,266 +2,266 @@
 /* map SDL2 scancodes to QKeyCode */
 
 static const int sdl2_scancode_to_qcode[SDL_NUM_SCANCODES] = {
-    [SDL_SCANCODE_A]                 = Q_KEY_CODE_A,
-    [SDL_SCANCODE_B]                 = Q_KEY_CODE_B,
-    [SDL_SCANCODE_C]                 = Q_KEY_CODE_C,
-    [SDL_SCANCODE_D]                 = Q_KEY_CODE_D,
-    [SDL_SCANCODE_E]                 = Q_KEY_CODE_E,
-    [SDL_SCANCODE_F]                 = Q_KEY_CODE_F,
-    [SDL_SCANCODE_G]                 = Q_KEY_CODE_G,
-    [SDL_SCANCODE_H]                 = Q_KEY_CODE_H,
-    [SDL_SCANCODE_I]                 = Q_KEY_CODE_I,
-    [SDL_SCANCODE_J]                 = Q_KEY_CODE_J,
-    [SDL_SCANCODE_K]                 = Q_KEY_CODE_K,
-    [SDL_SCANCODE_L]                 = Q_KEY_CODE_L,
-    [SDL_SCANCODE_M]                 = Q_KEY_CODE_M,
-    [SDL_SCANCODE_N]                 = Q_KEY_CODE_N,
-    [SDL_SCANCODE_O]                 = Q_KEY_CODE_O,
-    [SDL_SCANCODE_P]                 = Q_KEY_CODE_P,
-    [SDL_SCANCODE_Q]                 = Q_KEY_CODE_Q,
-    [SDL_SCANCODE_R]                 = Q_KEY_CODE_R,
-    [SDL_SCANCODE_S]                 = Q_KEY_CODE_S,
-    [SDL_SCANCODE_T]                 = Q_KEY_CODE_T,
-    [SDL_SCANCODE_U]                 = Q_KEY_CODE_U,
-    [SDL_SCANCODE_V]                 = Q_KEY_CODE_V,
-    [SDL_SCANCODE_W]                 = Q_KEY_CODE_W,
-    [SDL_SCANCODE_X]                 = Q_KEY_CODE_X,
-    [SDL_SCANCODE_Y]                 = Q_KEY_CODE_Y,
-    [SDL_SCANCODE_Z]                 = Q_KEY_CODE_Z,
+    [SDL_SCANCODE_A]                 = QKeyCode_a,
+    [SDL_SCANCODE_B]                 = QKeyCode_b,
+    [SDL_SCANCODE_C]                 = QKeyCode_c,
+    [SDL_SCANCODE_D]                 = QKeyCode_d,
+    [SDL_SCANCODE_E]                 = QKeyCode_e,
+    [SDL_SCANCODE_F]                 = QKeyCode_f,
+    [SDL_SCANCODE_G]                 = QKeyCode_g,
+    [SDL_SCANCODE_H]                 = QKeyCode_h,
+    [SDL_SCANCODE_I]                 = QKeyCode_i,
+    [SDL_SCANCODE_J]                 = QKeyCode_j,
+    [SDL_SCANCODE_K]                 = QKeyCode_k,
+    [SDL_SCANCODE_L]                 = QKeyCode_l,
+    [SDL_SCANCODE_M]                 = QKeyCode_m,
+    [SDL_SCANCODE_N]                 = QKeyCode_n,
+    [SDL_SCANCODE_O]                 = QKeyCode_o,
+    [SDL_SCANCODE_P]                 = QKeyCode_p,
+    [SDL_SCANCODE_Q]                 = QKeyCode_q,
+    [SDL_SCANCODE_R]                 = QKeyCode_r,
+    [SDL_SCANCODE_S]                 = QKeyCode_s,
+    [SDL_SCANCODE_T]                 = QKeyCode_t,
+    [SDL_SCANCODE_U]                 = QKeyCode_u,
+    [SDL_SCANCODE_V]                 = QKeyCode_v,
+    [SDL_SCANCODE_W]                 = QKeyCode_w,
+    [SDL_SCANCODE_X]                 = QKeyCode_x,
+    [SDL_SCANCODE_Y]                 = QKeyCode_y,
+    [SDL_SCANCODE_Z]                 = QKeyCode_z,
 
-    [SDL_SCANCODE_1]                 = Q_KEY_CODE_1,
-    [SDL_SCANCODE_2]                 = Q_KEY_CODE_2,
-    [SDL_SCANCODE_3]                 = Q_KEY_CODE_3,
-    [SDL_SCANCODE_4]                 = Q_KEY_CODE_4,
-    [SDL_SCANCODE_5]                 = Q_KEY_CODE_5,
-    [SDL_SCANCODE_6]                 = Q_KEY_CODE_6,
-    [SDL_SCANCODE_7]                 = Q_KEY_CODE_7,
-    [SDL_SCANCODE_8]                 = Q_KEY_CODE_8,
-    [SDL_SCANCODE_9]                 = Q_KEY_CODE_9,
-    [SDL_SCANCODE_0]                 = Q_KEY_CODE_0,
+    [SDL_SCANCODE_1]                 = QKeyCode_1,
+    [SDL_SCANCODE_2]                 = QKeyCode_2,
+    [SDL_SCANCODE_3]                 = QKeyCode_3,
+    [SDL_SCANCODE_4]                 = QKeyCode_4,
+    [SDL_SCANCODE_5]                 = QKeyCode_5,
+    [SDL_SCANCODE_6]                 = QKeyCode_6,
+    [SDL_SCANCODE_7]                 = QKeyCode_7,
+    [SDL_SCANCODE_8]                 = QKeyCode_8,
+    [SDL_SCANCODE_9]                 = QKeyCode_9,
+    [SDL_SCANCODE_0]                 = QKeyCode_0,
 
-    [SDL_SCANCODE_RETURN]            = Q_KEY_CODE_RET,
-    [SDL_SCANCODE_ESCAPE]            = Q_KEY_CODE_ESC,
-    [SDL_SCANCODE_BACKSPACE]         = Q_KEY_CODE_BACKSPACE,
-    [SDL_SCANCODE_TAB]               = Q_KEY_CODE_TAB,
-    [SDL_SCANCODE_SPACE]             = Q_KEY_CODE_SPC,
-    [SDL_SCANCODE_MINUS]             = Q_KEY_CODE_MINUS,
-    [SDL_SCANCODE_EQUALS]            = Q_KEY_CODE_EQUAL,
-    [SDL_SCANCODE_LEFTBRACKET]       = Q_KEY_CODE_BRACKET_LEFT,
-    [SDL_SCANCODE_RIGHTBRACKET]      = Q_KEY_CODE_BRACKET_RIGHT,
-    [SDL_SCANCODE_BACKSLASH]         = Q_KEY_CODE_BACKSLASH,
+    [SDL_SCANCODE_RETURN]            = QKeyCode_ret,
+    [SDL_SCANCODE_ESCAPE]            = QKeyCode_esc,
+    [SDL_SCANCODE_BACKSPACE]         = QKeyCode_backspace,
+    [SDL_SCANCODE_TAB]               = QKeyCode_tab,
+    [SDL_SCANCODE_SPACE]             = QKeyCode_spc,
+    [SDL_SCANCODE_MINUS]             = QKeyCode_minus,
+    [SDL_SCANCODE_EQUALS]            = QKeyCode_equal,
+    [SDL_SCANCODE_LEFTBRACKET]       = QKeyCode_bracket_left,
+    [SDL_SCANCODE_RIGHTBRACKET]      = QKeyCode_bracket_right,
+    [SDL_SCANCODE_BACKSLASH]         = QKeyCode_backslash,
 #if 0
-    [SDL_SCANCODE_NONUSHASH]         = Q_KEY_CODE_NONUSHASH,
+    [SDL_SCANCODE_NONUSHASH]         = QKeyCode_nonushash,
 #endif
-    [SDL_SCANCODE_SEMICOLON]         = Q_KEY_CODE_SEMICOLON,
-    [SDL_SCANCODE_APOSTROPHE]        = Q_KEY_CODE_APOSTROPHE,
-    [SDL_SCANCODE_GRAVE]             = Q_KEY_CODE_GRAVE_ACCENT,
-    [SDL_SCANCODE_COMMA]             = Q_KEY_CODE_COMMA,
-    [SDL_SCANCODE_PERIOD]            = Q_KEY_CODE_DOT,
-    [SDL_SCANCODE_SLASH]             = Q_KEY_CODE_SLASH,
-    [SDL_SCANCODE_CAPSLOCK]          = Q_KEY_CODE_CAPS_LOCK,
+    [SDL_SCANCODE_SEMICOLON]         = QKeyCode_semicolon,
+    [SDL_SCANCODE_APOSTROPHE]        = QKeyCode_apostrophe,
+    [SDL_SCANCODE_GRAVE]             = QKeyCode_grave_accent,
+    [SDL_SCANCODE_COMMA]             = QKeyCode_comma,
+    [SDL_SCANCODE_PERIOD]            = QKeyCode_dot,
+    [SDL_SCANCODE_SLASH]             = QKeyCode_slash,
+    [SDL_SCANCODE_CAPSLOCK]          = QKeyCode_caps_lock,
 
-    [SDL_SCANCODE_F1]                = Q_KEY_CODE_F1,
-    [SDL_SCANCODE_F2]                = Q_KEY_CODE_F2,
-    [SDL_SCANCODE_F3]                = Q_KEY_CODE_F3,
-    [SDL_SCANCODE_F4]                = Q_KEY_CODE_F4,
-    [SDL_SCANCODE_F5]                = Q_KEY_CODE_F5,
-    [SDL_SCANCODE_F6]                = Q_KEY_CODE_F6,
-    [SDL_SCANCODE_F7]                = Q_KEY_CODE_F7,
-    [SDL_SCANCODE_F8]                = Q_KEY_CODE_F8,
-    [SDL_SCANCODE_F9]                = Q_KEY_CODE_F9,
-    [SDL_SCANCODE_F10]               = Q_KEY_CODE_F10,
-    [SDL_SCANCODE_F11]               = Q_KEY_CODE_F11,
-    [SDL_SCANCODE_F12]               = Q_KEY_CODE_F12,
+    [SDL_SCANCODE_F1]                = QKeyCode_f1,
+    [SDL_SCANCODE_F2]                = QKeyCode_f2,
+    [SDL_SCANCODE_F3]                = QKeyCode_f3,
+    [SDL_SCANCODE_F4]                = QKeyCode_f4,
+    [SDL_SCANCODE_F5]                = QKeyCode_f5,
+    [SDL_SCANCODE_F6]                = QKeyCode_f6,
+    [SDL_SCANCODE_F7]                = QKeyCode_f7,
+    [SDL_SCANCODE_F8]                = QKeyCode_f8,
+    [SDL_SCANCODE_F9]                = QKeyCode_f9,
+    [SDL_SCANCODE_F10]               = QKeyCode_f10,
+    [SDL_SCANCODE_F11]               = QKeyCode_f11,
+    [SDL_SCANCODE_F12]               = QKeyCode_f12,
 
-    [SDL_SCANCODE_PRINTSCREEN]       = Q_KEY_CODE_PRINT,
-    [SDL_SCANCODE_SCROLLLOCK]        = Q_KEY_CODE_SCROLL_LOCK,
-    [SDL_SCANCODE_PAUSE]             = Q_KEY_CODE_PAUSE,
-    [SDL_SCANCODE_INSERT]            = Q_KEY_CODE_INSERT,
-    [SDL_SCANCODE_HOME]              = Q_KEY_CODE_HOME,
-    [SDL_SCANCODE_PAGEUP]            = Q_KEY_CODE_PGUP,
-    [SDL_SCANCODE_DELETE]            = Q_KEY_CODE_DELETE,
-    [SDL_SCANCODE_END]               = Q_KEY_CODE_END,
-    [SDL_SCANCODE_PAGEDOWN]          = Q_KEY_CODE_PGDN,
-    [SDL_SCANCODE_RIGHT]             = Q_KEY_CODE_RIGHT,
-    [SDL_SCANCODE_LEFT]              = Q_KEY_CODE_LEFT,
-    [SDL_SCANCODE_DOWN]              = Q_KEY_CODE_DOWN,
-    [SDL_SCANCODE_UP]                = Q_KEY_CODE_UP,
-    [SDL_SCANCODE_NUMLOCKCLEAR]      = Q_KEY_CODE_NUM_LOCK,
+    [SDL_SCANCODE_PRINTSCREEN]       = QKeyCode_print,
+    [SDL_SCANCODE_SCROLLLOCK]        = QKeyCode_scroll_lock,
+    [SDL_SCANCODE_PAUSE]             = QKeyCode_pause,
+    [SDL_SCANCODE_INSERT]            = QKeyCode_insert,
+    [SDL_SCANCODE_HOME]              = QKeyCode_home,
+    [SDL_SCANCODE_PAGEUP]            = QKeyCode_pgup,
+    [SDL_SCANCODE_DELETE]            = QKeyCode_delete,
+    [SDL_SCANCODE_END]               = QKeyCode_end,
+    [SDL_SCANCODE_PAGEDOWN]          = QKeyCode_pgdn,
+    [SDL_SCANCODE_RIGHT]             = QKeyCode_right,
+    [SDL_SCANCODE_LEFT]              = QKeyCode_left,
+    [SDL_SCANCODE_DOWN]              = QKeyCode_down,
+    [SDL_SCANCODE_UP]                = QKeyCode_up,
+    [SDL_SCANCODE_NUMLOCKCLEAR]      = QKeyCode_num_lock,
 
-    [SDL_SCANCODE_KP_DIVIDE]         = Q_KEY_CODE_KP_DIVIDE,
-    [SDL_SCANCODE_KP_MULTIPLY]       = Q_KEY_CODE_KP_MULTIPLY,
-    [SDL_SCANCODE_KP_MINUS]          = Q_KEY_CODE_KP_SUBTRACT,
-    [SDL_SCANCODE_KP_PLUS]           = Q_KEY_CODE_KP_ADD,
-    [SDL_SCANCODE_KP_ENTER]          = Q_KEY_CODE_KP_ENTER,
-    [SDL_SCANCODE_KP_1]              = Q_KEY_CODE_KP_1,
-    [SDL_SCANCODE_KP_2]              = Q_KEY_CODE_KP_2,
-    [SDL_SCANCODE_KP_3]              = Q_KEY_CODE_KP_3,
-    [SDL_SCANCODE_KP_4]              = Q_KEY_CODE_KP_4,
-    [SDL_SCANCODE_KP_5]              = Q_KEY_CODE_KP_5,
-    [SDL_SCANCODE_KP_6]              = Q_KEY_CODE_KP_6,
-    [SDL_SCANCODE_KP_7]              = Q_KEY_CODE_KP_7,
-    [SDL_SCANCODE_KP_8]              = Q_KEY_CODE_KP_8,
-    [SDL_SCANCODE_KP_9]              = Q_KEY_CODE_KP_9,
-    [SDL_SCANCODE_KP_0]              = Q_KEY_CODE_KP_0,
-    [SDL_SCANCODE_KP_PERIOD]         = Q_KEY_CODE_KP_DECIMAL,
+    [SDL_SCANCODE_KP_DIVIDE]         = QKeyCode_kp_divide,
+    [SDL_SCANCODE_KP_MULTIPLY]       = QKeyCode_kp_multiply,
+    [SDL_SCANCODE_KP_MINUS]          = QKeyCode_kp_subtract,
+    [SDL_SCANCODE_KP_PLUS]           = QKeyCode_kp_add,
+    [SDL_SCANCODE_KP_ENTER]          = QKeyCode_kp_enter,
+    [SDL_SCANCODE_KP_1]              = QKeyCode_kp_1,
+    [SDL_SCANCODE_KP_2]              = QKeyCode_kp_2,
+    [SDL_SCANCODE_KP_3]              = QKeyCode_kp_3,
+    [SDL_SCANCODE_KP_4]              = QKeyCode_kp_4,
+    [SDL_SCANCODE_KP_5]              = QKeyCode_kp_5,
+    [SDL_SCANCODE_KP_6]              = QKeyCode_kp_6,
+    [SDL_SCANCODE_KP_7]              = QKeyCode_kp_7,
+    [SDL_SCANCODE_KP_8]              = QKeyCode_kp_8,
+    [SDL_SCANCODE_KP_9]              = QKeyCode_kp_9,
+    [SDL_SCANCODE_KP_0]              = QKeyCode_kp_0,
+    [SDL_SCANCODE_KP_PERIOD]         = QKeyCode_kp_decimal,
 
-    [SDL_SCANCODE_NONUSBACKSLASH]    = Q_KEY_CODE_LESS,
-    [SDL_SCANCODE_APPLICATION]       = Q_KEY_CODE_MENU,
+    [SDL_SCANCODE_NONUSBACKSLASH]    = QKeyCode_less,
+    [SDL_SCANCODE_APPLICATION]       = QKeyCode_menu,
 #if 0
-    [SDL_SCANCODE_POWER]             = Q_KEY_CODE_POWER,
-    [SDL_SCANCODE_KP_EQUALS]         = Q_KEY_CODE_KP_EQUALS,
+    [SDL_SCANCODE_POWER]             = QKeyCode_power,
+    [SDL_SCANCODE_KP_EQUALS]         = QKeyCode_kp_equals,
 
-    [SDL_SCANCODE_F13]               = Q_KEY_CODE_F13,
-    [SDL_SCANCODE_F14]               = Q_KEY_CODE_F14,
-    [SDL_SCANCODE_F15]               = Q_KEY_CODE_F15,
-    [SDL_SCANCODE_F16]               = Q_KEY_CODE_F16,
-    [SDL_SCANCODE_F17]               = Q_KEY_CODE_F17,
-    [SDL_SCANCODE_F18]               = Q_KEY_CODE_F18,
-    [SDL_SCANCODE_F19]               = Q_KEY_CODE_F19,
-    [SDL_SCANCODE_F20]               = Q_KEY_CODE_F20,
-    [SDL_SCANCODE_F21]               = Q_KEY_CODE_F21,
-    [SDL_SCANCODE_F22]               = Q_KEY_CODE_F22,
-    [SDL_SCANCODE_F23]               = Q_KEY_CODE_F23,
-    [SDL_SCANCODE_F24]               = Q_KEY_CODE_F24,
+    [SDL_SCANCODE_F13]               = QKeyCode_f13,
+    [SDL_SCANCODE_F14]               = QKeyCode_f14,
+    [SDL_SCANCODE_F15]               = QKeyCode_f15,
+    [SDL_SCANCODE_F16]               = QKeyCode_f16,
+    [SDL_SCANCODE_F17]               = QKeyCode_f17,
+    [SDL_SCANCODE_F18]               = QKeyCode_f18,
+    [SDL_SCANCODE_F19]               = QKeyCode_f19,
+    [SDL_SCANCODE_F20]               = QKeyCode_f20,
+    [SDL_SCANCODE_F21]               = QKeyCode_f21,
+    [SDL_SCANCODE_F22]               = QKeyCode_f22,
+    [SDL_SCANCODE_F23]               = QKeyCode_f23,
+    [SDL_SCANCODE_F24]               = QKeyCode_f24,
 
-    [SDL_SCANCODE_EXECUTE]           = Q_KEY_CODE_EXECUTE,
+    [SDL_SCANCODE_EXECUTE]           = QKeyCode_execute,
 #endif
-    [SDL_SCANCODE_HELP]              = Q_KEY_CODE_HELP,
-    [SDL_SCANCODE_MENU]              = Q_KEY_CODE_MENU,
+    [SDL_SCANCODE_HELP]              = QKeyCode_help,
+    [SDL_SCANCODE_MENU]              = QKeyCode_menu,
 #if 0
-    [SDL_SCANCODE_SELECT]            = Q_KEY_CODE_SELECT,
+    [SDL_SCANCODE_SELECT]            = QKeyCode_select,
 #endif
-    [SDL_SCANCODE_STOP]              = Q_KEY_CODE_STOP,
-    [SDL_SCANCODE_AGAIN]             = Q_KEY_CODE_AGAIN,
-    [SDL_SCANCODE_UNDO]              = Q_KEY_CODE_UNDO,
-    [SDL_SCANCODE_CUT]               = Q_KEY_CODE_CUT,
-    [SDL_SCANCODE_COPY]              = Q_KEY_CODE_COPY,
-    [SDL_SCANCODE_PASTE]             = Q_KEY_CODE_PASTE,
-    [SDL_SCANCODE_FIND]              = Q_KEY_CODE_FIND,
+    [SDL_SCANCODE_STOP]              = QKeyCode_stop,
+    [SDL_SCANCODE_AGAIN]             = QKeyCode_again,
+    [SDL_SCANCODE_UNDO]              = QKeyCode_undo,
+    [SDL_SCANCODE_CUT]               = QKeyCode_cut,
+    [SDL_SCANCODE_COPY]              = QKeyCode_copy,
+    [SDL_SCANCODE_PASTE]             = QKeyCode_paste,
+    [SDL_SCANCODE_FIND]              = QKeyCode_find,
 #if 0
-    [SDL_SCANCODE_MUTE]              = Q_KEY_CODE_MUTE,
-    [SDL_SCANCODE_VOLUMEUP]          = Q_KEY_CODE_VOLUMEUP,
-    [SDL_SCANCODE_VOLUMEDOWN]        = Q_KEY_CODE_VOLUMEDOWN,
+    [SDL_SCANCODE_MUTE]              = QKeyCode_mute,
+    [SDL_SCANCODE_VOLUMEUP]          = QKeyCode_volumeup,
+    [SDL_SCANCODE_VOLUMEDOWN]        = QKeyCode_volumedown,
 
-    [SDL_SCANCODE_KP_COMMA]          = Q_KEY_CODE_KP_COMMA,
-    [SDL_SCANCODE_KP_EQUALSAS400]    = Q_KEY_CODE_KP_EQUALSAS400,
+    [SDL_SCANCODE_KP_COMMA]          = QKeyCode_kp_comma,
+    [SDL_SCANCODE_KP_EQUALSAS400]    = QKeyCode_kp_equalsas400,
 
-    [SDL_SCANCODE_INTERNATIONAL1]    = Q_KEY_CODE_INTERNATIONAL1,
-    [SDL_SCANCODE_INTERNATIONAL2]    = Q_KEY_CODE_INTERNATIONAL2,
-    [SDL_SCANCODE_INTERNATIONAL3]    = Q_KEY_CODE_INTERNATIONAL3,
-    [SDL_SCANCODE_INTERNATIONAL4]    = Q_KEY_CODE_INTERNATIONAL4,
-    [SDL_SCANCODE_INTERNATIONAL5]    = Q_KEY_CODE_INTERNATIONAL5,
-    [SDL_SCANCODE_INTERNATIONAL6]    = Q_KEY_CODE_INTERNATIONAL6,
-    [SDL_SCANCODE_INTERNATIONAL7]    = Q_KEY_CODE_INTERNATIONAL7,
-    [SDL_SCANCODE_INTERNATIONAL8]    = Q_KEY_CODE_INTERNATIONAL8,
-    [SDL_SCANCODE_INTERNATIONAL9]    = Q_KEY_CODE_INTERNATIONAL9,
-    [SDL_SCANCODE_LANG1]             = Q_KEY_CODE_LANG1,
-    [SDL_SCANCODE_LANG2]             = Q_KEY_CODE_LANG2,
-    [SDL_SCANCODE_LANG3]             = Q_KEY_CODE_LANG3,
-    [SDL_SCANCODE_LANG4]             = Q_KEY_CODE_LANG4,
-    [SDL_SCANCODE_LANG5]             = Q_KEY_CODE_LANG5,
-    [SDL_SCANCODE_LANG6]             = Q_KEY_CODE_LANG6,
-    [SDL_SCANCODE_LANG7]             = Q_KEY_CODE_LANG7,
-    [SDL_SCANCODE_LANG8]             = Q_KEY_CODE_LANG8,
-    [SDL_SCANCODE_LANG9]             = Q_KEY_CODE_LANG9,
-    [SDL_SCANCODE_ALTERASE]          = Q_KEY_CODE_ALTERASE,
+    [SDL_SCANCODE_INTERNATIONAL1]    = QKeyCode_international1,
+    [SDL_SCANCODE_INTERNATIONAL2]    = QKeyCode_international2,
+    [SDL_SCANCODE_INTERNATIONAL3]    = QKeyCode_international3,
+    [SDL_SCANCODE_INTERNATIONAL4]    = QKeyCode_international4,
+    [SDL_SCANCODE_INTERNATIONAL5]    = QKeyCode_international5,
+    [SDL_SCANCODE_INTERNATIONAL6]    = QKeyCode_international6,
+    [SDL_SCANCODE_INTERNATIONAL7]    = QKeyCode_international7,
+    [SDL_SCANCODE_INTERNATIONAL8]    = QKeyCode_international8,
+    [SDL_SCANCODE_INTERNATIONAL9]    = QKeyCode_international9,
+    [SDL_SCANCODE_LANG1]             = QKeyCode_lang1,
+    [SDL_SCANCODE_LANG2]             = QKeyCode_lang2,
+    [SDL_SCANCODE_LANG3]             = QKeyCode_lang3,
+    [SDL_SCANCODE_LANG4]             = QKeyCode_lang4,
+    [SDL_SCANCODE_LANG5]             = QKeyCode_lang5,
+    [SDL_SCANCODE_LANG6]             = QKeyCode_lang6,
+    [SDL_SCANCODE_LANG7]             = QKeyCode_lang7,
+    [SDL_SCANCODE_LANG8]             = QKeyCode_lang8,
+    [SDL_SCANCODE_LANG9]             = QKeyCode_lang9,
+    [SDL_SCANCODE_ALTERASE]          = QKeyCode_alterase,
 #endif
-    [SDL_SCANCODE_SYSREQ]            = Q_KEY_CODE_SYSRQ,
+    [SDL_SCANCODE_SYSREQ]            = QKeyCode_sysrq,
 #if 0
-    [SDL_SCANCODE_CANCEL]            = Q_KEY_CODE_CANCEL,
-    [SDL_SCANCODE_CLEAR]             = Q_KEY_CODE_CLEAR,
-    [SDL_SCANCODE_PRIOR]             = Q_KEY_CODE_PRIOR,
-    [SDL_SCANCODE_RETURN2]           = Q_KEY_CODE_RETURN2,
-    [SDL_SCANCODE_SEPARATOR]         = Q_KEY_CODE_SEPARATOR,
-    [SDL_SCANCODE_OUT]               = Q_KEY_CODE_OUT,
-    [SDL_SCANCODE_OPER]              = Q_KEY_CODE_OPER,
-    [SDL_SCANCODE_CLEARAGAIN]        = Q_KEY_CODE_CLEARAGAIN,
-    [SDL_SCANCODE_CRSEL]             = Q_KEY_CODE_CRSEL,
-    [SDL_SCANCODE_EXSEL]             = Q_KEY_CODE_EXSEL,
-    [SDL_SCANCODE_KP_00]             = Q_KEY_CODE_KP_00,
-    [SDL_SCANCODE_KP_000]            = Q_KEY_CODE_KP_000,
-    [SDL_SCANCODE_THOUSANDSSEPARATOR] = Q_KEY_CODE_THOUSANDSSEPARATOR,
-    [SDL_SCANCODE_DECIMALSEPARATOR]  = Q_KEY_CODE_DECIMALSEPARATOR,
-    [SDL_SCANCODE_CURRENCYUNIT]      = Q_KEY_CODE_CURRENCYUNIT,
-    [SDL_SCANCODE_CURRENCYSUBUNIT]   = Q_KEY_CODE_CURRENCYSUBUNIT,
-    [SDL_SCANCODE_KP_LEFTPAREN]      = Q_KEY_CODE_KP_LEFTPAREN,
-    [SDL_SCANCODE_KP_RIGHTPAREN]     = Q_KEY_CODE_KP_RIGHTPAREN,
-    [SDL_SCANCODE_KP_LEFTBRACE]      = Q_KEY_CODE_KP_LEFTBRACE,
-    [SDL_SCANCODE_KP_RIGHTBRACE]     = Q_KEY_CODE_KP_RIGHTBRACE,
-    [SDL_SCANCODE_KP_TAB]            = Q_KEY_CODE_KP_TAB,
-    [SDL_SCANCODE_KP_BACKSPACE]      = Q_KEY_CODE_KP_BACKSPACE,
-    [SDL_SCANCODE_KP_A]              = Q_KEY_CODE_KP_A,
-    [SDL_SCANCODE_KP_B]              = Q_KEY_CODE_KP_B,
-    [SDL_SCANCODE_KP_C]              = Q_KEY_CODE_KP_C,
-    [SDL_SCANCODE_KP_D]              = Q_KEY_CODE_KP_D,
-    [SDL_SCANCODE_KP_E]              = Q_KEY_CODE_KP_E,
-    [SDL_SCANCODE_KP_F]              = Q_KEY_CODE_KP_F,
-    [SDL_SCANCODE_KP_XOR]            = Q_KEY_CODE_KP_XOR,
-    [SDL_SCANCODE_KP_POWER]          = Q_KEY_CODE_KP_POWER,
-    [SDL_SCANCODE_KP_PERCENT]        = Q_KEY_CODE_KP_PERCENT,
-    [SDL_SCANCODE_KP_LESS]           = Q_KEY_CODE_KP_LESS,
-    [SDL_SCANCODE_KP_GREATER]        = Q_KEY_CODE_KP_GREATER,
-    [SDL_SCANCODE_KP_AMPERSAND]      = Q_KEY_CODE_KP_AMPERSAND,
-    [SDL_SCANCODE_KP_DBLAMPERSAND]   = Q_KEY_CODE_KP_DBLAMPERSAND,
-    [SDL_SCANCODE_KP_VERTICALBAR]    = Q_KEY_CODE_KP_VERTICALBAR,
-    [SDL_SCANCODE_KP_DBLVERTICALBAR] = Q_KEY_CODE_KP_DBLVERTICALBAR,
-    [SDL_SCANCODE_KP_COLON]          = Q_KEY_CODE_KP_COLON,
-    [SDL_SCANCODE_KP_HASH]           = Q_KEY_CODE_KP_HASH,
-    [SDL_SCANCODE_KP_SPACE]          = Q_KEY_CODE_KP_SPACE,
-    [SDL_SCANCODE_KP_AT]             = Q_KEY_CODE_KP_AT,
-    [SDL_SCANCODE_KP_EXCLAM]         = Q_KEY_CODE_KP_EXCLAM,
-    [SDL_SCANCODE_KP_MEMSTORE]       = Q_KEY_CODE_KP_MEMSTORE,
-    [SDL_SCANCODE_KP_MEMRECALL]      = Q_KEY_CODE_KP_MEMRECALL,
-    [SDL_SCANCODE_KP_MEMCLEAR]       = Q_KEY_CODE_KP_MEMCLEAR,
-    [SDL_SCANCODE_KP_MEMADD]         = Q_KEY_CODE_KP_MEMADD,
-    [SDL_SCANCODE_KP_MEMSUBTRACT]    = Q_KEY_CODE_KP_MEMSUBTRACT,
-    [SDL_SCANCODE_KP_MEMMULTIPLY]    = Q_KEY_CODE_KP_MEMMULTIPLY,
-    [SDL_SCANCODE_KP_MEMDIVIDE]      = Q_KEY_CODE_KP_MEMDIVIDE,
-    [SDL_SCANCODE_KP_PLUSMINUS]      = Q_KEY_CODE_KP_PLUSMINUS,
-    [SDL_SCANCODE_KP_CLEAR]          = Q_KEY_CODE_KP_CLEAR,
-    [SDL_SCANCODE_KP_CLEARENTRY]     = Q_KEY_CODE_KP_CLEARENTRY,
-    [SDL_SCANCODE_KP_BINARY]         = Q_KEY_CODE_KP_BINARY,
-    [SDL_SCANCODE_KP_OCTAL]          = Q_KEY_CODE_KP_OCTAL,
-    [SDL_SCANCODE_KP_DECIMAL]        = Q_KEY_CODE_KP_DECIMAL,
-    [SDL_SCANCODE_KP_HEXADECIMAL]    = Q_KEY_CODE_KP_HEXADECIMAL,
+    [SDL_SCANCODE_CANCEL]            = QKeyCode_cancel,
+    [SDL_SCANCODE_CLEAR]             = QKeyCode_clear,
+    [SDL_SCANCODE_PRIOR]             = QKeyCode_prior,
+    [SDL_SCANCODE_RETURN2]           = QKeyCode_return2,
+    [SDL_SCANCODE_SEPARATOR]         = QKeyCode_separator,
+    [SDL_SCANCODE_OUT]               = QKeyCode_out,
+    [SDL_SCANCODE_OPER]              = QKeyCode_oper,
+    [SDL_SCANCODE_CLEARAGAIN]        = QKeyCode_clearagain,
+    [SDL_SCANCODE_CRSEL]             = QKeyCode_crsel,
+    [SDL_SCANCODE_EXSEL]             = QKeyCode_exsel,
+    [SDL_SCANCODE_KP_00]             = QKeyCode_kp_00,
+    [SDL_SCANCODE_KP_000]            = QKeyCode_kp_000,
+    [SDL_SCANCODE_THOUSANDSSEPARATOR] = QKeyCode_thousandsseparator,
+    [SDL_SCANCODE_DECIMALSEPARATOR]  = QKeyCode_decimalseparator,
+    [SDL_SCANCODE_CURRENCYUNIT]      = QKeyCode_currencyunit,
+    [SDL_SCANCODE_CURRENCYSUBUNIT]   = QKeyCode_currencysubunit,
+    [SDL_SCANCODE_KP_LEFTPAREN]      = QKeyCode_kp_leftparen,
+    [SDL_SCANCODE_KP_RIGHTPAREN]     = QKeyCode_kp_rightparen,
+    [SDL_SCANCODE_KP_LEFTBRACE]      = QKeyCode_kp_leftbrace,
+    [SDL_SCANCODE_KP_RIGHTBRACE]     = QKeyCode_kp_rightbrace,
+    [SDL_SCANCODE_KP_TAB]            = QKeyCode_kp_tab,
+    [SDL_SCANCODE_KP_BACKSPACE]      = QKeyCode_kp_backspace,
+    [SDL_SCANCODE_KP_A]              = QKeyCode_kp_a,
+    [SDL_SCANCODE_KP_B]              = QKeyCode_kp_b,
+    [SDL_SCANCODE_KP_C]              = QKeyCode_kp_c,
+    [SDL_SCANCODE_KP_D]              = QKeyCode_kp_d,
+    [SDL_SCANCODE_KP_E]              = QKeyCode_kp_e,
+    [SDL_SCANCODE_KP_F]              = QKeyCode_kp_f,
+    [SDL_SCANCODE_KP_XOR]            = QKeyCode_kp_xor,
+    [SDL_SCANCODE_KP_POWER]          = QKeyCode_kp_power,
+    [SDL_SCANCODE_KP_PERCENT]        = QKeyCode_kp_percent,
+    [SDL_SCANCODE_KP_LESS]           = QKeyCode_kp_less,
+    [SDL_SCANCODE_KP_GREATER]        = QKeyCode_kp_greater,
+    [SDL_SCANCODE_KP_AMPERSAND]      = QKeyCode_kp_ampersand,
+    [SDL_SCANCODE_KP_DBLAMPERSAND]   = QKeyCode_kp_dblampersand,
+    [SDL_SCANCODE_KP_VERTICALBAR]    = QKeyCode_kp_verticalbar,
+    [SDL_SCANCODE_KP_DBLVERTICALBAR] = QKeyCode_kp_dblverticalbar,
+    [SDL_SCANCODE_KP_COLON]          = QKeyCode_kp_colon,
+    [SDL_SCANCODE_KP_HASH]           = QKeyCode_kp_hash,
+    [SDL_SCANCODE_KP_SPACE]          = QKeyCode_kp_space,
+    [SDL_SCANCODE_KP_AT]             = QKeyCode_kp_at,
+    [SDL_SCANCODE_KP_EXCLAM]         = QKeyCode_kp_exclam,
+    [SDL_SCANCODE_KP_MEMSTORE]       = QKeyCode_kp_memstore,
+    [SDL_SCANCODE_KP_MEMRECALL]      = QKeyCode_kp_memrecall,
+    [SDL_SCANCODE_KP_MEMCLEAR]       = QKeyCode_kp_memclear,
+    [SDL_SCANCODE_KP_MEMADD]         = QKeyCode_kp_memadd,
+    [SDL_SCANCODE_KP_MEMSUBTRACT]    = QKeyCode_kp_memsubtract,
+    [SDL_SCANCODE_KP_MEMMULTIPLY]    = QKeyCode_kp_memmultiply,
+    [SDL_SCANCODE_KP_MEMDIVIDE]      = QKeyCode_kp_memdivide,
+    [SDL_SCANCODE_KP_PLUSMINUS]      = QKeyCode_kp_plusminus,
+    [SDL_SCANCODE_KP_CLEAR]          = QKeyCode_kp_clear,
+    [SDL_SCANCODE_KP_CLEARENTRY]     = QKeyCode_kp_clearentry,
+    [SDL_SCANCODE_KP_BINARY]         = QKeyCode_kp_binary,
+    [SDL_SCANCODE_KP_OCTAL]          = QKeyCode_kp_octal,
+    [SDL_SCANCODE_KP_DECIMAL]        = QKeyCode_kp_decimal,
+    [SDL_SCANCODE_KP_HEXADECIMAL]    = QKeyCode_kp_hexadecimal,
 #endif
-    [SDL_SCANCODE_LCTRL]             = Q_KEY_CODE_CTRL,
-    [SDL_SCANCODE_LSHIFT]            = Q_KEY_CODE_SHIFT,
-    [SDL_SCANCODE_LALT]              = Q_KEY_CODE_ALT,
-    [SDL_SCANCODE_LGUI]              = Q_KEY_CODE_META_L,
-    [SDL_SCANCODE_RCTRL]             = Q_KEY_CODE_CTRL_R,
-    [SDL_SCANCODE_RSHIFT]            = Q_KEY_CODE_SHIFT_R,
-    [SDL_SCANCODE_RALT]              = Q_KEY_CODE_ALT_R,
-    [SDL_SCANCODE_RGUI]              = Q_KEY_CODE_META_R,
+    [SDL_SCANCODE_LCTRL]             = QKeyCode_ctrl,
+    [SDL_SCANCODE_LSHIFT]            = QKeyCode_shift,
+    [SDL_SCANCODE_LALT]              = QKeyCode_alt,
+    [SDL_SCANCODE_LGUI]              = QKeyCode_meta_l,
+    [SDL_SCANCODE_RCTRL]             = QKeyCode_ctrl_r,
+    [SDL_SCANCODE_RSHIFT]            = QKeyCode_shift_r,
+    [SDL_SCANCODE_RALT]              = QKeyCode_alt_r,
+    [SDL_SCANCODE_RGUI]              = QKeyCode_meta_r,
 #if 0
-    [SDL_SCANCODE_MODE]              = Q_KEY_CODE_MODE,
-    [SDL_SCANCODE_AUDIONEXT]         = Q_KEY_CODE_AUDIONEXT,
-    [SDL_SCANCODE_AUDIOPREV]         = Q_KEY_CODE_AUDIOPREV,
-    [SDL_SCANCODE_AUDIOSTOP]         = Q_KEY_CODE_AUDIOSTOP,
-    [SDL_SCANCODE_AUDIOPLAY]         = Q_KEY_CODE_AUDIOPLAY,
-    [SDL_SCANCODE_AUDIOMUTE]         = Q_KEY_CODE_AUDIOMUTE,
-    [SDL_SCANCODE_MEDIASELECT]       = Q_KEY_CODE_MEDIASELECT,
-    [SDL_SCANCODE_WWW]               = Q_KEY_CODE_WWW,
-    [SDL_SCANCODE_MAIL]              = Q_KEY_CODE_MAIL,
-    [SDL_SCANCODE_CALCULATOR]        = Q_KEY_CODE_CALCULATOR,
-    [SDL_SCANCODE_COMPUTER]          = Q_KEY_CODE_COMPUTER,
-    [SDL_SCANCODE_AC_SEARCH]         = Q_KEY_CODE_AC_SEARCH,
-    [SDL_SCANCODE_AC_HOME]           = Q_KEY_CODE_AC_HOME,
-    [SDL_SCANCODE_AC_BACK]           = Q_KEY_CODE_AC_BACK,
-    [SDL_SCANCODE_AC_FORWARD]        = Q_KEY_CODE_AC_FORWARD,
-    [SDL_SCANCODE_AC_STOP]           = Q_KEY_CODE_AC_STOP,
-    [SDL_SCANCODE_AC_REFRESH]        = Q_KEY_CODE_AC_REFRESH,
-    [SDL_SCANCODE_AC_BOOKMARKS]      = Q_KEY_CODE_AC_BOOKMARKS,
-    [SDL_SCANCODE_BRIGHTNESSDOWN]    = Q_KEY_CODE_BRIGHTNESSDOWN,
-    [SDL_SCANCODE_BRIGHTNESSUP]      = Q_KEY_CODE_BRIGHTNESSUP,
-    [SDL_SCANCODE_DISPLAYSWITCH]     = Q_KEY_CODE_DISPLAYSWITCH,
-    [SDL_SCANCODE_KBDILLUMTOGGLE]    = Q_KEY_CODE_KBDILLUMTOGGLE,
-    [SDL_SCANCODE_KBDILLUMDOWN]      = Q_KEY_CODE_KBDILLUMDOWN,
-    [SDL_SCANCODE_KBDILLUMUP]        = Q_KEY_CODE_KBDILLUMUP,
-    [SDL_SCANCODE_EJECT]             = Q_KEY_CODE_EJECT,
-    [SDL_SCANCODE_SLEEP]             = Q_KEY_CODE_SLEEP,
-    [SDL_SCANCODE_APP1]              = Q_KEY_CODE_APP1,
-    [SDL_SCANCODE_APP2]              = Q_KEY_CODE_APP2,
+    [SDL_SCANCODE_MODE]              = QKeyCode_mode,
+    [SDL_SCANCODE_AUDIONEXT]         = QKeyCode_audionext,
+    [SDL_SCANCODE_AUDIOPREV]         = QKeyCode_audioprev,
+    [SDL_SCANCODE_AUDIOSTOP]         = QKeyCode_audiostop,
+    [SDL_SCANCODE_AUDIOPLAY]         = QKeyCode_audioplay,
+    [SDL_SCANCODE_AUDIOMUTE]         = QKeyCode_audiomute,
+    [SDL_SCANCODE_MEDIASELECT]       = QKeyCode_mediaselect,
+    [SDL_SCANCODE_WWW]               = QKeyCode_www,
+    [SDL_SCANCODE_MAIL]              = QKeyCode_mail,
+    [SDL_SCANCODE_CALCULATOR]        = QKeyCode_calculator,
+    [SDL_SCANCODE_COMPUTER]          = QKeyCode_computer,
+    [SDL_SCANCODE_AC_SEARCH]         = QKeyCode_ac_search,
+    [SDL_SCANCODE_AC_HOME]           = QKeyCode_ac_home,
+    [SDL_SCANCODE_AC_BACK]           = QKeyCode_ac_back,
+    [SDL_SCANCODE_AC_FORWARD]        = QKeyCode_ac_forward,
+    [SDL_SCANCODE_AC_STOP]           = QKeyCode_ac_stop,
+    [SDL_SCANCODE_AC_REFRESH]        = QKeyCode_ac_refresh,
+    [SDL_SCANCODE_AC_BOOKMARKS]      = QKeyCode_ac_bookmarks,
+    [SDL_SCANCODE_BRIGHTNESSDOWN]    = QKeyCode_brightnessdown,
+    [SDL_SCANCODE_BRIGHTNESSUP]      = QKeyCode_brightnessup,
+    [SDL_SCANCODE_DISPLAYSWITCH]     = QKeyCode_displayswitch,
+    [SDL_SCANCODE_KBDILLUMTOGGLE]    = QKeyCode_kbdillumtoggle,
+    [SDL_SCANCODE_KBDILLUMDOWN]      = QKeyCode_kbdillumdown,
+    [SDL_SCANCODE_KBDILLUMUP]        = QKeyCode_kbdillumup,
+    [SDL_SCANCODE_EJECT]             = QKeyCode_eject,
+    [SDL_SCANCODE_SLEEP]             = QKeyCode_sleep,
+    [SDL_SCANCODE_APP1]              = QKeyCode_app1,
+    [SDL_SCANCODE_APP2]              = QKeyCode_app2,
 #endif
 };
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 5cb75aa..9a4a5ca 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -256,10 +256,10 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
 static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
                                  int x, int y, int state)
 {
-    static uint32_t bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]       = SDL_BUTTON(SDL_BUTTON_LEFT),
-        [INPUT_BUTTON_MIDDLE]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),
-        [INPUT_BUTTON_RIGHT]      = SDL_BUTTON(SDL_BUTTON_RIGHT),
+    static uint32_t bmap[InputButton_MAX] = {
+        [InputButton_Left]       = SDL_BUTTON(SDL_BUTTON_LEFT),
+        [InputButton_Middle]     = SDL_BUTTON(SDL_BUTTON_MIDDLE),
+        [InputButton_Right]      = SDL_BUTTON(SDL_BUTTON_RIGHT),
     };
     static uint32_t prev_state;
 
@@ -293,8 +293,8 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
                 }
             }
         }
-        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
-        qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
+        qemu_input_queue_abs(scon->dcl.con, InputAxis_X, off_x + x, max_w);
+        qemu_input_queue_abs(scon->dcl.con, InputAxis_Y, off_y + y, max_h);
     } else {
         if (guest_cursor) {
             x -= guest_x;
@@ -304,8 +304,8 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
             dx = x;
             dy = y;
         }
-        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
-        qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
+        qemu_input_queue_rel(scon->dcl.con, InputAxis_X, dx);
+        qemu_input_queue_rel(scon->dcl.con, InputAxis_Y, dy);
     }
     qemu_input_event_sync();
 }
@@ -504,9 +504,9 @@ static void handle_mousewheel(SDL_Event *ev)
     InputButton btn;
 
     if (wev->y > 0) {
-        btn = INPUT_BUTTON_WHEEL_UP;
+        btn = InputButton_WheelUp;
     } else if (wev->y < 0) {
-        btn = INPUT_BUTTON_WHEEL_DOWN;
+        btn = InputButton_WheelDown;
     } else {
         return;
     }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 6a62d71..e62a6f7 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -547,8 +547,8 @@ SpiceInfo *qmp_query_spice(Error **errp)
     }
 
     info->mouse_mode = spice_server_is_server_mouse(spice_server) ?
-                       SPICE_QUERY_MOUSE_MODE_SERVER :
-                       SPICE_QUERY_MOUSE_MODE_CLIENT;
+                       SpiceQueryMouseMode_server :
+                       SpiceQueryMouseMode_client;
 
     /* for compatibility with the original command */
     info->has_channels = true;
diff --git a/ui/spice-input.c b/ui/spice-input.c
index c342e0d..5dc2bb2 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -107,12 +107,12 @@ typedef struct QemuSpicePointer {
 static void spice_update_buttons(QemuSpicePointer *pointer,
                                  int wheel, uint32_t button_mask)
 {
-    static uint32_t bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]        = 0x01,
-        [INPUT_BUTTON_MIDDLE]      = 0x04,
-        [INPUT_BUTTON_RIGHT]       = 0x02,
-        [INPUT_BUTTON_WHEEL_UP]    = 0x10,
-        [INPUT_BUTTON_WHEEL_DOWN]  = 0x20,
+    static uint32_t bmap[InputButton_MAX] = {
+        [InputButton_Left]        = 0x01,
+        [InputButton_Middle]      = 0x04,
+        [InputButton_Right]       = 0x02,
+        [InputButton_WheelUp]    = 0x10,
+        [InputButton_WheelDown]  = 0x20,
     };
 
     if (wheel < 0) {
@@ -134,8 +134,8 @@ static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
 {
     QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, mouse);
     spice_update_buttons(pointer, dz, buttons_state);
-    qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
-    qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
+    qemu_input_queue_rel(NULL, InputAxis_X, dx);
+    qemu_input_queue_rel(NULL, InputAxis_Y, dy);
     qemu_input_event_sync();
 }
 
@@ -175,8 +175,8 @@ static void tablet_position(SpiceTabletInstance* sin, int x, int y,
     QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
 
     spice_update_buttons(pointer, 0, buttons_state);
-    qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, pointer->width);
-    qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, pointer->height);
+    qemu_input_queue_abs(NULL, InputAxis_X, x, pointer->width);
+    qemu_input_queue_abs(NULL, InputAxis_Y, y, pointer->height);
     qemu_input_event_sync();
 }
 
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index 44ac2fa..201cfc9 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -132,7 +132,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
         vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds,
                                           NULL,
                                           vs->vd->tlsaclname,
-                                          QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
+                                          QCRYPTO_TLS_CREDS_ENDPOINT_server,
                                           &err);
         if (!vs->tls) {
             VNC_DEBUG("Failed to setup TLS %s\n",
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index 175ea50..3804b73 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -68,7 +68,7 @@ void vncws_tls_handshake_io(void *opaque)
     vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds,
                                       NULL,
                                       vs->vd->tlsaclname,
-                                      QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
+                                      QCRYPTO_TLS_CREDS_ENDPOINT_server,
                                       &err);
     if (!vs->tls) {
         VNC_DEBUG("Failed to setup TLS %s\n",
diff --git a/ui/vnc.c b/ui/vnc.c
index 7b37e3b..0cd19f6 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -324,14 +324,14 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
     }
 
     switch (event) {
-    case QAPI_EVENT_VNC_CONNECTED:
+    case QAPIEvent_VNC_CONNECTED:
         qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
                                       &error_abort);
         break;
-    case QAPI_EVENT_VNC_INITIALIZED:
+    case QAPIEvent_VNC_INITIALIZED:
         qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
         break;
-    case QAPI_EVENT_VNC_DISCONNECTED:
+    case QAPIEvent_VNC_DISCONNECTED:
         qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
         break;
     default:
@@ -500,53 +500,53 @@ static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
 {
     switch (vd->auth) {
     case VNC_AUTH_VNC:
-        info->auth = VNC_PRIMARY_AUTH_VNC;
+        info->auth = VncPrimaryAuth_vnc;
         break;
     case VNC_AUTH_RA2:
-        info->auth = VNC_PRIMARY_AUTH_RA2;
+        info->auth = VncPrimaryAuth_ra2;
         break;
     case VNC_AUTH_RA2NE:
-        info->auth = VNC_PRIMARY_AUTH_RA2NE;
+        info->auth = VncPrimaryAuth_ra2ne;
         break;
     case VNC_AUTH_TIGHT:
-        info->auth = VNC_PRIMARY_AUTH_TIGHT;
+        info->auth = VncPrimaryAuth_tight;
         break;
     case VNC_AUTH_ULTRA:
-        info->auth = VNC_PRIMARY_AUTH_ULTRA;
+        info->auth = VncPrimaryAuth_ultra;
         break;
     case VNC_AUTH_TLS:
-        info->auth = VNC_PRIMARY_AUTH_TLS;
+        info->auth = VncPrimaryAuth_tls;
         break;
     case VNC_AUTH_VENCRYPT:
-        info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
+        info->auth = VncPrimaryAuth_vencrypt;
         info->has_vencrypt = true;
         switch (vd->subauth) {
         case VNC_AUTH_VENCRYPT_PLAIN:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
+            info->vencrypt = VncVencryptSubAuth_plain;
             break;
         case VNC_AUTH_VENCRYPT_TLSNONE:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
+            info->vencrypt = VncVencryptSubAuth_tls_none;
             break;
         case VNC_AUTH_VENCRYPT_TLSVNC:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
+            info->vencrypt = VncVencryptSubAuth_tls_vnc;
             break;
         case VNC_AUTH_VENCRYPT_TLSPLAIN:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
+            info->vencrypt = VncVencryptSubAuth_tls_plain;
             break;
         case VNC_AUTH_VENCRYPT_X509NONE:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
+            info->vencrypt = VncVencryptSubAuth_x509_none;
             break;
         case VNC_AUTH_VENCRYPT_X509VNC:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
+            info->vencrypt = VncVencryptSubAuth_x509_vnc;
             break;
         case VNC_AUTH_VENCRYPT_X509PLAIN:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
+            info->vencrypt = VncVencryptSubAuth_x509_plain;
             break;
         case VNC_AUTH_VENCRYPT_TLSSASL:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
+            info->vencrypt = VncVencryptSubAuth_tls_sasl;
             break;
         case VNC_AUTH_VENCRYPT_X509SASL:
-            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
+            info->vencrypt = VncVencryptSubAuth_x509_sasl;
             break;
         default:
             info->has_vencrypt = false;
@@ -554,11 +554,11 @@ static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
         }
         break;
     case VNC_AUTH_SASL:
-        info->auth = VNC_PRIMARY_AUTH_SASL;
+        info->auth = VncPrimaryAuth_sasl;
         break;
     case VNC_AUTH_NONE:
     default:
-        info->auth = VNC_PRIMARY_AUTH_NONE;
+        info->auth = VncPrimaryAuth_none;
         break;
     }
 }
@@ -1185,7 +1185,7 @@ void vnc_disconnect_finish(VncState *vs)
     vnc_jobs_join(vs); /* Wait encoding jobs */
 
     vnc_lock_output(vs);
-    vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
+    vnc_qmp_event(vs, QAPIEvent_VNC_DISCONNECTED);
 
     buffer_free(&vs->input);
     buffer_free(&vs->output);
@@ -1630,12 +1630,12 @@ static void check_pointer_type_change(Notifier *notifier, void *data)
 
 static void pointer_event(VncState *vs, int button_mask, int x, int y)
 {
-    static uint32_t bmap[INPUT_BUTTON_MAX] = {
-        [INPUT_BUTTON_LEFT]       = 0x01,
-        [INPUT_BUTTON_MIDDLE]     = 0x02,
-        [INPUT_BUTTON_RIGHT]      = 0x04,
-        [INPUT_BUTTON_WHEEL_UP]   = 0x08,
-        [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
+    static uint32_t bmap[InputButton_MAX] = {
+        [InputButton_Left]       = 0x01,
+        [InputButton_Middle]     = 0x02,
+        [InputButton_Right]      = 0x04,
+        [InputButton_WheelUp]   = 0x08,
+        [InputButton_WheelDown] = 0x10,
     };
     QemuConsole *con = vs->vd->dcl.con;
     int width = pixman_image_get_width(vs->vd->server);
@@ -1647,15 +1647,15 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
     }
 
     if (vs->absolute) {
-        qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
-        qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
+        qemu_input_queue_abs(con, InputAxis_X, x, width);
+        qemu_input_queue_abs(con, InputAxis_Y, y, height);
     } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
-        qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
-        qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
+        qemu_input_queue_rel(con, InputAxis_X, x - 0x7FFF);
+        qemu_input_queue_rel(con, InputAxis_Y, y - 0x7FFF);
     } else {
         if (vs->last_x != -1) {
-            qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
-            qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
+            qemu_input_queue_rel(con, InputAxis_X, x - vs->last_x);
+            qemu_input_queue_rel(con, InputAxis_Y, y - vs->last_y);
         }
         vs->last_x = x;
         vs->last_y = y;
@@ -2458,7 +2458,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
     vnc_flush(vs);
 
     vnc_client_cache_auth(vs);
-    vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
+    vnc_qmp_event(vs, QAPIEvent_VNC_INITIALIZED);
 
     vnc_read_when(vs, protocol_client_msg, 1);
 
@@ -3008,7 +3008,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
     }
 
     vnc_client_cache_addr(vs);
-    vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
+    vnc_qmp_event(vs, QAPIEvent_VNC_CONNECTED);
     vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
 
     if (!vs->websocket) {
@@ -3524,7 +3524,7 @@ void vnc_display_open(const char *id, Error **errp)
         }
 
         if (strncmp(vnc, "unix:", 5) == 0) {
-            saddr->type = SOCKET_ADDRESS_KIND_UNIX;
+            saddr->type = SocketAddressKind_unix;
             saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
             saddr->u.q_unix->path = g_strdup(vnc + 5);
 
@@ -3534,7 +3534,7 @@ void vnc_display_open(const char *id, Error **errp)
             }
         } else {
             unsigned long long baseport;
-            saddr->type = SOCKET_ADDRESS_KIND_INET;
+            saddr->type = SocketAddressKind_inet;
             saddr->u.inet = g_new0(InetSocketAddress, 1);
             if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
                 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
@@ -3561,7 +3561,7 @@ void vnc_display_open(const char *id, Error **errp)
             saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
 
             if (vs->ws_enabled) {
-                wsaddr->type = SOCKET_ADDRESS_KIND_INET;
+                wsaddr->type = SocketAddressKind_inet;
                 wsaddr->u.inet = g_new0(InetSocketAddress, 1);
                 wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
                 wsaddr->u.inet->port = g_strdup(websocket);
@@ -3634,7 +3634,7 @@ void vnc_display_open(const char *id, Error **errp)
         }
         object_ref(OBJECT(vs->tlscreds));
 
-        if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
+        if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_server) {
             error_setg(errp,
                        "Expecting TLS credentials with a server endpoint");
             goto fail;
@@ -3770,7 +3770,7 @@ void vnc_display_open(const char *id, Error **errp)
         if (csock < 0) {
             goto fail;
         }
-        vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+        vs->is_unix = saddr->type == SocketAddressKind_unix;
         vnc_connect(vs, csock, false, false);
     } else {
         /* listen for connects */
@@ -3778,7 +3778,7 @@ void vnc_display_open(const char *id, Error **errp)
         if (vs->lsock < 0) {
             goto fail;
         }
-        vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+        vs->is_unix = saddr->type == SocketAddressKind_unix;
         if (vs->ws_enabled) {
             vs->lwebsock = socket_listen(wsaddr, errp);
             if (vs->lwebsock < 0) {
diff --git a/util/error.c b/util/error.c
index 8b86490..8631612 100644
--- a/util/error.c
+++ b/util/error.c
@@ -85,7 +85,7 @@ void error_setg_internal(Error **errp,
     va_list ap;
 
     va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
+    error_setv(errp, src, line, func, ErrorClass_GenericError, fmt, ap);
     va_end(ap);
 }
 
@@ -102,7 +102,7 @@ void error_setg_errno_internal(Error **errp,
     }
 
     va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
+    error_setv(errp, src, line, func, ErrorClass_GenericError, fmt, ap);
     va_end(ap);
 
     if (os_errno != 0) {
@@ -158,7 +158,7 @@ void error_setg_win32_internal(Error **errp,
     }
 
     va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
+    error_setv(errp, src, line, func, ErrorClass_GenericError, fmt, ap);
     va_end(ap);
 
     if (win32_err != 0) {
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 687fd34..932b81f 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -62,16 +62,16 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
 
         switch (desc[i].type) {
         case QEMU_OPT_STRING:
-            info->type = COMMAND_LINE_PARAMETER_TYPE_STRING;
+            info->type = CommandLineParameterType_string;
             break;
         case QEMU_OPT_BOOL:
-            info->type = COMMAND_LINE_PARAMETER_TYPE_BOOLEAN;
+            info->type = CommandLineParameterType_boolean;
             break;
         case QEMU_OPT_NUMBER:
-            info->type = COMMAND_LINE_PARAMETER_TYPE_NUMBER;
+            info->type = CommandLineParameterType_number;
             break;
         case QEMU_OPT_SIZE:
-            info->type = COMMAND_LINE_PARAMETER_TYPE_SIZE;
+            info->type = CommandLineParameterType_size;
             break;
         }
 
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index dfe4587..bd9de9b 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -107,11 +107,11 @@ static void inet_setport(struct addrinfo *e, int port)
 NetworkAddressFamily inet_netfamily(int family)
 {
     switch (family) {
-    case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
-    case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
-    case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
+    case PF_INET6: return NetworkAddressFamily_ipv6;
+    case PF_INET:  return NetworkAddressFamily_ipv4;
+    case PF_UNIX:  return NetworkAddressFamily_unix;
     }
-    return NETWORK_ADDRESS_FAMILY_UNKNOWN;
+    return NetworkAddressFamily_unknown;
 }
 
 int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
@@ -918,7 +918,7 @@ SocketAddress *socket_parse(const char *str, Error **errp)
             error_setg(errp, "invalid Unix socket address");
             goto fail;
         } else {
-            addr->type = SOCKET_ADDRESS_KIND_UNIX;
+            addr->type = SocketAddressKind_unix;
             addr->u.q_unix = g_new(UnixSocketAddress, 1);
             addr->u.q_unix->path = g_strdup(str + 5);
         }
@@ -927,12 +927,12 @@ SocketAddress *socket_parse(const char *str, Error **errp)
             error_setg(errp, "invalid file descriptor address");
             goto fail;
         } else {
-            addr->type = SOCKET_ADDRESS_KIND_FD;
+            addr->type = SocketAddressKind_fd;
             addr->u.fd = g_new(String, 1);
             addr->u.fd->str = g_strdup(str + 3);
         }
     } else {
-        addr->type = SOCKET_ADDRESS_KIND_INET;
+        addr->type = SocketAddressKind_inet;
         addr->u.inet = inet_parse(str, errp);
         if (addr->u.inet == NULL) {
             goto fail;
@@ -953,17 +953,17 @@ int socket_connect(SocketAddress *addr, Error **errp,
 
     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
     switch (addr->type) {
-    case SOCKET_ADDRESS_KIND_INET:
+    case SocketAddressKind_inet:
         inet_addr_to_opts(opts, addr->u.inet);
         fd = inet_connect_opts(opts, errp, callback, opaque);
         break;
 
-    case SOCKET_ADDRESS_KIND_UNIX:
+    case SocketAddressKind_unix:
         qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
         fd = unix_connect_opts(opts, errp, callback, opaque);
         break;
 
-    case SOCKET_ADDRESS_KIND_FD:
+    case SocketAddressKind_fd:
         fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
         if (fd >= 0 && callback) {
             qemu_set_nonblock(fd);
@@ -985,17 +985,17 @@ int socket_listen(SocketAddress *addr, Error **errp)
 
     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
     switch (addr->type) {
-    case SOCKET_ADDRESS_KIND_INET:
+    case SocketAddressKind_inet:
         inet_addr_to_opts(opts, addr->u.inet);
         fd = inet_listen_opts(opts, 0, errp);
         break;
 
-    case SOCKET_ADDRESS_KIND_UNIX:
+    case SocketAddressKind_unix:
         qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
         fd = unix_listen_opts(opts, errp);
         break;
 
-    case SOCKET_ADDRESS_KIND_FD:
+    case SocketAddressKind_fd:
         fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
         break;
 
@@ -1013,7 +1013,7 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
 
     opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
     switch (remote->type) {
-    case SOCKET_ADDRESS_KIND_INET:
+    case SocketAddressKind_inet:
         inet_addr_to_opts(opts, remote->u.inet);
         if (local) {
             qemu_opt_set(opts, "localaddr", local->u.inet->host, &error_abort);
@@ -1052,7 +1052,7 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
     }
 
     addr = g_new0(SocketAddress, 1);
-    addr->type = SOCKET_ADDRESS_KIND_INET;
+    addr->type = SocketAddressKind_inet;
     addr->u.inet = g_new0(InetSocketAddress, 1);
     addr->u.inet->host = g_strdup(host);
     addr->u.inet->port = g_strdup(serv);
@@ -1076,7 +1076,7 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
     struct sockaddr_un *su = (struct sockaddr_un *)sa;
 
     addr = g_new0(SocketAddress, 1);
-    addr->type = SOCKET_ADDRESS_KIND_UNIX;
+    addr->type = SocketAddressKind_unix;
     addr->u.q_unix = g_new0(UnixSocketAddress, 1);
     if (su->sun_path[0]) {
         addr->u.q_unix->path = g_strndup(su->sun_path,
diff --git a/vl.c b/vl.c
index f5f7c3f..3e90205 100644
--- a/vl.c
+++ b/vl.c
@@ -560,10 +560,10 @@ static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
 /***********************************************************/
 /* QEMU state */
 
-static RunState current_run_state = RUN_STATE_PRELAUNCH;
+static RunState current_run_state = RunState_prelaunch;
 
-/* We use RUN_STATE_MAX but any invalid value will do */
-static RunState vmstop_requested = RUN_STATE_MAX;
+/* We use RunState_MAX but any invalid value will do */
+static RunState vmstop_requested = RunState_MAX;
 static QemuMutex vmstop_lock;
 
 typedef struct {
@@ -573,71 +573,71 @@ typedef struct {
 
 static const RunStateTransition runstate_transitions_def[] = {
     /*     from      ->     to      */
-    { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
-    { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
+    { RunState_debug, RunState_running },
+    { RunState_debug, RunState_finish_migrate },
 
-    { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
-    { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
-    { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
-    { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
-    { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
+    { RunState_inmigrate, RunState_internal_error },
+    { RunState_inmigrate, RunState_io_error },
+    { RunState_inmigrate, RunState_paused },
+    { RunState_inmigrate, RunState_running },
+    { RunState_inmigrate, RunState_shutdown },
+    { RunState_inmigrate, RunState_suspended },
+    { RunState_inmigrate, RunState_watchdog },
+    { RunState_inmigrate, RunState_guest_panicked },
+    { RunState_inmigrate, RunState_finish_migrate },
 
-    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
-    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
+    { RunState_internal_error, RunState_paused },
+    { RunState_internal_error, RunState_finish_migrate },
 
-    { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
-    { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
+    { RunState_io_error, RunState_running },
+    { RunState_io_error, RunState_finish_migrate },
 
-    { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
-    { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+    { RunState_paused, RunState_running },
+    { RunState_paused, RunState_finish_migrate },
 
-    { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
+    { RunState_postmigrate, RunState_running },
+    { RunState_postmigrate, RunState_finish_migrate },
 
-    { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
-    { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
+    { RunState_prelaunch, RunState_running },
+    { RunState_prelaunch, RunState_finish_migrate },
+    { RunState_prelaunch, RunState_inmigrate },
 
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
+    { RunState_finish_migrate, RunState_running },
+    { RunState_finish_migrate, RunState_postmigrate },
 
-    { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
+    { RunState_restore_vm, RunState_running },
 
-    { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
-    { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
-    { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
-    { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
-    { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
-    { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
-    { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
-    { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
-    { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
+    { RunState_running, RunState_debug },
+    { RunState_running, RunState_internal_error },
+    { RunState_running, RunState_io_error },
+    { RunState_running, RunState_paused },
+    { RunState_running, RunState_finish_migrate },
+    { RunState_running, RunState_restore_vm },
+    { RunState_running, RunState_save_vm },
+    { RunState_running, RunState_shutdown },
+    { RunState_running, RunState_watchdog },
+    { RunState_running, RunState_guest_panicked },
 
-    { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
+    { RunState_save_vm, RunState_running },
 
-    { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
-    { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
+    { RunState_shutdown, RunState_paused },
+    { RunState_shutdown, RunState_finish_migrate },
 
-    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
-    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
-    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
-    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
+    { RunState_debug, RunState_suspended },
+    { RunState_running, RunState_suspended },
+    { RunState_suspended, RunState_running },
+    { RunState_suspended, RunState_finish_migrate },
 
-    { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
-    { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
+    { RunState_watchdog, RunState_running },
+    { RunState_watchdog, RunState_finish_migrate },
 
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
+    { RunState_guest_panicked, RunState_running },
+    { RunState_guest_panicked, RunState_finish_migrate },
 
-    { RUN_STATE_MAX, RUN_STATE_MAX },
+    { RunState_MAX, RunState_MAX },
 };
 
-static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX];
+static bool runstate_valid_transitions[RunState_MAX][RunState_MAX];
 
 bool runstate_check(RunState state)
 {
@@ -661,7 +661,7 @@ static void runstate_init(void)
     const RunStateTransition *p;
 
     memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
-    for (p = &runstate_transitions_def[0]; p->from != RUN_STATE_MAX; p++) {
+    for (p = &runstate_transitions_def[0]; p->from != RunState_MAX; p++) {
         runstate_valid_transitions[p->from][p->to] = true;
     }
 
@@ -671,7 +671,7 @@ static void runstate_init(void)
 /* This function will abort() on invalid state transitions */
 void runstate_set(RunState new_state)
 {
-    assert(new_state < RUN_STATE_MAX);
+    assert(new_state < RunState_MAX);
 
     if (!runstate_valid_transitions[current_run_state][new_state]) {
         fprintf(stderr, "ERROR: invalid runstate transition: '%s' -> '%s'\n",
@@ -685,13 +685,13 @@ void runstate_set(RunState new_state)
 
 int runstate_is_running(void)
 {
-    return runstate_check(RUN_STATE_RUNNING);
+    return runstate_check(RunState_running);
 }
 
 bool runstate_needs_reset(void)
 {
-    return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
-        runstate_check(RUN_STATE_SHUTDOWN);
+    return runstate_check(RunState_internal_error) ||
+        runstate_check(RunState_shutdown);
 }
 
 StatusInfo *qmp_query_status(Error **errp)
@@ -709,9 +709,9 @@ static bool qemu_vmstop_requested(RunState *r)
 {
     qemu_mutex_lock(&vmstop_lock);
     *r = vmstop_requested;
-    vmstop_requested = RUN_STATE_MAX;
+    vmstop_requested = RunState_MAX;
     qemu_mutex_unlock(&vmstop_lock);
-    return *r < RUN_STATE_MAX;
+    return *r < RunState_MAX;
 }
 
 void qemu_system_vmstop_request_prepare(void)
@@ -731,7 +731,7 @@ void vm_start(void)
     RunState requested;
 
     qemu_vmstop_requested(&requested);
-    if (runstate_is_running() && requested == RUN_STATE_MAX) {
+    if (runstate_is_running() && requested == RunState_MAX) {
         return;
     }
 
@@ -744,8 +744,8 @@ void vm_start(void)
         qapi_event_send_stop(&error_abort);
     } else {
         cpu_enable_ticks();
-        runstate_set(RUN_STATE_RUNNING);
-        vm_state_notify(1, RUN_STATE_RUNNING);
+        runstate_set(RunState_running);
+        vm_state_notify(1, RunState_running);
         resume_all_vcpus();
     }
 
@@ -1724,8 +1724,8 @@ void qemu_system_guest_panicked(void)
     if (current_cpu) {
         current_cpu->crash_occurred = true;
     }
-    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
-    vm_stop(RUN_STATE_GUEST_PANICKED);
+    qapi_event_send_guest_panicked(GuestPanicAction_pause, &error_abort);
+    vm_stop(RunState_guest_panicked);
 }
 
 void qemu_system_reset_request(void)
@@ -1743,13 +1743,13 @@ static void qemu_system_suspend(void)
 {
     pause_all_vcpus();
     notifier_list_notify(&suspend_notifiers, NULL);
-    runstate_set(RUN_STATE_SUSPENDED);
+    runstate_set(RunState_suspended);
     qapi_event_send_suspend(&error_abort);
 }
 
 void qemu_system_suspend_request(void)
 {
-    if (runstate_check(RUN_STATE_SUSPENDED)) {
+    if (runstate_check(RunState_suspended)) {
         return;
     }
     suspend_requested = 1;
@@ -1766,13 +1766,13 @@ void qemu_system_wakeup_request(WakeupReason reason)
 {
     trace_system_wakeup_request(reason);
 
-    if (!runstate_check(RUN_STATE_SUSPENDED)) {
+    if (!runstate_check(RunState_suspended)) {
         return;
     }
     if (!(wakeup_reason_mask & (1 << reason))) {
         return;
     }
-    runstate_set(RUN_STATE_RUNNING);
+    runstate_set(RunState_running);
     wakeup_reason = reason;
     qemu_notify_event();
 }
@@ -1834,7 +1834,7 @@ static bool main_loop_should_exit(void)
 {
     RunState r;
     if (qemu_debug_requested()) {
-        vm_stop(RUN_STATE_DEBUG);
+        vm_stop(RunState_debug);
     }
     if (qemu_suspend_requested()) {
         qemu_system_suspend();
@@ -1843,7 +1843,7 @@ static bool main_loop_should_exit(void)
         qemu_kill_report();
         qapi_event_send_shutdown(&error_abort);
         if (no_shutdown) {
-            vm_stop(RUN_STATE_SHUTDOWN);
+            vm_stop(RunState_shutdown);
         } else {
             return true;
         }
@@ -1854,7 +1854,7 @@ static bool main_loop_should_exit(void)
         qemu_system_reset(VMRESET_REPORT);
         resume_all_vcpus();
         if (runstate_needs_reset()) {
-            runstate_set(RUN_STATE_PAUSED);
+            runstate_set(RunState_paused);
         }
     }
     if (qemu_wakeup_requested()) {
@@ -3024,7 +3024,7 @@ int main(int argc, char **argv, char **envp)
     cpu_model = NULL;
     snapshot = 0;
     cyls = heads = secs = 0;
-    translation = BIOS_ATA_TRANSLATION_AUTO;
+    translation = BiosAtaTranslation_auto;
 
     nb_nics = 0;
 
@@ -3095,9 +3095,9 @@ int main(int argc, char **argv, char **envp)
                         snprintf(buf, sizeof(buf),
                                  "%s,cyls=%d,heads=%d,secs=%d%s",
                                  HD_OPTS , cyls, heads, secs,
-                                 translation == BIOS_ATA_TRANSLATION_LBA ?
+                                 translation == BiosAtaTranslation_lba ?
                                  ",trans=lba" :
-                                 translation == BIOS_ATA_TRANSLATION_NONE ?
+                                 translation == BiosAtaTranslation_none ?
                                  ",trans=none" : "");
                     drive_add(IF_DEFAULT, 0, optarg, buf);
                     break;
@@ -3155,15 +3155,15 @@ int main(int argc, char **argv, char **envp)
                     if (*p == ',') {
                         p++;
                         if (!strcmp(p, "large")) {
-                            translation = BIOS_ATA_TRANSLATION_LARGE;
+                            translation = BiosAtaTranslation_large;
                         } else if (!strcmp(p, "rechs")) {
-                            translation = BIOS_ATA_TRANSLATION_RECHS;
+                            translation = BiosAtaTranslation_rechs;
                         } else if (!strcmp(p, "none")) {
-                            translation = BIOS_ATA_TRANSLATION_NONE;
+                            translation = BiosAtaTranslation_none;
                         } else if (!strcmp(p, "lba")) {
-                            translation = BIOS_ATA_TRANSLATION_LBA;
+                            translation = BiosAtaTranslation_lba;
                         } else if (!strcmp(p, "auto")) {
-                            translation = BIOS_ATA_TRANSLATION_AUTO;
+                            translation = BiosAtaTranslation_auto;
                         } else {
                             goto chs_fail;
                         }
@@ -3179,16 +3179,16 @@ int main(int argc, char **argv, char **envp)
                                             &error_abort);
                         qemu_opt_set_number(hda_opts, "secs", secs,
                                             &error_abort);
-                        if (translation == BIOS_ATA_TRANSLATION_LARGE) {
+                        if (translation == BiosAtaTranslation_large) {
                             qemu_opt_set(hda_opts, "trans", "large",
                                          &error_abort);
-                        } else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
+                        } else if (translation == BiosAtaTranslation_rechs) {
                             qemu_opt_set(hda_opts, "trans", "rechs",
                                          &error_abort);
-                        } else if (translation == BIOS_ATA_TRANSLATION_LBA) {
+                        } else if (translation == BiosAtaTranslation_lba) {
                             qemu_opt_set(hda_opts, "trans", "lba",
                                          &error_abort);
-                        } else if (translation == BIOS_ATA_TRANSLATION_NONE) {
+                        } else if (translation == BiosAtaTranslation_none) {
                             qemu_opt_set(hda_opts, "trans", "none",
                                          &error_abort);
                         }
@@ -3851,7 +3851,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_incoming:
                 if (!incoming) {
-                    runstate_set(RUN_STATE_INMIGRATE);
+                    runstate_set(RunState_inmigrate);
                 }
                 incoming = optarg;
                 break;
diff --git a/xen-hvm.c b/xen-hvm.c
index 3d78a0c..7ae87ce 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -244,7 +244,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
     xen_pfn_t *pfn_list;
     int i;
 
-    if (runstate_check(RUN_STATE_INMIGRATE)) {
+    if (runstate_check(RunState_inmigrate)) {
         /* RAM already populated in Xen */
         fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
                 " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
@@ -1124,7 +1124,7 @@ static void xen_hvm_change_state_handler(void *opaque, int running,
 
     xen_set_ioreq_server_state(xen_xc, xen_domid,
                                state->ioservid,
-                               (rstate == RUN_STATE_RUNNING));
+                               (rstate == RunState_running));
 }
 
 static void xen_exit_notifier(Notifier *n, void *data)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 4/5] crypto: Drop name mangling override
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
                       ` (2 preceding siblings ...)
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
@ 2015-11-05 15:30     ` Markus Armbruster
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 5/5] Revert "qapi: allow override of default enum prefix naming" Markus Armbruster
  4 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

Commit a090187 used the name mangling override, because the QAPI name
'QCryptoTLSCredsEndpoint' would have generated enumeration constants
with the rather unsatisfactory Q_CRYPTOTLS_CREDS_ENDPOINT_CLIENT
prefix without it.  It now generates QCryptoTLSCredsEndpoint without
it, which is just fine.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 crypto/tlscredsanon.c            |  6 +++---
 crypto/tlscredsx509.c            |  6 +++---
 crypto/tlssession.c              |  6 +++---
 include/crypto/tlssession.h      |  2 +-
 qapi/crypto.json                 |  1 -
 tests/test-crypto-tlscredsx509.c |  6 +++---
 tests/test-crypto-tlssession.c   | 12 ++++++------
 ui/vnc-auth-vencrypt.c           |  2 +-
 ui/vnc-ws.c                      |  2 +-
 ui/vnc.c                         |  2 +-
 10 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c
index 3f03c70..84460ec 100644
--- a/crypto/tlscredsanon.c
+++ b/crypto/tlscredsanon.c
@@ -38,7 +38,7 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds,
     trace_qcrypto_tls_creds_anon_load(creds,
             creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>");
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+    if (creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_server) {
         if (qcrypto_tls_creds_get_path(&creds->parent_obj,
                                        QCRYPTO_TLS_CREDS_DH_PARAMS,
                                        false, &dhparams, errp) < 0) {
@@ -79,7 +79,7 @@ qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds,
 static void
 qcrypto_tls_creds_anon_unload(QCryptoTLSCredsAnon *creds)
 {
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_client) {
+    if (creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_client) {
         if (creds->data.client) {
             gnutls_anon_free_client_credentials(creds->data.client);
             creds->data.client = NULL;
@@ -141,7 +141,7 @@ qcrypto_tls_creds_anon_prop_get_loaded(Object *obj,
 {
     QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj);
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+    if (creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_server) {
         return creds->data.server != NULL;
     } else {
         return creds->data.client != NULL;
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index 9137da3..bf97524 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -549,7 +549,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
     trace_qcrypto_tls_creds_x509_load(creds,
             creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>");
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+    if (creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_server) {
         if (qcrypto_tls_creds_get_path(&creds->parent_obj,
                                        QCRYPTO_TLS_CREDS_X509_CA_CERT,
                                        true, &cacert, errp) < 0 ||
@@ -583,7 +583,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
 
     if (creds->sanityCheck &&
         qcrypto_tls_creds_x509_sanity_check(creds,
-            creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server,
+            creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_server,
             cacert, cert, errp) < 0) {
         goto cleanup;
     }
@@ -626,7 +626,7 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
         }
     }
 
-    if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+    if (creds->parent_obj.endpoint == QCryptoTLSCredsEndpoint_server) {
         if (qcrypto_tls_creds_get_dh_params_file(&creds->parent_obj, dhparams,
                                                  &creds->parent_obj.dh_params,
                                                  errp) < 0) {
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index bd0bac4..0c77f85 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -116,7 +116,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
         goto error;
     }
 
-    if (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+    if (endpoint == QCryptoTLSCredsEndpoint_server) {
         ret = gnutls_init(&session->handle, GNUTLS_SERVER);
     } else {
         ret = gnutls_init(&session->handle, GNUTLS_CLIENT);
@@ -138,7 +138,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
                        gnutls_strerror(ret));
             goto error;
         }
-        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+        if (creds->endpoint == QCryptoTLSCredsEndpoint_server) {
             ret = gnutls_credentials_set(session->handle,
                                          GNUTLS_CRD_ANON,
                                          acreds->data.server);
@@ -171,7 +171,7 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
             goto error;
         }
 
-        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+        if (creds->endpoint == QCryptoTLSCredsEndpoint_server) {
             /* This requests, but does not enforce a client cert.
              * The cert checking code later does enforcement */
             gnutls_certificate_server_set_request(session->handle,
diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
index 1d9c7aa..411e8e0 100644
--- a/include/crypto/tlssession.h
+++ b/include/crypto/tlssession.h
@@ -63,7 +63,7 @@
  *    sess = qcrypto_tls_session_new(creds,
  *                                   "vnc.example.com",
  *                                   NULL,
- *                                   QCRYPTO_TLS_CREDS_ENDPOINT_client,
+ *                                   QCryptoTLSCredsEndpoint_client,
  *                                   errp);
  *    if (sess == NULL) {
  *       return -1;
diff --git a/qapi/crypto.json b/qapi/crypto.json
index b058b14..34c1422 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -17,5 +17,4 @@
 # Since: 2.5
 ##
 { 'enum': 'QCryptoTLSCredsEndpoint',
-  'prefix': 'QCRYPTO_TLS_CREDS_ENDPOINT',
   'data': ['client', 'server']}
diff --git a/tests/test-crypto-tlscredsx509.c b/tests/test-crypto-tlscredsx509.c
index a1e2d51..b97650c 100644
--- a/tests/test-crypto-tlscredsx509.c
+++ b/tests/test-crypto-tlscredsx509.c
@@ -48,7 +48,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
         parent,
         "testtlscreds",
         errp,
-        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
+        "endpoint", (endpoint == QCryptoTLSCredsEndpoint_server ?
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
@@ -111,8 +111,8 @@ static void test_tls_creds(const void *opaque)
 
     creds = test_tls_creds_create(
         (data->isServer ?
-         QCRYPTO_TLS_CREDS_ENDPOINT_server :
-         QCRYPTO_TLS_CREDS_ENDPOINT_client),
+         QCryptoTLSCredsEndpoint_server :
+         QCryptoTLSCredsEndpoint_client),
         CERT_DIR,
         &err);
 
diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c
index 4620086..ce0a146 100644
--- a/tests/test-crypto-tlssession.c
+++ b/tests/test-crypto-tlssession.c
@@ -69,10 +69,10 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
     Object *creds = object_new_with_props(
         TYPE_QCRYPTO_TLS_CREDS_X509,
         parent,
-        (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
+        (endpoint == QCryptoTLSCredsEndpoint_server ?
          "testtlscredsserver" : "testtlscredsclient"),
         &err,
-        "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_server ?
+        "endpoint", (endpoint == QCryptoTLSCredsEndpoint_server ?
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
@@ -160,13 +160,13 @@ static void test_crypto_tls_session(const void *opaque)
                   CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY) == 0);
 
     clientCreds = test_tls_creds_create(
-        QCRYPTO_TLS_CREDS_ENDPOINT_client,
+        QCryptoTLSCredsEndpoint_client,
         CLIENT_CERT_DIR,
         &err);
     g_assert(clientCreds != NULL);
 
     serverCreds = test_tls_creds_create(
-        QCRYPTO_TLS_CREDS_ENDPOINT_server,
+        QCryptoTLSCredsEndpoint_server,
         SERVER_CERT_DIR,
         &err);
     g_assert(serverCreds != NULL);
@@ -182,11 +182,11 @@ static void test_crypto_tls_session(const void *opaque)
     /* Now the real part of the test, setup the sessions */
     clientSess = qcrypto_tls_session_new(
         clientCreds, data->hostname, NULL,
-        QCRYPTO_TLS_CREDS_ENDPOINT_client, &err);
+        QCryptoTLSCredsEndpoint_client, &err);
     serverSess = qcrypto_tls_session_new(
         serverCreds, NULL,
         data->wildcards ? "tlssessionacl" : NULL,
-        QCRYPTO_TLS_CREDS_ENDPOINT_server, &err);
+        QCryptoTLSCredsEndpoint_server, &err);
 
     g_assert(clientSess != NULL);
     g_assert(serverSess != NULL);
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index 201cfc9..f2593da 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -132,7 +132,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
         vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds,
                                           NULL,
                                           vs->vd->tlsaclname,
-                                          QCRYPTO_TLS_CREDS_ENDPOINT_server,
+                                          QCryptoTLSCredsEndpoint_server,
                                           &err);
         if (!vs->tls) {
             VNC_DEBUG("Failed to setup TLS %s\n",
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index 3804b73..fab39c7 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -68,7 +68,7 @@ void vncws_tls_handshake_io(void *opaque)
     vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds,
                                       NULL,
                                       vs->vd->tlsaclname,
-                                      QCRYPTO_TLS_CREDS_ENDPOINT_server,
+                                      QCryptoTLSCredsEndpoint_server,
                                       &err);
     if (!vs->tls) {
         VNC_DEBUG("Failed to setup TLS %s\n",
diff --git a/ui/vnc.c b/ui/vnc.c
index 0cd19f6..711f664 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3634,7 +3634,7 @@ void vnc_display_open(const char *id, Error **errp)
         }
         object_ref(OBJECT(vs->tlscreds));
 
-        if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_server) {
+        if (vs->tlscreds->endpoint != QCryptoTLSCredsEndpoint_server) {
             error_setg(errp,
                        "Expecting TLS credentials with a server endpoint");
             goto fail;
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* [Qemu-devel] [PATCH RFC 5/5] Revert "qapi: allow override of default enum prefix naming"
  2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
                       ` (3 preceding siblings ...)
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 4/5] crypto: Drop name mangling override Markus Armbruster
@ 2015-11-05 15:30     ` Markus Armbruster
  4 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 15:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth

This reverts commit 351d36e454cddc67a1675740916636a7ccbf1c4b.

The previous commit removed the feature's lone user.  The common name
mangling should do going forward.

Conflicts:
	docs/qapi-code-gen.txt
	scripts/qapi-types.py
	scripts/qapi.py
	tests/Makefile
	tests/qapi-schema/qapi-schema-test.out

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 docs/qapi-code-gen.txt                  |  9 --------
 scripts/qapi-introspect.py              |  2 +-
 scripts/qapi-types.py                   |  6 +++---
 scripts/qapi-visit.py                   |  2 +-
 scripts/qapi.py                         | 37 ++++++++++++---------------------
 tests/Makefile                          |  1 -
 tests/qapi-schema/enum-bad-prefix.err   |  1 -
 tests/qapi-schema/enum-bad-prefix.exit  |  1 -
 tests/qapi-schema/enum-bad-prefix.json  |  2 --
 tests/qapi-schema/enum-bad-prefix.out   |  0
 tests/qapi-schema/qapi-schema-test.json |  5 -----
 tests/qapi-schema/qapi-schema-test.out  |  2 --
 tests/qapi-schema/test-qapi.py          |  4 +---
 13 files changed, 19 insertions(+), 53 deletions(-)
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.err
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.exit
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.json
 delete mode 100644 tests/qapi-schema/enum-bad-prefix.out

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 24ab324..01b52de 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -245,7 +245,6 @@ both fields like this:
 === Enumeration types ===
 
 Usage: { 'enum': STRING, 'data': ARRAY-OF-STRING }
-       { 'enum': STRING, '*prefix': STRING, 'data': ARRAY-OF-STRING }
 
 An enumeration type is a dictionary containing a single 'data' key
 whose value is a list of strings.  An example enumeration is:
@@ -257,14 +256,6 @@ useful.  The list of strings should be lower case; if an enum name
 represents multiple words, use '-' between words.  The string 'max' is
 not allowed as an enum value, and values should not be repeated.
 
-FIXME obsolete, rewrite
-The enum constants will be named by using a heuristic to turn the
-type name into a set of underscore separated words. For the example
-above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name
-of 'MY_ENUM_VALUE1' for the first value. If the default heuristic
-does not result in a desirable name, the optional 'prefix' field
-can be used when defining the enum.
-
 The enumeration values are passed as strings over the Client JSON
 Protocol, but are encoded as C enum integral values in generated code.
 While the C code starts numbering at 0, it is better to use explicit
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 64f2cd0..f693c49 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -134,7 +134,7 @@ const char %(c_name)s[] = %(c_string)s;
     def visit_builtin_type(self, name, info, json_type):
         self._gen_json(name, 'builtin', {'json-type': json_type})
 
-    def visit_enum_type(self, name, info, values, prefix):
+    def visit_enum_type(self, name, info, values):
         self._gen_json(name, 'enum', {'values': values})
 
     def visit_array_type(self, name, info, element_type):
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2f2f7df..247ea4f 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -232,9 +232,9 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
         self.decl += gen_type_cleanup_decl(name)
         self.defn += gen_type_cleanup(name)
 
-    def visit_enum_type(self, name, info, values, prefix):
-        self._fwdecl += gen_enum(name, values, prefix)
-        self._fwdefn += gen_enum_lookup(name, values, prefix)
+    def visit_enum_type(self, name, info, values):
+        self._fwdecl += gen_enum(name, values)
+        self._fwdefn += gen_enum_lookup(name, values)
 
     def visit_array_type(self, name, info, element_type):
         if isinstance(element_type, QAPISchemaBuiltinType):
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 94cd113..a8b3cd7 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -346,7 +346,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
         return not (entity.is_implicit() and
                     isinstance(entity, QAPISchemaObjectType))
 
-    def visit_enum_type(self, name, info, values, prefix):
+    def visit_enum_type(self, name, info, values):
         self.decl += gen_visit_decl(name, scalar=True)
         self.defn += gen_visit_enum(name)
 
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8e935d7..e761e33 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -666,15 +666,11 @@ def check_alternate(expr, expr_info):
 def check_enum(expr, expr_info):
     name = expr['enum']
     members = expr.get('data')
-    prefix = expr.get('prefix')
     values = {'MAX': '(automatic)'}
 
     if not isinstance(members, list):
         raise QAPIExprError(expr_info,
                             "Enum '%s' requires an array for 'data'" % name)
-    if prefix is not None and not isinstance(prefix, str):
-        raise QAPIExprError(expr_info,
-                            "Enum '%s' requires a string for 'prefix'" % name)
     for member in members:
         check_name(expr_info, "Member of enum '%s'" % name, member,
                    enum_member=True)
@@ -732,7 +728,7 @@ def check_exprs(exprs):
         expr = expr_elem['expr']
         info = expr_elem['info']
         if 'enum' in expr:
-            check_keys(expr_elem, 'enum', ['data'], ['prefix'])
+            check_keys(expr_elem, 'enum', ['data'])
             add_enum(expr['enum'], info, expr['data'])
         elif 'union' in expr:
             check_keys(expr_elem, 'union', ['data'],
@@ -831,7 +827,7 @@ class QAPISchemaVisitor(object):
     def visit_builtin_type(self, name, info, json_type):
         pass
 
-    def visit_enum_type(self, name, info, values, prefix):
+    def visit_enum_type(self, name, info, values):
         pass
 
     def visit_array_type(self, name, info, element_type):
@@ -904,13 +900,11 @@ class QAPISchemaBuiltinType(QAPISchemaType):
 
 
 class QAPISchemaEnumType(QAPISchemaType):
-    def __init__(self, name, info, values, prefix):
+    def __init__(self, name, info, values):
         QAPISchemaType.__init__(self, name, info)
         for v in values:
             assert isinstance(v, str)
-        assert prefix is None or isinstance(prefix, str)
         self.values = values
-        self.prefix = prefix
 
     def check(self, schema):
         assert len(set(self.values)) == len(self.values)
@@ -923,15 +917,13 @@ class QAPISchemaEnumType(QAPISchemaType):
         return c_name(self.name)
 
     def c_null(self):
-        return c_enum_const(self.name, (self.values + ['MAX'])[0],
-                            self.prefix)
+        return c_enum_const(self.name, (self.values + ['MAX'])[0])
 
     def json_type(self):
         return 'string'
 
     def visit(self, visitor):
-        visitor.visit_enum_type(self.name, self.info,
-                                self.values, self.prefix)
+        visitor.visit_enum_type(self.name, self.info, self.values)
 
 
 class QAPISchemaArrayType(QAPISchemaType):
@@ -1209,7 +1201,7 @@ class QAPISchema(object):
 
     def _make_implicit_enum_type(self, name, info, values):
         name = name + 'Kind'   # Use namespace reserved by add_name()
-        self._def_entity(QAPISchemaEnumType(name, info, values, None))
+        self._def_entity(QAPISchemaEnumType(name, info, values))
         return name
 
     def _make_array_type(self, element_type, info):
@@ -1230,8 +1222,7 @@ class QAPISchema(object):
     def _def_enum_type(self, expr, info):
         name = expr['enum']
         data = expr['data']
-        prefix = expr.get('prefix')
-        self._def_entity(QAPISchemaEnumType(name, info, data, prefix))
+        self._def_entity(QAPISchemaEnumType(name, info, data))
 
     def _make_member(self, name, typ, info):
         optional = False
@@ -1362,9 +1353,7 @@ class QAPISchema(object):
 # Code generation helpers
 #
 
-def c_enum_const(type_name, const_name, prefix=None):
-    if prefix is not None:
-        type_name = prefix
+def c_enum_const(type_name, const_name):
     return c_name(type_name + '_' + const_name)
 
 c_name_trans = string.maketrans('.-', '__')
@@ -1477,20 +1466,20 @@ def guardend(name):
                  name=guardname(name))
 
 
-def gen_enum_lookup(name, values, prefix=None):
+def gen_enum_lookup(name, values):
     ret = mcgen('''
 
 const char *const %(c_name)s_lookup[] = {
 ''',
                 c_name=c_name(name))
     for value in values:
-        index = c_enum_const(name, value, prefix)
+        index = c_enum_const(name, value)
         ret += mcgen('''
     [%(index)s] = "%(value)s",
 ''',
                      index=index, value=value)
 
-    max_index = c_enum_const(name, 'MAX', prefix)
+    max_index = c_enum_const(name, 'MAX')
     ret += mcgen('''
     [%(max_index)s] = NULL,
 };
@@ -1499,7 +1488,7 @@ const char *const %(c_name)s_lookup[] = {
     return ret
 
 
-def gen_enum(name, values, prefix=None):
+def gen_enum(name, values):
     # append automatically generated _MAX value
     enum_values = values + ['MAX']
 
@@ -1514,7 +1503,7 @@ typedef enum %(c_name)s {
         ret += mcgen('''
     %(c_enum)s = %(i)d,
 ''',
-                     c_enum=c_enum_const(name, value, prefix),
+                     c_enum=c_enum_const(name, value),
                      i=i)
         i += 1
 
diff --git a/tests/Makefile b/tests/Makefile
index 92969e8..1c8c8bf 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -259,7 +259,6 @@ qapi-schema += double-type.json
 qapi-schema += duplicate-key.json
 qapi-schema += empty.json
 qapi-schema += enum-bad-name.json
-qapi-schema += enum-bad-prefix.json
 qapi-schema += enum-clash-member.json
 qapi-schema += enum-dict-member.json
 qapi-schema += enum-int-member.json
diff --git a/tests/qapi-schema/enum-bad-prefix.err b/tests/qapi-schema/enum-bad-prefix.err
deleted file mode 100644
index 399f5f7..0000000
--- a/tests/qapi-schema/enum-bad-prefix.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/enum-bad-prefix.json:2: Enum 'MyEnum' requires a string for 'prefix'
diff --git a/tests/qapi-schema/enum-bad-prefix.exit b/tests/qapi-schema/enum-bad-prefix.exit
deleted file mode 100644
index d00491f..0000000
--- a/tests/qapi-schema/enum-bad-prefix.exit
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/enum-bad-prefix.json b/tests/qapi-schema/enum-bad-prefix.json
deleted file mode 100644
index 996f628..0000000
--- a/tests/qapi-schema/enum-bad-prefix.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# The prefix must be a string type
-{ 'enum': 'MyEnum', 'data': [ 'one' ], 'prefix': [ 'fish' ] }
diff --git a/tests/qapi-schema/enum-bad-prefix.out b/tests/qapi-schema/enum-bad-prefix.out
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 44638da..3b53b6a 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -18,11 +18,6 @@
 { 'struct': 'Empty1', 'data': { } }
 { 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
 
-# for testing override of default naming heuristic
-{ 'enum': 'QEnumTwo',
-  'prefix': 'QENUM_TWO',
-  'data': [ 'value1', 'value2' ] }
-
 # for testing nested structs
 { 'struct': 'UserDefOne',
   'base': 'UserDefZero',        # intentional forward reference
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 786024e..41e87dd 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -99,8 +99,6 @@ object NestedEnumsOne
     member enum2: EnumOne optional=True
     member enum3: EnumOne optional=False
     member enum4: EnumOne optional=True
-enum QEnumTwo ['value1', 'value2']
-    prefix QENUM_TWO
 object TestStruct
     member integer: int optional=False
     member boolean: bool optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 649677e..4602da7 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -17,10 +17,8 @@ import sys
 
 
 class QAPISchemaTestVisitor(QAPISchemaVisitor):
-    def visit_enum_type(self, name, info, values, prefix):
+    def visit_enum_type(self, name, info, values):
         print 'enum %s %s' % (name, values)
-        if prefix:
-            print '    prefix %s' % prefix
 
     def visit_object_type(self, name, info, base, members, variants):
         print 'object %s' % name
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
@ 2015-11-05 16:01       ` Daniel P. Berrange
  2015-11-05 16:41         ` Eric Blake
  2015-11-09  9:34         ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
  0 siblings, 2 replies; 75+ messages in thread
From: Daniel P. Berrange @ 2015-11-05 16:01 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, mdroth

On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
> QAPI names needn't be valid C identifiers, so we mangle them with
> c_name().  Except for enumeration constants, which we mangle with
> camel_to_upper().
> 
> c_name() is easy enough to understand: replace '.' and '-' by '_',
> prefix certain ticklish identifiers with 'q_'.
> 
> camel_to_upper() is a hairball of heuristics, and guessing how it'll
> mangle interesting input could serve as a (nerdy) game.  Despite some
> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
> (commit 351d36e).
> 
> Example: QAPI definition
> 
>     { 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }
> 
> generates
> 
>     typedef enum BlockDeviceIoStatus {
>         BLOCK_DEVICE_IO_STATUS_OK = 0,
>         BLOCK_DEVICE_IO_STATUS_FAILED = 1,
>         BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
>         BLOCK_DEVICE_IO_STATUS_MAX = 3,
>     } BlockDeviceIoStatus;
> 
> Observe that c_name() maps BlockDeviceIoStatus to itself, and
> camel_to_upper() maps it to BLOCK_DEVICE_IO_STATUS, i.e. the
> enumeration constants are shouted, the enumeration type isn't.
> 
> Because mangled names must not clash, name mangling restricts the
> names you can use.  For example, you can't have member 'a-b' and
> 'a_b'.
> 
> Having two separate manglings complicates this.  Enumeration constants
> must be distinct after mangling with camel_to_upper().  But as soon as
> you use the enumeration as union tag, they must *also* be distinct
> after mangling with c_name().
> 
> Having shouted enumeration constants isn't worth the complexity cost.

I rather disagree with this. Having all-uppercase for enum constants
is a really widely used convention and I think it is pretty useful
when reading to code to have constants (whether #define/enum) clearly
marked in uppercase.  After this change we'll have situation where
QAPI enums uses CamelCase, while all other non-QAPI enums (whether
defined in QEMU source, or via #included 3rd party headers use
UPPER_CASE for constants. I think that's rather unpleasant.


I agree with your premise that predicting the output of the qapi
name mangler though is essentially impossible for mortals. How
about a counter proposal....

First make 'prefix' compulsory for enums, instead of trying to
figure out a suitable prefix automatically. Then, have a very
simple rule for the enum constants where you just uppercase a-z
and translate any non-alpha-numeric character into a _. Don't
try todo anything else special like figuring out word boundaries.

That would get of much of the complexity in the qapi name mangler
and give a easily predictable enum constant name. Thus the vast
majority of .c source files (possibly even all of them) would not
need any change.


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 16:01       ` Daniel P. Berrange
@ 2015-11-05 16:41         ` Eric Blake
  2015-11-05 22:36           ` Eric Blake
  2015-11-06 10:03           ` Markus Armbruster
  2015-11-09  9:34         ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
  1 sibling, 2 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-05 16:41 UTC (permalink / raw)
  To: Daniel P. Berrange, Markus Armbruster; +Cc: qemu-devel, mdroth

[-- Attachment #1: Type: text/plain, Size: 4949 bytes --]

On 11/05/2015 09:01 AM, Daniel P. Berrange wrote:
> On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
>> QAPI names needn't be valid C identifiers, so we mangle them with
>> c_name().  Except for enumeration constants, which we mangle with
>> camel_to_upper().
>>
>> c_name() is easy enough to understand: replace '.' and '-' by '_',
>> prefix certain ticklish identifiers with 'q_'.
>>
>> camel_to_upper() is a hairball of heuristics, and guessing how it'll
>> mangle interesting input could serve as a (nerdy) game.  Despite some
>> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
>> (commit 351d36e).

One of the issues at hand is whether we want to (eventually) teach QMP
to be case-insensitive.  Right now, our c_name() mangling preserves case
(you can have a struct with members 'a' and 'A'), although (hopefully)
no one is relying on it.  But camel_to_upper() is case-insensitive ('a'
and 'A' would result in the same enum constant).

In order to (later) support case-insensitive QMP, we need to decide up
front that we will not allow any qapi member names to collide
case-insensitively (outlaw 'a' and 'A' in the same struct; although the
C code is still case-preserving); and now that this series is adding a
single check_clash() function, it's very easy to do.  In fact, I'll add
that to my series for 2.5 (it's always easier to reserve something now,
especially if no one was using it, and then relax later; than it is to
try and restrict things later but run into counter-cases).

>>
>> Having two separate manglings complicates this.  Enumeration constants
>> must be distinct after mangling with camel_to_upper().  But as soon as
>> you use the enumeration as union tag, they must *also* be distinct
>> after mangling with c_name().

But this should already be the case - can you come up with a pair of
valid enum values that won't clash under camel_to_upper() but would
result in in a c_name() value collision?  The converse is not true -
there ARE pairs of c_name() values that are distinct, but which map to
the same mangling with camel_to_upper().  But if we insist that names do
not collide case-insensitively, then that issue goes away - having
ALL_CAP enum constants won't cause any collisions even when those
constants are derived from member names, because member names are
already forbidden from case-insensitive clash.

There is still the question of whether we can get rid of the spurious
collision with 'max', by putting the enum sentinel out of the namespace
generated for other values.  But even with ALL_CAPS, that is possible:

        BLOCK_DEVICE_IO_STATUS_OK = 0,
        BLOCK_DEVICE_IO_STATUS_FAILED = 1,
        BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
        BLOCK_DEVICE_IO_STATUSMAX = 3,

Or insist that no enum value can start with a lone _ (double __ is okay
for downstream extensions, though):

        BLOCK_DEVICE_IO_STATUS_OK = 0,
        BLOCK_DEVICE_IO_STATUS_FAILED = 1,
        BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
        BLOCK_DEVICE_IO_STATUS__MAX = 3,


>>
>> Having shouted enumeration constants isn't worth the complexity cost.
> 
> I rather disagree with this. Having all-uppercase for enum constants
> is a really widely used convention and I think it is pretty useful
> when reading to code to have constants (whether #define/enum) clearly
> marked in uppercase.  After this change we'll have situation where
> QAPI enums uses CamelCase, while all other non-QAPI enums (whether
> defined in QEMU source, or via #included 3rd party headers use
> UPPER_CASE for constants. I think that's rather unpleasant.
> 
> 
> I agree with your premise that predicting the output of the qapi
> name mangler though is essentially impossible for mortals. How
> about a counter proposal....
> 
> First make 'prefix' compulsory for enums, instead of trying to
> figure out a suitable prefix automatically. Then, have a very
> simple rule for the enum constants where you just uppercase a-z
> and translate any non-alpha-numeric character into a _. Don't
> try todo anything else special like figuring out word boundaries.

Basically, prefix + '_' + c_name(value).to_upper().

Auto-generating prefix via heuristics may still be okay, but what we
want to gain is that the suffix portion is easily predictable if we know
the c_name() mangling of the enum identifer.

> 
> That would get of much of the complexity in the qapi name mangler
> and give a easily predictable enum constant name. Thus the vast
> majority of .c source files (possibly even all of them) would not
> need any change.

I also feel like this RFC is bordering on feature rather than bugfix,
making it risky to take in 2.5 softfreeze.  If we decide we want this, I
think it belongs better in 2.6.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types Eric Blake
@ 2015-11-05 17:01   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 17:01 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Previously, working with alternates required two lookup arrays
> and some indirection: for type Foo, we created Foo_qtypes[]
> which maps each qtype to a value of the generated FooKind enum,
> then look up that value in FooKind_lookup[] like we do for other
> union types.
>
> This has a couple of subtle bugs.  First, the generator was
> creating a call with a parameter '(int *) &(*obj)->type' where
> type is an enum type; this is unsafe if the compiler chooses
> to store the enum type in a different size than int, where
> assigning through the wrong size pointer can corrupt data or
> cause a SIGBUS.
>
> Second, since the values of the FooKind enum start at zero, all
> entries of the Foo_qtypes[] array that were not explicitly
> initialized will map to the same branch of the union as the
> first member of the alternate, rather than triggering a desired
> failure in visit_get_next_type().  Fortunately, the bug seldom
> bites; the very next thing the input visitor does is try to
> parse the incoming JSON with the wrong parser, which normally
> fails; the output visitor is not used with a C struct in that
> state, and the dealloc visitor has nothing to clean up (so
> there is no leak).
>
> However, the second bug IS observable in one case: the behavior
> of an alternate that contains a 'number' member but no 'int'
> member differs according to whether the 'number' was first in
> the qapi definition,

This is confusing.  If there is a 'number' but no 'int', and the 'number
is first, what's second?

>                      and when the input being parsed is an
> integer; this is because the 'number' parser accepts QTYPE_QINT
> in addition to the expected QTYPE_QFLOAT.  A later patch will
> worry about fixing alternates to parse all inputs that a
> non-alternate 'number' would accept, for now this is still
> marked FIXME, and the test merely updated to point out that

and tests/test-qmp-input-visitor.c merely updated

> new undesired behavior of 'ans' matches the existing undesired
> behavior of 'asn'.
>
> This patch fixes the validation bug by deleting the indirection,

What's the validation bug?  I guess it's the one involving
default-initialized FooKind_lookup[].

> and modifying get_next_type() to directly assign a qtype_code
> parameter.  This in turn fixes the type-casting bug, as we are
> no longer casting a pointer to enum to a questionable size.
> There is no longer a need to generate an implicit FooKind enum
> associated with the alternate type (since the QMP wire format
> never uses the stringized counterparts of the C union member
> names); that also means we no longer have a collision with an
> alternate branch named 'max'.  Since visit_get_next_type() does
> not know which qtypes are expected, the generated visitor is
> modified to generate an error statement if an unexpected type
> is encountered.
>
> The code relies on a new QAPISchemaAlternateTypeTag subclass
> and the use of a new member.c_type() method for generating
> qapi-types.h; this is because we don't want to expose
> 'qtype_code' as a built-in type usable from .json files.

I'd be totally cool with that, actually.

> The new subtype happens to work by keeping tag_member.type
> as None, although this feels a bit unclean, and may be touched
> up further in a later patch.

I hate special cases like this one.

> Callers now have to know the QTYPE_* mapping when looking at the
> discriminator; but so far, only the testsuite was even using the
> C struct of an alternate types.  I considered the possibility of
> keeping the internal enum FooKind, but initialized differently
> than most generated arrays, as in:
>   typedef enum FooKind {
>       FOO_KIND_A = QTYPE_QDICT,
>       FOO_KIND_B = QTYPE_QINT,
>   } FooKind;
> to create nicer aliases for knowing when to use foo->a or foo->b
> when inspecting foo->type; but it turned out to add too much
> complexity, especially without a client.

Having to use QTYPE_FOOs seems good enough.

> There is a user-visible side effect to this change, but I
> consider it to be an improvement. Previously,
> the invalid QMP command:
>   {"execute":"blockdev-add", "arguments":{"options":
>     {"driver":"raw", "id":"a", "file":true}}}
> failed with:
>   {"error": {"class": "GenericError",
>     "desc": "Invalid parameter type for 'file', expected: QDict"}}
> (visit_get_next_type() succeeded, and the error comes from the
> visit_type_BlockdevOptions() expecting {}; there is no mention of
> the fact that a string would also work).  Now it fails with:
>   {"error": {"class": "GenericError",
>     "desc": "Invalid parameter type for 'file', expected: BlockdevRef"}}
> (the error when the next type doesn't match any expected types for
> the overall alternate).
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: rebase to earlier changes, rework commit message to mention second
> bug fix; move positive test in qapi-schema-test to later patch
> v8: no change
> v7: rebase onto earlier changes, rework how subtype makes things work
> v6: rebase onto tag_member subclass, testsuite, gen_err_check(),
> and info improvements
> ---
>  docs/qapi-code-gen.txt                 |  3 ---
>  include/qapi/visitor-impl.h            |  3 ++-
>  include/qapi/visitor.h                 |  8 ++++++-
>  qapi/qapi-visit-core.c                 |  4 ++--
>  qapi/qmp-input-visitor.c               |  4 ++--
>  scripts/qapi-types.py                  | 36 +---------------------------
>  scripts/qapi-visit.py                  | 14 +++++++----
>  scripts/qapi.py                        | 44 +++++++++++++++++++++++++---------
>  tests/qapi-schema/alternate-empty.out  |  1 -
>  tests/qapi-schema/qapi-schema-test.out |  8 -------
>  tests/test-qmp-input-visitor.c         | 31 ++++++++++++------------
>  tests/test-qmp-output-visitor.c        |  4 ++--
>  12 files changed, 74 insertions(+), 86 deletions(-)
>
> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
> index 20e6907..9196e5c 100644
> --- a/docs/qapi-code-gen.txt
> +++ b/docs/qapi-code-gen.txt
> @@ -383,9 +383,6 @@ where each branch of the union names a QAPI type.  For example:
>     'data': { 'definition': 'BlockdevOptions',
>               'reference': 'str' } }
>
> -Just like for a simple union, an implicit C enum 'NameKind' is created
> -to enumerate the branches for the alternate 'Name'.
> -
>  Unlike a union, the discriminator string is never passed on the wire
>  for the Client JSON Protocol.  Instead, the value's JSON type serves
>  as an implicit discriminator, which in turn means that an alternate
> diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
> index 8c0ba57..6d95b36 100644
> --- a/include/qapi/visitor-impl.h
> +++ b/include/qapi/visitor-impl.h
> @@ -32,7 +32,8 @@ struct Visitor
>
>      void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
>                        const char *kind, const char *name, Error **errp);
> -    void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
> +    /* May be NULL; most useful for input visitors. */
> +    void (*get_next_type)(Visitor *v, qtype_code *type,
>                            const char *name, Error **errp);
>
>      void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
> diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
> index cfc19a6..b765993 100644
> --- a/include/qapi/visitor.h
> +++ b/include/qapi/visitor.h
> @@ -41,7 +41,13 @@ GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
>  void visit_end_list(Visitor *v, Error **errp);
>  void visit_optional(Visitor *v, bool *present, const char *name,
>                      Error **errp);
> -void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
> +
> +/**
> + * Determine the qtype of the item @name in the current object visit.
> + * For input visitors, set *@type to the correct qtype of a qapi
> + * alternate type; for other visitors, leave *@type unchanged.

Aside: I can't think of a reason for an output visitor to implement this
method.

> + */
> +void visit_get_next_type(Visitor *v, qtype_code *type,
>                           const char *name, Error **errp);
>  void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
>                       const char *kind, const char *name, Error **errp);
> diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
> index 59ed506..3f24daa 100644
> --- a/qapi/qapi-visit-core.c
> +++ b/qapi/qapi-visit-core.c
> @@ -81,11 +81,11 @@ void visit_optional(Visitor *v, bool *present, const char *name,
>      }
>  }
>
> -void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
> +void visit_get_next_type(Visitor *v, qtype_code *type,
>                           const char *name, Error **errp)
>  {
>      if (v->get_next_type) {
> -        v->get_next_type(v, obj, qtypes, name, errp);
> +        v->get_next_type(v, type, name, errp);
>      }
>  }
>
> diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
> index eb6e110..c1e7ec8 100644
> --- a/qapi/qmp-input-visitor.c
> +++ b/qapi/qmp-input-visitor.c
> @@ -208,7 +208,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp)
>      qmp_input_pop(qiv, errp);
>  }
>
> -static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
> +static void qmp_input_get_next_type(Visitor *v, qtype_code *type,
>                                      const char *name, Error **errp)
>  {
>      QmpInputVisitor *qiv = to_qiv(v);
> @@ -218,7 +218,7 @@ static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
>          error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
>          return;
>      }
> -    *kind = qobjects[qobject_type(qobj)];
> +    *type = qobject_type(qobj);
>  }
>
>  static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 2f2f7df..2ac1405 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -47,7 +47,7 @@ def gen_struct_fields(members):
>          ret += mcgen('''
>      %(c_type)s %(c_name)s;
>  ''',
> -                     c_type=memb.type.c_type(), c_name=c_name(memb.name))
> +                     c_type=memb.c_type(), c_name=c_name(memb.name))
>      return ret
>
>
> @@ -101,38 +101,6 @@ static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
>                   c_name=c_name(name), base=base.c_name())
>
>
> -def gen_alternate_qtypes_decl(name):
> -    return mcgen('''
> -
> -extern const int %(c_name)s_qtypes[];
> -''',
> -                 c_name=c_name(name))
> -
> -
> -def gen_alternate_qtypes(name, variants):
> -    ret = mcgen('''
> -
> -const int %(c_name)s_qtypes[QTYPE_MAX] = {
> -''',
> -                c_name=c_name(name))
> -
> -    for var in variants.variants:
> -        qtype = var.type.alternate_qtype()
> -        assert qtype
> -
> -        ret += mcgen('''
> -    [%(qtype)s] = %(enum_const)s,
> -''',
> -                     qtype=qtype,
> -                     enum_const=c_enum_const(variants.tag_member.type.name,
> -                                             var.name))
> -
> -    ret += mcgen('''
> -};
> -''')
> -    return ret
> -
> -
>  def gen_variants(variants):
>      # FIXME: What purpose does data serve, besides preventing a union that
>      # has a branch named 'data'? We use it in qapi-visit.py to decide
> @@ -257,9 +225,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>
>      def visit_alternate_type(self, name, info, variants):
>          self._fwdecl += gen_fwd_object_or_array(name)
> -        self._fwdefn += gen_alternate_qtypes(name, variants)
>          self.decl += gen_object(name, None, [variants.tag_member], variants)
> -        self.decl += gen_alternate_qtypes_decl(name)
>          self._gen_type_cleanup(name)
>
>  # If you link code generated from multiple schemata, you want only one
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 94cd113..af80e6d 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -193,7 +193,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
>      if (err) {
>          goto out;
>      }
> -    visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err);
> +    visit_get_next_type(v, &(*obj)->type, name, &err);
>      if (err) {
>          goto out_obj;
>      }
> @@ -201,20 +201,22 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
>  ''',
>                  c_name=c_name(name))
>
> +    # FIXME: When 'number' but not 'int' is present in the alternate, we
> +    # should allow QTYPE_INT to promote to QTYPE_FLOAT.
>      for var in variants.variants:
>          ret += mcgen('''
>      case %(case)s:
>          visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
>          break;
>  ''',
> -                     case=c_enum_const(variants.tag_member.type.name,
> -                                       var.name),
> +                     case=var.type.alternate_qtype(),
>                       c_type=var.type.c_name(),
>                       c_name=c_name(var.name))
>
>      ret += mcgen('''
>      default:
> -        abort();
> +        error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
> +                   "%(name)s");

Craptastic error reporting, but it's widely done elsewhere already, and
cleaning it up is out of scope.

>      }
>  out_obj:
>      error_propagate(errp, err);
> @@ -223,7 +225,8 @@ out_obj:
>  out:
>      error_propagate(errp, err);
>  }
> -''')
> +''',
> +                 name=name)
>
>      return ret
>
> @@ -430,6 +433,7 @@ fdef.write(mcgen('''
>
>  fdecl.write(mcgen('''
>  #include "qapi/visitor.h"
> +#include "qapi/qmp/qerror.h"
>  #include "%(prefix)sqapi-types.h"
>
>  ''',
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index f5aa1d5..9a1f0ac 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -627,15 +627,15 @@ def check_union(expr, expr_info):
>  def check_alternate(expr, expr_info):
>      name = expr['alternate']
>      members = expr['data']
> -    values = {'MAX': '(automatic)'}
> +    values = {}
>      types_seen = {}
>
>      # Check every branch
>      for (key, value) in members.items():
>          check_name(expr_info, "Member of alternate '%s'" % name, key)
>
> -        # Check for conflicts in the generated enum
> -        c_key = camel_to_upper(key)
> +        # Check for conflicts in the branch names
> +        c_key = c_name(key)
>          if c_key in values:
>              raise QAPIExprError(expr_info,
>                                  "Alternate '%s' member '%s' clashes with '%s'"
> @@ -1029,13 +1029,17 @@ class QAPISchemaObjectTypeMember(object):
>          assert self.name not in seen
>          seen[self.name] = self
>
> +    def c_type(self):
> +        return self.type.c_type()
> +
>
>  class QAPISchemaObjectTypeVariants(object):
>      def __init__(self, tag_name, tag_member, variants):
>          # Flat unions pass tag_name but not tag_member.
>          # Simple unions and alternates pass tag_member but not tag_name.
>          # After check(), tag_member is always set, and tag_name remains
> -        # a reliable witness of being used by a flat union.
> +        # a reliable witness of being used by a flat union, and
> +        # tag_member.type being None is a reliable witness of an alternate.
>          assert bool(tag_member) != bool(tag_name)
>          assert (isinstance(tag_name, str) or
>                  isinstance(tag_member, QAPISchemaObjectTypeMember))
> @@ -1049,7 +1053,11 @@ class QAPISchemaObjectTypeVariants(object):
>          # seen is non-empty for unions, empty for alternates
>          if self.tag_name:    # flat union
>              self.tag_member = seen[self.tag_name]
> -        assert isinstance(self.tag_member.type, QAPISchemaEnumType)
> +        if seen:
> +            assert isinstance(self.tag_member.type, QAPISchemaEnumType)
> +        else:
> +            assert isinstance(self.tag_member, QAPISchemaAlternateTypeTag)
> +            assert not self.tag_member.type

Awkward.

>          for v in self.variants:
>              # Reset seen array for each variant, since qapi names from one
>              # branch do not affect another branch
> @@ -1062,10 +1070,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>
>      def check(self, schema, tag_type, seen):
>          QAPISchemaObjectTypeMember.check(self, schema)
> -        assert self.name in tag_type.values
> -        if seen:
> -            # This variant is used within a union; ensure each qapi member
> -            # field does not collide with the union's non-variant members.
> +        if seen:     # in a union
> +            assert self.name in tag_type.values
>              self.type.check_clash(schema, seen)
>
>      # This function exists to support ugly simple union special cases
> @@ -1087,8 +1093,12 @@ class QAPISchemaAlternateType(QAPISchemaType):
>          self.variants = variants
>
>      def check(self, schema):
> -        self.variants.tag_member.check(schema)
>          self.variants.check(schema, {})
> +        # Since we have no enum mapping, we have to check for potential
> +        # case name collisions ourselves.
> +        cases = {}
> +        for var in self.variants.variants:
> +            var.check_clash(cases)
>
>      def json_type(self):
>          return 'value'
> @@ -1097,6 +1107,18 @@ class QAPISchemaAlternateType(QAPISchemaType):
>          visitor.visit_alternate_type(self.name, self.info, self.variants)
>
>
> +class QAPISchemaAlternateTypeTag(QAPISchemaObjectTypeMember):
> +    # TODO: This subclass intentionally leaves self.tag_type as None,
> +    # and intentionally has no check() method. It might be easier to
> +    # reason about the overall QAPISchema if we also subclassed
> +    # QAPISchemaBuiltinType to supply an internal-only 'qtype_code' type.

Sure we need to subclass?  I do hope an instance will do!  Something
like

        self.the_qtype_code_type = QAPISchemaEnumType(':qtype_code', None,
            ['NONE', 'QNULL', ...])

in _def_predefineds().

Also avoids the awkward conditional in
QAPISchemaObjectTypeVariants.check().

Fewer special cases are worth a bit of scaffolding.

> +    def __init__(self):
> +        QAPISchemaObjectTypeMember.__init__(self, 'type', '', False)
> +
> +    def c_type(self):
> +        return 'qtype_code'
> +
> +
>  class QAPISchemaCommand(QAPISchemaEntity):
>      def __init__(self, name, info, arg_type, ret_type, gen, success_response):
>          QAPISchemaEntity.__init__(self, name, info)
> @@ -1290,7 +1312,7 @@ class QAPISchema(object):
>          data = expr['data']
>          variants = [self._make_variant(key, value)
>                      for (key, value) in data.iteritems()]
> -        tag_member = self._make_implicit_tag(name, info, variants)
> +        tag_member = QAPISchemaAlternateTypeTag()
>          self._def_entity(
>              QAPISchemaAlternateType(name, info,
>                                      QAPISchemaObjectTypeVariants(None,
[Tests snipped...]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test Eric Blake
@ 2015-11-05 18:44   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 18:44 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Add positive tests to qapi-schema-test for things that were
> made possible by recent patches but which caused compile errors
> due to collisions prior to that point.  The focus is mainly on
> collisions due to names we have reserved for qapi, even though
> it is unlikely that anyone will want to abuse these names in
> actual .json files.
>
> The added tests includes:

Checking sanity aloud:

> Use of a member name ending in 'Kind' or 'List' [1, 4]

Reserved for type names, because we generate typedef FOOList for
['FOO'], and FOOKind for a simple union FOO.

> Use of a type name starting with 'has_' [1, 5]

Reserved for member names, because we generate has_FOO for an optional
member FOO in the same name space.

See below for union branch.

Could additionally test command and event names, but I very much doubt
that's worth the bother.

> Use of a type named 'u' [1, 6]
> Use of a union branch name of 'u' [2, 6]

Reserved for member names, because we generate u in the same name space
for unions.

> Use of a union branch name starting with 'has_' [2, 5]

See above.

> Use of an alternate branch name of 'max' [3]

I'd prefer keeping "branch name can't be MAX" as artificial restriction
just for similarity to unions.

> [1] Never broken, but could break if reservations are too strict
> [2] Broken prior to commit e4ba22b
> [3] Broken prior to previous commit
> [4] See reservations in commit 4dc2e69 and 255960d
> [5] See reservations in commit 9fb081e
> [6] See reservation in commit 5e59baf
>
> Not worth testing here: we no longer have a collision with a
> member named 'base' (commit ddf2190) or with a branch named
> 'type' (commit e4ba22b).
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Patch looks good.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code
  2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code Eric Blake
@ 2015-11-05 19:05   ` Markus Armbruster
  2015-11-11  6:13     ` Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 19:05 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Michael Roth

Eric Blake <eblake@redhat.com> writes:

> Commit cbc95538 removed unused start_handle() and end_handle(),
> but forgot got remove their declarations.
>
> Commit 4e27e819 introduced optional visitor callbacks for all
> sorts of int types, but except for type_uint64 and type_size,
> none of them have ever been supplied (the generic implementation
> based on using type_int then bounds-checking works just fine).
> In the interest of simplicity, it's easier to make the visitor
> callback interface not have to worry about the other sizes.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v9: no change
> v8: no change
> v7: no change
> v6: no change
> ---
>  include/qapi/visitor-impl.h |  19 +++----
>  include/qapi/visitor.h      |   3 -
>  qapi/qapi-visit-core.c      | 131 +++++++++++++++++---------------------------
>  3 files changed, 58 insertions(+), 95 deletions(-)

Easier to review with whitespace change ignored:

| diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
| index 1d09b7b..370935a 100644
| --- a/include/qapi/visitor-impl.h
| +++ b/include/qapi/visitor-impl.h
| @@ -1,7 +1,7 @@
|  /*
|   * Core Definitions for QAPI Visitor implementations
|   *
| - * Copyright (C) 2012 Red Hat, Inc.
| + * Copyright (C) 2012, 2015 Red Hat, Inc.
|   *
|   * Author: Paolo Bonizni <pbonzini@redhat.com>
|   *
| @@ -48,18 +48,15 @@ struct Visitor
|      void (*optional)(Visitor *v, bool *present, const char *name,
|                       Error **errp);
|  
| -    void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
| -    void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
| -    void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error **errp);
| -    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
| -    void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
| -    void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error **errp);
| -    void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error **errp);
| -    void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
| -    /* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
| -    void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|      bool (*start_union)(Visitor *v, bool data_present, Error **errp);
|      void (*end_union)(Visitor *v, bool data_present, Error **errp);
| +
| +    /* Only required to visit uint64 differently than (*type_int)().  */

If you don't supply it, what happens for uint64_t values that aren't
representable as int64_t?

| +    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name,
| +                        Error **errp);
| +    /* Only required to visit sizes differently than (*type_uint64)().  */
| +    void (*type_size)(Visitor *v, uint64_t *obj, const char *name,
| +                      Error **errp);
|  };
|  
|  void input_type_enum(Visitor *v, int *obj, const char * const strings[],
| diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
| index baea594..67ddd83 100644
| --- a/include/qapi/visitor.h
| +++ b/include/qapi/visitor.h
| @@ -27,9 +27,6 @@ typedef struct GenericList
|      struct GenericList *next;
|  } GenericList;
|  
| -void visit_start_handle(Visitor *v, void **obj, const char *kind,
| -                        const char *name, Error **errp);
| -void visit_end_handle(Visitor *v, Error **errp);
|  void visit_start_struct(Visitor *v, void **obj, const char *kind,
|                          const char *name, size_t size, Error **errp);
|  void visit_end_struct(Visitor *v, Error **errp);
| diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
| index 884fe94..cbf7780 100644
| --- a/qapi/qapi-visit-core.c
| +++ b/qapi/qapi-visit-core.c
| @@ -104,9 +104,6 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_uint8) {
| -        v->type_uint8(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < 0 || value > UINT8_MAX) {
| @@ -116,15 +113,12 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
|      }
|      *obj = value;
|  }
| -}
|  
| -void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
| +void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name,
| +                       Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_uint16) {
| -        v->type_uint16(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < 0 || value > UINT16_MAX) {
| @@ -134,15 +128,12 @@ void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp
|      }
|      *obj = value;
|  }
| -}
|  
| -void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
| +void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name,
| +                       Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_uint32) {
| -        v->type_uint32(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < 0 || value > UINT32_MAX) {
| @@ -152,9 +143,9 @@ void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp
|      }
|      *obj = value;
|  }
| -}
|  
| -void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
| +void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name,
| +                       Error **errp)
|  {
|      int64_t value;
|  
       if (v->type_uint64) {
           v->type_uint64(v, obj, name, errp);
       } else {
           value = *obj;
           v->type_int(v, &value, name, errp);
           *obj = value;
       }
   }

Answering my "what happens" question:

* Input visitor

  If your type_int() accepts large positive input values and casts them
  to the corresponding large negative value, *obj = value will cast them
  right back, and the sloppiness cancels out.

  If it rejects them, they stay rejected.

* Output visitor

  You'll output large positive values as the corresponding large
  negative value.

I doubt not defining this makes much sense.  Do we have such visitors?

| @@ -171,9 +162,6 @@ void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_int8) {
| -        v->type_int8(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < INT8_MIN || value > INT8_MAX) {
| @@ -183,15 +171,11 @@ void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
|      }
|      *obj = value;
|  }
| -}
|  
|  void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_int16) {
| -        v->type_int16(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < INT16_MIN || value > INT16_MAX) {
| @@ -201,15 +185,11 @@ void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
|      }
|      *obj = value;
|  }
| -}
|  
|  void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
|  {
|      int64_t value;
|  
| -    if (v->type_int32) {
| -        v->type_int32(v, obj, name, errp);
| -    } else {
|      value = *obj;
|      v->type_int(v, &value, name, errp);
|      if (value < INT32_MIN || value > INT32_MAX) {
| @@ -219,29 +199,18 @@ void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
|      }
|      *obj = value;
|  }
| -}
|  
|  void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
|  {
| -    if (v->type_int64) {
| -        v->type_int64(v, obj, name, errp);
| -    } else {
|      v->type_int(v, obj, name, errp);
|  }
| -}
|  
|  void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
|  {
| -    int64_t value;
| -
|      if (v->type_size) {
|          v->type_size(v, obj, name, errp);
| -    } else if (v->type_uint64) {
| -        v->type_uint64(v, obj, name, errp);
|      } else {
| -        value = *obj;
| -        v->type_int(v, &value, name, errp);
| -        *obj = value;
| +        visit_type_uint64(v, obj, name, errp);
|      }
|  }
|  

This one's problematic, I think.  If you supply type_uint64(), but not
type_size(), I'd certainly expect type_uint64() to be used.  If not,
what happens for values that can be represented as uint64_t, but not as
int64_t?

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C)
  2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
                   ` (27 preceding siblings ...)
  2015-11-04 10:22 ` [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Markus Armbruster
@ 2015-11-05 19:45 ` Markus Armbruster
  28 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-05 19:45 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

Got through, puh!  Most patches are basically fine, but there are a few
open questions.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 16:41         ` Eric Blake
@ 2015-11-05 22:36           ` Eric Blake
  2015-11-06 10:03           ` Markus Armbruster
  1 sibling, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-05 22:36 UTC (permalink / raw)
  To: Daniel P. Berrange, Markus Armbruster; +Cc: qemu-devel, mdroth

[-- Attachment #1: Type: text/plain, Size: 1334 bytes --]

On 11/05/2015 09:41 AM, Eric Blake wrote:

> In order to (later) support case-insensitive QMP, we need to decide up
> front that we will not allow any qapi member names to collide
> case-insensitively (outlaw 'a' and 'A' in the same struct; although the
> C code is still case-preserving); and now that this series is adding a
> single check_clash() function, it's very easy to do.  In fact, I'll add
> that to my series for 2.5 (it's always easier to reserve something now,
> especially if no one was using it, and then relax later; than it is to
> try and restrict things later but run into counter-cases).

Eww - it's not quite as trivial as I thought: we have QMP struct
'CpuInfo' as part of command 'query-cpus' that has both a 'pc' and 'PC'
member.  However, it's not unsalvageable: the type is made up of a bunch
of architecture-specific optional fields along with documentation that
"field x is only present for architecture y".  So it would be possible
to turn this type into a flat union, adding a new enum for architecture,
and separating the object so that 'pc' is part of the 'i386', 'x86_64',
and 'Sparc' branches, while 'PC' is part of the 'Mips' branch.

At any rate, I'll post an RFC.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 16:41         ` Eric Blake
  2015-11-05 22:36           ` Eric Blake
@ 2015-11-06 10:03           ` Markus Armbruster
  2015-11-06 13:35             ` Markus Armbruster
  1 sibling, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-06 10:03 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> On 11/05/2015 09:01 AM, Daniel P. Berrange wrote:
>> On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
>>> QAPI names needn't be valid C identifiers, so we mangle them with
>>> c_name().  Except for enumeration constants, which we mangle with
>>> camel_to_upper().
>>>
>>> c_name() is easy enough to understand: replace '.' and '-' by '_',
>>> prefix certain ticklish identifiers with 'q_'.
>>>
>>> camel_to_upper() is a hairball of heuristics, and guessing how it'll
>>> mangle interesting input could serve as a (nerdy) game.  Despite some
>>> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
>>> (commit 351d36e).
>
> One of the issues at hand is whether we want to (eventually) teach QMP
> to be case-insensitive.  Right now, our c_name() mangling preserves case
> (you can have a struct with members 'a' and 'A'), although (hopefully)
> no one is relying on it.  But camel_to_upper() is case-insensitive ('a'
> and 'A' would result in the same enum constant).
>
> In order to (later) support case-insensitive QMP, we need to decide up
> front that we will not allow any qapi member names to collide
> case-insensitively (outlaw 'a' and 'A' in the same struct; although the
> C code is still case-preserving); and now that this series is adding a
> single check_clash() function, it's very easy to do.  In fact, I'll add
> that to my series for 2.5 (it's always easier to reserve something now,
> especially if no one was using it, and then relax later; than it is to
> try and restrict things later but run into counter-cases).

I doubt QMP should be made case-insensitive.  JSON isn't, C isn't.  Our
use of case is actually fairly consistent: event names are ALL_CAPS,
everything else is in lower case.  Complete list of exceptions found in
result of query-qmp-schema:

* struct UuidInfo member UUID
* struct CpuInfo members CPU and PC
* enum ACPISlotType member DIMM
* enum InputButton members Left, Middle, Right, WheelUp, WheelDown
* enum InputAxis members X, Y

That said, an interface where names differ only in case is a badly
designed interface.  I'd be fine with rejecting such abuse.

Oddballs not related to case:

* enum BlkdebugEvent uses '.' in member names
* enum QKeyCode uses member names starting with a digit

For me, the one argument for some kind of insensitivity is our idiotic
habit to sometimes string words together with '_' instead of '-', which
has led to an unholy mess.  The offenders are

* commands block_passwd, block_resize, block_set_io_throttle,
  client_migrate_info, device_del, expire_password, migrate_cancel,
  migrate_set_downtime, migrate_set_speed, netdev_add, netdev_del,
  set_link, set_password, system_powerdown, system_reset, system_wakeup
* enum types BlkdebugEvent, BlockdevDriver, QKeyCode
* object types BlkdebugSetStateOptions, BlockDeviceInfo,
  BlockDeviceInfo, BlockDeviceStats, BlockInfo, CpuInfo, PciBusInfo,
  PciDeviceInfo, PciMemoryRegion, VncClientInfo

>>> Having two separate manglings complicates this.  Enumeration constants
>>> must be distinct after mangling with camel_to_upper().  But as soon as
>>> you use the enumeration as union tag, they must *also* be distinct
>>> after mangling with c_name().
>
> But this should already be the case - can you come up with a pair of
> valid enum values that won't clash under camel_to_upper() but would
> result in in a c_name() value collision?

One glance at camel_to_upper() should make it obvious why I'd prefer not
to have to know.  But since you asked...  I guess it can't happen,
because camel_to_upper() first mangles with c_name(), then mangles some
more.  If c_name() clashes, further mangling can't make it clash less.

>                                           The converse is not true -
> there ARE pairs of c_name() values that are distinct, but which map to
> the same mangling with camel_to_upper().

Yes.  Example: 'GotCha' and 'got-cha' both map to 'GOT_CHA'.

>                                           But if we insist that names do
> not collide case-insensitively, then that issue goes away - having
> ALL_CAP enum constants won't cause any collisions even when those
> constants are derived from member names, because member names are
> already forbidden from case-insensitive clash.
>
> There is still the question of whether we can get rid of the spurious
> collision with 'max', by putting the enum sentinel out of the namespace
> generated for other values.

I wanted to get out an RFC quickly, so I didn't try.

>                              But even with ALL_CAPS, that is possible:
>
>         BLOCK_DEVICE_IO_STATUS_OK = 0,
>         BLOCK_DEVICE_IO_STATUS_FAILED = 1,
>         BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
>         BLOCK_DEVICE_IO_STATUSMAX = 3,

Running shouted words together like STATUSMAX is even less legible than
StatusMax.  There's a reason why scriptio continua was abandoned in the
middle ages.

> Or insist that no enum value can start with a lone _ (double __ is okay
> for downstream extensions, though):
>
>         BLOCK_DEVICE_IO_STATUS_OK = 0,
>         BLOCK_DEVICE_IO_STATUS_FAILED = 1,
>         BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
>         BLOCK_DEVICE_IO_STATUS__MAX = 3,

Workable.  With the separate mangling dropped, we could do

    typedef enum BlockDeviceIoStatus {
        BlockDeviceIoStatus_ok = 0,
        BlockDeviceIoStatus_failed = 1,
        BlockDeviceIoStatus_nospace = 2,
        BlockDeviceIoStatusMAX = 3,
    } BlockDeviceIoStatus;

which I think is a least ugly solution given our convention to use
CamelCase for type names and my proposal to use the enum name as enum
constant prefix.

I'll reply to Dan separately.

[...]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-06 10:03           ` Markus Armbruster
@ 2015-11-06 13:35             ` Markus Armbruster
  2015-11-10 14:35               ` [Qemu-devel] What to do about QAPI naming convention violations (was: [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants) Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-06 13:35 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, mdroth

Markus Armbruster <armbru@redhat.com> writes:

> Eric Blake <eblake@redhat.com> writes:
>
>> On 11/05/2015 09:01 AM, Daniel P. Berrange wrote:
>>> On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
>>>> QAPI names needn't be valid C identifiers, so we mangle them with
>>>> c_name().  Except for enumeration constants, which we mangle with
>>>> camel_to_upper().
>>>>
>>>> c_name() is easy enough to understand: replace '.' and '-' by '_',
>>>> prefix certain ticklish identifiers with 'q_'.
>>>>
>>>> camel_to_upper() is a hairball of heuristics, and guessing how it'll
>>>> mangle interesting input could serve as a (nerdy) game.  Despite some
>>>> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
>>>> (commit 351d36e).
>>
>> One of the issues at hand is whether we want to (eventually) teach QMP
>> to be case-insensitive.  Right now, our c_name() mangling preserves case
>> (you can have a struct with members 'a' and 'A'), although (hopefully)
>> no one is relying on it.  But camel_to_upper() is case-insensitive ('a'
>> and 'A' would result in the same enum constant).
>>
>> In order to (later) support case-insensitive QMP, we need to decide up
>> front that we will not allow any qapi member names to collide
>> case-insensitively (outlaw 'a' and 'A' in the same struct; although the
>> C code is still case-preserving); and now that this series is adding a
>> single check_clash() function, it's very easy to do.  In fact, I'll add
>> that to my series for 2.5 (it's always easier to reserve something now,
>> especially if no one was using it, and then relax later; than it is to
>> try and restrict things later but run into counter-cases).
>
> I doubt QMP should be made case-insensitive.  JSON isn't, C isn't.  Our
> use of case is actually fairly consistent: event names are ALL_CAPS,
> everything else is in lower case.  Complete list of exceptions found in
> result of query-qmp-schema:
>
> * struct UuidInfo member UUID
> * struct CpuInfo members CPU and PC
> * enum ACPISlotType member DIMM
> * enum InputButton members Left, Middle, Right, WheelUp, WheelDown
> * enum InputAxis members X, Y
>
> That said, an interface where names differ only in case is a badly
> designed interface.  I'd be fine with rejecting such abuse.
>
> Oddballs not related to case:
>
> * enum BlkdebugEvent uses '.' in member names
> * enum QKeyCode uses member names starting with a digit
>
> For me, the one argument for some kind of insensitivity is our idiotic
> habit to sometimes string words together with '_' instead of '-', which
> has led to an unholy mess.  The offenders are
>
> * commands block_passwd, block_resize, block_set_io_throttle,
>   client_migrate_info, device_del, expire_password, migrate_cancel,
>   migrate_set_downtime, migrate_set_speed, netdev_add, netdev_del,
>   set_link, set_password, system_powerdown, system_reset, system_wakeup
> * enum types BlkdebugEvent, BlockdevDriver, QKeyCode
> * object types BlkdebugSetStateOptions, BlockDeviceInfo,
>   BlockDeviceInfo, BlockDeviceStats, BlockInfo, CpuInfo, PciBusInfo,
>   PciDeviceInfo, PciMemoryRegion, VncClientInfo

I can think of a few ways to clean up the '_' vs. '-' mess:

1. Fix the offenders, keep the unfixed names as aliases.

   Requires an alias mechanism.

   If we do it in 2.5, we can keep the aliases out of QMP introspection.

2. Fix the offenders, map '_' to '-' in QMP input, but only in object
   keys and values of enumeration type, not other strings.

   Distinguishing the two kinds of strings might be non-trivial, dunno.

3. Compare '_' and '-' equal in all the necessary places.

   Need to find these places.

   The mess remains visible in QMP introspection unless we also fix the
   offenders.

Fixing the offenders without keeping the unfixed names along changes QMP
introspection value incompatibly.  May not be practical after 2.5.

I wish I had made the connection between the '_' vs. '-' mess and
introspection earlier.

If we decide to clean up '_' vs. '-', then other irregularities like
case could be cleaned up along with it.

Thoughts?

[...]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-05 16:01       ` Daniel P. Berrange
  2015-11-05 16:41         ` Eric Blake
@ 2015-11-09  9:34         ` Markus Armbruster
  2015-11-09 10:53           ` Daniel P. Berrange
  1 sibling, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-09  9:34 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel, mdroth

"Daniel P. Berrange" <berrange@redhat.com> writes:

> On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
>> QAPI names needn't be valid C identifiers, so we mangle them with
>> c_name().  Except for enumeration constants, which we mangle with
>> camel_to_upper().
>> 
>> c_name() is easy enough to understand: replace '.' and '-' by '_',
>> prefix certain ticklish identifiers with 'q_'.
>> 
>> camel_to_upper() is a hairball of heuristics, and guessing how it'll
>> mangle interesting input could serve as a (nerdy) game.  Despite some
>> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
>> (commit 351d36e).
>> 
>> Example: QAPI definition
>> 
>>     { 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }
>> 
>> generates
>> 
>>     typedef enum BlockDeviceIoStatus {
>>         BLOCK_DEVICE_IO_STATUS_OK = 0,
>>         BLOCK_DEVICE_IO_STATUS_FAILED = 1,
>>         BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
>>         BLOCK_DEVICE_IO_STATUS_MAX = 3,
>>     } BlockDeviceIoStatus;
>> 
>> Observe that c_name() maps BlockDeviceIoStatus to itself, and
>> camel_to_upper() maps it to BLOCK_DEVICE_IO_STATUS, i.e. the
>> enumeration constants are shouted, the enumeration type isn't.
>> 
>> Because mangled names must not clash, name mangling restricts the
>> names you can use.  For example, you can't have member 'a-b' and
>> 'a_b'.
>> 
>> Having two separate manglings complicates this.  Enumeration constants
>> must be distinct after mangling with camel_to_upper().  But as soon as
>> you use the enumeration as union tag, they must *also* be distinct
>> after mangling with c_name().
>> 
>> Having shouted enumeration constants isn't worth the complexity cost.
>
> I rather disagree with this. Having all-uppercase for enum constants
> is a really widely used convention and I think it is pretty useful
> when reading to code to have constants (whether #define/enum) clearly
> marked in uppercase.  After this change we'll have situation where
> QAPI enums uses CamelCase, while all other non-QAPI enums (whether
> defined in QEMU source, or via #included 3rd party headers use
> UPPER_CASE for constants. I think that's rather unpleasant.

CODING_STYLE doesn't mandate shouting constants.

Existing code doesn't shout constants consistently.

Third parties don't shout constants consistently.

A competing convention is to use the enumeration type's name as prefix
for the constants.

> I agree with your premise that predicting the output of the qapi
> name mangler though is essentially impossible for mortals. How
> about a counter proposal....
>
> First make 'prefix' compulsory for enums, instead of trying to
> figure out a suitable prefix automatically. Then, have a very
> simple rule for the enum constants where you just uppercase a-z
> and translate any non-alpha-numeric character into a _. Don't
> try todo anything else special like figuring out word boundaries.

Essentially c_name(qapi_name).upper().

> That would get of much of the complexity in the qapi name mangler
> and give a easily predictable enum constant name. Thus the vast
> majority of .c source files (possibly even all of them) would not
> need any change.

'prefix' is a work-around for deficient name mangling.  Making it
mandatory declares defeat on enumeration constant name mangling.  The
reason for defeat are unreasonable goals, namely combining these three
conventions:

* QAPI and C type names are in CamelCase

* Enumeration constants are prefixed by the type name

* Enumeration constants are shouted, including the prefix

They necessitate converting the CamelCase prefix to shouting, which is
the troublesome part.  Note that shouting the remainder (the QAPI member
name) is trivial: .upper() serves.


Let's take a step back and examine what I want to achieve.


First, I want simple, consistent rules for QAPI names.  Two kinds:
reserved names and name clashes.

A few names are globally reserved (e.g. prefix 'q_') , and a few more
only in certain name spaces (e.g. type name suffix 'List').  Simple
enough.

Two names clash if they're equal after replacing '-' and '.' by '_'.
Simple enough.

*Except* for enumeration member names, which can clash in other ways
(example: 'GotCha' with 'got-cha').  The exact special clashing rules
haven't been written down.  Nobody knows them, actually.  Instead of
writing them down, I want to get rid of then.

We could change the normal clashing rule to additionally ignore case.
Still simple enough, and makes sense to me.

Ignoring case would let us safely shout names in generated code.


Second, I want our C names generated in a simple, predictable way.  This
is largely the case:

* We use the QAPI name with '-' and '.' replaced by '_'

* Sometimes, we prepend a 'q_' to avoid certain ticklish names

* We prepend and append fixed strings

*Except* for enumeration member names, which undergo a different
mangling that is neither simple nor predictable.

My proposal simply drops the special case.

Your counter-proposal instead moves the name mangling from the generator
to the QAPI schema.  In other words, it abuses the programmer as name
mangler.  I don't like that, and I wouldn't call it "simple".  It does
address the "not predictable" part.


If we must have shouting in enumeration constants, we could do the
following: use the unadulterated type name as prefix, shout the member
name.  Example:

    typedef enum BlockDeviceIoStatus {
        BlockDeviceIoStatus_OK = 0,
        BlockDeviceIoStatus_FAILED = 1,
        BlockDeviceIoStatus_NOSPACE = 2,
        BlockDeviceIoStatus_MAX = 3,
    } BlockDeviceIoStatus;

If the QAPI enumeration constant rename flag day bothers us, we can keep
the 'prefix' feature for now, use it to avoid the renames that touch
code we don't want to touch now, then rename them one by one at our
convenience.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants
  2015-11-09  9:34         ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
@ 2015-11-09 10:53           ` Daniel P. Berrange
  0 siblings, 0 replies; 75+ messages in thread
From: Daniel P. Berrange @ 2015-11-09 10:53 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, mdroth

[-- Attachment #1: Type: text/plain, Size: 10598 bytes --]

On Mon, Nov 09, 2015 at 10:34:41AM +0100, Markus Armbruster wrote:
> "Daniel P. Berrange" <berrange@redhat.com> writes:
> 
> > On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
> >> QAPI names needn't be valid C identifiers, so we mangle them with
> >> c_name().  Except for enumeration constants, which we mangle with
> >> camel_to_upper().
> >> 
> >> c_name() is easy enough to understand: replace '.' and '-' by '_',
> >> prefix certain ticklish identifiers with 'q_'.
> >> 
> >> camel_to_upper() is a hairball of heuristics, and guessing how it'll
> >> mangle interesting input could serve as a (nerdy) game.  Despite some
> >> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
> >> (commit 351d36e).
> >> 
> >> Example: QAPI definition
> >> 
> >>     { 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }
> >> 
> >> generates
> >> 
> >>     typedef enum BlockDeviceIoStatus {
> >>         BLOCK_DEVICE_IO_STATUS_OK = 0,
> >>         BLOCK_DEVICE_IO_STATUS_FAILED = 1,
> >>         BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
> >>         BLOCK_DEVICE_IO_STATUS_MAX = 3,
> >>     } BlockDeviceIoStatus;
> >> 
> >> Observe that c_name() maps BlockDeviceIoStatus to itself, and
> >> camel_to_upper() maps it to BLOCK_DEVICE_IO_STATUS, i.e. the
> >> enumeration constants are shouted, the enumeration type isn't.
> >> 
> >> Because mangled names must not clash, name mangling restricts the
> >> names you can use.  For example, you can't have member 'a-b' and
> >> 'a_b'.
> >> 
> >> Having two separate manglings complicates this.  Enumeration constants
> >> must be distinct after mangling with camel_to_upper().  But as soon as
> >> you use the enumeration as union tag, they must *also* be distinct
> >> after mangling with c_name().
> >> 
> >> Having shouted enumeration constants isn't worth the complexity cost.
> >
> > I rather disagree with this. Having all-uppercase for enum constants
> > is a really widely used convention and I think it is pretty useful
> > when reading to code to have constants (whether #define/enum) clearly
> > marked in uppercase.  After this change we'll have situation where
> > QAPI enums uses CamelCase, while all other non-QAPI enums (whether
> > defined in QEMU source, or via #included 3rd party headers use
> > UPPER_CASE for constants. I think that's rather unpleasant.
> 
> CODING_STYLE doesn't mandate shouting constants.
> 
> Existing code doesn't shout constants consistently.

I wrote a script (attached) to parse the code and try to get extract
some data on upper/lower/mixed case usage in enum declarations

Enum member naming
  Uppercase: 993 in 325 files
  Lowercase: 119 in 76 files
  Mixedcase: 110 in 22 files

So, uppercase is preferred 10:1 over both lowercase and mixedcase
The filecount for uppercase would be far higher were it not for
fact that all QAPI enums end up in one file.

If we try to count #define's which provide constants, again
all uppercase is the clear majority

  Upper 32256
  Lower 829
  Mixed 8869

(50% of those Mixed constants come from the userspace emulator
 #defines for syscall numbers)

> Third parties don't shout constants consistently.

Running the same script across all the QEMU RPM dependancies again
shows uppercase is the favoured style:

Enum member naming
  Uppercase: 538 in 178 files
  Lowercase: 38 in 17 files
  Mixedcase: 141 in 53 files

The breakdown per-RPM is as follows:

bluez-libs-devel
Enum member naming
  Uppercase: 4 in 3 files

brlapi-devel
Enum member naming
  Uppercase: 43 in 23 files
  Mixedcase: 83 in 29 files

bzip2-devel
Enum member naming
  None

ceph-devel
Enum member naming
  None

cyrus-sasl-devel
Enum member naming
  Uppercase: 1 in 1 files

glusterfs-api-devel
Enum member naming
  Uppercase: 1 in 1 files

glusterfs-devel
Enum member naming
  Uppercase: 94 in 26 files
  Lowercase: 10 in 6 files
  Mixedcase: 2 in 1 files

gnutls-devel
Enum member naming
  Uppercase: 63 in 10 files

gtk3-devel
Enum member naming
  Uppercase: 152 in 60 files
  Lowercase: 1 in 1 files

libaio-devel
Enum member naming
  Uppercase: 1 in 1 files

libattr-devel
Enum member naming
  None

libcap-devel
Enum member naming
  None

libcurl-devel
Enum member naming
  Uppercase: 17 in 2 files
  Lowercase: 3 in 1 files
  Mixedcase: 1 in 1 files

libfdt-devel
Enum member naming
  None

libiscsi-devel
Enum member naming
  Uppercase: 32 in 2 files

libjpeg-devel
Enum member naming
  None

libpng-devel
Enum member naming
  None

librdmacm-devel
Enum member naming
  Uppercase: 7 in 3 files

libseccomp-devel
Enum member naming
  Uppercase: 2 in 1 files

libssh2-devel
Enum member naming
  None

libusbx-devel
Enum member naming
  Uppercase: 21 in 1 files

libuuid-devel
Enum member naming
  None

ncurses-devel
Enum member naming
  Uppercase: 3 in 3 files
  Mixedcase: 6 in 6 files

nss-devel
Enum member naming
  Uppercase: 2 in 2 files
  Lowercase: 10 in 2 files
  Mixedcase: 41 in 10 files

numactl-devel
Enum member naming
  None

pciutils-devel
Enum member naming
  Uppercase: 2 in 1 files

pixman-devel
Enum member naming
  Uppercase: 5 in 1 files
  Mixedcase: 1 in 1 files

pulseaudio-libs-devel
Enum member naming
  Uppercase: 17 in 6 files

SDL2-devel
Enum member naming
  Uppercase: 30 in 17 files
  Mixedcase: 3 in 2 files

spice-server-devel
Enum member naming
  Uppercase: 5 in 3 files

systemtap-sdt-devel
Enum member naming
  None

usbredir-devel
Enum member naming
  Lowercase: 11 in 4 files

vte3-devel
Enum member naming
  Uppercase: 7 in 3 files

xen-devel
Enum member naming
  Uppercase: 29 in 8 files
  Lowercase: 3 in 3 files
  Mixedcase: 2 in 2 files

xfsprogs-devel
Enum member naming
  Mixedcase: 2 in 1 files

zlib-devel
Enum member naming
  None

> A competing convention is to use the enumeration type's name as prefix
> for the constants.

That is counted by the 'mixedcase' stats and as seen above that's still
10:1 less popular than all uppercase.

> 
> > I agree with your premise that predicting the output of the qapi
> > name mangler though is essentially impossible for mortals. How
> > about a counter proposal....
> >
> > First make 'prefix' compulsory for enums, instead of trying to
> > figure out a suitable prefix automatically. Then, have a very
> > simple rule for the enum constants where you just uppercase a-z
> > and translate any non-alpha-numeric character into a _. Don't
> > try todo anything else special like figuring out word boundaries.
> 
> Essentially c_name(qapi_name).upper().
> 
> > That would get of much of the complexity in the qapi name mangler
> > and give a easily predictable enum constant name. Thus the vast
> > majority of .c source files (possibly even all of them) would not
> > need any change.
> 
> 'prefix' is a work-around for deficient name mangling.  Making it
> mandatory declares defeat on enumeration constant name mangling.  The
> reason for defeat are unreasonable goals, namely combining these three
> conventions:
> 
> * QAPI and C type names are in CamelCase
> 
> * Enumeration constants are prefixed by the type name
> 
> * Enumeration constants are shouted, including the prefix
> 
> They necessitate converting the CamelCase prefix to shouting, which is
> the troublesome part.  Note that shouting the remainder (the QAPI member
> name) is trivial: .upper() serves.
> 
> 
> Let's take a step back and examine what I want to achieve.
> 
> 
> First, I want simple, consistent rules for QAPI names.  Two kinds:
> reserved names and name clashes.
> 
> A few names are globally reserved (e.g. prefix 'q_') , and a few more
> only in certain name spaces (e.g. type name suffix 'List').  Simple
> enough.
> 
> Two names clash if they're equal after replacing '-' and '.' by '_'.
> Simple enough.
> 
> *Except* for enumeration member names, which can clash in other ways
> (example: 'GotCha' with 'got-cha').  The exact special clashing rules
> haven't been written down.  Nobody knows them, actually.  Instead of
> writing them down, I want to get rid of then.
> 
> We could change the normal clashing rule to additionally ignore case.
> Still simple enough, and makes sense to me.
> 
> Ignoring case would let us safely shout names in generated code.
> 
> 
> Second, I want our C names generated in a simple, predictable way.  This
> is largely the case:
> 
> * We use the QAPI name with '-' and '.' replaced by '_'
> 
> * Sometimes, we prepend a 'q_' to avoid certain ticklish names
> 
> * We prepend and append fixed strings
> 
> *Except* for enumeration member names, which undergo a different
> mangling that is neither simple nor predictable.
> 
> My proposal simply drops the special case.

This is really all about the POV you look at the problem from. From
the code generator's POV having enum's all uppercase is a special
case scenario. From the general developer's POV, having enums all
uppercase is the normal case scenario.  IMHO the code generator is
there to serve the developers, so following the developer's normal
case should be the priority, even if that makes life harder for
maintaining the code generator.

> Your counter-proposal instead moves the name mangling from the generator
> to the QAPI schema.  In other words, it abuses the programmer as name
> mangler.  I don't like that, and I wouldn't call it "simple".  It does
> address the "not predictable" part.

Saying it abuses the programmer is pretty extreme. When a programmer
is defining an enum, they will always intuitively have an idea of
what they expect the enum constants to look like. Simply defining
that in the QAPI schema at that time is no burden at all and really
is simple/trivial for the programmer.

> If we must have shouting in enumeration constants, we could do the
> following: use the unadulterated type name as prefix, shout the member
> name.  Example:
> 
>     typedef enum BlockDeviceIoStatus {
>         BlockDeviceIoStatus_OK = 0,
>         BlockDeviceIoStatus_FAILED = 1,
>         BlockDeviceIoStatus_NOSPACE = 2,
>         BlockDeviceIoStatus_MAX = 3,
>     } BlockDeviceIoStatus;
> 
> If the QAPI enumeration constant rename flag day bothers us, we can keep
> the 'prefix' feature for now, use it to avoid the renames that touch
> code we don't want to touch now, then rename them one by one at our
> convenience.


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

[-- Attachment #2: check-enum.pl --]
[-- Type: application/x-perl, Size: 1384 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] What to do about QAPI naming convention violations (was: [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants)
  2015-11-06 13:35             ` Markus Armbruster
@ 2015-11-10 14:35               ` Markus Armbruster
  2015-11-16 22:13                 ` [Qemu-devel] blkdebug event names [was: What to do about QAPI naming convention violations] Eric Blake
  0 siblings, 1 reply; 75+ messages in thread
From: Markus Armbruster @ 2015-11-10 14:35 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, mdroth

Markus Armbruster <armbru@redhat.com> writes:

> Markus Armbruster <armbru@redhat.com> writes:
>
>> Eric Blake <eblake@redhat.com> writes:
>>
>>> On 11/05/2015 09:01 AM, Daniel P. Berrange wrote:
>>>> On Thu, Nov 05, 2015 at 04:30:00PM +0100, Markus Armbruster wrote:
>>>>> QAPI names needn't be valid C identifiers, so we mangle them with
>>>>> c_name().  Except for enumeration constants, which we mangle with
>>>>> camel_to_upper().
>>>>>
>>>>> c_name() is easy enough to understand: replace '.' and '-' by '_',
>>>>> prefix certain ticklish identifiers with 'q_'.
>>>>>
>>>>> camel_to_upper() is a hairball of heuristics, and guessing how it'll
>>>>> mangle interesting input could serve as a (nerdy) game.  Despite some
>>>>> tweaking (commit 5d371f4), it's still inadqeuate for some QAPI names
>>>>> (commit 351d36e).
>>>
>>> One of the issues at hand is whether we want to (eventually) teach QMP
>>> to be case-insensitive.  Right now, our c_name() mangling preserves case
>>> (you can have a struct with members 'a' and 'A'), although (hopefully)
>>> no one is relying on it.  But camel_to_upper() is case-insensitive ('a'
>>> and 'A' would result in the same enum constant).
>>>
>>> In order to (later) support case-insensitive QMP, we need to decide up
>>> front that we will not allow any qapi member names to collide
>>> case-insensitively (outlaw 'a' and 'A' in the same struct; although the
>>> C code is still case-preserving); and now that this series is adding a
>>> single check_clash() function, it's very easy to do.  In fact, I'll add
>>> that to my series for 2.5 (it's always easier to reserve something now,
>>> especially if no one was using it, and then relax later; than it is to
>>> try and restrict things later but run into counter-cases).
>>
>> I doubt QMP should be made case-insensitive.  JSON isn't, C isn't.  Our
>> use of case is actually fairly consistent: event names are ALL_CAPS,
>> everything else is in lower case.  Complete list of exceptions found in
>> result of query-qmp-schema:
>>
>> * struct UuidInfo member UUID
>> * struct CpuInfo members CPU and PC
>> * enum ACPISlotType member DIMM
>> * enum InputButton members Left, Middle, Right, WheelUp, WheelDown
>> * enum InputAxis members X, Y
>>
>> That said, an interface where names differ only in case is a badly
>> designed interface.  I'd be fine with rejecting such abuse.
>>
>> Oddballs not related to case:
>>
>> * enum BlkdebugEvent uses '.' in member names
>> * enum QKeyCode uses member names starting with a digit
>>
>> For me, the one argument for some kind of insensitivity is our idiotic
>> habit to sometimes string words together with '_' instead of '-', which
>> has led to an unholy mess.  The offenders are
>>
>> * commands block_passwd, block_resize, block_set_io_throttle,
>>   client_migrate_info, device_del, expire_password, migrate_cancel,
>>   migrate_set_downtime, migrate_set_speed, netdev_add, netdev_del,
>>   set_link, set_password, system_powerdown, system_reset, system_wakeup

Missing: add_client.

>> * enum types BlkdebugEvent, BlockdevDriver, QKeyCode
>> * object types BlkdebugSetStateOptions, BlockDeviceInfo,
>>   BlockDeviceInfo, BlockDeviceStats, BlockInfo, CpuInfo, PciBusInfo,
>>   PciDeviceInfo, PciMemoryRegion, VncClientInfo
>
> I can think of a few ways to clean up the '_' vs. '-' mess:
>
> 1. Fix the offenders, keep the unfixed names as aliases.
>
>    Requires an alias mechanism.
>
>    If we do it in 2.5, we can keep the aliases out of QMP introspection.
>
> 2. Fix the offenders, map '_' to '-' in QMP input, but only in object
>    keys and values of enumeration type, not other strings.
>
>    Distinguishing the two kinds of strings might be non-trivial, dunno.
>
> 3. Compare '_' and '-' equal in all the necessary places.
>
>    Need to find these places.
>
>    The mess remains visible in QMP introspection unless we also fix the
>    offenders.

Of course, there's a big difference between QMP input and output.

On input, we can accept a nicer name in addition to the ugly name, and
that's compatible.

On output, we can only duplicate data with an ugly name under a nicer
one.  Duplicating members or events doesn't feel like an improvement.
That leaves deprecating commands.

I had a closer look at how the screwy names are used in QMP to see how
much of the mess is fixable within reason.

Command names are all fixable.

InputButton and InputAxis are input for x-input-send-event.  Fixable.
May not even need backward compatibility.

QKeyCode is input for x-input-send-event and send-key.  Fixable.
However, I think we want to bend the rules instead.

ACPISlotType, BlockDeviceInfo, BlockDeviceStats, BlockInfo, CpuInfo,
PciBusInfo, PciDeviceInfo, PciMemoryRegion, UuidInfo, VncClientInfo are
all output of some query command.  The only fix is deprecating the query
commands, which is a big hammer.

BlkdebugEvent is related to the external blkdebug interface described by
docs/blkdebug.txt.  The two are actually decoupled, i.e. changing the
QAPI names doesn't affect the external debugging interface, and vice
versa.  Making them different can only cause confusion, though.  Not
sure we can fix the names.

BlkdebugSetStateOptions and BlockdevDriver are input for blockdev-add.
Fixable.  May not even need backward compatibility.

> Fixing the offenders without keeping the unfixed names along changes QMP
> introspection value incompatibly.  May not be practical after 2.5.
>
> I wish I had made the connection between the '_' vs. '-' mess and
> introspection earlier.
>
> If we decide to clean up '_' vs. '-', then other irregularities like
> case could be cleaned up along with it.
>
> Thoughts?
>
> [...]

Here's what I think we should do:

* Make qapi.py enforce the naming conventions, to stop us from digging
  ourselves deeper into this hole.

  Requires a whitelist, similar to returns_whitelist.  I'd whitelist
  whole types, not members.

* Try to fix x-input-send-event and blockdev-add before they become
  unfixable.

* Live with the rest.

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code
  2015-11-05 19:05   ` Markus Armbruster
@ 2015-11-11  6:13     ` Eric Blake
  0 siblings, 0 replies; 75+ messages in thread
From: Eric Blake @ 2015-11-11  6:13 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Michael Roth

[-- Attachment #1: Type: text/plain, Size: 1907 bytes --]

On 11/05/2015 12:05 PM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> Commit cbc95538 removed unused start_handle() and end_handle(),
>> but forgot got remove their declarations.
>>
>> Commit 4e27e819 introduced optional visitor callbacks for all
>> sorts of int types, but except for type_uint64 and type_size,
>> none of them have ever been supplied (the generic implementation
>> based on using type_int then bounds-checking works just fine).
>> In the interest of simplicity, it's easier to make the visitor
>> callback interface not have to worry about the other sizes.
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>

> | +
> | +    /* Only required to visit uint64 differently than (*type_int)().  */
> 
> If you don't supply it, what happens for uint64_t values that aren't
> representable as int64_t?
> 
> | +    void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name,

> Answering my "what happens" question:
> 
> * Input visitor
> 
>   If your type_int() accepts large positive input values and casts them
>   to the corresponding large negative value, *obj = value will cast them
>   right back, and the sloppiness cancels out.
> 
>   If it rejects them, they stay rejected.
> 
> * Output visitor
> 
>   You'll output large positive values as the corresponding large
>   negative value.
> 
> I doubt not defining this makes much sense.  Do we have such visitors?

Yes (qapi-dealloc-visitor.c gets away with it, but qmp-input-visitor.c,
qmp-output-visitor.c, string-input-visitor.c, and
string-output-visitor.c are all afflicted). But we shouldn't. For my
next spin of this patch, I'll first add another patch that guarantees
that all visitors have both signed and unsigned int handled correctly.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* [Qemu-devel] blkdebug event names [was: What to do about QAPI naming convention violations]
  2015-11-10 14:35               ` [Qemu-devel] What to do about QAPI naming convention violations (was: [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants) Markus Armbruster
@ 2015-11-16 22:13                 ` Eric Blake
  2015-11-17  7:38                   ` Markus Armbruster
  0 siblings, 1 reply; 75+ messages in thread
From: Eric Blake @ 2015-11-16 22:13 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, qemu block, mdroth

[-- Attachment #1: Type: text/plain, Size: 1739 bytes --]

On 11/10/2015 07:35 AM, Markus Armbruster wrote:

>>> Oddballs not related to case:
>>>
>>> * enum BlkdebugEvent uses '.' in member names

> I had a closer look at how the screwy names are used in QMP to see how
> much of the mess is fixable within reason.
> 

> BlkdebugEvent is related to the external blkdebug interface described by
> docs/blkdebug.txt.  The two are actually decoupled, i.e. changing the
> QAPI names doesn't affect the external debugging interface, and vice
> versa.  Making them different can only cause confusion, though.  Not
> sure we can fix the names.

I think that having block/blkdebug.c:event_name[] duplicate qapi
BlkdebugEvent is a mistake, and that we are better off unifying them.
The other question is whether backwards compatibility is important here,
or if we can just break the naming conventions to something sane.  That
is, if the primary user of blkdebug is our testsuite, and we fix our
testsuite to match the new names, will we be breaking external users?
Libvirt certainly doesn't expose blkdebug, and I doubt any other
external wrapper will be that upset if we force better names here.

> 
> BlkdebugSetStateOptions and BlockdevDriver are input for blockdev-add.
> Fixable.  May not even need backward compatibility.

Yep, I concur that blockdev-add is not stable yet, and that there are no
other QMP uses of BlkdebugEvent, so unless anyone else complains, I
think we can make the change to conventional spelling.

At this point, I think 2.5 is too late, so the change will have to go
into 2.6, but I'm preparing a patch for fixing this interface.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 75+ messages in thread

* Re: [Qemu-devel] blkdebug event names [was: What to do about QAPI naming convention violations]
  2015-11-16 22:13                 ` [Qemu-devel] blkdebug event names [was: What to do about QAPI naming convention violations] Eric Blake
@ 2015-11-17  7:38                   ` Markus Armbruster
  0 siblings, 0 replies; 75+ messages in thread
From: Markus Armbruster @ 2015-11-17  7:38 UTC (permalink / raw)
  To: Eric Blake; +Cc: Kevin Wolf, qemu-devel, qemu block, mdroth

Eric Blake <eblake@redhat.com> writes:

> On 11/10/2015 07:35 AM, Markus Armbruster wrote:
>
>>>> Oddballs not related to case:
>>>>
>>>> * enum BlkdebugEvent uses '.' in member names
>
>> I had a closer look at how the screwy names are used in QMP to see how
>> much of the mess is fixable within reason.
>> 
>
>> BlkdebugEvent is related to the external blkdebug interface described by
>> docs/blkdebug.txt.  The two are actually decoupled, i.e. changing the
>> QAPI names doesn't affect the external debugging interface, and vice
>> versa.  Making them different can only cause confusion, though.  Not
>> sure we can fix the names.
>
> I think that having block/blkdebug.c:event_name[] duplicate qapi
> BlkdebugEvent is a mistake, and that we are better off unifying them.
> The other question is whether backwards compatibility is important here,
> or if we can just break the naming conventions to something sane.  That
> is, if the primary user of blkdebug is our testsuite, and we fix our
> testsuite to match the new names, will we be breaking external users?
> Libvirt certainly doesn't expose blkdebug, and I doubt any other
> external wrapper will be that upset if we force better names here.
>
>> 
>> BlkdebugSetStateOptions and BlockdevDriver are input for blockdev-add.
>> Fixable.  May not even need backward compatibility.
>
> Yep, I concur that blockdev-add is not stable yet, and that there are no
> other QMP uses of BlkdebugEvent, so unless anyone else complains, I
> think we can make the change to conventional spelling.
>
> At this point, I think 2.5 is too late, so the change will have to go
> into 2.6, but I'm preparing a patch for fixing this interface.

Definitely 2.6.  Make sure to cc: Kevin (blkdebug maintainer).

^ permalink raw reply	[flat|nested] 75+ messages in thread

end of thread, other threads:[~2015-11-17  7:38 UTC | newest]

Thread overview: 75+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-04  6:20 [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 01/27] qapi: Use generated TestStruct machinery in tests Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 02/27] qapi: Strengthen test of TestStructList Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 03/27] qapi: Plug leaks in test-qmp-* Eric Blake
2015-11-04  8:19   ` Markus Armbruster
2015-11-04 17:24     ` Eric Blake
2015-11-04 17:44       ` Markus Armbruster
2015-11-05 13:09         ` Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 04/27] qapi: Simplify error testing " Eric Blake
2015-11-04  8:40   ` Markus Armbruster
2015-11-04 21:05     ` Eric Blake
2015-11-05  7:53       ` Markus Armbruster
2015-11-05 15:04         ` Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 05/27] qapi: More tests of alternate output Eric Blake
2015-11-04  9:04   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 06/27] qapi: Test failure in middle of array parse Eric Blake
2015-11-04  9:07   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 07/27] qapi: More tests of input arrays Eric Blake
2015-11-04  9:11   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 08/27] qapi: Provide nicer array names in introspection Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 09/27] qapi-introspect: Document lack of sorting Eric Blake
2015-11-04 10:09   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 10/27] qapi: Track simple union tag in object.local_members Eric Blake
2015-11-04 11:02   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 11/27] qapi-types: Consolidate gen_struct() and gen_union() Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 12/27] qapi-types: Simplify gen_struct_field[s] Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 13/27] qapi: Drop obsolete tag value collision assertions Eric Blake
2015-11-04 13:30   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 14/27] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
2015-11-04 13:36   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 15/27] qapi: Simplify QAPISchemaObjectTypeMember.check() Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 16/27] qapi: Eliminate QAPISchemaObjectType.check() variable members Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 17/27] qapi: Clean up after previous commit Eric Blake
2015-11-04 13:43   ` Markus Armbruster
2015-11-04 23:03     ` Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 18/27] qapi: Factor out QAPISchemaObjectTypeMember.check_clash() Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 19/27] qapi: Check for qapi collisions of flat union branches Eric Blake
2015-11-04 19:01   ` Markus Armbruster
2015-11-04 23:11     ` Eric Blake
2015-11-04 23:25       ` Eric Blake
2015-11-05  7:59         ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 20/27] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
2015-11-04 19:02   ` Markus Armbruster
2015-11-04 23:12     ` Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 21/27] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
2015-11-05 15:29   ` [Qemu-devel] [PATCH RFC 0/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 1/5] qapi: Generate a sed script to help eliminate camel_to_upper() Markus Armbruster
2015-11-05 15:29     ` [Qemu-devel] [PATCH RFC 2/5] Revert "qapi: Generate a sed script to help eliminate camel_to_upper()" Markus Armbruster
2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
2015-11-05 16:01       ` Daniel P. Berrange
2015-11-05 16:41         ` Eric Blake
2015-11-05 22:36           ` Eric Blake
2015-11-06 10:03           ` Markus Armbruster
2015-11-06 13:35             ` Markus Armbruster
2015-11-10 14:35               ` [Qemu-devel] What to do about QAPI naming convention violations (was: [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants) Markus Armbruster
2015-11-16 22:13                 ` [Qemu-devel] blkdebug event names [was: What to do about QAPI naming convention violations] Eric Blake
2015-11-17  7:38                   ` Markus Armbruster
2015-11-09  9:34         ` [Qemu-devel] [PATCH RFC 3/5] qapi: Use common name mangling for enumeration constants Markus Armbruster
2015-11-09 10:53           ` Daniel P. Berrange
2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 4/5] crypto: Drop name mangling override Markus Armbruster
2015-11-05 15:30     ` [Qemu-devel] [PATCH RFC 5/5] Revert "qapi: allow override of default enum prefix naming" Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 22/27] qapi: Remove outdated tests related to QMP/branch collisions Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 23/27] qapi: Simplify visiting of alternate types Eric Blake
2015-11-05 17:01   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 24/27] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 25/27] qapi: Add positive tests to qapi-schema-test Eric Blake
2015-11-05 18:44   ` Markus Armbruster
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 26/27] qapi: Remove dead visitor code Eric Blake
2015-11-05 19:05   ` Markus Armbruster
2015-11-11  6:13     ` Eric Blake
2015-11-04  6:20 ` [Qemu-devel] [PATCH v9 27/27] qapi: Simplify visits of optional fields Eric Blake
2015-11-04 10:22 ` [Qemu-devel] [PATCH v9 00/27] alternate layout (post-introspection cleanups, subset C) Markus Armbruster
2015-11-04 15:06   ` Eric Blake
2015-11-04 18:04     ` Markus Armbruster
2015-11-05 19:45 ` Markus Armbruster

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.