From 3becc939081097ccfed6968771f33d65ce8551eb Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 3 Jul 2024 11:53:10 +0200 Subject: qapi/qom: Document feature unstable of @x-vfio-user-server Commit 8f9a9259d32c added ObjectType member @x-vfio-user-server with feature unstable, but neglected to explain why it is unstable. Do that now. Fixes: 8f9a9259d32c (vfio-user: define vfio-user-server object) Cc: Elena Ufimtseva Cc: John G Johnson Cc: Jagannathan Raman Cc: qemu-stable@nongnu.org Signed-off-by: Markus Armbruster Message-ID: <20240703095310.1242102-1-armbru@redhat.com> Reviewed-by: John Snow [Indentation fixed] --- qapi/qom.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qapi/qom.json b/qapi/qom.json index 8e75a41..3e52aec 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -1024,7 +1024,8 @@ # # Features: # -# @unstable: Member @x-remote-object is experimental. +# @unstable: Members @x-remote-object and @x-vfio-user-server are +# experimental. # # Since: 6.0 ## -- cgit v1.1 From fbcb6e0c487abd09cf1fab7913302174c3a2fa16 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 11 Jul 2024 13:22:24 +0200 Subject: qapi/pci: Clean up documentation around PciDeviceClass PciDeviceInfo's doc comment has a note on PciDeviceClass member @desc. Since the note applies always, not just within PciDeviceInfo, merge it into PciDeviceClass's description of member @desc. Signed-off-by: Markus Armbruster Message-ID: <20240711112228.2140606-2-armbru@redhat.com> Reviewed-by: Michael S. Tsirkin Reviewed-by: John Snow --- qapi/pci.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qapi/pci.json b/qapi/pci.json index 8287d15..9717992 100644 --- a/qapi/pci.json +++ b/qapi/pci.json @@ -93,7 +93,8 @@ # # Information about the Class of a PCI device # -# @desc: a string description of the device's class +# @desc: a string description of the device's class (not stable, and +# should only be treated as informational) # # @class: the class code of the device # @@ -146,9 +147,6 @@ # # @regions: a list of the PCI I/O regions associated with the device # -# .. note:: The contents of @class_info.desc are not stable and should -# only be treated as informational. -# # Since: 0.14 ## { 'struct': 'PciDeviceInfo', -- cgit v1.1 From d07f0efcbca66178d42f8c9c4f624e9de517100a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 11 Jul 2024 13:22:25 +0200 Subject: qapi/machine: Clean up documentation around CpuInstanceProperties CpuInstanceProperties' doc comment describes its members as properties to be passed to device_add when hot-plugging a CPU. This was in fact the initial use of this type, with query-hotpluggable-cpus: letting management applications find out what properties need to be passed with device_add to hot-plug a CPU. We've since added other uses: set-numa-node (commit 419fcdec3c1 and f3be67812c2), and query-cpus-fast (commit ce74ee3dea6). These are not about device-add. query-hotpluggable-cpus uses CpuInstanceProperties within HotpluggableCPU. Lift the documentation related to device-add from CpuInstanceProperties to HotpluggableCPU. Signed-off-by: Markus Armbruster Message-ID: <20240711112228.2140606-3-armbru@redhat.com> Reviewed-by: Michael S. Tsirkin Reviewed-by: John Snow --- qapi/machine.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/qapi/machine.json b/qapi/machine.json index f15ad1b..50ff102 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -960,9 +960,7 @@ ## # @CpuInstanceProperties: # -# List of properties to be used for hotplugging a CPU instance, it -# should be passed by management with device_add command when a CPU is -# being hotplugged. +# Properties identifying a CPU. # # Which members are optional and which mandatory depends on the # architecture and board. @@ -996,9 +994,6 @@ # # @thread-id: thread number within the core the CPU belongs to # -# .. note:: Management should be prepared to pass through additional -# properties with device_add. -# # Since: 2.7 ## { 'struct': 'CpuInstanceProperties', @@ -1020,7 +1015,8 @@ # # @type: CPU object type for usage with device_add command # -# @props: list of properties to be used for hotplugging CPU +# @props: list of properties to pass for hotplugging a CPU with +# device_add # # @vcpus-count: number of logical VCPU threads @HotpluggableCPU # provides @@ -1028,6 +1024,9 @@ # @qom-path: link to existing CPU object if CPU is present or omitted # if CPU is not present. # +# .. note:: Management should be prepared to pass through additional +# properties with device_add. +# # Since: 2.7 ## { 'struct': 'HotpluggableCPU', -- cgit v1.1 From dd950220c08938e14abb0357107ca8500cb913c9 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 11 Jul 2024 13:22:26 +0200 Subject: qapi/machine: Clarify query-uuid value when none has been specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When no UUID has been specified, query-uuid returns {"UUID": "00000000-0000-0000-0000-000000000000"} The doc comment calls this "a null UUID", which I find less than clear. RFC 9562 calls it "the nil UUID (all zeroes)", so use that instead. Signed-off-by: Markus Armbruster Message-ID: <20240711112228.2140606-4-armbru@redhat.com> Reviewed-by: Michael S. Tsirkin Reviewed-by: John Snow [Wording improved, commit message adjusted] Reviewed-by: Philippe Mathieu-Daudé --- qapi/machine.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qapi/machine.json b/qapi/machine.json index 50ff102..eb2fd01 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -305,9 +305,8 @@ # # Since: 0.14 # -# .. note:: If no UUID was specified for the guest, a null UUID is -# returned. -# +# .. note:: If no UUID was specified for the guest, the nil UUID (all +# zeroes) is returned. ## { 'struct': 'UuidInfo', 'data': {'UUID': 'str'} } -- cgit v1.1 From 6cab0537926bafbb6be2fc93202611fa5113219b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 11 Jul 2024 13:22:27 +0200 Subject: qapi/sockets: Move deprecation note out of SocketAddress doc comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doc comments are reference documentation for users of QMP. SocketAddress's doc comment contains a deprecation note advising developers to use SocketAddress for new code. Irrelevant for users of QMP. Move the note out of the doc comment. Signed-off-by: Markus Armbruster Message-ID: <20240711112228.2140606-5-armbru@redhat.com> Reviewed-by: John Snow Reviewed-by: Philippe Mathieu-Daudé --- qapi/sockets.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/qapi/sockets.json b/qapi/sockets.json index 4d78d2c..e76fdb9 100644 --- a/qapi/sockets.json +++ b/qapi/sockets.json @@ -179,10 +179,6 @@ # # @type: Transport type # -# .. note:: This type is deprecated in favor of SocketAddress. The -# difference between SocketAddressLegacy and SocketAddress is that -# the latter has fewer ``{}`` on the wire. -# # Since: 1.3 ## { 'union': 'SocketAddressLegacy', @@ -193,6 +189,9 @@ 'unix': 'UnixSocketAddressWrapper', 'vsock': 'VsockSocketAddressWrapper', 'fd': 'FdSocketAddressWrapper' } } +# Note: This type is deprecated in favor of SocketAddress. The +# difference between SocketAddressLegacy and SocketAddress is that the +# latter has fewer ``{}`` on the wire. ## # @SocketAddressType: -- cgit v1.1 From 29a9efb09f95cf54a45d4ed97b82d2158b1a3983 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 11 Jul 2024 13:22:28 +0200 Subject: qapi/ui: Drop note on naming of SpiceQueryMouseMode Doc comments are reference documentation for users of QMP. SpiceQueryMouseMode's doc comment contains a note explaining why it's not named SpiceMouseMode: spice/enums.h has it already. Irrelevant for users of QMP; delete the note. Signed-off-by: Markus Armbruster Message-ID: <20240711112228.2140606-6-armbru@redhat.com> Reviewed-by: John Snow --- qapi/ui.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/qapi/ui.json b/qapi/ui.json index 5bcccbf..df08986 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -273,8 +273,6 @@ # @unknown: No information is available about mouse mode used by the # spice server. # -# .. note:: spice/enums.h has a SpiceMouseMode already, hence the name. -# # Since: 1.1 ## { 'enum': 'SpiceQueryMouseMode', -- cgit v1.1 From a7d07ccd208dc1a8dbd0b03d95761a6424ccb375 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:04 -0400 Subject: docs/qapidoc: factor out do_parse() Factor out the compatibility parser helper into a base class, so it can be shared by other directives. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Message-ID: <20240717021312.606116-3-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 62b3983..b3be829 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -481,7 +481,25 @@ class QAPISchemaGenDepVisitor(QAPISchemaVisitor): super().visit_module(name) -class QAPIDocDirective(Directive): +class NestedDirective(Directive): + def run(self): + raise NotImplementedError + + def do_parse(self, rstlist, node): + """ + Parse rST source lines and add them to the specified node + + Take the list of rST source lines rstlist, parse them as + rST, and add the resulting docutils nodes as children of node. + The nodes are parsed in a way that allows them to include + subheadings (titles) without confusing the rendering of + anything else. + """ + with switch_source_input(self.state, rstlist): + nested_parse_with_titles(self.state, rstlist, node) + + +class QAPIDocDirective(NestedDirective): """Extract documentation from the specified QAPI .json file""" required_argument = 1 @@ -519,18 +537,6 @@ class QAPIDocDirective(Directive): # so they are displayed nicely to the user raise ExtensionError(str(err)) from err - def do_parse(self, rstlist, node): - """Parse rST source lines and add them to the specified node - - Take the list of rST source lines rstlist, parse them as - rST, and add the resulting docutils nodes as children of node. - The nodes are parsed in a way that allows them to include - subheadings (titles) without confusing the rendering of - anything else. - """ - with switch_source_input(self.state, rstlist): - nested_parse_with_titles(self.state, rstlist, node) - def setup(app): """Register qapi-doc directive with Sphinx""" -- cgit v1.1 From 547864f9d4cead4fe70981d2c4ffa5905b40e671 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:05 -0400 Subject: docs/qapidoc: create qmp-example directive This is a directive that creates a syntactic sugar for creating "Example" boxes very similar to the ones already used in the bitmaps.rst document, please see e.g. https://www.qemu.org/docs/master/interop/bitmaps.html#creation-block-dirty-bitmap-add In its simplest form, when a custom title is not needed or wanted, and the example body is *solely* a QMP example: ``` .. qmp-example:: {body} ``` is syntactic sugar for: ``` .. admonition:: Example: .. code-block:: QMP {body} ``` When a custom, plaintext title that describes the example is desired, this form: ``` .. qmp-example:: :title: Defrobnification {body} ``` Is syntactic sugar for: ``` .. admonition:: Example: Defrobnification .. code-block:: QMP {body} ``` Lastly, when Examples are multi-step processes that require non-QMP exposition, have lengthy titles, or otherwise involve prose with rST markup (lists, cross-references, etc), the most complex form: ``` .. qmp-example:: :annotated: This example shows how to use `foo-command`:: {body} For more information, please see `frobnozz`. ``` Is desugared to: ``` .. admonition:: Example: This example shows how to use `foo-command`:: {body} For more information, please see `frobnozz`. ``` Note that :annotated: and :title: options can be combined together, if desired. The primary benefit here being documentation source consistently using the same directive for all forms of examples to ensure consistent visual styling, and ensuring all relevant prose is visually grouped alongside the code literal block. Note that as of this commit, the code-block rST syntax "::" does not apply QMP highlighting; you would need to use ".. code-block:: QMP". The very next commit changes this behavior to assume all "::" code blocks within this directive are QMP blocks. Signed-off-by: John Snow Acked-by: Markus Armbruster Message-ID: <20240717021312.606116-4-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index b3be829..11defcf 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -27,6 +27,7 @@ https://www.sphinx-doc.org/en/master/development/index.html import os import re import textwrap +from typing import List from docutils import nodes from docutils.parsers.rst import Directive, directives @@ -35,6 +36,7 @@ from qapi.error import QAPIError, QAPISemError from qapi.gen import QAPISchemaVisitor from qapi.schema import QAPISchema +from sphinx.directives.code import CodeBlock from sphinx.errors import ExtensionError from sphinx.util.docutils import switch_source_input from sphinx.util.nodes import nested_parse_with_titles @@ -538,10 +540,63 @@ class QAPIDocDirective(NestedDirective): raise ExtensionError(str(err)) from err +class QMPExample(CodeBlock, NestedDirective): + """ + Custom admonition for QMP code examples. + + When the :annotated: option is present, the body of this directive + is parsed as normal rST instead. Code blocks must be explicitly + written by the user, but this allows for intermingling explanatory + paragraphs with arbitrary rST syntax and code blocks for more + involved examples. + + When :annotated: is absent, the directive body is treated as a + simple standalone QMP code block literal. + """ + + required_argument = 0 + optional_arguments = 0 + has_content = True + option_spec = { + "annotated": directives.flag, + "title": directives.unchanged, + } + + def admonition_wrap(self, *content) -> List[nodes.Node]: + title = "Example:" + if "title" in self.options: + title = f"{title} {self.options['title']}" + + admon = nodes.admonition( + "", + nodes.title("", title), + *content, + classes=["admonition", "admonition-example"], + ) + return [admon] + + def run_annotated(self) -> List[nodes.Node]: + content_node: nodes.Element = nodes.section() + self.do_parse(self.content, content_node) + return content_node.children + + def run(self) -> List[nodes.Node]: + annotated = "annotated" in self.options + + if annotated: + content_nodes = self.run_annotated() + else: + self.arguments = ["QMP"] + content_nodes = super().run() + + return self.admonition_wrap(*content_nodes) + + def setup(app): """Register qapi-doc directive with Sphinx""" app.add_config_value("qapidoc_srctree", None, "env") app.add_directive("qapi-doc", QAPIDocDirective) + app.add_directive("qmp-example", QMPExample) return { "version": __version__, -- cgit v1.1 From 76e375fc3c538bd6e4232314f693b56536a50b73 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:06 -0400 Subject: docs/qapidoc: add QMP highlighting to annotated qmp-example blocks For any code literal blocks inside of a qmp-example directive, apply and enforce the QMP lexer/highlighter to those blocks. This way, you won't need to write: ``` .. qmp-example:: :annotated: Blah blah .. code-block:: QMP -> { "lorem": "ipsum" } ``` But instead, simply: ``` .. qmp-example:: :annotated: Blah blah:: -> { "lorem": "ipsum" } ``` Once the directive block is exited, whatever the previous default highlight language was will be restored; localizing the forced QMP lexing to exclusively this directive. Note, if the default language is *already* QMP, this directive will not generate and restore redundant highlight configuration nodes. We may well decide that the default language ought to be QMP for any QAPI reference pages, but this way the directive behaves consistently no matter where it is used. Signed-off-by: John Snow Acked-by: Markus Armbruster Message-ID: <20240717021312.606116-5-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- docs/sphinx/qapidoc.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index 11defcf..738b245 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -26,6 +26,7 @@ https://www.sphinx-doc.org/en/master/development/index.html import os import re +import sys import textwrap from typing import List @@ -36,6 +37,7 @@ from qapi.error import QAPIError, QAPISemError from qapi.gen import QAPISchemaVisitor from qapi.schema import QAPISchema +from sphinx import addnodes from sphinx.directives.code import CodeBlock from sphinx.errors import ExtensionError from sphinx.util.docutils import switch_source_input @@ -545,10 +547,10 @@ class QMPExample(CodeBlock, NestedDirective): Custom admonition for QMP code examples. When the :annotated: option is present, the body of this directive - is parsed as normal rST instead. Code blocks must be explicitly - written by the user, but this allows for intermingling explanatory - paragraphs with arbitrary rST syntax and code blocks for more - involved examples. + is parsed as normal rST, but with any '::' code blocks set to use + the QMP lexer. Code blocks must be explicitly written by the user, + but this allows for intermingling explanatory paragraphs with + arbitrary rST syntax and code blocks for more involved examples. When :annotated: is absent, the directive body is treated as a simple standalone QMP code block literal. @@ -562,6 +564,33 @@ class QMPExample(CodeBlock, NestedDirective): "title": directives.unchanged, } + def _highlightlang(self) -> addnodes.highlightlang: + """Return the current highlightlang setting for the document""" + node = None + doc = self.state.document + + if hasattr(doc, "findall"): + # docutils >= 0.18.1 + for node in doc.findall(addnodes.highlightlang): + pass + else: + for elem in doc.traverse(): + if isinstance(elem, addnodes.highlightlang): + node = elem + + if node: + return node + + # No explicit directive found, use defaults + node = addnodes.highlightlang( + lang=self.env.config.highlight_language, + force=False, + # Yes, Sphinx uses this value to effectively disable line + # numbers and not 0 or None or -1 or something. ¯\_(ツ)_/¯ + linenothreshold=sys.maxsize, + ) + return node + def admonition_wrap(self, *content) -> List[nodes.Node]: title = "Example:" if "title" in self.options: @@ -576,8 +605,24 @@ class QMPExample(CodeBlock, NestedDirective): return [admon] def run_annotated(self) -> List[nodes.Node]: + lang_node = self._highlightlang() + content_node: nodes.Element = nodes.section() + + # Configure QMP highlighting for "::" blocks, if needed + if lang_node["lang"] != "QMP": + content_node += addnodes.highlightlang( + lang="QMP", + force=False, # "True" ignores lexing errors + linenothreshold=lang_node["linenothreshold"], + ) + self.do_parse(self.content, content_node) + + # Restore prior language highlighting, if needed + if lang_node["lang"] != "QMP": + content_node += addnodes.highlightlang(**lang_node.attributes) + return content_node.children def run(self) -> List[nodes.Node]: -- cgit v1.1 From e597a73a8c561141f757b3b1ef13470ebdec5640 Mon Sep 17 00:00:00 2001 From: Harmonie Snow Date: Tue, 16 Jul 2024 22:13:07 -0400 Subject: docs/sphinx: add CSS styling for qmp-example directive Add CSS styling for qmp-example directives to increase readability and consistently style all example blocks. Signed-off-by: Harmonie Snow Signed-off-by: John Snow Acked-by: Markus Armbruster Message-ID: <20240717021312.606116-6-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- docs/sphinx-static/theme_overrides.css | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index c70ef95..965ecac 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -87,6 +87,55 @@ div[class^="highlight"] pre { padding-bottom: 1px; } +/* qmp-example directive styling */ + +.rst-content .admonition-example { + /* do not apply the standard admonition background */ + background-color: transparent; + border: solid #ffd2ed 1px; +} + +.rst-content .admonition-example > .admonition-title:before { + content: "▷"; +} + +.rst-content .admonition-example > .admonition-title { + background-color: #5980a6; +} + +.rst-content .admonition-example > div[class^="highlight"] { + /* make code boxes take up the full width of the admonition w/o margin */ + margin-left: -12px; + margin-right: -12px; + + border-top: 1px solid #ffd2ed; + border-bottom: 1px solid #ffd2ed; + border-left: 0px; + border-right: 0px; +} + +.rst-content .admonition-example > div[class^="highlight"]:nth-child(2) { + /* If a code box is the second element in an example admonition, + * it is the first child after the title. let it sit flush against + * the title. */ + margin-top: -12px; + border-top: 0px; +} + +.rst-content .admonition-example > div[class^="highlight"]:last-child { + /* If a code box is the final element in an example admonition, don't + * render margin below it; let it sit flush with the end of the + * admonition box */ + margin-bottom: -12px; + border-bottom: 0px; +} + +.rst-content .admonition-example .highlight { + background-color: #fffafd; +} + +/* end qmp-example styling */ + @media screen { /* content column -- cgit v1.1 From 14b48aaab92de5962e8cdb563875fc6937ef916e Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:08 -0400 Subject: qapi: convert "Example" sections without titles Use the no-option form of ".. qmp-example::" to convert any Examples that do not have any form of caption or explanation whatsoever. Note that in a few cases, example sections are split into two or more separate example blocks. This is only done stylistically to create a delineation between two or more logically independent examples. See commit-3: "docs/qapidoc: create qmp-example directive", for a detailed explanation of this custom directive syntax. See commit+3: "qapi: remove "Example" doc section" for a detailed explanation of why. Note: an empty "TODO" line was added to announce-self to keep the example from floating up into the body; this will be addressed more rigorously in the new qapidoc generator. Signed-off-by: John Snow Message-ID: <20240717021312.606116-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster [Markup fixed in one place] Signed-off-by: Markus Armbruster --- qapi/acpi.json | 4 +-- qapi/block-core.json | 64 +++++++++++++++++++++++++----------------------- qapi/block.json | 18 ++++++++------ qapi/char.json | 24 +++++++++++------- qapi/control.json | 8 +++--- qapi/dump.json | 8 +++--- qapi/machine-target.json | 2 +- qapi/machine.json | 38 ++++++++++++++-------------- qapi/migration.json | 58 +++++++++++++++++++++---------------------- qapi/misc-target.json | 22 ++++++++--------- qapi/misc.json | 32 ++++++++++++------------ qapi/net.json | 22 ++++++++++------- qapi/pci.json | 2 +- qapi/qdev.json | 10 +++++--- qapi/qom.json | 8 +++--- qapi/replay.json | 8 +++--- qapi/rocker.json | 8 +++--- qapi/run-state.json | 32 ++++++++++++------------ qapi/tpm.json | 6 ++--- qapi/trace.json | 4 +-- qapi/transaction.json | 2 +- qapi/ui.json | 34 ++++++++++++------------- qapi/vfio.json | 2 +- qapi/virtio.json | 2 +- qapi/yank.json | 4 +-- 25 files changed, 219 insertions(+), 203 deletions(-) diff --git a/qapi/acpi.json b/qapi/acpi.json index aa4dbe5..045dab6 100644 --- a/qapi/acpi.json +++ b/qapi/acpi.json @@ -111,7 +111,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-acpi-ospm-status" } # <- { "return": [ { "device": "d1", "slot": "0", "slot-type": "DIMM", "source": 1, "status": 0}, @@ -131,7 +131,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # <- { "event": "ACPI_DEVICE_OST", # "data": { "info": { "device": "d1", "slot": "0", diff --git a/qapi/block-core.json b/qapi/block-core.json index 096bdbe..84a020a 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -764,7 +764,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-block" } # <- { @@ -1168,7 +1168,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-blockstats" } # <- { @@ -1461,7 +1461,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "block_resize", # "arguments": { "device": "scratch", "size": 1073741824 } } @@ -1680,7 +1680,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-snapshot-sync", # "arguments": { "device": "ide-hd0", @@ -1711,7 +1711,7 @@ # # Since: 2.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-add", # "arguments": { "driver": "qcow2", @@ -1857,7 +1857,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-commit", # "arguments": { "device": "virtio0", @@ -1895,7 +1895,7 @@ # # Since: 1.6 # -# Example: +# .. qmp-example:: # # -> { "execute": "drive-backup", # "arguments": { "device": "drive0", @@ -1921,7 +1921,7 @@ # # Since: 2.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-backup", # "arguments": { "device": "src-id", @@ -1945,7 +1945,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-named-block-nodes" } # <- { "return": [ { "ro":false, @@ -2126,7 +2126,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "drive-mirror", # "arguments": { "device": "ide-hd0", @@ -2303,7 +2303,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-add", # "arguments": { "node": "drive0", "name": "bitmap0" } } @@ -2327,7 +2327,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-remove", # "arguments": { "node": "drive0", "name": "bitmap0" } } @@ -2350,7 +2350,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-clear", # "arguments": { "node": "drive0", "name": "bitmap0" } } @@ -2371,7 +2371,7 @@ # # Since: 4.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-enable", # "arguments": { "node": "drive0", "name": "bitmap0" } } @@ -2392,7 +2392,7 @@ # # Since: 4.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-disable", # "arguments": { "node": "drive0", "name": "bitmap0" } } @@ -2424,7 +2424,7 @@ # # Since: 4.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-dirty-bitmap-merge", # "arguments": { "node": "drive0", "target": "bitmap0", @@ -2533,7 +2533,7 @@ # # Since: 2.6 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-mirror", # "arguments": { "device": "ide-hd0", @@ -2858,7 +2858,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-stream", # "arguments": { "device": "virtio0", @@ -4797,7 +4797,7 @@ # # Since: 2.9 # -# Examples: +# .. qmp-example:: # # -> { "execute": "blockdev-add", # "arguments": { @@ -4811,6 +4811,8 @@ # } # <- { "return": {} } # +# .. qmp-example:: +# # -> { "execute": "blockdev-add", # "arguments": { # "driver": "qcow2", @@ -4895,7 +4897,7 @@ # # Since: 2.9 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-add", # "arguments": { @@ -5544,7 +5546,7 @@ # .. note:: If action is "stop", a STOP event will eventually follow the # BLOCK_IO_ERROR event. # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_IMAGE_CORRUPTED", # "data": { "device": "", "node-name": "drive", "fatal": false, @@ -5593,7 +5595,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_IO_ERROR", # "data": { "device": "ide0-hd1", @@ -5633,7 +5635,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_JOB_COMPLETED", # "data": { "type": "stream", "device": "virtio-disk0", @@ -5668,7 +5670,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_JOB_CANCELLED", # "data": { "type": "stream", "device": "virtio-disk0", @@ -5697,7 +5699,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_JOB_ERROR", # "data": { "device": "ide0-hd1", @@ -5732,7 +5734,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_JOB_READY", # "data": { "device": "drive0", "type": "mirror", "speed": 0, @@ -5760,7 +5762,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # <- { "event": "BLOCK_JOB_PENDING", # "data": { "type": "mirror", "id": "backup_1" }, @@ -5834,7 +5836,7 @@ # # Since: 2.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "block-set-write-threshold", # "arguments": { "node-name": "mydev", @@ -5985,7 +5987,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # <- { "event": "QUORUM_FAILURE", # "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 }, @@ -6070,7 +6072,7 @@ # # Since: 1.7 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-snapshot-internal-sync", # "arguments": { "device": "ide-hd0", @@ -6109,7 +6111,7 @@ # # Since: 1.7 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-snapshot-delete-internal-sync", # "arguments": { "device": "ide-hd0", diff --git a/qapi/block.json b/qapi/block.json index ea81d9e..c8e52bc 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -117,7 +117,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "eject", "arguments": { "id": "ide1-0-1" } } # <- { "return": {} } @@ -161,7 +161,7 @@ # # Since: 2.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-open-tray", # "arguments": { "id": "ide0-1-0" } } @@ -199,7 +199,7 @@ # # Since: 2.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-close-tray", # "arguments": { "id": "ide0-1-0" } } @@ -231,7 +231,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-remove-medium", # "arguments": { "id": "ide0-1-0" } } @@ -272,7 +272,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "blockdev-add", # "arguments": { @@ -397,7 +397,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # <- { "event": "DEVICE_TRAY_MOVED", # "data": { "device": "ide1-cd0", @@ -421,7 +421,7 @@ # # Since: 3.0 # -# Example: +# .. qmp-example:: # # <- { "event": "PR_MANAGER_STATUS_CHANGED", # "data": { "id": "pr-helper0", @@ -463,7 +463,7 @@ # # Since: 1.1 # -# Examples: +# .. qmp-example:: # # -> { "execute": "block_set_io_throttle", # "arguments": { "id": "virtio-blk-pci0/virtio-backend", @@ -483,6 +483,8 @@ # "iops_size": 0 } } # <- { "return": {} } # +# .. qmp-example:: +# # -> { "execute": "block_set_io_throttle", # "arguments": { "id": "ide0-1-0", # "bps": 1000000, diff --git a/qapi/char.json b/qapi/char.json index 5eabf8e..5e4aeb9 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -40,7 +40,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-chardev" } # <- { @@ -86,7 +86,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-chardev-backends" } # <- { @@ -141,7 +141,7 @@ # # Since: 1.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "ringbuf-write", # "arguments": { "device": "foo", @@ -177,7 +177,7 @@ # # Since: 1.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "ringbuf-read", # "arguments": { "device": "foo", @@ -699,19 +699,23 @@ # # Since: 1.4 # -# Examples: +# .. qmp-example:: # # -> { "execute" : "chardev-add", # "arguments" : { "id" : "foo", # "backend" : { "type" : "null", "data" : {} } } } # <- { "return": {} } # +# .. qmp-example:: +# # -> { "execute" : "chardev-add", # "arguments" : { "id" : "bar", # "backend" : { "type" : "file", # "data" : { "out" : "/tmp/bar.log" } } } } # <- { "return": {} } # +# .. qmp-example:: +# # -> { "execute" : "chardev-add", # "arguments" : { "id" : "baz", # "backend" : { "type" : "pty", "data" : {} } } } @@ -735,13 +739,15 @@ # # Since: 2.10 # -# Examples: +# .. qmp-example:: # # -> { "execute" : "chardev-change", # "arguments" : { "id" : "baz", # "backend" : { "type" : "pty", "data" : {} } } } # <- { "return": { "pty" : "/dev/pty/42" } } # +# .. qmp-example:: +# # -> {"execute" : "chardev-change", # "arguments" : { # "id" : "charchannel2", @@ -772,7 +778,7 @@ # # Since: 1.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "chardev-remove", "arguments": { "id" : "foo" } } # <- { "return": {} } @@ -789,7 +795,7 @@ # # Since: 2.10 # -# Example: +# .. qmp-example:: # # -> { "execute": "chardev-send-break", "arguments": { "id" : "foo" } } # <- { "return": {} } @@ -810,7 +816,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # <- { "event": "VSERPORT_CHANGE", # "data": { "id": "channel0", "open": true }, diff --git a/qapi/control.json b/qapi/control.json index fe2af45..950443d 100644 --- a/qapi/control.json +++ b/qapi/control.json @@ -16,7 +16,7 @@ # the QMP greeting message. If the field is not provided, it # means no QMP capabilities will be enabled. (since 2.12) # -# Example: +# .. qmp-example:: # # -> { "execute": "qmp_capabilities", # "arguments": { "enable": [ "oob" ] } } @@ -97,7 +97,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-version" } # <- { @@ -134,7 +134,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-commands" } # <- { @@ -165,7 +165,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "quit" } # <- { "return": {} } diff --git a/qapi/dump.json b/qapi/dump.json index f9aee7e..d8145da 100644 --- a/qapi/dump.json +++ b/qapi/dump.json @@ -94,7 +94,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "dump-guest-memory", # "arguments": { "paging": false, "protocol": "fd:dump" } } @@ -150,7 +150,7 @@ # # Since: 2.6 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-dump" } # <- { "return": { "status": "active", "completed": 1024000, @@ -171,7 +171,7 @@ # # Since: 2.6 # -# Example: +# .. qmp-example:: # # <- { "event": "DUMP_COMPLETED", # "data": { "result": { "total": 1090650112, "status": "completed", @@ -202,7 +202,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-dump-guest-memory-capability" } # <- { "return": { "formats": diff --git a/qapi/machine-target.json b/qapi/machine-target.json index a8d9ec8..7edb876 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -475,7 +475,7 @@ # # Since: 8.2 # -# Example: +# .. qmp-example:: # # <- { "event": "CPU_POLARIZATION_CHANGE", # "data": { "polarization": "horizontal" }, diff --git a/qapi/machine.json b/qapi/machine.json index eb2fd01..193b2b7 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -104,7 +104,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-cpus-fast" } # <- { "return": [ @@ -221,7 +221,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-machines", "arguments": { "compat-props": true } } # <- { "return": [ @@ -319,7 +319,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-uuid" } # <- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } } @@ -353,7 +353,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "system_reset" } # <- { "return": {} } @@ -372,7 +372,7 @@ # request or that it has shut down. Many guests will respond to this # command by prompting the user in some way. # -# Example: +# .. qmp-example:: # # -> { "execute": "system_powerdown" } # <- { "return": {} } @@ -392,7 +392,7 @@ # .. note:: Prior to 4.0, this command does nothing in case the guest # isn't suspended. # -# Example: +# .. qmp-example:: # # -> { "execute": "system_wakeup" } # <- { "return": {} } @@ -443,7 +443,7 @@ # .. note:: Prior to 2.1, this command was only supported for x86 and # s390 VMs. # -# Example: +# .. qmp-example:: # # -> { "execute": "inject-nmi" } # <- { "return": {} } @@ -472,7 +472,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-kvm" } # <- { "return": { "enabled": true, "present": true } } @@ -841,7 +841,7 @@ # # .. caution:: Errors were not reliably returned until 1.1. # -# Example: +# .. qmp-example:: # # -> { "execute": "memsave", # "arguments": { "val": 10, @@ -867,7 +867,7 @@ # # .. caution:: Errors were not reliably returned until 1.1. # -# Example: +# .. qmp-example:: # # -> { "execute": "pmemsave", # "arguments": { "val": 10, @@ -928,7 +928,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-memdev" } # <- { "return": [ @@ -1164,7 +1164,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-balloon" } # <- { "return": { @@ -1188,7 +1188,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # <- { "event": "BALLOON_CHANGE", # "data": { "actual": 944766976 }, @@ -1230,7 +1230,7 @@ # # Since: 8.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-hv-balloon-status-report" } # <- { "return": { @@ -1251,7 +1251,7 @@ # # Since: 8.2 # -# Example: +# .. qmp-example:: # # <- { "event": "HV_BALLOON_STATUS_REPORT", # "data": { "committed": 816640000, "available": 3333054464 }, @@ -1283,7 +1283,7 @@ # Return the amount of initially allocated and present hotpluggable # (if enabled) memory in bytes. # -# Example: +# .. qmp-example:: # # -> { "execute": "query-memory-size-summary" } # <- { "return": { "base-memory": 4294967296, "plugged-memory": 0 } } @@ -1562,7 +1562,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-memory-devices" } # <- { "return": [ { "data": @@ -1596,7 +1596,7 @@ # # Since: 5.1 # -# Example: +# .. qmp-example:: # # <- { "event": "MEMORY_DEVICE_SIZE_CHANGE", # "data": { "id": "vm0", "size": 1073741824, @@ -1854,7 +1854,7 @@ # # Since: 7.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "dumpdtb" } # "arguments": { "filename": "fdt.dtb" } } diff --git a/qapi/migration.json b/qapi/migration.json index 1234bef..3c65720 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -514,7 +514,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-set-capabilities" , "arguments": # { "capabilities": [ { "capability": "xbzrle", "state": true } ] } } @@ -532,7 +532,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-migrate-capabilities" } # <- { "return": [ @@ -1053,7 +1053,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-set-parameters" , # "arguments": { "multifd-channels": 5 } } @@ -1256,7 +1256,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-migrate-parameters" } # <- { "return": { @@ -1280,7 +1280,7 @@ # # Since: 2.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-start-postcopy" } # <- { "return": {} } @@ -1296,7 +1296,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # <- {"timestamp": {"seconds": 1432121972, "microseconds": 744001}, # "event": "MIGRATION", @@ -1315,7 +1315,7 @@ # # Since: 2.6 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 1449669631, "microseconds": 239225}, # "event": "MIGRATION_PASS", "data": {"pass": 2} } @@ -1399,7 +1399,7 @@ # # Since: 3.1 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 2032141960, "microseconds": 417172}, # "event": "COLO_EXIT", "data": {"mode": "primary", "reason": "request" } } @@ -1442,7 +1442,7 @@ # # Since: 2.8 # -# Example: +# .. qmp-example:: # # -> { "execute": "x-colo-lost-heartbeat" } # <- { "return": {} } @@ -1461,7 +1461,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate_cancel" } # <- { "return": {} } @@ -1477,7 +1477,7 @@ # # Since: 2.11 # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-continue" , "arguments": # { "state": "pre-switchover" } } @@ -1610,7 +1610,7 @@ # 6. The 'uri' and 'channels' arguments are mutually exclusive; # exactly one of the two should be present. # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } } # <- { "return": {} } @@ -1689,7 +1689,7 @@ # 5. The 'uri' and 'channels' arguments are mutually exclusive; # exactly one of the two should be present. # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-incoming", # "arguments": { "uri": "tcp:0:4446" } } @@ -1740,7 +1740,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-save-devices-state", # "arguments": { "filename": "/tmp/save" } } @@ -1758,7 +1758,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-set-global-dirty-log", # "arguments": { "enable": true } } @@ -1778,7 +1778,7 @@ # # Since: 2.7 # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-load-devices-state", # "arguments": { "filename": "/tmp/resume" } } @@ -1798,7 +1798,7 @@ # @failover: true to do failover, false to stop. Cannot be specified # if 'enable' is true. Default value is false. # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-set-replication", # "arguments": {"enable": true, "primary": false} } @@ -1833,7 +1833,7 @@ # # Returns: A @ReplicationStatus object showing the status. # -# Example: +# .. qmp-example:: # # -> { "execute": "query-xen-replication-status" } # <- { "return": { "error": false } } @@ -1849,7 +1849,7 @@ # # Xen uses this command to notify replication to trigger a checkpoint. # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-colo-do-checkpoint" } # <- { "return": {} } @@ -1887,7 +1887,7 @@ # # Returns: A @COLOStatus object showing the status. # -# Example: +# .. qmp-example:: # # -> { "execute": "query-colo-status" } # <- { "return": { "mode": "primary", "last-mode": "none", "reason": "request" } } @@ -1905,7 +1905,7 @@ # # @uri: the URI to be used for the recovery of migration stream. # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-recover", # "arguments": { "uri": "tcp:192.168.1.200:12345" } } @@ -1922,7 +1922,7 @@ # # Pause a migration. Currently it only supports postcopy. # -# Example: +# .. qmp-example:: # # -> { "execute": "migrate-pause" } # <- { "return": {} } @@ -1943,7 +1943,7 @@ # # Since: 4.2 # -# Example: +# .. qmp-example:: # # <- { "event": "UNPLUG_PRIMARY", # "data": { "device-id": "hostdev0" }, @@ -2182,7 +2182,7 @@ # # Since: 7.1 # -# Example: +# .. qmp-example:: # # -> {"execute": "set-vcpu-dirty-limit"} # "arguments": { "dirty-rate": 200, @@ -2206,7 +2206,7 @@ # # Since: 7.1 # -# Example: +# .. qmp-example:: # # -> {"execute": "cancel-vcpu-dirty-limit"}, # "arguments": { "cpu-index": 1 } } @@ -2223,7 +2223,7 @@ # # Since: 7.1 # -# Example: +# .. qmp-example:: # # -> {"execute": "query-vcpu-dirty-limit"} # <- {"return": [ @@ -2287,7 +2287,7 @@ # # If @tag already exists, an error will be reported # -# Example: +# .. qmp-example:: # # -> { "execute": "snapshot-save", # "arguments": { @@ -2357,7 +2357,7 @@ # device nodes that can have changed since the original @snapshot-save # command execution. # -# Example: +# .. qmp-example:: # # -> { "execute": "snapshot-load", # "arguments": { @@ -2418,7 +2418,7 @@ # to determine completion and to fetch details of any errors that # arise. # -# Example: +# .. qmp-example:: # # -> { "execute": "snapshot-delete", # "arguments": { diff --git a/qapi/misc-target.json b/qapi/misc-target.json index 2d7d4d8..8d70bd2 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -11,7 +11,7 @@ # # Since: 2.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "rtc-reset-reinjection" } # <- { "return": {} } @@ -133,7 +133,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-sev" } # <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0, @@ -164,7 +164,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-sev-launch-measure" } # <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } } @@ -209,7 +209,7 @@ # # Since: 2.12 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-sev-capabilities" } # <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE", @@ -263,7 +263,7 @@ # # Since: 6.1 # -# Example: +# .. qmp-example:: # # -> { "execute" : "query-sev-attestation-report", # "arguments": { "mnonce": "aaaaaaa" } } @@ -283,7 +283,7 @@ # # Since: 2.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "dump-skeys", # "arguments": { "filename": "/tmp/skeys" } } @@ -328,7 +328,7 @@ # # Since: 2.6 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-gic-capabilities" } # <- { "return": [{ "version": 2, "emulated": true, "kernel": false }, @@ -386,7 +386,7 @@ # # Since: 6.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-sgx" } # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, @@ -405,7 +405,7 @@ # # Since: 6.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-sgx-capabilities" } # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, @@ -480,7 +480,7 @@ # # Since: 8.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-event-list" } # <- { "return": [ @@ -518,7 +518,7 @@ # # Since: 8.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "xen-event-inject", "arguments": { "port": 1 } } # <- { "return": { } } diff --git a/qapi/misc.json b/qapi/misc.json index b04efba..4a6f3ba 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -30,7 +30,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "add_client", "arguments": { "protocol": "vnc", # "fdname": "myclient" } } @@ -60,7 +60,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-name" } # <- { "return": { "name": "qemu-name" } } @@ -111,7 +111,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-iothreads" } # <- { "return": [ @@ -144,7 +144,7 @@ # In the "suspended" state, it will completely stop the VM and cause # a transition to the "paused" state. (Since 9.0) # -# Example: +# .. qmp-example:: # # -> { "execute": "stop" } # <- { "return": {} } @@ -168,7 +168,7 @@ # this command will transition back to the "suspended" state. (Since # 9.0) # -# Example: +# .. qmp-example:: # # -> { "execute": "cont" } # <- { "return": {} } @@ -192,7 +192,7 @@ # # Since: 3.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "x-exit-preconfig" } # <- { "return": {} } @@ -232,7 +232,7 @@ # # * Commands that prompt the user for data don't currently work. # -# Example: +# .. qmp-example:: # # -> { "execute": "human-monitor-command", # "arguments": { "command-line": "info kvm" } } @@ -258,7 +258,7 @@ # The 'closefd' command can be used to explicitly close the file # descriptor when it is no longer needed. # -# Example: +# .. qmp-example:: # # -> { "execute": "getfd", "arguments": { "fdname": "fd1" } } # <- { "return": {} } @@ -285,7 +285,7 @@ # The 'closefd' command can be used to explicitly close the file # descriptor when it is no longer needed. # -# Example: +# .. qmp-example:: # # -> { "execute": "get-win32-socket", # "arguments": { "info": "abcd123..", "fdname": "skclient" } } @@ -302,7 +302,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "closefd", "arguments": { "fdname": "fd1" } } # <- { "return": {} } @@ -345,7 +345,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "add-fd", "arguments": { "fdset-id": 1 } } # <- { "return": { "fdset-id": 1, "fd": 3 } } @@ -374,7 +374,7 @@ # .. note:: If @fd is not specified, all file descriptors in @fdset-id # will be removed. # -# Example: +# .. qmp-example:: # # -> { "execute": "remove-fd", "arguments": { "fdset-id": 1, "fd": 3 } } # <- { "return": {} } @@ -420,7 +420,7 @@ # # .. note:: The list of fd sets is shared by all monitor connections. # -# Example: +# .. qmp-example:: # # -> { "execute": "query-fdsets" } # <- { "return": [ @@ -523,7 +523,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-command-line-options", # "arguments": { "option": "option-rom" } } @@ -565,7 +565,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "RTC_CHANGE", # "data": { "offset": 78 }, @@ -592,7 +592,7 @@ # # Since: 7.1 # -# Example: +# .. qmp-example:: # # <- { "event": "VFU_CLIENT_HANGUP", # "data": { "vfu-id": "vfu1", diff --git a/qapi/net.json b/qapi/net.json index dd6c365..31b3417 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -26,7 +26,7 @@ # command will succeed even if the network adapter does not support # link status notification. # -# Example: +# .. qmp-example:: # # -> { "execute": "set_link", # "arguments": { "name": "e1000.0", "up": false } } @@ -46,7 +46,7 @@ # Errors: # - If @type is not a valid network backend, DeviceNotFound # -# Example: +# .. qmp-example:: # # -> { "execute": "netdev_add", # "arguments": { "type": "user", "id": "netdev1", @@ -68,7 +68,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "netdev_del", "arguments": { "id": "netdev1" } } # <- { "return": {} } @@ -836,7 +836,7 @@ # # Since: 1.6 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } } # <- { "return": [ @@ -881,7 +881,7 @@ # # Since: 1.6 # -# Example: +# .. qmp-example:: # # <- { "event": "NIC_RX_FILTER_CHANGED", # "data": { "name": "vnet0", @@ -930,7 +930,9 @@ # switches. This can be useful when network bonds fail-over the # active slave. # -# Example: +# TODO: This line is a hack to separate the example from the body +# +# .. qmp-example:: # # -> { "execute": "announce-self", # "arguments": { @@ -955,7 +957,7 @@ # # Since: 4.2 # -# Example: +# .. qmp-example:: # # <- { "event": "FAILOVER_NEGOTIATED", # "data": { "device-id": "net1" }, @@ -975,7 +977,7 @@ # # Since: 7.2 # -# Examples: +# .. qmp-example:: # # <- { "event": "NETDEV_STREAM_CONNECTED", # "data": { "netdev-id": "netdev0", @@ -983,6 +985,8 @@ # "host": "::1", "type": "inet" } }, # "timestamp": { "seconds": 1666269863, "microseconds": 311222 } } # +# .. qmp-example:: +# # <- { "event": "NETDEV_STREAM_CONNECTED", # "data": { "netdev-id": "netdev0", # "addr": { "path": "/tmp/qemu0", "type": "unix" } }, @@ -1001,7 +1005,7 @@ # # Since: 7.2 # -# Example: +# .. qmp-example:: # # <- { "event": "NETDEV_STREAM_DISCONNECTED", # "data": {"netdev-id": "netdev0"}, diff --git a/qapi/pci.json b/qapi/pci.json index 9717992..ec28f1d 100644 --- a/qapi/pci.json +++ b/qapi/pci.json @@ -180,7 +180,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-pci" } # <- { "return": [ diff --git a/qapi/qdev.json b/qapi/qdev.json index d031fc3..e91ca03 100644 --- a/qapi/qdev.json +++ b/qapi/qdev.json @@ -62,7 +62,7 @@ # the ``-device DEVICE,help`` command-line argument, where DEVICE # is the device's name. # -# Example: +# .. qmp-example:: # # -> { "execute": "device_add", # "arguments": { "driver": "e1000", "id": "net1", @@ -104,12 +104,14 @@ # # Since: 0.14 # -# Examples: +# .. qmp-example:: # # -> { "execute": "device_del", # "arguments": { "id": "net1" } } # <- { "return": {} } # +# .. qmp-example:: +# # -> { "execute": "device_del", # "arguments": { "id": "/machine/peripheral-anon/device[0]" } } # <- { "return": {} } @@ -130,7 +132,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # <- { "event": "DEVICE_DELETED", # "data": { "device": "virtio-net-pci-0", @@ -152,7 +154,7 @@ # # Since: 6.2 # -# Example: +# .. qmp-example:: # # <- { "event": "DEVICE_UNPLUG_GUEST_ERROR", # "data": { "device": "core1", diff --git a/qapi/qom.json b/qapi/qom.json index 3e52aec..46096a8 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -59,7 +59,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "qom-list", # "arguments": { "path": "/chardevs" } } @@ -139,7 +139,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "qom-set", # "arguments": { "path": "/machine", @@ -1172,7 +1172,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "object-add", # "arguments": { "qom-type": "rng-random", "id": "rng1", @@ -1194,7 +1194,7 @@ # # Since: 2.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "object-del", "arguments": { "id": "rng1" } } # <- { "return": {} } diff --git a/qapi/replay.json b/qapi/replay.json index d3559f9..35e0c4a 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -54,7 +54,7 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-replay" } # <- { "return": { "mode": "play", "filename": "log.rr", "icount": 220414 } } @@ -76,7 +76,7 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "replay-break", "arguments": { "icount": 220414 } } # <- { "return": {} } @@ -91,7 +91,7 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "replay-delete-break" } # <- { "return": {} } @@ -112,7 +112,7 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "replay-seek", "arguments": { "icount": 220414 } } # <- { "return": {} } diff --git a/qapi/rocker.json b/qapi/rocker.json index 9f95e63..2e63dcb 100644 --- a/qapi/rocker.json +++ b/qapi/rocker.json @@ -30,7 +30,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-rocker", "arguments": { "name": "sw1" } } # <- { "return": {"name": "sw1", "ports": 2, "id": 1327446905938}} @@ -98,7 +98,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-rocker-ports", "arguments": { "name": "sw1" } } # <- { "return": [ {"duplex": "full", "enabled": true, "name": "sw1.1", @@ -240,7 +240,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-rocker-of-dpa-flows", # "arguments": { "name": "sw1" } } @@ -315,7 +315,7 @@ # # Since: 2.4 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-rocker-of-dpa-groups", # "arguments": { "name": "sw1" } } diff --git a/qapi/run-state.json b/qapi/run-state.json index 4d40c88..287691c 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -123,7 +123,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-status" } # <- { "return": { "running": true, @@ -152,7 +152,7 @@ # # Since: 0.12 # -# Example: +# .. qmp-example:: # # <- { "event": "SHUTDOWN", # "data": { "guest": true, "reason": "guest-shutdown" }, @@ -168,7 +168,7 @@ # # Since: 0.12 # -# Example: +# .. qmp-example:: # # <- { "event": "POWERDOWN", # "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } @@ -189,7 +189,7 @@ # # Since: 0.12 # -# Example: +# .. qmp-example:: # # <- { "event": "RESET", # "data": { "guest": false, "reason": "guest-reset" }, @@ -204,7 +204,7 @@ # # Since: 0.12 # -# Example: +# .. qmp-example:: # # <- { "event": "STOP", # "timestamp": { "seconds": 1267041730, "microseconds": 281295 } } @@ -218,7 +218,7 @@ # # Since: 0.12 # -# Example: +# .. qmp-example:: # # <- { "event": "RESUME", # "timestamp": { "seconds": 1271770767, "microseconds": 582542 } } @@ -233,7 +233,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # <- { "event": "SUSPEND", # "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } @@ -252,7 +252,7 @@ # # Since: 1.2 # -# Example: +# .. qmp-example:: # # <- { "event": "SUSPEND_DISK", # "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } @@ -267,7 +267,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # <- { "event": "WAKEUP", # "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } @@ -289,7 +289,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "WATCHDOG", # "data": { "action": "reset" }, @@ -382,7 +382,7 @@ # # Since: 2.11 # -# Example: +# .. qmp-example:: # # -> { "execute": "watchdog-set-action", # "arguments": { "action": "inject-nmi" } } @@ -406,7 +406,7 @@ # # Since: 6.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "set-action", # "arguments": { "reboot": "shutdown", @@ -433,7 +433,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # <- { "event": "GUEST_PANICKED", # "data": { "action": "pause" }, @@ -453,7 +453,7 @@ # # Since: 5.0 # -# Example: +# .. qmp-example:: # # <- { "event": "GUEST_CRASHLOADED", # "data": { "action": "run" }, @@ -469,7 +469,7 @@ # # Since: 9.1 # -# Example: +# .. qmp-example:: # # <- { "event": "GUEST_PVSHUTDOWN", # "timestamp": { "seconds": 1648245259, "microseconds": 893771 } } @@ -611,7 +611,7 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # <- { "event": "MEMORY_FAILURE", # "data": { "recipient": "hypervisor", diff --git a/qapi/tpm.json b/qapi/tpm.json index 1577b5c..a16a72e 100644 --- a/qapi/tpm.json +++ b/qapi/tpm.json @@ -31,7 +31,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-tpm-models" } # <- { "return": [ "tpm-tis", "tpm-crb", "tpm-spapr" ] } @@ -62,7 +62,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-tpm-types" } # <- { "return": [ "passthrough", "emulator" ] } @@ -168,7 +168,7 @@ # # Since: 1.5 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-tpm" } # <- { "return": diff --git a/qapi/trace.json b/qapi/trace.json index 9ebb6d9..eb5f63f 100644 --- a/qapi/trace.json +++ b/qapi/trace.json @@ -51,7 +51,7 @@ # # Since: 2.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "trace-event-get-state", # "arguments": { "name": "qemu_memalign" } } @@ -74,7 +74,7 @@ # # Since: 2.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "trace-event-set-state", # "arguments": { "name": "qemu_memalign", "enable": true } } diff --git a/qapi/transaction.json b/qapi/transaction.json index bcb05fd..b0ae343 100644 --- a/qapi/transaction.json +++ b/qapi/transaction.json @@ -244,7 +244,7 @@ # # Since: 1.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "transaction", # "arguments": { "actions": [ diff --git a/qapi/ui.json b/qapi/ui.json index df08986..6bda984 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -83,7 +83,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "set_password", "arguments": { "protocol": "vnc", # "password": "secret" } } @@ -144,7 +144,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "expire_password", "arguments": { "protocol": "vnc", # "time": "+60" } } @@ -186,7 +186,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "screendump", # "arguments": { "filename": "/tmp/image" } } @@ -328,7 +328,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-spice" } # <- { "return": { @@ -377,7 +377,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, # "event": "SPICE_CONNECTED", @@ -403,7 +403,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, # "event": "SPICE_INITIALIZED", @@ -430,7 +430,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, # "event": "SPICE_DISCONNECTED", @@ -451,7 +451,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, # "event": "SPICE_MIGRATE_COMPLETED" } @@ -659,7 +659,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-vnc" } # <- { "return": { @@ -724,7 +724,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "VNC_CONNECTED", # "data": { @@ -751,7 +751,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "VNC_INITIALIZED", # "data": { @@ -777,7 +777,7 @@ # # Since: 0.13 # -# Example: +# .. qmp-example:: # # <- { "event": "VNC_DISCONNECTED", # "data": { @@ -825,7 +825,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "query-mice" } # <- { "return": [ @@ -1034,7 +1034,7 @@ # # Since: 1.3 # -# Example: +# .. qmp-example:: # # -> { "execute": "send-key", # "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" }, @@ -1613,7 +1613,7 @@ # # Since: 6.0 # -# Example: +# .. qmp-example:: # # -> { "execute": "display-reload", # "arguments": { "type": "vnc", "tls-certs": true } } @@ -1670,7 +1670,7 @@ # # Since: 7.1 # -# Example: +# .. qmp-example:: # # -> { "execute": "display-update", # "arguments": { "type": "vnc", "addresses": @@ -1701,7 +1701,7 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: # # -> { "execute": "client_migrate_info", # "arguments": { "protocol": "spice", diff --git a/qapi/vfio.json b/qapi/vfio.json index a0e5013..40cbcde 100644 --- a/qapi/vfio.json +++ b/qapi/vfio.json @@ -50,7 +50,7 @@ # # Since: 9.1 # -# Example: +# .. qmp-example:: # # <- { "timestamp": { "seconds": 1713771323, "microseconds": 212268 }, # "event": "VFIO_MIGRATION", diff --git a/qapi/virtio.json b/qapi/virtio.json index b91f3cd..f4323cc 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -34,7 +34,7 @@ # # Since: 7.2 # -# Example: +# .. qmp-example:: # # -> { "execute": "x-query-virtio" } # <- { "return": [ diff --git a/qapi/yank.json b/qapi/yank.json index 89f2f4d..30f46c9 100644 --- a/qapi/yank.json +++ b/qapi/yank.json @@ -81,7 +81,7 @@ # Errors: # - If any of the YankInstances doesn't exist, DeviceNotFound # -# Example: +# .. qmp-example:: # # -> { "execute": "yank", # "arguments": { @@ -104,7 +104,7 @@ # # Returns: list of @YankInstance # -# Example: +# .. qmp-example:: # # -> { "execute": "query-yank" } # <- { "return": [ -- cgit v1.1 From a9eab6e2e65f5b876ededec1cd4bacc58cd4bce0 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:09 -0400 Subject: qapi: convert "Example" sections with titles When an Example section has a brief explanation, convert it to a qmp-example:: section using the :title: option. Rule of thumb: If the title can fit on a single line and requires no rST markup, it's a good candidate for using the :title: option of qmp-example. In this patch, trailing punctuation is removed from the title section for consistent headline aesthetics. In just one case, specifics of the example are removed to make the title read better. See commit-4: "docs/qapidoc: create qmp-example directive", for a detailed explanation of this custom directive syntax. See commit+2: "qapi: remove "Example" doc section" for a detailed explanation of why. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Message-ID: <20240717021312.606116-8-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- qapi/block-core.json | 24 ++++++++++++------------ qapi/block.json | 13 ++++++------- qapi/migration.json | 25 ++++++++++++++----------- qapi/qom.json | 8 ++++---- qapi/ui.json | 11 ++++++----- qapi/virtio.json | 19 ++++++++++--------- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 84a020a..f400b33 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -5881,9 +5881,8 @@ # # Since: 2.7 # -# Examples: -# -# 1. Add a new node to a quorum +# .. qmp-example:: +# :title: Add a new node to a quorum # # -> { "execute": "blockdev-add", # "arguments": { @@ -5897,7 +5896,8 @@ # "node": "new_node" } } # <- { "return": {} } # -# 2. Delete a quorum's node +# .. qmp-example:: +# :title: Delete a quorum's node # # -> { "execute": "x-blockdev-change", # "arguments": { "parent": "disk1", @@ -5933,16 +5933,16 @@ # # Since: 2.12 # -# Examples: -# -# 1. Move a node into an IOThread +# .. qmp-example:: +# :title: Move a node into an IOThread # # -> { "execute": "x-blockdev-set-iothread", # "arguments": { "node-name": "disk1", # "iothread": "iothread0" } } # <- { "return": {} } # -# 2. Move a node into the main loop +# .. qmp-example:: +# :title: Move a node into the main loop # # -> { "execute": "x-blockdev-set-iothread", # "arguments": { "node-name": "disk1", @@ -6018,16 +6018,16 @@ # # Since: 2.0 # -# Examples: -# -# 1. Read operation +# .. qmp-example:: +# :title: Read operation # # <- { "event": "QUORUM_REPORT_BAD", # "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5, # "type": "read" }, # "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } # -# 2. Flush operation +# .. qmp-example:: +# :title: Flush operation # # <- { "event": "QUORUM_REPORT_BAD", # "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120, diff --git a/qapi/block.json b/qapi/block.json index c8e52bc..5ddd061 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -342,9 +342,8 @@ # # Since: 2.5 # -# Examples: -# -# 1. Change a removable medium +# .. qmp-example:: +# :title: Change a removable medium # # -> { "execute": "blockdev-change-medium", # "arguments": { "id": "ide0-1-0", @@ -352,7 +351,8 @@ # "format": "raw" } } # <- { "return": {} } # -# 2. Load a read-only medium into a writable drive +# .. qmp-example:: +# :title: Load a read-only medium into a writable drive # # -> { "execute": "blockdev-change-medium", # "arguments": { "id": "floppyA", @@ -577,9 +577,8 @@ # "boundaries-write": [1000, 5000] } } # <- { "return": {} } # -# Example: -# -# Remove all latency histograms: +# .. qmp-example:: +# :title: Remove all latency histograms # # -> { "execute": "block-latency-histogram-set", # "arguments": { "id": "drive0" } } diff --git a/qapi/migration.json b/qapi/migration.json index 3c65720..74968a1 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -287,14 +287,14 @@ # # Since: 0.14 # -# Examples: -# -# 1. Before the first migration +# .. qmp-example:: +# :title: Before the first migration # # -> { "execute": "query-migrate" } # <- { "return": {} } # -# 2. Migration is done and has succeeded +# .. qmp-example:: +# :title: Migration is done and has succeeded # # -> { "execute": "query-migrate" } # <- { "return": { @@ -314,12 +314,14 @@ # } # } # -# 3. Migration is done and has failed +# .. qmp-example:: +# :title: Migration is done and has failed # # -> { "execute": "query-migrate" } # <- { "return": { "status": "failed" } } # -# 4. Migration is being performed: +# .. qmp-example:: +# :title: Migration is being performed # # -> { "execute": "query-migrate" } # <- { @@ -340,7 +342,8 @@ # } # } # -# 5. Migration is being performed and XBZRLE is active: +# .. qmp-example:: +# :title: Migration is being performed and XBZRLE is active # # -> { "execute": "query-migrate" } # <- { @@ -2131,15 +2134,15 @@ # # Since: 5.2 # -# Examples: -# -# 1. Measurement is in progress: +# .. qmp-example:: +# :title: Measurement is in progress # # <- {"status": "measuring", "sample-pages": 512, # "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10, # "calc-time-unit": "second"} # -# 2. Measurement has been completed: +# .. qmp-example:: +# :title: Measurement has been completed # # <- {"status": "measured", "sample-pages": 512, "dirty-rate": 108, # "mode": "page-sampling", "start-time": 1693900454, "calc-time": 10, diff --git a/qapi/qom.json b/qapi/qom.json index 46096a8..ae947e0 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -104,16 +104,16 @@ # # Since: 1.2 # -# Examples: -# -# 1. Use absolute path +# .. qmp-example:: +# :title: Use absolute path # # -> { "execute": "qom-get", # "arguments": { "path": "/machine/unattached/device[0]", # "property": "hotplugged" } } # <- { "return": false } # -# 2. Use partial path +# .. qmp-example:: +# :title: Use partial path # # -> { "execute": "qom-get", # "arguments": { "path": "unattached/sysbus", diff --git a/qapi/ui.json b/qapi/ui.json index 6bda984..5daca51 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1270,9 +1270,8 @@ # property, so it is possible to map which console belongs to which # device and display. # -# Examples: -# -# 1. Press left mouse button. +# .. qmp-example:: +# :title: Press left mouse button # # -> { "execute": "input-send-event", # "arguments": { "device": "video0", @@ -1286,7 +1285,8 @@ # "data" : { "down": false, "button": "left" } } ] } } # <- { "return": {} } # -# 2. Press ctrl-alt-del. +# .. qmp-example:: +# :title: Press ctrl-alt-del # # -> { "execute": "input-send-event", # "arguments": { "events": [ @@ -1298,7 +1298,8 @@ # "key": {"type": "qcode", "data": "delete" } } } ] } } # <- { "return": {} } # -# 3. Move mouse pointer to absolute coordinates (20000, 400). +# .. qmp-example:: +# :title: Move mouse pointer to absolute coordinates # # -> { "execute": "input-send-event" , # "arguments": { "events": [ diff --git a/qapi/virtio.json b/qapi/virtio.json index f4323cc..d965c98 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -690,9 +690,8 @@ # # Since: 7.2 # -# Examples: -# -# 1. Get vhost_virtqueue status for vhost-crypto +# .. qmp-example:: +# :title: Get vhost_virtqueue status for vhost-crypto # # -> { "execute": "x-query-virtio-vhost-queue-status", # "arguments": { "path": "/machine/peripheral/crypto0/virtio-backend", @@ -715,7 +714,8 @@ # } # } # -# 2. Get vhost_virtqueue status for vhost-vsock +# .. qmp-example:: +# :title: Get vhost_virtqueue status for vhost-vsock # # -> { "execute": "x-query-virtio-vhost-queue-status", # "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend", @@ -839,9 +839,8 @@ # # Since: 7.2 # -# Examples: -# -# 1. Introspect on virtio-net's VirtQueue 0 at index 5 +# .. qmp-example:: +# :title: Introspect on virtio-net's VirtQueue 0 at index 5 # # -> { "execute": "x-query-virtio-queue-element", # "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend", @@ -870,7 +869,8 @@ # } # } # -# 2. Introspect on virtio-crypto's VirtQueue 1 at head +# .. qmp-example:: +# :title: Introspect on virtio-crypto's VirtQueue 1 at head # # -> { "execute": "x-query-virtio-queue-element", # "arguments": { "path": "/machine/peripheral/crypto0/virtio-backend", @@ -898,7 +898,8 @@ # } # } # -# 3. Introspect on virtio-scsi's VirtQueue 2 at head +# .. qmp-example:: +# :title: Introspect on virtio-scsi's VirtQueue 2 at head # # -> { "execute": "x-query-virtio-queue-element", # "arguments": { "path": "/machine/peripheral-anon/device[2]/virtio-backend", -- cgit v1.1 From 6f07c59fb16c68e91de82c086ce6c27d9e4748ca Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:10 -0400 Subject: qapi: convert "Example" sections with longer prose These examples require longer explanations or have explanations that require markup to look reasonable when rendered and so use the longer form of the ".. qmp-example::" directive. By using the :annotated: option, the content in the example block is assumed *not* to be a code block literal and is instead parsed as normal rST - with the exception that any code literal blocks after `::` will assumed to be a QMP code literal block. Note: There's one title-less conversion in this patch that comes along for the ride because it's part of a larger "Examples" block that was better to convert all at once. See commit-5: "docs/qapidoc: create qmp-example directive", for a detailed explanation of this custom directive syntax. See commit+1: "qapi: remove "Example" doc section" for a detailed explanation of why. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Message-ID: <20240717021312.606116-9-jsnow@redhat.com> Signed-off-by: Markus Armbruster --- qapi/block.json | 30 +++++++++++++++++++----------- qapi/machine.json | 30 ++++++++++++++++++++---------- qapi/migration.json | 7 +++++-- qapi/virtio.json | 24 ++++++++++++++++++------ 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index 5ddd061..ce9490a 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -545,31 +545,37 @@ # # Since: 4.0 # -# Example: +# .. qmp-example:: +# :annotated: # -# Set new histograms for all io types with intervals -# [0, 10), [10, 50), [50, 100), [100, +inf): +# Set new histograms for all io types with intervals +# [0, 10), [10, 50), [50, 100), [100, +inf):: # # -> { "execute": "block-latency-histogram-set", # "arguments": { "id": "drive0", # "boundaries": [10, 50, 100] } } # <- { "return": {} } # -# Example: +# .. qmp-example:: +# :annotated: # -# Set new histogram only for write, other histograms will remain -# not changed (or not created): +# Set new histogram only for write, other histograms will remain +# not changed (or not created):: # # -> { "execute": "block-latency-histogram-set", # "arguments": { "id": "drive0", # "boundaries-write": [10, 50, 100] } } # <- { "return": {} } # -# Example: +# .. qmp-example:: +# :annotated: +# +# Set new histograms with the following intervals: +# +# - read, flush: [0, 10), [10, 50), [50, 100), [100, +inf) +# - write: [0, 1000), [1000, 5000), [5000, +inf) # -# Set new histograms with the following intervals: -# read, flush: [0, 10), [10, 50), [50, 100), [100, +inf) -# write: [0, 1000), [1000, 5000), [5000, +inf) +# :: # # -> { "execute": "block-latency-histogram-set", # "arguments": { "id": "drive0", @@ -578,7 +584,9 @@ # <- { "return": {} } # # .. qmp-example:: -# :title: Remove all latency histograms +# :annotated: +# +# Remove all latency histograms:: # # -> { "execute": "block-latency-histogram-set", # "arguments": { "id": "drive0" } } diff --git a/qapi/machine.json b/qapi/machine.json index 193b2b7..f9ea6b3 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1045,10 +1045,11 @@ # # Since: 2.7 # -# Examples: +# .. qmp-example:: +# :annotated: # -# For pseries machine type started with -smp 2,cores=2,maxcpus=4 -# -cpu POWER8: +# For pseries machine type started with +# ``-smp 2,cores=2,maxcpus=4 -cpu POWER8``:: # # -> { "execute": "query-hotpluggable-cpus" } # <- {"return": [ @@ -1058,7 +1059,10 @@ # "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"} # ]} # -# For pc machine type started with -smp 1,maxcpus=2: +# .. qmp-example:: +# :annotated: +# +# For pc machine type started with ``-smp 1,maxcpus=2``:: # # -> { "execute": "query-hotpluggable-cpus" } # <- {"return": [ @@ -1073,8 +1077,11 @@ # } # ]} # -# For s390x-virtio-ccw machine type started with -smp 1,maxcpus=2 -# -cpu qemu (Since: 2.11): +# .. qmp-example:: +# :annotated: +# +# For s390x-virtio-ccw machine type started with +# ``-smp 1,maxcpus=2 -cpu qemu`` (Since: 2.11):: # # -> { "execute": "query-hotpluggable-cpus" } # <- {"return": [ @@ -1128,12 +1135,15 @@ # # Since: 0.14 # -# Example: +# .. qmp-example:: +# :annotated: +# +# :: # -# -> { "execute": "balloon", "arguments": { "value": 536870912 } } -# <- { "return": {} } +# -> { "execute": "balloon", "arguments": { "value": 536870912 } } +# <- { "return": {} } # -# With a 2.5GiB guest this command inflated the ballon to 3GiB. +# With a 2.5GiB guest this command inflated the ballon to 3GiB. ## { 'command': 'balloon', 'data': {'value': 'int'} } diff --git a/qapi/migration.json b/qapi/migration.json index 74968a1..073b67c 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -2106,13 +2106,16 @@ # # Since: 5.2 # -# Example: +# .. qmp-example:: # # -> {"execute": "calc-dirty-rate", "arguments": {"calc-time": 1, # "sample-pages": 512} } # <- { "return": {} } # -# Measure dirty rate using dirty bitmap for 500 milliseconds: +# .. qmp-example:: +# :annotated: +# +# Measure dirty rate using dirty bitmap for 500 milliseconds:: # # -> {"execute": "calc-dirty-rate", "arguments": {"calc-time": 500, # "calc-time-unit": "millisecond", "mode": "dirty-bitmap"} } diff --git a/qapi/virtio.json b/qapi/virtio.json index d965c98..26df8b3 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -203,9 +203,11 @@ # # Since: 7.2 # -# Examples: +# .. qmp-example:: +# :annotated: # -# 1. Poll for the status of virtio-crypto (no vhost-crypto active) +# Poll for the status of virtio-crypto (no vhost-crypto active) +# :: # # -> { "execute": "x-query-virtio-status", # "arguments": { "path": "/machine/peripheral/crypto0/virtio-backend" } @@ -261,7 +263,11 @@ # } # } # -# 2. Poll for the status of virtio-net (vhost-net is active) +# .. qmp-example:: +# :annotated: +# +# Poll for the status of virtio-net (vhost-net is active) +# :: # # -> { "execute": "x-query-virtio-status", # "arguments": { "path": "/machine/peripheral-anon/device[1]/virtio-backend" } @@ -568,9 +574,11 @@ # # Since: 7.2 # -# Examples: +# .. qmp-example:: +# :annotated: # -# 1. Get VirtQueueStatus for virtio-vsock (vhost-vsock running) +# Get VirtQueueStatus for virtio-vsock (vhost-vsock running) +# :: # # -> { "execute": "x-query-virtio-queue-status", # "arguments": { "path": "/machine/peripheral/vsock0/virtio-backend", @@ -593,7 +601,11 @@ # } # } # -# 2. Get VirtQueueStatus for virtio-serial (no vhost) +# .. qmp-example:: +# :annotated: +# +# Get VirtQueueStatus for virtio-serial (no vhost) +# :: # # -> { "execute": "x-query-virtio-queue-status", # "arguments": { "path": "/machine/peripheral-anon/device[0]/virtio-backend", -- cgit v1.1 From 3c5f6114d9ffc70bc9b1a7cc0dddd72a911f966d Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 16 Jul 2024 22:13:11 -0400 Subject: qapi: remove "Example" doc section Fully eliminate the "Example" sections in QAPI doc blocks now that they have all been converted to arbitrary rST syntax using the ".. qmp-example::" directive. Update tests to match. Migrating to the new syntax --------------------------- The old "Example:" or "Examples:" section syntax is now caught as an error, but "Example::" is stil permitted as explicit rST syntax for an un-lexed, generic preformatted text block. ('Example' is not special in this case, any sentence that ends with "::" will start an indented code block in rST.) Arbitrary rST for Examples is now possible, but it's strongly recommended that documentation authors use the ".. qmp-example::" directive for consistent visual formatting in rendered HTML docs. The ":title:" directive option may be used to add extra information into the title bar for the example. The ":annotated:" option can be used to write arbitrary rST instead, with nested "::" blocks applying QMP formatting where desired. Other choices available are ".. code-block:: QMP" which will not create an "Example:" box, or the short-form "::" code-block syntax which will not apply QMP highlighting when used outside of the qmp-example directive. Why? ---- This patch has several benefits: 1. Example sections can now be written more arbitrarily, mixing explanatory paragraphs and code blocks however desired. 2. Example sections can now use fully arbitrary rST. 3. All code blocks are now lexed and validated as QMP; increasing usability of the docs and ensuring validity of example snippets. (To some extent - This patch only gaurantees it lexes correctly, not that it's valid under the JSON or QMP grammars. It will catch most small mistakes, however.) 4. Each qmp-example can be titled or annotated independently without bypassing the QMP lexer/validator. (i.e. code blocks are now for *code* only, so we don't have to sacrifice exposition for having lexically valid examples.) NOTE: As with the "Notes" conversion (d461c279737), this patch (and the three preceding) may change the rendering order for Examples in the current generator. The forthcoming qapidoc rewrite will fix this by always generating documentation in source order. Signed-off-by: John Snow Message-ID: <20240717021312.606116-10-jsnow@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.rst | 58 ++++++++++++++++++++++++++++++++++------- scripts/qapi/parser.py | 10 ++++++- tests/qapi-schema/doc-good.json | 19 +++++++++----- tests/qapi-schema/doc-good.out | 26 ++++++++++++------ tests/qapi-schema/doc-good.txt | 23 +++++++--------- 5 files changed, 98 insertions(+), 38 deletions(-) diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index ae97b33..583207a 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -899,7 +899,7 @@ Documentation markup ~~~~~~~~~~~~~~~~~~~~ Documentation comments can use most rST markup. In particular, -a ``::`` literal block can be used for examples:: +a ``::`` literal block can be used for pre-formatted text:: # :: # @@ -995,8 +995,8 @@ line "Features:", like this:: # @feature: Description text A tagged section begins with a paragraph that starts with one of the -following words: "Since:", "Example:"/"Examples:", "Returns:", -"Errors:", "TODO:". It ends with the start of a new section. +following words: "Since:", "Returns:", "Errors:", "TODO:". It ends with +the start of a new section. The second and subsequent lines of tagged sections must be indented like this:: @@ -1020,13 +1020,53 @@ detailing a relevant error condition. For example:: A "Since: x.y.z" tagged section lists the release that introduced the definition. -An "Example" or "Examples" section is rendered entirely -as literal fixed-width text. "TODO" sections are not rendered at all -(they are for developers, not users of QMP). In other sections, the -text is formatted, and rST markup can be used. +"TODO" sections are not rendered (they are for developers, not users of +QMP). In other sections, the text is formatted, and rST markup can be +used. + +QMP Examples can be added by using the ``.. qmp-example::`` +directive. In its simplest form, this can be used to contain a single +QMP code block which accepts standard JSON syntax with additional server +directionality indicators (``->`` and ``<-``), and elisions (``...``). + +Optionally, a plaintext title may be provided by using the ``:title:`` +directive option. If the title is omitted, the example title will +default to "Example:". + +A simple QMP example:: + + # .. qmp-example:: + # :title: Using query-block + # + # -> { "execute": "query-block" } + # <- { ... } + +More complex or multi-step examples where exposition is needed before or +between QMP code blocks can be created by using the ``:annotated:`` +directive option. When using this option, nested QMP code blocks must be +entered explicitly with rST's ``::`` syntax. + +Highlighting in non-QMP languages can be accomplished by using the +``.. code-block:: lang`` directive, and non-highlighted text can be +achieved by omitting the language argument. For example:: + # .. qmp-example:: + # :annotated: + # :title: A more complex demonstration + # + # This is a more complex example that can use + # ``arbitrary rST syntax`` in its exposition:: + # + # -> { "execute": "query-block" } + # <- { ... } + # + # Above, lengthy output has been omitted for brevity. + + +Examples of complete definition documentation:: + ## # @BlockStats: # @@ -1058,11 +1098,11 @@ For example:: # # Since: 0.14 # - # Example: + # .. qmp-example:: # # -> { "execute": "query-blockstats" } # <- { - # ... lots of output ... + # ... # } ## { 'command': 'query-blockstats', diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index 6ad5663..adc85b5 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -553,7 +553,7 @@ class QAPISchemaParser: # Note: "sections" with two colons are left alone as # rST markup and not interpreted as a section heading. - # TODO: Remove this error sometime in 2025 or so + # TODO: Remove these errors sometime in 2025 or so # after we've fully transitioned to the new qapidoc # generator. @@ -567,6 +567,14 @@ class QAPISchemaParser: ) raise QAPIParseError(self, emsg) + if 'Example' in match.group(1): + emsg = ( + f"The '{match.group(1)}' section is no longer " + "supported. Please use the '.. qmp-example::' " + "directive, or other suitable markup instead." + ) + raise QAPIParseError(self, emsg) + doc.new_tagged_section(self.info, match.group(1)) text = line[match.end():] if text: diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index b565895..f64bf38 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -172,12 +172,17 @@ # # Duis aute irure dolor # -# Example: +# .. qmp-example:: +# :title: Ideal fast-food burger situation # -# -> in -# <- out +# -> "in" +# <- "out" # -# Examples: +# Examples:: +# +# - Not a QMP code block +# - Merely a preformatted code block literal +# It isn't even an rST list. # - *verbatim* # - {braces} # @@ -199,11 +204,11 @@ # @cmd-feat1: a feature # @cmd-feat2: another feature # -# Example: +# .. qmp-example:: # -# -> in +# -> "this example" # -# <- out +# <- "has no title" ## { 'command': 'cmd-boxed', 'boxed': true, 'data': 'Object', diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index a8e9456..6d24f11 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -184,13 +184,21 @@ frobnicate - Ut enim ad minim veniam Duis aute irure dolor - section=Example - -> in - <- out - section=Examples + +.. qmp-example:: + :title: Ideal fast-food burger situation + + -> "in" + <- "out" + +Examples:: + + - Not a QMP code block + - Merely a preformatted code block literal + It isn't even an rST list. - *verbatim* - {braces} - section=None + Note:: Ceci n'est pas une note section=Since @@ -202,10 +210,12 @@ If you're bored enough to read this, go see a video of boxed cats a feature feature=cmd-feat2 another feature - section=Example - -> in + section=None +.. qmp-example:: + + -> "this example" - <- out + <- "has no title" doc symbol=EVT_BOXED body= diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 30d457e..cb37db6 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -217,17 +217,16 @@ Notes: Duis aute irure dolor +Example: Ideal fast-food burger situation: -Example -~~~~~~~ - - -> in - <- out - + -> "in" + <- "out" -Examples -~~~~~~~~ +Examples: + - Not a QMP code block + - Merely a preformatted code block literal + It isn't even an rST list. - *verbatim* - {braces} @@ -261,13 +260,11 @@ Features "cmd-feat2" another feature +Example:: -Example -~~~~~~~ - - -> in + -> "this example" - <- out + <- "has no title" "EVT_BOXED" (Event) -- cgit v1.1