qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, pkrempa@redhat.com, qemu-block@nongnu.org
Subject: [Qemu-devel] [PATCH 5/7] qapi: Allow documentation for features
Date: Thu,  6 Jun 2019 17:38:01 +0200	[thread overview]
Message-ID: <20190606153803.5278-6-armbru@redhat.com> (raw)
In-Reply-To: <20190606153803.5278-1-armbru@redhat.com>

From: Kevin Wolf <kwolf@redhat.com>

Features will be documented in a new part introduced by a "Features:"
line, after arguments and before named sections.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 scripts/qapi/common.py | 43 ++++++++++++++++++++++++++++++++++++++----
 scripts/qapi/doc.py    | 12 ++++++++++++
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index f40a2cd4c5..1164301edf 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -129,6 +129,7 @@ class QAPIDoc(object):
           optional overview
         * an ARGS part: description of each argument (for commands and
           events) or member (for structs, unions and alternates),
+        * a FEATURES part: description of each feature,
         * a VARIOUS part: optional tagged sections.
 
         Free-form documentation blocks consist only of a BODY part.
@@ -136,7 +137,8 @@ class QAPIDoc(object):
         # TODO Make it a subclass of Enum when Python 2 support is removed
         BODY = 1
         ARGS = 2
-        VARIOUS = 3
+        FEATURES = 3
+        VARIOUS = 4
 
     def __init__(self, parser, info):
         # self._parser is used to report errors with QAPIParseError.  The
@@ -149,6 +151,7 @@ class QAPIDoc(object):
         self.body = QAPIDoc.Section()
         # dict mapping parameter name to ArgSection
         self.args = OrderedDict()
+        self.features = OrderedDict()
         # a list of Section
         self.sections = []
         # the current section
@@ -197,6 +200,8 @@ class QAPIDoc(object):
             self._append_body_line(line)
         elif self._part == QAPIDoc.DocPart.ARGS:
             self._append_args_line(line)
+        elif self._part == QAPIDoc.DocPart.FEATURES:
+            self._append_features_line(line)
         elif self._part == QAPIDoc.DocPart.VARIOUS:
             self._append_various_line(line)
         else:
@@ -229,6 +234,8 @@ class QAPIDoc(object):
             if name.startswith('@') and name.endswith(':'):
                 self._part = QAPIDoc.DocPart.ARGS
                 self._append_args_line(line)
+            elif line == 'Features:':
+                self._part = QAPIDoc.DocPart.FEATURES
             elif self._is_section_tag(name):
                 self._part = QAPIDoc.DocPart.VARIOUS
                 self._append_various_line(line)
@@ -248,6 +255,28 @@ class QAPIDoc(object):
             self._part = QAPIDoc.DocPart.VARIOUS
             self._append_various_line(line)
             return
+        elif (self._section.text.endswith('\n\n')
+              and line and not line[0].isspace()):
+            if line == 'Features:':
+                self._part = QAPIDoc.DocPart.FEATURES
+            else:
+                self._start_section()
+                self._part = QAPIDoc.DocPart.VARIOUS
+                self._append_various_line(line)
+            return
+
+        self._append_freeform(line.strip())
+
+    def _append_features_line(self, line):
+        name = line.split(' ', 1)[0]
+
+        if name.startswith('@') and name.endswith(':'):
+            line = line[len(name)+1:]
+            self._start_features_section(name[1:-1])
+        elif self._is_section_tag(name):
+            self._part = QAPIDoc.DocPart.VARIOUS
+            self._append_various_line(line)
+            return
         elif (self._section.text.endswith('\n\n')
               and line and not line[0].isspace()):
             self._start_section()
@@ -274,17 +303,23 @@ class QAPIDoc(object):
 
         self._append_freeform(line)
 
-    def _start_args_section(self, name):
+    def _start_symbol_section(self, symbols_dict, name):
         # FIXME invalid names other than the empty string aren't flagged
         if not name:
             raise QAPIParseError(self._parser, "Invalid parameter name")
-        if name in self.args:
+        if name in symbols_dict:
             raise QAPIParseError(self._parser,
                                  "'%s' parameter name duplicated" % name)
         assert not self.sections
         self._end_section()
         self._section = QAPIDoc.ArgSection(name)
-        self.args[name] = self._section
+        symbols_dict[name] = self._section
+
+    def _start_args_section(self, name):
+        self._start_symbol_section(self.args, name)
+
+    def _start_features_section(self, name):
+        self._start_symbol_section(self.features, name)
 
     def _start_section(self, name=None):
         if name in ('Returns', 'Since') and self.has_section(name):
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 433e9fcbfb..5fc0fc7e06 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -182,6 +182,17 @@ def texi_members(doc, what, base, variants, member_func):
     return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items)
 
 
+def texi_features(doc):
+    """Format the table of features"""
+    items = ''
+    for section in doc.features.values():
+        desc = texi_format(section.text)
+        items += '@item @code{%s}\n%s' % (section.name, desc)
+    if not items:
+        return ''
+    return '\n@b{Features:}\n@table @asis\n%s@end table\n' % (items)
+
+
 def texi_sections(doc, ifcond):
     """Format additional sections following arguments"""
     body = ''
@@ -201,6 +212,7 @@ def texi_entity(doc, what, ifcond, base=None, variants=None,
                 member_func=texi_member):
     return (texi_body(doc)
             + texi_members(doc, what, base, variants, member_func)
+            + texi_features(doc)
             + texi_sections(doc, ifcond))
 
 
-- 
2.21.0



  parent reply	other threads:[~2019-06-06 15:43 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-06 15:37 [Qemu-devel] [PATCH 0/7] file-posix: Add dynamic-auto-read-only QAPI feature Markus Armbruster
2019-06-06 15:37 ` [Qemu-devel] [PATCH 1/7] qapi: Add feature flags to struct types Markus Armbruster
2019-06-06 15:37 ` [Qemu-devel] [PATCH 2/7] tests/qapi-schema: Test for good feature lists in structs Markus Armbruster
2019-06-06 15:37 ` [Qemu-devel] [PATCH 3/7] tests/qapi-schema: Error case tests for features " Markus Armbruster
2019-06-06 15:38 ` [Qemu-devel] [PATCH 4/7] qapi: Disentangle QAPIDoc code Markus Armbruster
2019-06-06 15:38 ` Markus Armbruster [this message]
2019-06-06 15:38 ` [Qemu-devel] [PATCH 6/7] file-posix: Add dynamic-auto-read-only QAPI feature Markus Armbruster
2019-06-06 15:54   ` Eric Blake
2019-06-12 16:31     ` Markus Armbruster
2019-06-06 15:38 ` [Qemu-devel] [PATCH 7/7] qapi: Simplify QAPIDoc implements its state machine Markus Armbruster
2019-06-07 15:02 ` [Qemu-devel] [PATCH 0/7] file-posix: Add dynamic-auto-read-only QAPI feature Kevin Wolf
2019-06-12 16:45 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190606153803.5278-6-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pkrempa@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).