Skip to content
Commits on Source (52)
......@@ -16,5 +16,6 @@ include docs/*.py
include docs/Makefile
include examples/*.js
include examples/*.toml
include meson_options.txt
recursive-include docs *.rst
recursive-include gidocgen/templates *
Metadata-Version: 2.1
Name: gi-docgen
Version: 2021.5
Version: 2021.6
Summary: Documentation tool for GObject-based libraries
Home-page: https://gitlab.gnome.org/GNOME/gi-docgen
Author: Emmanuele Bassi
......@@ -8,95 +8,6 @@ Author-email: ebassi@gnome.org
License: GPL-3.0-or-later AND Apache-2.0 AND CC0-1.0
Project-URL: Bug tracker, https://gitlab.gnome.org/GNOME/gi-docgen/issues/
Project-URL: Documentation, https://gnome.pages.gitlab.gnome.org/gi-docgen/
Description: <!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
-->
GI-DocGen: Documentation tool for GObject-based libraries
-------------------------------------------------------------------------------
GI-DocGen is a document generator for GObject-based libraries. GObject is
the base type system of the GNOME project. GI-Docgen reuses the
introspection data generated by GObject-based libraries to generate the API
reference of these libraries, as well as other ancillary documentation.
## Installation
### Running GI-DocGen uninstalled
You can run GI-DocGen from its repository, by calling:
```
./gi-docgen.py
```
GI-DocGen will automatically detect this case.
### Installing GI-DocGen via pip
To install GI-DocGen, you will need to have the following pieces of software
available on your computer:
- Python 3.6, or later
- pip
Run the following command:
```
pip3 install --user gi-docgen
```
After running the command above, make sure to have the `~/.local/bin`
directory listed in your `$PATH` environment variable.
To update GI-DocGen, run the following command:
```
pip3 install --user --upgrade gi-docgen
```
## Usage
First, read [the GI-DocGen tutorial](https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html).
The documentation for GI-DocGen is [available online](https://gnome.pages.gitlab.gnome.org/gi-docgen/).
The `examples` directory in the repository contains simple project files for
various GNOME libraries.
## Disclaimer
GI-DocGen is **not** a general purpose documentation tool for C libraries.
While GI-DocGen can be used to generate API references for most GObject/C
libraries that expose introspection data, its main goal is to generate the
reference for GTK and its immediate dependencies. Any and all attempts at
making this tool more generic, or to cover more use cases, will be weighted
heavily against its primary goal.
GI-DocGen is still in development. The recommended use of GI-DocGen is to
add it as a sub-project to your [Meson build system](https://mesonbuild.com),
and vendor it when releasing dist archives.
You should **not** depend on a system-wide installation until GI-DocGen is
declared stable.
If you need a general purpose documentation tool, I strongly recommend:
- [HotDoc](https://hotdoc.github.io/)
- [Doxygen](https://www.doxygen.nl/index.html)
- [GTK-Doc](https://gitlab.gnome.org/GNOME/gtk-doc/)
## Copyright and Licensing terms
Copyright 2021 GNOME Foundation
GI-DocGen is released under the terms of the Apache License, version 2.0, or
under the terms of the GNU General Publice License, either version 3.0 or,
at your option, any later version.
Keywords: documentation,introspection,gobject,gtk
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
......@@ -118,3 +29,96 @@ Classifier: Topic :: Desktop Environment :: Gnome
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.6.0
Description-Content-Type: text/markdown
License-File: LICENSES/Apache-2.0.txt
License-File: LICENSES/GPL-3.0-or-later.txt
<!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
-->
GI-DocGen: Documentation tool for GObject-based libraries
-------------------------------------------------------------------------------
GI-DocGen is a document generator for GObject-based libraries. GObject is
the base type system of the GNOME project. GI-Docgen reuses the
introspection data generated by GObject-based libraries to generate the API
reference of these libraries, as well as other ancillary documentation.
## Installation
### Running GI-DocGen uninstalled
You can run GI-DocGen from its repository, by calling:
```
./gi-docgen.py
```
GI-DocGen will automatically detect this case.
### Installing GI-DocGen via pip
To install GI-DocGen, you will need to have the following pieces of software
available on your computer:
- Python 3.6, or later
- pip
Run the following command:
```
pip3 install --user gi-docgen
```
After running the command above, make sure to have the `~/.local/bin`
directory listed in your `$PATH` environment variable.
To update GI-DocGen, run the following command:
```
pip3 install --user --upgrade gi-docgen
```
## Usage
First, read [the GI-DocGen tutorial](https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html).
The documentation for GI-DocGen is [available online](https://gnome.pages.gitlab.gnome.org/gi-docgen/).
The `examples` directory in the repository contains simple project files for
various GNOME libraries.
## Disclaimer
GI-DocGen is **not** a general purpose documentation tool for C libraries.
While GI-DocGen can be used to generate API references for most GObject/C
libraries that expose introspection data, its main goal is to generate the
reference for GTK and its immediate dependencies. Any and all attempts at
making this tool more generic, or to cover more use cases, will be weighted
heavily against its primary goal.
GI-DocGen is still in development. The recommended use of GI-DocGen is to
add it as a sub-project to your [Meson build system](https://mesonbuild.com),
and vendor it when releasing dist archives.
You should **not** depend on a system-wide installation until GI-DocGen is
declared stable.
If you need a general purpose documentation tool, I strongly recommend:
- [HotDoc](https://hotdoc.github.io/)
- [Doxygen](https://www.doxygen.nl/index.html)
- [GTK-Doc](https://gitlab.gnome.org/GNOME/gtk-doc/)
## Copyright and Licensing terms
Copyright 2021 GNOME Foundation
GI-DocGen is released under the terms of the Apache License, version 2.0, or
under the terms of the GNU General Publice License, either version 3.0 or,
at your option, any later version.
......@@ -37,7 +37,7 @@ will all link to ``Bar``.
Backticks will be stripped, so ``[`class@Foo`]`` will correctly link to ``Foo``.
The link can either be a fully qualified name, which includes the namespace; or
a name relative to the current names; for instance, both of the following links
a name relative to the current namespace; for instance, both of the following links
will point to ``ExampleFoo`` when generating the documentation for the "Example"
namespace:
......@@ -56,6 +56,9 @@ The available qualifier fragments are:
* - ``alias``
- An alias to another type
- ``[alias@Allocation]``
* - ``callback``
- A callback type
- ``[callback@Gtk.ListBoxForeachFunc]``
* - ``class``
- An object class
- ``[class@Widget]``, ``[class@Gdk.Surface]``, ``[class@Gsk.RenderNode]``
......@@ -96,7 +99,23 @@ The available qualifier fragments are:
- A virtual function in a class or interface
- ``[vfunc@Gtk.Widget.measure]``
Additionally, the ``id`` fragment, followed by a C symbol identifier, will try to link to the function; for instance:
The generic ``type`` fragment, followed by a type, will look up the given type
and generate the appropriate link for it. The type can be fully qualified or
relative to the current namespace:
::
// Equivalent to [class@Gtk.Window]
[type@Gtk.Window]
// Equivalent to [enum@Gtk.Orientation]
[type@Gtk.Orientation]
Anything that is a known type—aliases, callbacks, classes, constants,
enumerations, interfaces, structures—can be linked using the ``type`` fragment.
Additionally, the ``id`` fragment, followed by a C symbol identifier, will try
to link to the function; for instance:
::
......
Metadata-Version: 2.1
Name: gi-docgen
Version: 2021.5
Version: 2021.6
Summary: Documentation tool for GObject-based libraries
Home-page: https://gitlab.gnome.org/GNOME/gi-docgen
Author: Emmanuele Bassi
......@@ -8,95 +8,6 @@ Author-email: ebassi@gnome.org
License: GPL-3.0-or-later AND Apache-2.0 AND CC0-1.0
Project-URL: Bug tracker, https://gitlab.gnome.org/GNOME/gi-docgen/issues/
Project-URL: Documentation, https://gnome.pages.gitlab.gnome.org/gi-docgen/
Description: <!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
-->
GI-DocGen: Documentation tool for GObject-based libraries
-------------------------------------------------------------------------------
GI-DocGen is a document generator for GObject-based libraries. GObject is
the base type system of the GNOME project. GI-Docgen reuses the
introspection data generated by GObject-based libraries to generate the API
reference of these libraries, as well as other ancillary documentation.
## Installation
### Running GI-DocGen uninstalled
You can run GI-DocGen from its repository, by calling:
```
./gi-docgen.py
```
GI-DocGen will automatically detect this case.
### Installing GI-DocGen via pip
To install GI-DocGen, you will need to have the following pieces of software
available on your computer:
- Python 3.6, or later
- pip
Run the following command:
```
pip3 install --user gi-docgen
```
After running the command above, make sure to have the `~/.local/bin`
directory listed in your `$PATH` environment variable.
To update GI-DocGen, run the following command:
```
pip3 install --user --upgrade gi-docgen
```
## Usage
First, read [the GI-DocGen tutorial](https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html).
The documentation for GI-DocGen is [available online](https://gnome.pages.gitlab.gnome.org/gi-docgen/).
The `examples` directory in the repository contains simple project files for
various GNOME libraries.
## Disclaimer
GI-DocGen is **not** a general purpose documentation tool for C libraries.
While GI-DocGen can be used to generate API references for most GObject/C
libraries that expose introspection data, its main goal is to generate the
reference for GTK and its immediate dependencies. Any and all attempts at
making this tool more generic, or to cover more use cases, will be weighted
heavily against its primary goal.
GI-DocGen is still in development. The recommended use of GI-DocGen is to
add it as a sub-project to your [Meson build system](https://mesonbuild.com),
and vendor it when releasing dist archives.
You should **not** depend on a system-wide installation until GI-DocGen is
declared stable.
If you need a general purpose documentation tool, I strongly recommend:
- [HotDoc](https://hotdoc.github.io/)
- [Doxygen](https://www.doxygen.nl/index.html)
- [GTK-Doc](https://gitlab.gnome.org/GNOME/gtk-doc/)
## Copyright and Licensing terms
Copyright 2021 GNOME Foundation
GI-DocGen is released under the terms of the Apache License, version 2.0, or
under the terms of the GNU General Publice License, either version 3.0 or,
at your option, any later version.
Keywords: documentation,introspection,gobject,gtk
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
......@@ -118,3 +29,96 @@ Classifier: Topic :: Desktop Environment :: Gnome
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.6.0
Description-Content-Type: text/markdown
License-File: LICENSES/Apache-2.0.txt
License-File: LICENSES/GPL-3.0-or-later.txt
<!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
-->
GI-DocGen: Documentation tool for GObject-based libraries
-------------------------------------------------------------------------------
GI-DocGen is a document generator for GObject-based libraries. GObject is
the base type system of the GNOME project. GI-Docgen reuses the
introspection data generated by GObject-based libraries to generate the API
reference of these libraries, as well as other ancillary documentation.
## Installation
### Running GI-DocGen uninstalled
You can run GI-DocGen from its repository, by calling:
```
./gi-docgen.py
```
GI-DocGen will automatically detect this case.
### Installing GI-DocGen via pip
To install GI-DocGen, you will need to have the following pieces of software
available on your computer:
- Python 3.6, or later
- pip
Run the following command:
```
pip3 install --user gi-docgen
```
After running the command above, make sure to have the `~/.local/bin`
directory listed in your `$PATH` environment variable.
To update GI-DocGen, run the following command:
```
pip3 install --user --upgrade gi-docgen
```
## Usage
First, read [the GI-DocGen tutorial](https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html).
The documentation for GI-DocGen is [available online](https://gnome.pages.gitlab.gnome.org/gi-docgen/).
The `examples` directory in the repository contains simple project files for
various GNOME libraries.
## Disclaimer
GI-DocGen is **not** a general purpose documentation tool for C libraries.
While GI-DocGen can be used to generate API references for most GObject/C
libraries that expose introspection data, its main goal is to generate the
reference for GTK and its immediate dependencies. Any and all attempts at
making this tool more generic, or to cover more use cases, will be weighted
heavily against its primary goal.
GI-DocGen is still in development. The recommended use of GI-DocGen is to
add it as a sub-project to your [Meson build system](https://mesonbuild.com),
and vendor it when releasing dist archives.
You should **not** depend on a system-wide installation until GI-DocGen is
declared stable.
If you need a general purpose documentation tool, I strongly recommend:
- [HotDoc](https://hotdoc.github.io/)
- [Doxygen](https://www.doxygen.nl/index.html)
- [GTK-Doc](https://gitlab.gnome.org/GNOME/gtk-doc/)
## Copyright and Licensing terms
Copyright 2021 GNOME Foundation
GI-DocGen is released under the terms of the Apache License, version 2.0, or
under the terms of the GNU General Publice License, either version 3.0 or,
at your option, any later version.
......@@ -7,6 +7,7 @@ code-of-conduct.md
gi-docgen.pc.in
gi-docgen.py
meson.build
meson_options.txt
pyproject.toml
setup.cfg
setup.py
......
......@@ -6,7 +6,7 @@ import toml
from urllib.parse import urljoin
from . import log
from . import log, utils
class GIDocConfig:
......@@ -138,6 +138,8 @@ class GIDocConfig:
@property
def show_class_hierarchy(self):
if utils.find_program('dot') is None:
return False
return self.theme.get('show_class_hierarchy', False)
def source_link(self, *args):
......
# SPDX-FileCopyrightText: 2020 GNOME Foundation <https://gnome.org>
# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
version = "2021.5"
version = "2021.6"
......@@ -22,40 +22,53 @@ HELP_MSG = "Generates the reference"
MISSING_DESCRIPTION = "No description available."
STRING_TYPES = {
'utf8': 'The string is a NUL terminated UTF-8 string',
'filename': 'The string is a file system path, using the OS encoding',
'utf8': 'The string is a NUL terminated UTF-8 string.',
'filename': 'The string is a file system path, using the OS encoding.',
}
ARG_TRANSFER_MODES = {
'none': 'The data is owned by the caller of the function',
'container': 'The called function takes ownership of the data container, but not the data inside it',
'full': 'The called function takes ownership of the data, and is responsible for freeing it',
'none': 'The data is owned by the caller of the function.',
'container': 'The called function takes ownership of the data container, but not the data inside it.',
'full': 'The called function takes ownership of the data, and is responsible for freeing it.',
}
METHOD_ARG_TRANSFER_MODES = {
'none': 'The data is owned by the caller of the function.',
'container': 'The instance takes ownership of the data container, but not the data inside it.',
'full': 'The instance takes ownership of the data, and is responsible for freeing it.',
}
RETVAL_TRANSFER_MODES = {
'none': 'The data is owned by the called function',
'container': 'The caller of the function takes ownership of the data container, but not the data inside it',
'full': 'The caller of the function takes ownership of the data, and is responsible for freeing it',
'floating': 'The returned data has a floating reference',
'none': 'The data is owned by the called function.',
'container': 'The caller of the function takes ownership of the data container, but not the data inside it.',
'full': 'The caller of the function takes ownership of the data, and is responsible for freeing it.',
'floating': 'The returned data has a floating reference.',
}
METHOD_RETVAL_TRANSFER_MODES = {
'none': 'The data is owned by the instance.',
'container': 'The caller of the function takes ownership of the data container, but not the data inside it.',
'full': 'The caller of the function takes ownership of the data, and is responsible for freeing it.',
'floating': 'The returned data has a floating reference.',
}
DIRECTION_MODES = {
'in': 'in',
'inout': 'in-out',
'out': 'out',
'in': '-',
'inout': 'The argument will be modified by the function.',
'out': 'The argument will be set by the function.',
}
SCOPE_MODES = {
'none': '-',
'call': 'Arguments are valid during the call',
'notified': 'Arguments are valid until the notify function is called',
'async': 'Arguments are valid until the call is completed',
'call': 'Arguments are valid during the call.',
'notified': 'Arguments are valid until the notify function is called.',
'async': 'Arguments are valid until the call is completed.',
}
SIGNAL_WHEN = {
'first': "The default handler is called before the handlers added via `g_signal_connect()`",
'last': "The default handler is called after the handlers added via `g_signal_connect()`",
'cleanup': "The default handler is called after the handlers added via `g_signal_connect_after()`",
'first': "The default handler is called before the handlers added via `g_signal_connect()`.",
'last': "The default handler is called after the handlers added via `g_signal_connect()`.",
'cleanup': "The default handler is called after the handlers added via `g_signal_connect_after()`.",
}
FRAGMENT = {
......@@ -348,8 +361,13 @@ class TemplateArgument:
self.is_varargs = isinstance(argument.target, gir.VarArgs)
self.is_macro = isinstance(call, gir.FunctionMacro)
self.transfer = argument.transfer or 'none'
self.transfer_note = ARG_TRANSFER_MODES[argument.transfer or 'none']
self.direction = DIRECTION_MODES[argument.direction]
if isinstance(call, gir.Method):
self.transfer_note = METHOD_ARG_TRANSFER_MODES[argument.transfer or 'none']
else:
self.transfer_note = ARG_TRANSFER_MODES[argument.transfer or 'none']
self.direction = argument.direction or 'in'
self.direction_note = DIRECTION_MODES[argument.direction]
self.optional = argument.optional
self.nullable = argument.nullable
self.scope = SCOPE_MODES[argument.scope or 'none']
self.introspectable = argument.introspectable
......@@ -414,7 +432,10 @@ class TemplateReturnValue:
self.is_array = isinstance(retval.target, gir.ArrayType)
self.is_list = isinstance(retval.target, gir.ListType)
self.transfer = retval.transfer or 'none'
self.transfer_note = RETVAL_TRANSFER_MODES[retval.transfer or 'none']
if isinstance(call, gir.Method):
self.transfer_note = METHOD_RETVAL_TRANSFER_MODES[retval.transfer or 'none']
else:
self.transfer_note = RETVAL_TRANSFER_MODES[retval.transfer or 'none']
self.nullable = retval.nullable
if self.is_array:
self.value_type = retval.target.value_type.name
......@@ -1592,7 +1613,7 @@ def _gen_classes(config, theme_config, output_dir, jinja_env, repository, all_cl
tmpl = TemplateClass(namespace, cls)
template_classes.append(tmpl)
if config.show_class_hierarchy and utils.find_program('dot') is not None:
if config.show_class_hierarchy:
tmpl.hierarchy_svg = utils.render_dot(tmpl.dot, output_format="svg")
with open(class_file, "w") as out:
......@@ -2294,44 +2315,22 @@ def gen_content_images(config, content_dir, output_dir):
def gen_types_hierarchy(config, theme_config, output_dir, jinja_env, repository):
namespace = repository.namespace
# Gather all class types and their parent to build a flat list
flat_tree = []
for cls in namespace.get_classes():
name = cls.name
if cls.parent is not None:
parent = cls.parent.name
else:
parent = None
flat_tree.append((name, parent))
# A subtly elegant way to rebuild the tree from a flat
# list of (name, parent) tuples. See:
#
# https://stackoverflow.com/a/43728268/771066
def subtree(cls, rel):
return {
v: subtree(v, rel)
for v in [x[0] for x in rel if x[1] == cls]
}
# All GObject sub-types
objects_tree = subtree('Object', flat_tree)
# All GInitiallyUnowned sub-types
unowned_tree = subtree('InitiallyUnowned', flat_tree)
objects_tree = repository.get_class_hierarchy(root="GObject.Object")
# All GTypeInstance sub-types
typed_tree = subtree(None, flat_tree)
typed_tree = repository.get_class_hierarchy()
res = ["<h1>Classes Hierarchy</h1>"]
def dump_tree(node, out):
for k in node:
out.append(f"<li class=\"type\"><a href=\"class.{k}.html\"><code>{k}</code></a>")
if '.' in k:
out.append(f'<li class="type"><code>{k}</code>')
else:
out.append(f'<li class="type"><a href="class.{k}.html"><code>{k}</code></a>')
if len(node[k]) != 0:
out.append("<ul class=\"type\">")
out.append('<ul class="type">')
dump_tree(node[k], out)
out.append("</ul>")
out.append("</li>")
......@@ -2345,19 +2344,12 @@ def gen_types_hierarchy(config, theme_config, output_dir, jinja_env, repository)
res += ["</ul>"]
res += ["</div>"]
if len(unowned_tree) != 0:
res += ["<div class=\"docblock\">"]
res += ["<ul class=\"type root\">"]
res += [" <li class=\"type\"><code>GInitiallyUnowned</code></li><ul class=\"type\">"]
dump_tree(unowned_tree, res)
res += [" </ul></li>"]
res += ["</ul>"]
res += ["</div>"]
if len(typed_tree) != 0:
res += ["<div class=\"docblock\">"]
res += ["<ul class=\"type root\">"]
res += [" <li class=\"type\"><code>GTypeInstance</code></li><ul class=\"type\">"]
dump_tree(typed_tree, res)
res += [" </ul></li>"]
res += ["</ul>"]
res += ["</div>"]
......@@ -2372,6 +2364,8 @@ def gen_types_hierarchy(config, theme_config, output_dir, jinja_env, repository)
content_tmpl = jinja_env.get_template(theme_config.content_template)
namespace = repository.namespace
dst_file = os.path.join(output_dir, content["output_file"])
log.info(f"Generating type hierarchy file: {dst_file}")
with open(dst_file, "w") as outfile:
......
......@@ -480,7 +480,7 @@ def gen_tree(repository):
title = str(log.color('Unions', 36))
log.log(f' ├── {title}')
if len(records) == 0:
if len(unions) == 0:
log.log(' │ └── None')
else:
for i, union in enumerate(unions):
......
......@@ -390,6 +390,12 @@ class Callback(Callable):
super().__init__(name=name, namespace=namespace, identifier=None, throws=throws)
self.ctype = ctype
@property
def base_ctype(self):
if self.ctype is None:
return None
return self.ctype.replace('*', '')
class Member(GIRElement):
"""A member in an enumeration, error domain, or bitfield"""
......@@ -689,7 +695,7 @@ class Namespace:
self._aliases: T.Mapping[str, Alias] = {}
self._bitfields: T.Mapping[str, BitField] = {}
self._boxeds: T.Mapping[str, Boxed] = {}
self._callbacks: T.List[Callback] = []
self._callbacks: T.Mapping[str, Callback] = {}
self._classes: T.Mapping[str, Class] = {}
self._constants: T.Mapping[str, Constant] = {}
self._enumerations: T.Mapping[str, Enumeration] = {}
......@@ -758,7 +764,7 @@ class Namespace:
self._function_macros[function.name] = function
def add_callback(self, callback: Callback) -> None:
self._callbacks.append(callback)
self._callbacks[callback.name] = callback
def get_classes(self) -> T.List[Class]:
return self._classes.values()
......@@ -835,7 +841,7 @@ class Namespace:
return [x for x in self._function_macros.values() if is_effective(x, self)]
def get_callbacks(self) -> T.List[Callback]:
return self._callbacks
return self._callbacks.values()
def find_class(self, cls: str) -> T.Optional[Class]:
return self._classes.get(cls)
......@@ -873,6 +879,10 @@ class Namespace:
return self._aliases[name]
if name in self._bitfields:
return self._bitfields[name]
if name in self._callbacks:
return self._callbacks[name]
if name in self._constants:
return self._constants[name]
if name in self._enumerations:
return self._enumerations[name]
if name in self._error_domains:
......@@ -1019,13 +1029,14 @@ class Repository:
def resolve_class_ancestors(self) -> None:
def find_parent_class(includes, ns, name):
for repo in includes.values():
if repo.namespace.name != ns:
continue
parent = repo.namespace.find_class(name)
if parent is not None:
return parent
return None
repository = includes.get(ns)
if repository is None:
return None
parent_class = repository.namespace.find_class(name)
# If the parent type is unqualified, then we qualify it here
if '.' not in parent_class.name:
parent_class.name = f"{repository.namespace.name}.{parent_class.name}"
return parent_class
classes = self.namespace.get_classes()
for cls in classes:
......@@ -1037,17 +1048,23 @@ class Repository:
if '.' in parent.name:
ns, name = parent.name.split('.')
if ns == self.namespace.name:
parent = self.namespace.find_class(name)
real_parent = self.namespace.find_class(name)
else:
parent = find_parent_class(self.includes, ns, name)
real_parent = find_parent_class(self.includes, ns, name)
else:
parent = self.namespace.find_class(parent.name)
if parent is not None:
if parent.ctype is None:
t = self.find_type(parent.name)
parent.ctype = t.ctype
ancestors.append(parent)
parent = parent.parent
real_parent = self.namespace.find_class(parent.name)
if real_parent is None:
break
if real_parent.parent is not None and real_parent.parent.name == parent.name:
log.warning(f"Found a loop in the ancestors for {cls}: {real_parent} matches {parent}")
break
if real_parent.ctype is None:
log.debug(f"Looking up C type for {parent.fqtn}")
t = self.find_type(parent.name)
real_parent.ctype = t.ctype
log.debug(f"Adding ancestor {real_parent} for {cls}")
ancestors.append(real_parent)
parent = real_parent.parent
cls.ancestors = ancestors
cls.parent = ancestors[0]
log.debug(f"Ancestors for {cls}: parent: {cls.parent}, ancestors: {cls.ancestors}")
......@@ -1101,6 +1118,46 @@ class Repository:
symbols[m.identifier] = union
self.namespace._symbols = symbols
def get_class_hierarchy(self, root=None):
flat_tree = []
seen_types = {}
def window(iterable, size=2):
i = iter(iterable)
win = []
for e in range(0, size):
win.append(next(i))
yield win
for e in i:
win = win[1:] + [e]
yield win
for cls in self.namespace.get_classes():
if cls.parent is None:
flat_tree.append((cls.name, None))
continue
if len(cls.ancestors) < 2:
flat_tree.append((cls.name, cls.ancestors[0].name))
else:
flat_tree.append((cls.name, cls.ancestors[0].name))
for chunk in window(cls.ancestors, size=2):
if chunk[0].name in seen_types:
continue
if len(chunk) == 2:
flat_tree.append((chunk[0].name, chunk[1].name))
else:
flat_tree.append((chunk[0].name, None))
seen_types[chunk[0].name] = 1
def subtree(cls, rel):
return {
v: subtree(v, rel)
for v in [x[0] for x in rel if x[1] == cls]
}
return subtree(root, flat_tree)
@property
def namespace(self) -> T.Optional[Namespace]:
return self._namespaces[0]
......
......@@ -652,13 +652,11 @@ class GirParser:
res: ast.ErrorDomain = ast.ErrorDomain(name=name, namespace=ns.name,
ctype=ctype, gtype=gtype,
domain=error_domain)
if ns is not None:
ns.add_error_domain(res)
ns.add_error_domain(res)
else:
res: ast.Enumeration = ast.Enumeration(name=name, namespace=ns.name,
ctype=ctype, gtype=gtype)
if ns is not None:
ns.add_enumeration(res)
ns.add_enumeration(res)
res.set_members(members)
res.set_functions(functions)
......
......@@ -17,8 +17,6 @@ ARG_SIGIL_RE = re.compile(r"(^|\W)@([A-Za-z0-9_]+)\b")
CONST_SIGIL_RE = re.compile(r"(^|\W)%([A-Z0-9_]+)\b")
FUNC_POSTFIX_RE = re.compile(r"([A-Za-z0-9_]+)\(\)")
class GtkDocPreprocessor(Preprocessor):
"""Remove all gtk-doc sigils from the Markdown text"""
......@@ -44,9 +42,6 @@ class GtkDocPreprocessor(Preprocessor):
# Argument sygil
new_line = re.sub(ARG_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
# Function postfix
new_line = re.sub(FUNC_POSTFIX_RE, r"`\g<1>()`", new_line)
new_lines.append(new_line)
return new_lines
......
......@@ -62,7 +62,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
{% if CONFIG.search_index %}
<div class="search section">
<form id="search-form" autocomplete="off">
<input id="search-input" type="text" name="do-not-autocomplete" placeholder="Search docs" autocomplete="off"/>
<input id="search-input" type="text" name="do-not-autocomplete" placeholder="Click, or press 's' to search" autocomplete="off"/>
</form>
</div>
{% endif %}
......
......@@ -35,36 +35,41 @@ style = "style.css"
[extra_files]
files = [
"main.js",
"fonts.css",
"fzy.js",
"search.js",
"go-up-symbolic.png",
"main.js",
"pygment.css",
"fonts.css",
"RedHatDisplay-Regular.woff2",
"RedHatDisplay-Regular.woff",
"RedHatDisplay-Medium.woff2",
"RedHatDisplay-Medium.woff",
"RedHatDisplay-MediumItalic.woff2",
"RedHatDisplay-MediumItalic.woff",
"RedHatDisplay-Bold.woff2",
"RedHatDisplay-Bold.woff",
"RedHatDisplay-BoldItalic.woff2",
"RedHatDisplay-BoldItalic.woff",
"RedHatDisplay-Black.woff2",
"search.js",
"RedHatDisplay-Black.woff",
"RedHatDisplay-BlackItalic.woff2",
"RedHatDisplay-Black.woff2",
"RedHatDisplay-BlackItalic.woff",
"RedHatText-BoldItalic.woff",
"RedHatText-BoldItalic.woff2",
"RedHatDisplay-BlackItalic.woff2",
"RedHatDisplay-Bold.woff",
"RedHatDisplay-Bold.woff2",
"RedHatDisplay-BoldItalic.woff",
"RedHatDisplay-BoldItalic.woff2",
"RedHatDisplay-Italic.woff",
"RedHatDisplay-Italic.woff2",
"RedHatDisplay-Medium.woff",
"RedHatDisplay-Medium.woff2",
"RedHatDisplay-MediumItalic.woff",
"RedHatDisplay-MediumItalic.woff2",
"RedHatDisplay-Regular.woff",
"RedHatDisplay-Regular.woff2",
"RedHatText-Bold.woff",
"RedHatText-Bold.woff2",
"RedHatText-BoldItalic.woff",
"RedHatText-BoldItalic.woff2",
"RedHatText-Italic.woff",
"RedHatText-Italic.woff2",
"RedHatText-MediumItalic.woff",
"RedHatText-MediumItalic.woff2",
"RedHatText-Medium.woff",
"RedHatText-Medium.woff2",
"RedHatText-MediumItalic.woff",
"RedHatText-MediumItalic.woff2",
"RedHatText-Regular.woff",
"RedHatText-Regular.woff2",
"go-up-symbolic.png"
"SourceCodePro-It.ttf.woff",
"SourceCodePro-Regular.ttf.woff",
"SourceCodePro-Semibold.ttf.woff",
]
......@@ -49,7 +49,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Class</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.{{ class.name }}</h1>
<h1 aria-label="Name"><a href="index.html">{{ namespace.name }}</a><span class="sep" role="presentation"></span>{{ class.name }}</h1>
</header>
<section>
......
......@@ -34,7 +34,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Class method</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.<a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.class_name }}</a>.{{ class_method.name }}</h1>
<h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.class_name }}</a><span class="sep"></span>{{ class_method.name }}</h1>
</header>
<section>
......@@ -99,14 +99,14 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="arguments">
{% for arg in class_method.arguments %}
<tr class="arg-name">
<td><code>{{ arg.name }}</code></td>
<td>
{%- if arg.link -%}
{%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
{%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
{%- if arg.link -%}
{{ arg.link|safe }}
{%- else -%}
<code>{{ arg.type_cname }}</code>
......@@ -115,17 +115,28 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>{{ arg.description }}</td>
<td>{{ arg.description|safe }}</td>
</tr>
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td>Direction: {{ arg.direction }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.direction == "out" and arg.optional %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ arg.len_arg }}</code> argument</td></tr>{% endif %}
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
{% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
{% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
{% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
{% endfor %}
{% if class_method.throws %}
<tr class="arg-name">
<td><code>error</code></td>
<td><code>GError **</code></td>
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
</tr>
{% endif %}
</table>
</div>
</div>
......@@ -139,12 +150,13 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="returns">
<tr class="arg-name">
<td colspan="2">Returns:&nbsp;
{%- if class_method.return_value.link -%}
<td>Returns:</td>
<td>
{%- if class_method.return_value.is_array -%}An array of&nbsp;{%- endif -%}
{%- if class_method.return_value.is_list -%}A list of&nbsp;{%- endif -%}
{%- if class_method.return_value.link -%}
{{ class_method.return_value.link|safe }}
{%- else -%}
<code>{{ class_method.return_value.type_cname }}</code>
......@@ -152,14 +164,15 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</td>
</tr>
<tr class="arg-description">
<td colspan="2">{{ class_method.return_value.description }}</td>
<td>&nbsp;</td>
<td>{{ class_method.return_value.description|safe }}</td>
</tr>
{% if class_method.return_value.is_array and class_method.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if class_method.return_value.is_array and class_method.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ class_method.return_value.fixed_size }} elements</td></tr>{% endif %}
{% if class_method.return_value.is_array and class_method.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ class_method.return_value.len_arg }}</code> argument</td></tr>{% endif %}
{% if class_method.return_value.is_pointer %}<tr><td title="transfer: {{ class_method.return_value.transfer }}">{{ class_method.return_value.transfer }}</td></tr>{% endif %}
{% if class_method.return_value.is_pointer and class_method.return_value.nullable %}<tr><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if class_method.return_value.string_note %}<tr><td>{{ class_method.return_value.string_note }}</td></tr>{% endif %}
{% if class_method.return_value.is_array and class_method.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if class_method.return_value.is_array and class_method.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ class_method.return_value.fixed_size }} elements.</td></tr>{% endif %}
{% if class_method.return_value.is_array and class_method.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ class_method.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
{% if class_method.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ class_method.return_value.transfer }}">{{ class_method.return_value.transfer_note }}</td></tr>{% endif %}
{% if class_method.return_value.is_pointer and class_method.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
{% if class_method.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ class_method.return_value.string_note }}</td></tr>{% endif %}
</table>
</div>
</div>
......
......@@ -28,7 +28,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Constant</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.{{ constant.name }}</h1>
<h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ constant.name }}</h1>
</header>
<section>
......
......@@ -36,7 +36,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Constructor</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.<a href="{{ class.link_prefix }}.{{class.name}}.html">{{ class.name }}</a>.{{ type_func.name }}</h1>
<h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{class.name}}.html">{{ class.name }}</a><span class="sep"></span>{{ type_func.name }}</h1>
</header>
<section>
......@@ -101,14 +101,14 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="arguments">
{% for arg in type_func.arguments %}
<tr class="arg-name">
<td><code>{{ arg.name }}</code></td>
<td>
{%- if arg.link -%}
{%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
{%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
{%- if arg.link -%}
{{ arg.link|safe }}
{%- else -%}
<code>{{ arg.type_cname }}</code>
......@@ -117,17 +117,28 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>{{ arg.description }}</td>
<td>{{ arg.description|safe }}</td>
</tr>
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td>Direction: {{ arg.direction }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.direction == "out" and arg.optional %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ arg.len_arg }}</code> argument</td></tr>{% endif %}
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
{% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
{% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
{% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
{% endfor %}
{% if type_func.throws %}
<tr class="arg-name">
<td><code>error</code></td>
<td><code>GError **</code></td>
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
</tr>
{% endif %}
</table>
</div>
</div>
......@@ -141,12 +152,13 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="returns">
<tr class="arg-name">
<td colspan="2">Returns:&nbsp;
{%- if type_func.return_value.link -%}
<td>Returns:</td>
<td>
{%- if type_func.return_value.is_array -%}An array of&nbsp;{%- endif -%}
{%- if type_func.return_value.is_list -%}A list of&nbsp;{%- endif -%}
{%- if type_func.return_value.link -%}
{{ type_func.return_value.link|safe }}
{%- else -%}
<code>{{ type_func.return_value.type_cname }}</code>
......@@ -154,14 +166,15 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</td>
</tr>
<tr class="arg-description">
<td colspan="2">{{ type_func.return_value.description }}</td>
<td>&nbsp;</td>
<td>{{ type_func.return_value.description|safe }}</td>
</tr>
{% if type_func.return_value.is_array and type_func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if type_func.return_value.is_array and type_func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ type_func.return_value.fixed_size }} elements</td></tr>{% endif %}
{% if type_func.return_value.is_array and type_func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ type_func.return_value.len_arg }}</code> argument</td></tr>{% endif %}
{% if type_func.return_value.is_pointer %}<tr><td title="transfer: {{ type_func.return_value.transfer }}">{{ type_func.return_value.transfer_note }}</td></tr>{% endif %}
{% if type_func.return_value.is_pointer and type_func.return_value.nullable %}<tr><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if type_func.return_value.string_note %}<tr><td>{{ type_func.return_value.string_note }}</td></tr>{% endif %}
{% if type_func.return_value.is_array and type_func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if type_func.return_value.is_array and type_func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ type_func.return_value.fixed_size }} elements.</td></tr>{% endif %}
{% if type_func.return_value.is_array and type_func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ type_func.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
{% if type_func.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ type_func.return_value.transfer }}">{{ type_func.return_value.transfer_note }}</td></tr>{% endif %}
{% if type_func.return_value.is_pointer and type_func.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
{% if type_func.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ type_func.return_value.string_note }}</td></tr>{% endif %}
</table>
</div>
</div>
......
......@@ -43,7 +43,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Enumeration</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.{{ enum.name }}</h1>
<h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ enum.name }}</h1>
</header>
<section>
......
......@@ -41,7 +41,7 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
<section id="main" class="content">
<header>
<h3>Function {% if func.is_macro %}Macro{% endif %}</h3>
<h1><a href="index.html">{{ namespace.name }}</a>.{{ func.name }}</h1>
<h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ func.name }}</h1>
</header>
<section>
......@@ -106,35 +106,44 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="arguments">
{% for arg in func.arguments %}
<tr class="arg-name">
<td><code>{{ arg.name }}</code></td>
{% if not arg.is_macro %}
<td>
{%- if arg.link -%}
{%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
{%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
{%- if arg.link -%}
{{ arg.link|safe }}
{%- else -%}
<code>{{ arg.type_cname }}</code>
{%- endif -%}
</td>
{% endif %}
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>{{ arg.description }}</td>
<td>{{ arg.description|safe }}</td>
</tr>
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td>Direction: {{ arg.direction }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.direction == "out" and arg.optional %}<tr><td>&nbsp;</td><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ arg.len_arg }}</code> argument</td></tr>{% endif %}
{% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
{% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
{% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
{% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
{% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
{% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
{% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
{% endfor %}
{% if func.throws %}
<tr class="arg-name">
<td><code>error</code></td>
<td><code>GError **</code></td>
</tr>
<tr class="arg-description">
<td>&nbsp;</td>
<td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
</tr>
{% endif %}
</table>
</div>
</div>
......@@ -148,12 +157,13 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</h4>
<div class="docblock">
<table>
<table class="returns">
<tr class="arg-name">
<td colspan="2">Returns:&nbsp;
{%- if func.return_value.link -%}
<td>Returns:</td>
<td>
{%- if func.return_value.is_array -%}An array of&nbsp;{%- endif -%}
{%- if func.return_value.is_list -%}A list of&nbsp;{%- endif -%}
{%- if func.return_value.link -%}
{{ func.return_value.link|safe }}
{%- else -%}
<code>{{ func.return_value.type_cname }}</code>
......@@ -161,14 +171,15 @@ SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
</td>
</tr>
<tr class="arg-description">
<td colspan="2">{{ func.return_value.description }}</td>
<td>&nbsp;</td>
<td>{{ func.return_value.description|safe }}</td>
</tr>
{% if func.return_value.is_array and func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code> terminated</td></tr>{% endif %}
{% if func.return_value.is_array and func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ func.return_value.fixed_size }} elements</td></tr>{% endif %}
{% if func.return_value.is_array and func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ func.return_value.len_arg }}</code> argument</td></tr>{% endif %}
{% if func.return_value.is_pointer %}<tr><td title="transfer: {{ func.return_value.transfer }}">{{ func.return_value.transfer_note }}</td></tr>{% endif %}
{% if func.return_value.is_pointer and func.return_value.nullable %}<tr><td>Can be <code>NULL</code></td></tr>{% endif %}
{% if func.return_value.string_note %}<tr><td>{{ func.return_value.string_note }}</td></tr>{% endif %}
{% if func.return_value.is_array and func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
{% if func.return_value.is_array and func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ func.return_value.fixed_size }} elements.</td></tr>{% endif %}
{% if func.return_value.is_array and func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ func.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
{% if func.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ func.return_value.transfer }}">{{ func.return_value.transfer_note }}</td></tr>{% endif %}
{% if func.return_value.is_pointer and func.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
{% if func.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ func.return_value.string_note }}</td></tr>{% endif %}
</table>
</div>
</div>
......