Browse Source

docs/sphinx: remove special parsing for freeform sections

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 <jsnow@redhat.com>
Message-ID: <20250618165353.1980365-5-jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Add more detail to commit message]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
pull/294/head
John Snow 10 months ago
committed by Markus Armbruster
parent
commit
6c10778826
  1. 28
      docs/devel/qapi-code-gen.rst
  2. 4
      docs/interop/firmware.json
  3. 4
      docs/interop/vhost-user.json
  4. 37
      docs/sphinx/qapidoc.py
  5. 4
      qapi/acpi.json
  6. 4
      qapi/audio.json
  7. 4
      qapi/authz.json
  8. 3
      qapi/block-core.json
  9. 3
      qapi/block-export.json
  10. 7
      qapi/block.json
  11. 4
      qapi/char.json
  12. 4
      qapi/common.json
  13. 4
      qapi/compat.json
  14. 4
      qapi/control.json
  15. 4
      qapi/crypto.json
  16. 4
      qapi/cryptodev.json
  17. 4
      qapi/cxl.json
  18. 4
      qapi/dump.json
  19. 4
      qapi/ebpf.json
  20. 4
      qapi/error.json
  21. 4
      qapi/introspect.json
  22. 4
      qapi/job.json
  23. 4
      qapi/machine-common.json
  24. 4
      qapi/machine.json
  25. 4
      qapi/migration.json
  26. 4
      qapi/misc.json
  27. 4
      qapi/net.json
  28. 4
      qapi/pci.json
  29. 4
      qapi/qapi-schema.json
  30. 4
      qapi/qdev.json
  31. 4
      qapi/qom.json
  32. 4
      qapi/replay.json
  33. 4
      qapi/rocker.json
  34. 4
      qapi/run-state.json
  35. 4
      qapi/sockets.json
  36. 4
      qapi/stats.json
  37. 4
      qapi/tpm.json
  38. 4
      qapi/trace.json
  39. 4
      qapi/transaction.json
  40. 4
      qapi/uefi.json
  41. 14
      qapi/ui.json
  42. 4
      qapi/vfio.json
  43. 4
      qapi/virtio.json
  44. 4
      qapi/yank.json
  45. 7
      scripts/qapi/parser.py
  46. 8
      storage-daemon/qapi/qapi-schema.json
  47. 10
      tests/qapi-schema/doc-good.json
  48. 10
      tests/qapi-schema/doc-good.out

28
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

4
docs/interop/firmware.json

@ -11,7 +11,9 @@
# later. See the COPYING file in the top-level directory.
##
# = Firmware
# ********
# Firmware
# ********
##
{ 'pragma': {

4
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
# *******************************************
##
##

37
docs/sphinx/qapidoc.py

@ -399,44 +399,9 @@ class Transmogrifier:
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:

4
qapi/acpi.json

@ -6,7 +6,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
##
# = ACPI
# ****
# ACPI
# ****
##
##

4
qapi/audio.json

@ -7,7 +7,9 @@
# See the COPYING file in the top-level directory.
##
# = Audio
# *****
# Audio
# *****
##
##

4
qapi/authz.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = User authorization
# ******************
# User authorization
# ******************
##
##

3
qapi/block-core.json

@ -2,7 +2,8 @@
# vim: filetype=python
##
# == Block core (VM unrelated)
# Block core (VM unrelated)
# =========================
##
{ 'include': 'common.json' }

3
qapi/block-export.json

@ -2,7 +2,8 @@
# vim: filetype=python
##
# == Block device exports
# Block device exports
# ====================
##
{ 'include': 'sockets.json' }

7
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)
# ===================================
##
##

4
qapi/char.json

@ -3,7 +3,9 @@
#
##
# = Character devices
# *****************
# Character devices
# *****************
##
{ 'include': 'sockets.json' }

4
qapi/common.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = Common data types
# *****************
# Common data types
# *****************
##
##

4
qapi/compat.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = Compatibility policy
# ********************
# Compatibility policy
# ********************
##
##

4
qapi/control.json

@ -3,7 +3,9 @@
#
##
# = QMP monitor control
# *******************
# QMP monitor control
# *******************
##
##

4
qapi/crypto.json

@ -3,7 +3,9 @@
#
##
# = Cryptography
# ************
# Cryptography
# ************
##
##

4
qapi/cryptodev.json

@ -5,7 +5,9 @@
# See the COPYING file in the top-level directory.
##
# = Cryptography devices
# ********************
# Cryptography devices
# ********************
##
##

4
qapi/cxl.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = CXL devices
# ***********
# CXL devices
# ***********
##
##

4
qapi/dump.json

@ -5,7 +5,9 @@
# See the COPYING file in the top-level directory.
##
# = Dump guest memory
# *****************
# Dump guest memory
# *****************
##
##

4
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

4
qapi/error.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = QMP errors
# **********
# QMP errors
# **********
##
##

4
qapi/introspect.json

@ -10,7 +10,9 @@
# See the COPYING file in the top-level directory.
##
# = QMP introspection
# *****************
# QMP introspection
# *****************
##
##

4
qapi/job.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = Background jobs
# ***************
# Background jobs
# ***************
##
##

4
qapi/machine-common.json

@ -5,7 +5,9 @@
# See the COPYING file in the top-level directory.
##
# = Common machine types
# ********************
# Common machine types
# ********************
##
##

4
qapi/machine.json

@ -5,7 +5,9 @@
# See the COPYING file in the top-level directory.
##
# = Machines
# ********
# Machines
# ********
##
{ 'include': 'common.json' }

4
qapi/migration.json

@ -3,7 +3,9 @@
#
##
# = Migration
# *********
# Migration
# *********
##
{ 'include': 'common.json' }

4
qapi/misc.json

@ -3,7 +3,9 @@
#
##
# = Miscellanea
# ***********
# Miscellanea
# ***********
##
{ 'include': 'common.json' }

4
qapi/net.json

@ -3,7 +3,9 @@
#
##
# = Net devices
# ***********
# Net devices
# ***********
##
{ 'include': 'sockets.json' }

4
qapi/pci.json

@ -6,7 +6,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
##
# = PCI
# ***
# PCI
# ***
##
##

4
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).

4
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' }

4
qapi/qom.json

@ -10,7 +10,9 @@
{ 'include': 'crypto.json' }
##
# = QEMU Object Model (QOM)
# ***********************
# QEMU Object Model (QOM)
# ***********************
##
##

4
qapi/replay.json

@ -3,7 +3,9 @@
#
##
# = Record/replay
# *************
# Record/replay
# *************
##
{ 'include': 'common.json' }

4
qapi/rocker.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = Rocker switch device
# ********************
# Rocker switch device
# ********************
##
##

4
qapi/run-state.json

@ -3,7 +3,9 @@
#
##
# = VM run state
# ************
# VM run state
# ************
##
##

4
qapi/sockets.json

@ -2,7 +2,9 @@
# vim: filetype=python
##
# = Socket data types
# *****************
# Socket data types
# *****************
##
##

4
qapi/stats.json

@ -9,7 +9,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
##
# = Statistics
# **********
# Statistics
# **********
##
##

4
qapi/tpm.json

@ -3,7 +3,9 @@
#
##
# = TPM (trusted platform module) devices
# *************************************
# TPM (trusted platform module) devices
# *************************************
##
##

4
qapi/trace.json

@ -7,7 +7,9 @@
# See the COPYING file in the top-level directory.
##
# = Tracing
# *******
# Tracing
# *******
##
##

4
qapi/transaction.json

@ -3,7 +3,9 @@
#
##
# = Transactions
# ************
# Transactions
# ************
##
{ 'include': 'block-core.json' }

4
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.

14
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
# *****
##
##

4
qapi/vfio.json

@ -3,7 +3,9 @@
#
##
# = VFIO devices
# ************
# VFIO devices
# ************
##
##

4
qapi/virtio.json

@ -3,7 +3,9 @@
#
##
# = Virtio devices
# **************
# Virtio devices
# **************
##
##

4
qapi/yank.json

@ -3,7 +3,9 @@
#
##
# = Yank feature
# ************
# Yank feature
# ************
##
##

7
scripts/qapi/parser.py

@ -597,22 +597,15 @@ class QAPISchemaParser:
# 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()

8
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' }

10
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
# ==================
##
##

10
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=

Loading…
Cancel
Save