qapi: Improve qobject input visitor error reporting

Error messages refer to nodes of the QObject being visited by name.
Trouble is the names are sometimes less than helpful:

* The name of the root QObject is whatever @name argument got passed
  to the visitor, except NULL gets mapped to "null".  We commonly pass
  NULL.  Not good.

  Avoiding errors "at the root" mitigates.  For instance,
  visit_start_struct() can only fail when the visited object is not a
  dictionary, and we commonly ensure it is beforehand.

* The name of a QDict's member is the member key.  Good enough only
  when this happens to be unique.

* The name of a QList's member is "null".  Not good.

Improve error messages by referring to nodes by path instead, as
follows:

* The path of the root QObject is whatever @name argument got passed
  to the visitor, except NULL gets mapped to "<anonymous>".

* The path of a root QDict's member is the member key.

* The path of a root QList's member is "[%u]", where %u is the list
  index, starting at zero.

* The path of a non-root QDict's member is the path of the QDict
  concatenated with "." and the member key.

* The path of a non-root QList's member is the path of the QList
  concatenated with "[%u]", where %u is the list index.

For example, the incorrect QMP command

    { "execute": "blockdev-add", "arguments": { "node-name": "foo", "driver": "raw", "file": {"driver": "file" } } }

now fails with

    {"error": {"class": "GenericError", "desc": "Parameter 'file.filename' is missing"}}

instead of

    {"error": {"class": "GenericError", "desc": "Parameter 'filename' is missing"}}

and

    { "execute": "input-send-event", "arguments": { "device": "bar", "events": [ [] ] } }

now fails with

    {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'events[0]', expected: object"}}

instead of

    {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'null', expected: QDict"}}

Aside: calling the thing "parameter" is suboptimal for QMP, because
the root object is "arguments" there.

The qobject output visitor doesn't have this problem because it should
not fail.  Same for dealloc and clone visitors.

The string visitors don't have this problem because they visit just
one value, whose name needs to be passed to the visitor as @name.  The
string output visitor shouldn't fail anyway.

The options visitor uses QemuOpts names.  Their name space is flat, so
the use of QDict member keys as names is fine.  NULL names used with
roots and lists could conceivably result in bad error messages.  Left
for another day.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1488544368-30622-15-git-send-email-armbru@redhat.com>
2 files changed
tree: 7aa1635b85662333f32640eccfd59d09cead0a90
  1. audio/
  2. backends/
  3. block/
  4. bsd-user/
  5. chardev/
  6. contrib/
  7. crypto/
  8. default-configs/
  9. disas/
  10. docs/
  11. fpu/
  12. fsdev/
  13. gdb-xml/
  14. hw/
  15. include/
  16. io/
  17. libdecnumber/
  18. linux-headers/
  19. linux-user/
  20. migration/
  21. nbd/
  22. net/
  23. pc-bios/
  24. po/
  25. qapi/
  26. qga/
  27. qobject/
  28. qom/
  29. replay/
  30. roms/
  31. scripts/
  32. slirp/
  33. stubs/
  34. target/
  35. tcg/
  36. tests/
  37. trace/
  38. ui/
  39. util/
  40. .dir-locals.el
  41. .exrc
  42. .gitignore
  43. .gitmodules
  44. .mailmap
  45. .shippable.yml
  46. .travis.yml
  47. accel.c
  48. arch_init.c
  49. atomic_template.h
  50. balloon.c
  51. block.c
  52. blockdev-nbd.c
  53. blockdev.c
  54. blockjob.c
  55. bootdevice.c
  56. bt-host.c
  57. bt-vhci.c
  58. Changelog
  59. CODING_STYLE
  60. configure
  61. COPYING
  62. COPYING.LIB
  63. cpu-exec-common.c
  64. cpu-exec.c
  65. cpus-common.c
  66. cpus.c
  67. cputlb.c
  68. device-hotplug.c
  69. device_tree.c
  70. disas.c
  71. dma-helpers.c
  72. dump.c
  73. exec.c
  74. gdbstub.c
  75. HACKING
  76. hax-stub.c
  77. hmp-commands-info.hx
  78. hmp-commands.hx
  79. hmp.c
  80. hmp.h
  81. ioport.c
  82. iothread.c
  83. kvm-all.c
  84. kvm-stub.c
  85. LICENSE
  86. MAINTAINERS
  87. Makefile
  88. Makefile.objs
  89. Makefile.target
  90. memory.c
  91. memory_ldst.inc.c
  92. memory_mapping.c
  93. module-common.c
  94. monitor.c
  95. numa.c
  96. os-posix.c
  97. os-win32.c
  98. page_cache.c
  99. qapi-schema.json
  100. qdev-monitor.c
  101. qdict-test-data.txt
  102. qemu-bridge-helper.c
  103. qemu-doc.texi
  104. qemu-ga.texi
  105. qemu-img-cmds.hx
  106. qemu-img.c
  107. qemu-img.texi
  108. qemu-io-cmds.c
  109. qemu-io.c
  110. qemu-nbd.c
  111. qemu-nbd.texi
  112. qemu-option-trace.texi
  113. qemu-options-wrapper.h
  114. qemu-options.h
  115. qemu-options.hx
  116. qemu-seccomp.c
  117. qemu-tech.texi
  118. qemu.nsi
  119. qemu.sasl
  120. qmp.c
  121. qtest.c
  122. README
  123. replication.c
  124. replication.h
  125. rules.mak
  126. softmmu_template.h
  127. spice-qemu-char.c
  128. tcg-runtime.c
  129. tci.c
  130. thunk.c
  131. tpm.c
  132. trace-events
  133. translate-all.c
  134. translate-all.h
  135. translate-common.c
  136. user-exec-stub.c
  137. user-exec.c
  138. VERSION
  139. version.rc
  140. vl.c
  141. xen-common-stub.c
  142. xen-common.c
  143. xen-hvm-stub.c
  144. xen-hvm.c
  145. xen-mapcache.c