[rtems-central commit] interfacedoc: Various improvements

Sebastian Huber sebh at rtems.org
Thu Oct 8 13:25:41 UTC 2020


Module:    rtems-central
Branch:    master
Commit:    fcc887ef7a41c700252f7d27317e822308f78ec3
Changeset: http://git.rtems.org/rtems-central/commit/?id=fcc887ef7a41c700252f7d27317e822308f78ec3

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Sep 30 14:47:06 2020 +0200

interfacedoc: Various improvements

---

 rtemsspec/interfacedoc.py                | 115 ++++++++++-----
 rtemsspec/sphinxcontent.py               |   2 +
 rtemsspec/tests/spec-interface/func2.yml |   2 +
 rtemsspec/tests/spec-interface/gb.yml    |   6 +
 rtemsspec/tests/test_interface.py        |   2 +
 rtemsspec/tests/test_interfacedoc.py     | 246 ++++++++++++++++++++++---------
 6 files changed, 267 insertions(+), 106 deletions(-)

diff --git a/rtemsspec/interfacedoc.py b/rtemsspec/interfacedoc.py
index 81e1d3c..b977ab8 100644
--- a/rtemsspec/interfacedoc.py
+++ b/rtemsspec/interfacedoc.py
@@ -27,7 +27,7 @@ This module provides functions for the generation of interface documentation.
 # POSSIBILITY OF SUCH DAMAGE.
 
 import os
-from typing import Any, Callable, Dict, List
+from typing import Any, Callable, Dict, List, Set
 
 from rtemsspec.content import CContent, enabled_by_to_exp, ExpressionMapper
 from rtemsspec.sphinxcontent import get_label, get_reference, SphinxContent, \
@@ -74,13 +74,22 @@ def _generate_introduction(target: str, group: Item,
                            items: List[Item]) -> None:
     content = SphinxContent()
     content.register_license_and_copyrights_of_item(group)
+    content.add_automatically_generated_warning()
     group_name = group["name"]
+    content.add(f".. Generated from spec:{group.uid}")
     with content.section("Introduction", get_label(group_name)):
+        # This needs to be in front of the list since comment blocks have an
+        # effect on the list layout in the HTML output
+        content.add(".. The following list was generated from:")
+        for item in items:
+            content.append(f".. spec:{item.uid}")
+
         content.append("")
         content.gap = False
         content.wrap(group["brief"])
         content.wrap(group["description"])
         content.paste(f"The directives provided by the {group_name} are:")
+
         for item in items:
             content.register_license_and_copyrights_of_item(item)
             name = item["name"]
@@ -132,50 +141,69 @@ def _add_definition(content: CContent, mapper: ItemMapper, item: Item,
             add_definition(content, mapper, item, default)
 
 
+def _generate_directive(content: SphinxContent, mapper: _Mapper,
+                        code_mapper: _CodeMapper, item: Item) -> None:
+    content.wrap(item["brief"])
+    content.add(".. rubric:: CALLING SEQUENCE:")
+    with content.directive("code-block", "c"):
+        code = CContent()
+        _add_definition(code, code_mapper, item, "definition",
+                        item["definition"], _add_function_definition)
+        content.add(code)
+    if item["params"]:
+        content.add(".. rubric:: PARAMETERS:")
+        for param in item["params"]:
+            param_name = mapper.substitute(param["name"])
+            content.add_definition_item(
+                f"``{param_name}``",
+                mapper.substitute(f"This parameter {param['description']}"),
+                wrap=True)
+    if item["description"]:
+        content.add(".. rubric:: DESCRIPTION:")
+        content.wrap(mapper.substitute(item["description"]))
+    ret = item["return"]
+    if ret["return"] or ret["return-values"]:
+        content.add(".. rubric:: RETURN VALUES:")
+        if ret["return-values"]:
+            for retval in ret["return-values"]:
+                if isinstance(retval["value"], str):
+                    value = mapper.substitute(str(retval["value"]))
+                else:
+                    value = f"``{str(retval['value'])}``"
+                content.add_definition_item(value,
+                                            mapper.substitute(
+                                                retval["description"]),
+                                            wrap=True)
+        content.wrap(mapper.substitute(ret["return"]))
+    if item["notes"]:
+        content.add(".. rubric:: NOTES:")
+        content.wrap(mapper.substitute(item["notes"]))
+
+
 def _generate_directives(target: str, group: Item, items: List[Item]) -> None:
     content = SphinxContent()
     content.register_license_and_copyrights_of_item(group)
+    content.add_automatically_generated_warning()
     group_name = group["name"]
     with content.section("Directives", get_label(group_name)):
+        content.wrap([
+            f"This section details the directives of the {group_name}.",
+            "A subsection is dedicated to each of this manager's directives",
+            "and lists the calling sequence, parameters, description,",
+            "return values, and notes of the directive."
+        ])
         for item in items:
             content.register_license_and_copyrights_of_item(item)
             name = item["name"]
             code_mapper = _CodeMapper(item)
             mapper = _Mapper(item)
-            with content.section(f"{name}()", "Interface"):
-                content.wrap(item["brief"])
-                with content.definition_item("CALLING SEQUENCE:"):
-                    with content.directive("code-block", "c"):
-                        code = CContent()
-                        _add_definition(code, code_mapper, item, "definition",
-                                        item["definition"],
-                                        _add_function_definition)
-                        content.add(code)
-                if item["params"]:
-                    with content.definition_item("DIRECTIVE PARAMETERS:"):
-                        for param in item["params"]:
-                            content.add_definition_item(
-                                mapper.substitute(param["name"]),
-                                mapper.substitute(
-                                    f"This parameter {param['description']}"),
-                                wrap=True)
-                ret = item["return"]
-                if ret["return"] or ret["return-values"]:
-                    with content.definition_item("DIRECTIVE RETURN VALUES:"):
-                        if ret["return-values"]:
-                            for retval in ret["return-values"]:
-                                content.add_definition_item(
-                                    mapper.substitute(str(retval["value"])),
-                                    mapper.substitute(retval["description"]),
-                                    wrap=True)
-                        content.wrap(mapper.substitute(ret["return"]))
-                content.add_definition_item("DESCRIPTION:",
-                                            mapper.substitute(
-                                                item["description"]),
-                                            wrap=True)
-                content.add_definition_item("NOTES:",
-                                            mapper.substitute(item["notes"]),
-                                            wrap=True)
+            content.add(f".. Generated from spec:{item.uid}")
+            with content.directive("raw", "latex"):
+                content.add("\\clearpage")
+            directive = f"{name}()"
+            content.add_index_entries([directive] + item["index-entries"])
+            with content.section(directive, "Interface"):
+                _generate_directive(content, mapper, code_mapper, item)
     content.add_licence_and_copyrights()
     content.write(target)
 
@@ -188,13 +216,20 @@ def generate(config: list, item_cache: ItemCache) -> None:
     :param item_cache: The specification item cache containing the interfaces.
     """
     for doc_config in config:
-        items = []  # type: List[Item]
+        items = set()  # type: Set[Item]
         group = item_cache[doc_config["group"]]
         assert group["type"] == "interface"
         assert group["interface-type"] == "group"
         for child in group.children("interface-ingroup"):
             if child["interface-type"] in ["function"]:
-                items.append(child)
-        items.sort(key=lambda x: x["name"])
-        _generate_introduction(doc_config["introduction-target"], group, items)
-        _generate_directives(doc_config["directives-target"], group, items)
+                items.add(child)
+        ordered_items = []  # type: List[Item]
+        for parent in group.parents("documentation-order"):
+            if parent in items:
+                ordered_items.append(parent)
+                items.remove(parent)
+        ordered_items.extend(sorted(items, key=lambda x: x["name"]))
+        _generate_introduction(doc_config["introduction-target"], group,
+                               ordered_items)
+        _generate_directives(doc_config["directives-target"], group,
+                             ordered_items)
diff --git a/rtemsspec/sphinxcontent.py b/rtemsspec/sphinxcontent.py
index f9bafa7..b303d92 100644
--- a/rtemsspec/sphinxcontent.py
+++ b/rtemsspec/sphinxcontent.py
@@ -265,6 +265,8 @@ class SphinxMapper(ItemMapper):
                            _get_appl_config_option)
         self.add_get_value("interface/define:/name", _get_value_sphinx_macro)
         self.add_get_value("interface/enum:/name", _get_value_sphinx_type)
+        self.add_get_value("interface/enumerator:/name",
+                           _get_value_sphinx_macro)
         self.add_get_value("interface/function:/name",
                            _get_value_sphinx_function)
         self.add_get_value("interface/macro:/name", _get_value_sphinx_function)
diff --git a/rtemsspec/tests/spec-interface/func2.yml b/rtemsspec/tests/spec-interface/func2.yml
index a156f24..9d05233 100644
--- a/rtemsspec/tests/spec-interface/func2.yml
+++ b/rtemsspec/tests/spec-interface/func2.yml
@@ -51,4 +51,6 @@ return:
     value: 1
   - description: is returned, in case B.
     value: 2
+  - description: is returned, in case C.
+    value: ${enum:/name}
 type: interface
diff --git a/rtemsspec/tests/spec-interface/gb.yml b/rtemsspec/tests/spec-interface/gb.yml
index b4251a5..fc98b70 100644
--- a/rtemsspec/tests/spec-interface/gb.yml
+++ b/rtemsspec/tests/spec-interface/gb.yml
@@ -14,5 +14,11 @@ links:
   uid: other
 - role: interface-placement
   uid: h
+- role: documentation-order
+  uid: func4
+- role: documentation-order
+  uid: func2
+- role: documentation-order
+  uid: enum
 name: Group B
 type: interface
diff --git a/rtemsspec/tests/test_interface.py b/rtemsspec/tests/test_interface.py
index e589d66..f518c16 100644
--- a/rtemsspec/tests/test_interface.py
+++ b/rtemsspec/tests/test_interface.py
@@ -224,6 +224,8 @@ void Function( int Param0, const int *Param1, int *Param2, int *Param3 );
  *
  * @retval 2 is returned, in case B.
  *
+ * @retval #Enum is returned, in case C.
+ *
  * @return Sometimes some value.  See Function().
  */
 static inline int VeryLongFunction(
diff --git a/rtemsspec/tests/test_interfacedoc.py b/rtemsspec/tests/test_interfacedoc.py
index 07dc8b1..919ac9d 100644
--- a/rtemsspec/tests/test_interfacedoc.py
+++ b/rtemsspec/tests/test_interfacedoc.py
@@ -56,18 +56,37 @@ def test_interfacedoc(tmpdir):
 
 .. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
 
+.. Do not manually edit this file.  It is part of the RTEMS quality process
+.. and was automatically generated.
+..
+.. If you find something that needs to be fixed or worded better please
+.. post a report to an RTEMS mailing list or raise a bug report:
+..
+.. https://docs.rtems.org/branches/master/user/support/bugs.html
+..
+.. For information on updating and regenerating please refer to:
+..
+.. https://docs.rtems.org/branches/master/eng/req/howto.html
+
+.. Generated from spec:/gb
+
 .. _GroupBIntroduction:
 
 Introduction
 ============
 
-The directives provided by the Group B are:
+.. The following list was generated from:
+.. spec:/func4
+.. spec:/func2
+.. spec:/func3
 
-* :ref:`InterfaceVeryLongFunction` - Very long function brief description.
+The directives provided by the Group B are:
 
 * :ref:`InterfaceVeryLongTypeFunction` - Function brief description with very
   long return type.
 
+* :ref:`InterfaceVeryLongFunction` - Very long function brief description.
+
 * :ref:`InterfaceVoidFunction`
 """
         assert content == src.read()
@@ -77,11 +96,65 @@ The directives provided by the Group B are:
 
 .. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
 
+.. Do not manually edit this file.  It is part of the RTEMS quality process
+.. and was automatically generated.
+..
+.. If you find something that needs to be fixed or worded better please
+.. post a report to an RTEMS mailing list or raise a bug report:
+..
+.. https://docs.rtems.org/branches/master/user/support/bugs.html
+..
+.. For information on updating and regenerating please refer to:
+..
+.. https://docs.rtems.org/branches/master/eng/req/howto.html
+
 .. _GroupBDirectives:
 
 Directives
 ==========
 
+This section details the directives of the Group B. A subsection is dedicated
+to each of this manager's directives and lists the calling sequence,
+parameters, description, return values, and notes of the directive.
+
+.. Generated from spec:/func4
+
+.. raw:: latex
+
+    \\clearpage
+
+.. index:: VeryLongTypeFunction()
+
+.. _InterfaceVeryLongTypeFunction:
+
+VeryLongTypeFunction()
+----------------------
+
+Function brief description with very long return type.
+
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
+
+    #if 1
+      NotSoVeryLongType VeryLongTypeFunction( void );
+    #else
+      VeryLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongType
+      VeryLongTypeFunction( void );
+    #endif
+
+.. rubric:: RETURN VALUES:
+
+This function returns an object with a very long type.
+
+.. Generated from spec:/func2
+
+.. raw:: latex
+
+    \\clearpage
+
+.. index:: VeryLongFunction()
+
 .. _InterfaceVeryLongFunction:
 
 VeryLongFunction()
@@ -89,76 +162,73 @@ VeryLongFunction()
 
 Very long function brief description.
 
-CALLING SEQUENCE:
-    .. code-block:: c
+.. rubric:: CALLING SEQUENCE:
 
-        int VeryLongFunction(
-          int                  VeryLongParam0,
-          const struct Struct *VeryLongParam1,
-          struct Struct    *( *VeryLongParam2 )( void ),
-          struct Struct       *VeryLongParam3
-        );
+.. code-block:: c
 
-DIRECTIVE PARAMETERS:
-    VeryLongParam0
-        This parameter is very long parameter 0 with some super important and
-        extra very long description which makes a lot of sense.
+    int VeryLongFunction(
+      int                  VeryLongParam0,
+      const struct Struct *VeryLongParam1,
+      struct Struct    *( *VeryLongParam2 )( void ),
+      struct Struct       *VeryLongParam3
+    );
 
-    VeryLongParam1
-        This parameter is very long parameter 1.
+.. rubric:: PARAMETERS:
 
-    VeryLongParam2
-        This parameter is very long parameter 2.
+``VeryLongParam0``
+    This parameter is very long parameter 0 with some super important and extra
+    very long description which makes a lot of sense.
 
-    VeryLongParam3
-        This parameter is very long parameter 3.
+``VeryLongParam1``
+    This parameter is very long parameter 1.
 
-DIRECTIVE RETURN VALUES:
-    1
-        is returned, in case A.
+``VeryLongParam2``
+    This parameter is very long parameter 2.
 
-    2
-        is returned, in case B.
+``VeryLongParam3``
+    This parameter is very long parameter 3.
 
-    Sometimes some value.  See :ref:`InterfaceFunction`.
+.. rubric:: DESCRIPTION:
 
-DESCRIPTION:
-    VeryLongFunction description.
+VeryLongFunction description.
 
-NOTES:
-    VeryLongFunction notes.
+.. rubric:: RETURN VALUES:
 
-.. _InterfaceVeryLongTypeFunction:
+``1``
+    is returned, in case A.
 
-VeryLongTypeFunction()
-----------------------
+``2``
+    is returned, in case B.
 
-Function brief description with very long return type.
+:c:type:`Enum`
+    is returned, in case C.
+
+Sometimes some value.  See :ref:`InterfaceFunction`.
+
+.. rubric:: NOTES:
 
-CALLING SEQUENCE:
-    .. code-block:: c
+VeryLongFunction notes.
 
-        #if 1
-          NotSoVeryLongType VeryLongTypeFunction( void );
-        #else
-          VeryLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongType
-          VeryLongTypeFunction( void );
-        #endif
+.. Generated from spec:/func3
 
-DIRECTIVE RETURN VALUES:
-    This function returns an object with a very long type.
+.. raw:: latex
+
+    \\clearpage
+
+.. index:: VoidFunction()
 
 .. _InterfaceVoidFunction:
 
 VoidFunction()
 --------------
 
-CALLING SEQUENCE:
-    .. code-block:: c
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
 
-        #if 1
-          void VoidFunction( void );
-        #endif
+    #if 1
+      void VoidFunction( void );
+    #endif
 """
         assert content == src.read()
 
@@ -167,11 +237,28 @@ CALLING SEQUENCE:
 
 .. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
 
+.. Do not manually edit this file.  It is part of the RTEMS quality process
+.. and was automatically generated.
+..
+.. If you find something that needs to be fixed or worded better please
+.. post a report to an RTEMS mailing list or raise a bug report:
+..
+.. https://docs.rtems.org/branches/master/user/support/bugs.html
+..
+.. For information on updating and regenerating please refer to:
+..
+.. https://docs.rtems.org/branches/master/eng/req/howto.html
+
+.. Generated from spec:/ga
+
 .. _GroupAIntroduction:
 
 Introduction
 ============
 
+.. The following list was generated from:
+.. spec:/func
+
 Group A brief description.
 
 Group A description. The directives provided by the Group A are:
@@ -185,11 +272,35 @@ Group A description. The directives provided by the Group A are:
 
 .. Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
 
+.. Do not manually edit this file.  It is part of the RTEMS quality process
+.. and was automatically generated.
+..
+.. If you find something that needs to be fixed or worded better please
+.. post a report to an RTEMS mailing list or raise a bug report:
+..
+.. https://docs.rtems.org/branches/master/user/support/bugs.html
+..
+.. For information on updating and regenerating please refer to:
+..
+.. https://docs.rtems.org/branches/master/eng/req/howto.html
+
 .. _GroupADirectives:
 
 Directives
 ==========
 
+This section details the directives of the Group A. A subsection is dedicated
+to each of this manager's directives and lists the calling sequence,
+parameters, description, return values, and notes of the directive.
+
+.. Generated from spec:/func
+
+.. raw:: latex
+
+    \\clearpage
+
+.. index:: Function()
+
 .. _InterfaceFunction:
 
 Function()
@@ -197,28 +308,31 @@ Function()
 
 Function brief description.
 
-CALLING SEQUENCE:
-    .. code-block:: c
+.. rubric:: CALLING SEQUENCE:
+
+.. code-block:: c
+
+    void Function( int Param0, const int *Param1, int *Param2, int *Param3 );
+
+.. rubric:: PARAMETERS:
 
-        void Function( int Param0, const int *Param1, int *Param2, int *Param3 );
+``Param0``
+    This parameter is parameter 0.
 
-DIRECTIVE PARAMETERS:
-    Param0
-        This parameter is parameter 0.
+``Param1``
+    This parameter is parameter 1.
 
-    Param1
-        This parameter is parameter 1.
+``Param2``
+    This parameter is parameter 2.
 
-    Param2
-        This parameter is parameter 2.
+``Param3``
+    This parameter is parameter 3.
 
-    Param3
-        This parameter is parameter 3.
+.. rubric:: DESCRIPTION:
 
-DESCRIPTION:
-    Function description.  References to :ref:`InterfaceVeryLongFunction`,
-    :c:type:`Integer`, :c:type:`Enum`, :c:macro:`DEFINE`,
-    :c:func:`VERY_LONG_MACRO`, Variable, ENUMERATOR_0, :c:type:`Struct`,
-    :ref:`a`, and interface.
+Function description.  References to :ref:`InterfaceVeryLongFunction`,
+:c:type:`Integer`, :c:type:`Enum`, :c:macro:`DEFINE`,
+:c:func:`VERY_LONG_MACRO`, Variable, :c:macro:`ENUMERATOR_0`, :c:type:`Struct`,
+:ref:`a`, and interface.
 """
         assert content == src.read()



More information about the vc mailing list