From: John Snow <js...@redhat.com> Remove the QAPI doc section heading syntax, use plain rST section headings instead.
Tests and documentation are updated to match. Interestingly, Plain rST headings work fine before this patch, except for over- and underlining with '=', which the doc parser rejected as invalid QAPI doc section heading in free-form comments. Signed-off-by: John Snow <js...@redhat.com> Message-ID: <20250618165353.1980365-5-js...@redhat.com> Reviewed-by: Markus Armbruster <arm...@redhat.com> [Add more detail to commit message] Signed-off-by: Markus Armbruster <arm...@redhat.com> --- docs/devel/qapi-code-gen.rst | 28 ++++++++++++++------- docs/interop/firmware.json | 4 ++- docs/interop/vhost-user.json | 4 ++- docs/sphinx/qapidoc.py | 37 +--------------------------- qapi/acpi.json | 4 ++- qapi/audio.json | 4 ++- qapi/authz.json | 4 ++- qapi/block-core.json | 3 ++- qapi/block-export.json | 3 ++- qapi/block.json | 7 ++++-- qapi/char.json | 4 ++- qapi/common.json | 4 ++- qapi/compat.json | 4 ++- qapi/control.json | 4 ++- qapi/crypto.json | 4 ++- qapi/cryptodev.json | 4 ++- qapi/cxl.json | 4 ++- qapi/dump.json | 4 ++- qapi/ebpf.json | 4 ++- qapi/error.json | 4 ++- qapi/introspect.json | 4 ++- qapi/job.json | 4 ++- qapi/machine-common.json | 4 ++- qapi/machine.json | 4 ++- qapi/migration.json | 4 ++- qapi/misc.json | 4 ++- qapi/net.json | 4 ++- qapi/pci.json | 4 ++- qapi/qapi-schema.json | 4 ++- qapi/qdev.json | 4 ++- qapi/qom.json | 4 ++- qapi/replay.json | 4 ++- qapi/rocker.json | 4 ++- qapi/run-state.json | 4 ++- qapi/sockets.json | 4 ++- qapi/stats.json | 4 ++- qapi/tpm.json | 4 ++- qapi/trace.json | 4 ++- qapi/transaction.json | 4 ++- qapi/uefi.json | 4 ++- qapi/ui.json | 14 ++++++++--- qapi/vfio.json | 4 ++- qapi/virtio.json | 4 ++- qapi/yank.json | 4 ++- scripts/qapi/parser.py | 7 ------ storage-daemon/qapi/qapi-schema.json | 8 ++++-- tests/qapi-schema/doc-good.json | 10 +++++--- tests/qapi-schema/doc-good.out | 10 +++++--- 48 files changed, 173 insertions(+), 106 deletions(-) diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index 231cc0fecf..dfdbeac5a5 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -876,25 +876,35 @@ structuring content. Headings and subheadings ~~~~~~~~~~~~~~~~~~~~~~~~ -A free-form documentation comment containing a line which starts with -some ``=`` symbols and then a space defines a section heading:: +Free-form documentation does not start with ``@SYMBOL`` and can contain +arbitrary rST markup. Headings can be marked up using the standard rST +syntax:: ## - # = This is a top level heading + # ************************* + # This is a level 2 heading + # ************************* # # This is a free-form comment which will go under the # top level heading. ## ## - # == This is a second level heading + # This is a third level heading + # ============================== + # + # Level 4 + # _______ + # + # Level 5 + # ^^^^^^^ + # + # Level 6 + # """"""" ## -A heading line must be the first line of the documentation -comment block. - -Section headings must always be correctly nested, so you can only -define a third-level heading inside a second-level heading, and so on. +Level 1 headings are reserved for use by the generated documentation +page itself, leaving level 2 as the highest level that should be used. Documentation markup diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json index 745d21d822..f46fdedfa8 100644 --- a/docs/interop/firmware.json +++ b/docs/interop/firmware.json @@ -11,7 +11,9 @@ # later. See the COPYING file in the top-level directory. ## -# = Firmware +# ******** +# Firmware +# ******** ## { 'pragma': { diff --git a/docs/interop/vhost-user.json b/docs/interop/vhost-user.json index b6ade9e493..095eb99cf7 100644 --- a/docs/interop/vhost-user.json +++ b/docs/interop/vhost-user.json @@ -10,7 +10,9 @@ # later. See the COPYING file in the top-level directory. ## -# = vhost user backend discovery & capabilities +# ******************************************* +# vhost user backend discovery & capabilities +# ******************************************* ## ## diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py index d5d2b5eeb5..b794cde697 100644 --- a/docs/sphinx/qapidoc.py +++ b/docs/sphinx/qapidoc.py @@ -399,44 +399,9 @@ def visit_module(self, path: str) -> None: self.ensure_blank_line() def visit_freeform(self, doc: QAPIDoc) -> None: - # TODO: Once the old qapidoc transformer is deprecated, freeform - # sections can be updated to pure rST, and this transformed removed. - # - # For now, translate our micro-format into rST. Code adapted - # from Peter Maydell's freeform(). - assert len(doc.all_sections) == 1, doc.all_sections body = doc.all_sections[0] - text = self.reformat_arobase(body.text) - info = doc.info - - if re.match(r"=+ ", text): - # Section/subsection heading (if present, will always be the - # first line of the block) - (heading, _, text) = text.partition("\n") - (leader, _, heading) = heading.partition(" ") - # Implicit +1 for heading in the containing .rst doc - level = len(leader) + 1 - - # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#sections - markers = ' #*=_^"' - overline = level <= 2 - marker = markers[level] - - self.ensure_blank_line() - # This credits all 2 or 3 lines to the single source line. - if overline: - self.add_line(marker * len(heading), info) - self.add_line(heading, info) - self.add_line(marker * len(heading), info) - self.ensure_blank_line() - - # Eat blank line(s) and advance info - trimmed = text.lstrip("\n") - text = trimmed - info = info.next_line(len(text) - len(trimmed) + 1) - - self.add_lines(text, info) + self.add_lines(self.reformat_arobase(body.text), doc.info) self.ensure_blank_line() def visit_entity(self, ent: QAPISchemaDefinition) -> None: diff --git a/qapi/acpi.json b/qapi/acpi.json index 2d53b82365..90f8f564fd 100644 --- a/qapi/acpi.json +++ b/qapi/acpi.json @@ -6,7 +6,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later ## -# = ACPI +# **** +# ACPI +# **** ## ## diff --git a/qapi/audio.json b/qapi/audio.json index 16de231f6d..6a22ca384a 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -7,7 +7,9 @@ # See the COPYING file in the top-level directory. ## -# = Audio +# ***** +# Audio +# ***** ## ## diff --git a/qapi/authz.json b/qapi/authz.json index 7fc6e3032e..ad1b4b3af0 100644 --- a/qapi/authz.json +++ b/qapi/authz.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = User authorization +# ****************** +# User authorization +# ****************** ## ## diff --git a/qapi/block-core.json b/qapi/block-core.json index 1df6644f0d..8b413946ff 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2,7 +2,8 @@ # vim: filetype=python ## -# == Block core (VM unrelated) +# Block core (VM unrelated) +# ========================= ## { 'include': 'common.json' } diff --git a/qapi/block-export.json b/qapi/block-export.json index ed4deb54db..2241bfecf2 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -2,7 +2,8 @@ # vim: filetype=python ## -# == Block device exports +# Block device exports +# ==================== ## { 'include': 'sockets.json' } diff --git a/qapi/block.json b/qapi/block.json index 1490a1a17f..2d54a81c36 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -2,13 +2,16 @@ # vim: filetype=python ## -# = Block devices +# ************* +# Block devices +# ************* ## { 'include': 'block-core.json' } ## -# == Additional block stuff (VM related) +# Additional block stuff (VM related) +# =================================== ## ## diff --git a/qapi/char.json b/qapi/char.json index df6e325e2e..f38d04986d 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -3,7 +3,9 @@ # ## -# = Character devices +# ***************** +# Character devices +# ***************** ## { 'include': 'sockets.json' } diff --git a/qapi/common.json b/qapi/common.json index 0e3a0bbbfb..af7e3d618a 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = Common data types +# ***************** +# Common data types +# ***************** ## ## diff --git a/qapi/compat.json b/qapi/compat.json index 42034d9368..90b8d51cf2 100644 --- a/qapi/compat.json +++ b/qapi/compat.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = Compatibility policy +# ******************** +# Compatibility policy +# ******************** ## ## diff --git a/qapi/control.json b/qapi/control.json index 34b733f63b..ab0b3a3bbe 100644 --- a/qapi/control.json +++ b/qapi/control.json @@ -3,7 +3,9 @@ # ## -# = QMP monitor control +# ******************* +# QMP monitor control +# ******************* ## ## diff --git a/qapi/crypto.json b/qapi/crypto.json index 9ec6301e18..21006de36c 100644 --- a/qapi/crypto.json +++ b/qapi/crypto.json @@ -3,7 +3,9 @@ # ## -# = Cryptography +# ************ +# Cryptography +# ************ ## ## diff --git a/qapi/cryptodev.json b/qapi/cryptodev.json index b13db26403..1f49e1822c 100644 --- a/qapi/cryptodev.json +++ b/qapi/cryptodev.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = Cryptography devices +# ******************** +# Cryptography devices +# ******************** ## ## diff --git a/qapi/cxl.json b/qapi/cxl.json index 8f2e9237b1..52cc5d4f33 100644 --- a/qapi/cxl.json +++ b/qapi/cxl.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = CXL devices +# *********** +# CXL devices +# *********** ## ## diff --git a/qapi/dump.json b/qapi/dump.json index d0ba1f0596..0642ca157b 100644 --- a/qapi/dump.json +++ b/qapi/dump.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = Dump guest memory +# ***************** +# Dump guest memory +# ***************** ## ## diff --git a/qapi/ebpf.json b/qapi/ebpf.json index db19ae850f..d45054e666 100644 --- a/qapi/ebpf.json +++ b/qapi/ebpf.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = eBPF Objects +# ************ +# eBPF Objects +# ************ # # eBPF object is an ELF binary that contains the eBPF program and eBPF # map description(BTF). Overall, eBPF object should contain the diff --git a/qapi/error.json b/qapi/error.json index 135c1e8231..54cb02fb88 100644 --- a/qapi/error.json +++ b/qapi/error.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = QMP errors +# ********** +# QMP errors +# ********** ## ## diff --git a/qapi/introspect.json b/qapi/introspect.json index e9e0297282..26d8839f19 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -10,7 +10,9 @@ # See the COPYING file in the top-level directory. ## -# = QMP introspection +# ***************** +# QMP introspection +# ***************** ## ## diff --git a/qapi/job.json b/qapi/job.json index 126fa5ce60..16b280f52f 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = Background jobs +# *************** +# Background jobs +# *************** ## ## diff --git a/qapi/machine-common.json b/qapi/machine-common.json index 298e51f373..0f01599130 100644 --- a/qapi/machine-common.json +++ b/qapi/machine-common.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = Common machine types +# ******************** +# Common machine types +# ******************** ## ## diff --git a/qapi/machine.json b/qapi/machine.json index f712e7da6d..af00a20b1f 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = Machines +# ******** +# Machines +# ******** ## { 'include': 'common.json' } diff --git a/qapi/migration.json b/qapi/migration.json index 2d39a8f748..3bf97df5d8 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -3,7 +3,9 @@ # ## -# = Migration +# ********* +# Migration +# ********* ## { 'include': 'common.json' } diff --git a/qapi/misc.json b/qapi/misc.json index 4b9e601cfa..a180c16db2 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3,7 +3,9 @@ # ## -# = Miscellanea +# *********** +# Miscellanea +# *********** ## { 'include': 'common.json' } diff --git a/qapi/net.json b/qapi/net.json index 97ea183981..3b03843c16 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -3,7 +3,9 @@ # ## -# = Net devices +# *********** +# Net devices +# *********** ## { 'include': 'sockets.json' } diff --git a/qapi/pci.json b/qapi/pci.json index dc85a41d28..a8671cd9ac 100644 --- a/qapi/pci.json +++ b/qapi/pci.json @@ -6,7 +6,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later ## -# = PCI +# *** +# PCI +# *** ## ## diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index a8f66163cb..49b9a0267d 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -1,7 +1,9 @@ # -*- Mode: Python -*- # vim: filetype=python ## -# = Introduction +# ************ +# Introduction +# ************ # # This manual describes the commands and events supported by the QEMU # Monitor Protocol (QMP). diff --git a/qapi/qdev.json b/qapi/qdev.json index 32c7d10046..441ed518b8 100644 --- a/qapi/qdev.json +++ b/qapi/qdev.json @@ -5,7 +5,9 @@ # See the COPYING file in the top-level directory. ## -# = Device infrastructure (qdev) +# **************************** +# Device infrastructure (qdev) +# **************************** ## { 'include': 'qom.json' } diff --git a/qapi/qom.json b/qapi/qom.json index b133b06447..f68f72fbbc 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -10,7 +10,9 @@ { 'include': 'crypto.json' } ## -# = QEMU Object Model (QOM) +# *********************** +# QEMU Object Model (QOM) +# *********************** ## ## diff --git a/qapi/replay.json b/qapi/replay.json index 35e0c4a692..e46c5c1d3f 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -3,7 +3,9 @@ # ## -# = Record/replay +# ************* +# Record/replay +# ************* ## { 'include': 'common.json' } diff --git a/qapi/rocker.json b/qapi/rocker.json index 0c7ef1f77c..e494964952 100644 --- a/qapi/rocker.json +++ b/qapi/rocker.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = Rocker switch device +# ******************** +# Rocker switch device +# ******************** ## ## diff --git a/qapi/run-state.json b/qapi/run-state.json index fd09beb35c..083a3c5eb3 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -3,7 +3,9 @@ # ## -# = VM run state +# ************ +# VM run state +# ************ ## ## diff --git a/qapi/sockets.json b/qapi/sockets.json index f9f559daba..b5f4a8fecd 100644 --- a/qapi/sockets.json +++ b/qapi/sockets.json @@ -2,7 +2,9 @@ # vim: filetype=python ## -# = Socket data types +# ***************** +# Socket data types +# ***************** ## ## diff --git a/qapi/stats.json b/qapi/stats.json index 8902ef94e0..78b88881ea 100644 --- a/qapi/stats.json +++ b/qapi/stats.json @@ -9,7 +9,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later ## -# = Statistics +# ********** +# Statistics +# ********** ## ## diff --git a/qapi/tpm.json b/qapi/tpm.json index a16a72edb9..e66b107f1d 100644 --- a/qapi/tpm.json +++ b/qapi/tpm.json @@ -3,7 +3,9 @@ # ## -# = TPM (trusted platform module) devices +# ************************************* +# TPM (trusted platform module) devices +# ************************************* ## ## diff --git a/qapi/trace.json b/qapi/trace.json index eb5f63f513..d08c9c6a88 100644 --- a/qapi/trace.json +++ b/qapi/trace.json @@ -7,7 +7,9 @@ # See the COPYING file in the top-level directory. ## -# = Tracing +# ******* +# Tracing +# ******* ## ## diff --git a/qapi/transaction.json b/qapi/transaction.json index 9d9e7af26c..927035f5a7 100644 --- a/qapi/transaction.json +++ b/qapi/transaction.json @@ -3,7 +3,9 @@ # ## -# = Transactions +# ************ +# Transactions +# ************ ## { 'include': 'block-core.json' } diff --git a/qapi/uefi.json b/qapi/uefi.json index 6592183d6c..a206c2e953 100644 --- a/qapi/uefi.json +++ b/qapi/uefi.json @@ -3,7 +3,9 @@ # ## -# = UEFI Variable Store +# ******************* +# UEFI Variable Store +# ******************* # # The QEMU efi variable store implementation (hw/uefi/) uses this to # store non-volatile variables in json format on disk. diff --git a/qapi/ui.json b/qapi/ui.json index 514fa159b1..f5e77ae19d 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -3,7 +3,9 @@ # ## -# = Remote desktop +# ************** +# Remote desktop +# ************** ## { 'include': 'common.json' } @@ -200,7 +202,8 @@ 'if': 'CONFIG_PIXMAN' } ## -# == Spice +# Spice +# ===== ## ## @@ -461,7 +464,8 @@ 'if': 'CONFIG_SPICE' } ## -# == VNC +# VNC +# === ## ## @@ -794,7 +798,9 @@ 'if': 'CONFIG_VNC' } ## -# = Input +# ***** +# Input +# ***** ## ## diff --git a/qapi/vfio.json b/qapi/vfio.json index b53b7caecd..a1a9c5b673 100644 --- a/qapi/vfio.json +++ b/qapi/vfio.json @@ -3,7 +3,9 @@ # ## -# = VFIO devices +# ************ +# VFIO devices +# ************ ## ## diff --git a/qapi/virtio.json b/qapi/virtio.json index 73df718a26..3cac0774f7 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -3,7 +3,9 @@ # ## -# = Virtio devices +# ************** +# Virtio devices +# ************** ## ## diff --git a/qapi/yank.json b/qapi/yank.json index 30f46c97c9..d13a8e9117 100644 --- a/qapi/yank.json +++ b/qapi/yank.json @@ -3,7 +3,9 @@ # ## -# = Yank feature +# ************ +# Yank feature +# ************ ## ## diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index 949d9e8bff..aad7e249f8 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -597,22 +597,15 @@ def get_doc(self) -> 'QAPIDoc': # Free-form documentation doc = QAPIDoc(info) doc.ensure_untagged_section(self.info) - first = True while line is not None: if match := self._match_at_name_colon(line): raise QAPIParseError( self, "'@%s:' not allowed in free-form documentation" % match.group(1)) - if line.startswith('='): - if not first: - raise QAPIParseError( - self, - "'=' heading must come first in a comment block") doc.append_line(line) self.accept(False) line = self.get_doc_line() - first = False self.accept() doc.end() diff --git a/storage-daemon/qapi/qapi-schema.json b/storage-daemon/qapi/qapi-schema.json index 0427594c98..478e7a92b2 100644 --- a/storage-daemon/qapi/qapi-schema.json +++ b/storage-daemon/qapi/qapi-schema.json @@ -14,7 +14,9 @@ # storage daemon. ## -# = Introduction +# ************ +# Introduction +# ************ # # This manual describes the commands and events supported by the QEMU # storage daemon QMP. @@ -51,7 +53,9 @@ { 'include': '../../qapi/job.json' } ## -# = Block devices +# ************* +# Block devices +# ************* ## { 'include': '../../qapi/block-core.json' } { 'include': '../../qapi/block-export.json' } diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 14b808f909..fac13425b7 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -8,7 +8,9 @@ 'documentation-exceptions': [ 'Enum', 'Variant1', 'Alternate', 'cmd' ] } } ## -# = Section +# ******* +# Section +# ******* ## ## @@ -16,7 +18,8 @@ ## ## -# == Subsection +# Subsection +# ========== # # *with emphasis* # @var {in braces} @@ -144,7 +147,8 @@ 'if': { 'not': { 'any': [ 'IFONE', 'IFTWO' ] } } } ## -# == Another subsection +# Another subsection +# ================== ## ## diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index dc8352eed4..04a5507264 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -55,13 +55,16 @@ event EVT_BOXED Object feature feat3 doc freeform body= -= Section +******* +Section +******* doc freeform body= Just text, no heading. doc freeform body= -== Subsection +Subsection +========== *with emphasis* @var {in braces} @@ -155,7 +158,8 @@ description starts on the same line a feature doc freeform body= -== Another subsection +Another subsection +================== doc symbol=cmd body= -- 2.49.0