No longer RFC, but depends on Markus' pull-qapi-2015-09-21 tag (https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05257.html) which had not been merged as of this email.
Also available at this location (although I may rebase it): git fetch git://repo.or.cz/qemu/ericb.git qapi http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi 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 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 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 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 v5: 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. Although v1-v4 didn't get much review, here's a backport-diff to v4 in case it proves useful. Key: [----] : patches are identical [####] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/46:[down] 'qapi: Sort qapi-schema tests' 002/46:[0006] [FC] 'qapi: Clean up qapi.py per pep8' 003/46:[down] 'qapi: Test for C member name collisions' 004/46:[0006] [FC] 'qapi: Add tests for empty unions' 005/46:[0018] [FC] 'qapi: Test use of 'number' within alternates' 006/46:[down] 'qapi: Improve 'include' error message' 007/46:[----] [-C] 'qapi: Don't pass pre-existing error to later call' 008/46:[down] 'qapi: Reuse code for flat union base validation' 009/46:[0126] [FC] 'qapi: Use consistent generated code patterns' 010/46:[down] 'qapi: Merge generation of per-member visits' 011/46:[down] 'qapi: Don't use info as witness of implicit object type' 012/46:[down] 'qapi: Track location that created an implicit type' 013/46:[down] 'qapi: Track owner of each object member' 014/46:[down] 'qapi: Detect collisions in C member names' 015/46:[down] 'qapi: Defer duplicate member checks to schema check()' 016/46:[down] 'qapi: Detect base class loops' 017/46:[----] [--] 'qapi: Provide nicer array names in introspection' 018/46:[down] 'qapi-introspect: Guarantee particular sorting' 019/46:[0053] [FC] 'qapi: Simplify visiting of alternate types' 020/46:[0005] [FC] 'qapi: Fix alternates that accept 'number' but not 'int'' 021/46:[down] 'qmp: Fix reference-counting of qnull on empty output visit' 022/46:[down] 'qapi: Don't abuse stack to track qmp-output root' 023/46:[0007] [FC] 'qapi: Remove dead visitor code' 024/46:[0024] [FC] 'qapi: Document visitor interfaces' 025/46:[----] [--] 'qapi: Plug leaks in test-qmp-input-visitor' 026/46:[----] [-C] 'qapi: Test failure in middle of array parse' 027/46:[down] 'qapi: Simplify visits of optional fields' 028/46:[0023] [FC] 'qapi: Rework deallocation of partial struct' 029/46:[0016] [FC] 'qapi: Change visit_type_FOO() to no longer return partial objects' 030/46:[----] [--] 'net: use Netdev instead of NetClientOptions in client init' 031/46:[0018] [FC] 'qapi: use 'type' in generated C code to match QMP union wire form' 032/46:[0008] [FC] 'qapi: Hide tag_name data member of variants' 033/46:[----] [--] 'vnc: hoist allocation of VncBasicInfo to callers' 034/46:[0022] [FC] 'qapi: Unbox base members' 035/46:[0024] [FC] 'qapi-visit: Remove redundant functions for flat union base' 036/46:[----] [--] 'qapi: Avoid use of 'data' member of qapi unions' 037/46:[0002] [FC] 'qapi: Forbid empty unions and useless alternates' 038/46:[0012] [FC] 'qapi: Drop useless 'data' member of unions' 039/46:[0083] [FC] 'qapi: Plumb in 'box' to qapi generator lower levels' 040/46:[0010] [FC] 'qapi: Implement boxed structs for commands/events' 041/46:[0008] [FC] 'qapi: Support boxed unions' 042/46:[down] 'qapi: support implicit structs in OptsVisitor' 043/46:[----] [-C] 'qapi: Change Netdev into a flat union' 044/46:[----] [--] 'net: Use correct type for bool flag' 045/46:[----] [--] 'net: Complete qapi-fication of netdev_add' 046/46:[down] 'qapi: Allow anonymous base for flat union' Eric Blake (43): qapi: Sort qapi-schema tests qapi: Clean up qapi.py per pep8 qapi: Test for C member name collisions qapi: Add tests for empty unions qapi: Test use of 'number' within alternates qapi: Improve 'include' error message qapi: Don't pass pre-existing error to later call qapi: Reuse code for flat union base validation qapi: Use consistent generated code patterns qapi: Merge generation of per-member visits qapi: Don't use info as witness of implicit object type qapi: Track location that created an implicit type qapi: Track owner of each object member qapi: Detect collisions in C member names qapi: Defer duplicate member checks to schema check() qapi: Detect base class loops qapi: Provide nicer array names in introspection qapi-introspect: Guarantee particular sorting qapi: Simplify visiting of alternate types qapi: Fix alternates that accept 'number' but not 'int' qmp: Fix reference-counting of qnull on empty output visit qapi: Don't abuse stack to track qmp-output root qapi: Remove dead visitor code qapi: Document visitor interfaces qapi: Plug leaks in test-qmp-input-visitor qapi: Test failure in middle of array parse qapi: Simplify visits of optional fields qapi: Rework deallocation of partial struct qapi: Change visit_type_FOO() to no longer return partial objects qapi: use 'type' in generated C code to match QMP union wire form qapi: Hide tag_name data member of variants vnc: hoist allocation of VncBasicInfo to callers qapi: Unbox base members qapi-visit: Remove redundant functions for flat union base qapi: Avoid use of 'data' member of qapi unions qapi: Forbid empty unions and useless alternates qapi: Drop useless 'data' member of unions qapi: Plumb in 'box' to qapi generator lower levels qapi: Implement boxed structs for commands/events qapi: Support boxed unions net: Use correct type for bool flag net: Complete qapi-fication of netdev_add qapi: Allow anonymous base for flat union Kővágó, Zoltán (3): net: use Netdev instead of NetClientOptions in client init qapi: support implicit structs in OptsVisitor qapi: Change Netdev into a flat union block/qcow2.c | 2 +- block/vmdk.c | 2 +- blockdev.c | 34 +- docs/qapi-code-gen.txt | 98 ++-- hmp.c | 18 +- hw/arm/musicpal.c | 2 +- hw/core/qdev-properties-system.c | 2 +- hw/input/hid.c | 2 +- hw/input/ps2.c | 2 +- hw/input/virtio-input-hid.c | 2 +- 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_fp.c | 2 +- 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 | 6 +- 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/usb/dev-network.c | 4 +- include/net/net.h | 7 +- include/qapi/visitor-impl.h | 60 ++- include/qapi/visitor.h | 225 ++++++++- monitor.c | 14 +- net/clients.h | 20 +- net/dump.c | 8 +- net/hub.c | 24 +- net/l2tpv3.c | 8 +- net/net.c | 180 +++---- net/netmap.c | 6 +- net/slirp.c | 8 +- net/socket.c | 10 +- net/tap-win32.c | 8 +- net/tap.c | 28 +- net/vde.c | 8 +- net/vhost-user.c | 14 +- numa.c | 4 +- qapi-schema.json | 72 ++- qapi/introspect.json | 22 +- qapi/opts-visitor.c | 17 +- qapi/qapi-dealloc-visitor.c | 26 - qapi/qapi-visit-core.c | 164 +++---- qapi/qmp-input-visitor.c | 11 +- qapi/qmp-output-visitor.c | 70 +-- qapi/string-input-visitor.c | 3 +- qemu-char.c | 24 +- qmp-commands.hx | 2 +- scripts/qapi-commands.py | 123 +++-- scripts/qapi-event.py | 92 ++-- scripts/qapi-introspect.py | 21 +- scripts/qapi-types.py | 86 +--- scripts/qapi-visit.py | 223 +++++---- scripts/qapi.py | 528 ++++++++++++++------- tests/Makefile | 170 +++++-- tests/qapi-schema/alternate-empty.err | 1 + ...at-union-bad-base.exit => alternate-empty.exit} | 0 tests/qapi-schema/alternate-empty.json | 2 + ...flat-union-bad-base.out => alternate-empty.out} | 0 tests/qapi-schema/alternate-good.out | 1 - tests/qapi-schema/alternate-nested.json | 2 +- tests/qapi-schema/alternate-unknown.json | 2 +- tests/qapi-schema/args-bad-box.err | 1 + tests/qapi-schema/args-bad-box.exit | 1 + tests/qapi-schema/args-bad-box.json | 2 + tests/qapi-schema/args-bad-box.out | 0 tests/qapi-schema/args-box-anon.err | 1 + tests/qapi-schema/args-box-anon.exit | 1 + tests/qapi-schema/args-box-anon.json | 2 + tests/qapi-schema/args-box-anon.out | 0 tests/qapi-schema/args-box-empty.err | 1 + tests/qapi-schema/args-box-empty.exit | 1 + tests/qapi-schema/args-box-empty.json | 2 + tests/qapi-schema/args-box-empty.out | 0 tests/qapi-schema/args-member-array.out | 2 +- tests/qapi-schema/args-name-clash.err | 1 + tests/qapi-schema/args-name-clash.exit | 1 + tests/qapi-schema/args-name-clash.json | 2 + tests/qapi-schema/args-name-clash.out | 0 tests/qapi-schema/args-union.err | 2 +- tests/qapi-schema/args-union.json | 3 +- tests/qapi-schema/base-cycle.err | 1 + tests/qapi-schema/base-cycle.exit | 1 + tests/qapi-schema/base-cycle.json | 3 + tests/qapi-schema/base-cycle.out | 0 tests/qapi-schema/event-case.out | 1 + tests/qapi-schema/flat-union-bad-base.err | 1 - tests/qapi-schema/flat-union-bad-base.json | 13 - tests/qapi-schema/flat-union-base-any.err | 2 +- tests/qapi-schema/flat-union-base-union.err | 2 +- tests/qapi-schema/flat-union-branch-clash.err | 2 +- tests/qapi-schema/flat-union-branch-clash.json | 2 +- tests/qapi-schema/flat-union-branch-clash2.err | 1 + tests/qapi-schema/flat-union-branch-clash2.exit | 1 + tests/qapi-schema/flat-union-branch-clash2.json | 14 + tests/qapi-schema/flat-union-branch-clash2.out | 0 tests/qapi-schema/flat-union-cycle.err | 1 + tests/qapi-schema/flat-union-cycle.exit | 1 + tests/qapi-schema/flat-union-cycle.json | 6 + tests/qapi-schema/flat-union-cycle.out | 0 tests/qapi-schema/flat-union-empty.err | 1 + tests/qapi-schema/flat-union-empty.exit | 1 + tests/qapi-schema/flat-union-empty.json | 4 + tests/qapi-schema/flat-union-empty.out | 0 tests/qapi-schema/flat-union-inline.err | 2 +- tests/qapi-schema/flat-union-inline.json | 4 +- tests/qapi-schema/flat-union-no-base.err | 2 +- tests/qapi-schema/ident-with-escape.out | 2 +- tests/qapi-schema/include-non-file.err | 2 +- tests/qapi-schema/include-non-file.json | 2 +- tests/qapi-schema/indented-expr.out | 4 +- tests/qapi-schema/qapi-schema-test.json | 25 +- tests/qapi-schema/qapi-schema-test.out | 59 ++- tests/qapi-schema/returns-int.out | 2 +- tests/qapi-schema/struct-base-clash-deep.err | 2 +- tests/qapi-schema/struct-base-clash.err | 2 +- tests/qapi-schema/test-qapi.py | 14 +- tests/qapi-schema/union-clash.err | 1 + tests/qapi-schema/union-clash.exit | 1 + tests/qapi-schema/union-clash.json | 3 + tests/qapi-schema/union-clash.out | 0 tests/qapi-schema/union-empty.err | 1 + tests/qapi-schema/union-empty.exit | 1 + tests/qapi-schema/union-empty.json | 2 + tests/qapi-schema/union-empty.out | 0 tests/qapi-schema/union-invalid-base.err | 2 +- tests/test-qmp-commands.c | 40 +- tests/test-qmp-event.c | 8 +- tests/test-qmp-input-visitor.c | 198 +++++++- tests/test-qmp-output-visitor.c | 41 +- tests/test-visitor-serialization.c | 14 +- tpm.c | 2 +- ui/input-keymap.c | 10 +- ui/input-legacy.c | 2 +- ui/input.c | 24 +- ui/spice-core.c | 23 +- ui/vnc.c | 64 +-- util/qemu-sockets.c | 12 +- 158 files changed, 1945 insertions(+), 1249 deletions(-) create mode 100644 tests/qapi-schema/alternate-empty.err rename tests/qapi-schema/{flat-union-bad-base.exit => alternate-empty.exit} (100%) create mode 100644 tests/qapi-schema/alternate-empty.json rename tests/qapi-schema/{flat-union-bad-base.out => alternate-empty.out} (100%) create mode 100644 tests/qapi-schema/args-bad-box.err create mode 100644 tests/qapi-schema/args-bad-box.exit create mode 100644 tests/qapi-schema/args-bad-box.json create mode 100644 tests/qapi-schema/args-bad-box.out create mode 100644 tests/qapi-schema/args-box-anon.err create mode 100644 tests/qapi-schema/args-box-anon.exit create mode 100644 tests/qapi-schema/args-box-anon.json create mode 100644 tests/qapi-schema/args-box-anon.out create mode 100644 tests/qapi-schema/args-box-empty.err create mode 100644 tests/qapi-schema/args-box-empty.exit create mode 100644 tests/qapi-schema/args-box-empty.json create mode 100644 tests/qapi-schema/args-box-empty.out create mode 100644 tests/qapi-schema/args-name-clash.err create mode 100644 tests/qapi-schema/args-name-clash.exit create mode 100644 tests/qapi-schema/args-name-clash.json create mode 100644 tests/qapi-schema/args-name-clash.out create mode 100644 tests/qapi-schema/base-cycle.err create mode 100644 tests/qapi-schema/base-cycle.exit create mode 100644 tests/qapi-schema/base-cycle.json create mode 100644 tests/qapi-schema/base-cycle.out delete mode 100644 tests/qapi-schema/flat-union-bad-base.err delete mode 100644 tests/qapi-schema/flat-union-bad-base.json create mode 100644 tests/qapi-schema/flat-union-branch-clash2.err create mode 100644 tests/qapi-schema/flat-union-branch-clash2.exit create mode 100644 tests/qapi-schema/flat-union-branch-clash2.json create mode 100644 tests/qapi-schema/flat-union-branch-clash2.out create mode 100644 tests/qapi-schema/flat-union-cycle.err create mode 100644 tests/qapi-schema/flat-union-cycle.exit create mode 100644 tests/qapi-schema/flat-union-cycle.json create mode 100644 tests/qapi-schema/flat-union-cycle.out create mode 100644 tests/qapi-schema/flat-union-empty.err create mode 100644 tests/qapi-schema/flat-union-empty.exit create mode 100644 tests/qapi-schema/flat-union-empty.json create mode 100644 tests/qapi-schema/flat-union-empty.out create mode 100644 tests/qapi-schema/union-clash.err create mode 100644 tests/qapi-schema/union-clash.exit create mode 100644 tests/qapi-schema/union-clash.json create mode 100644 tests/qapi-schema/union-clash.out create mode 100644 tests/qapi-schema/union-empty.err create mode 100644 tests/qapi-schema/union-empty.exit create mode 100644 tests/qapi-schema/union-empty.json create mode 100644 tests/qapi-schema/union-empty.out -- 2.4.3