Commit f3ed93d5 authored by Kevin Wolf's avatar Kevin Wolf Committed by Markus Armbruster
Browse files

qapi: Allow documentation for features



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

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Message-Id: <20190606153803.5278-6-armbru@redhat.com>
Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
parent 03bf06bd
Loading
Loading
Loading
Loading
+39 −4
Original line number Diff line number Diff line
@@ -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):
+12 −0
Original line number Diff line number Diff line
@@ -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))