From b99435279a281f2c541100b693c96e67d6c1bd62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20No=C3=ABl?= Date: Sat, 29 Apr 2023 23:18:31 +0200 Subject: Allow to specify the format of the documentation Helps the consumers of the documentation to assume that the documentation is using gtk-doc format or gi-docgen. --- Makefile.introspection | 3 +++ docs/gir-1.2.rnc | 12 +++++++++++- docs/website/tools/g-ir-scanner.rst | 4 ++++ examples/library/Makefile.am | 1 + examples/library/meson.build | 1 + girepository/girparser.c | 15 ++++++++++++++- giscanner/ast.py | 1 + giscanner/girparser.py | 12 ++++++++++++ giscanner/girwriter.py | 6 ++++++ giscanner/scannermain.py | 8 ++++++++ tests/scanner/meson.build | 2 ++ 11 files changed, 63 insertions(+), 2 deletions(-) diff --git a/Makefile.introspection b/Makefile.introspection index 7fabff60..0f7a68b0 100644 --- a/Makefile.introspection +++ b/Makefile.introspection @@ -63,6 +63,7 @@ _gir_packages = $(foreach pkg,$($(_gir_name)_PACKAGES),--pkg=$(pkg)) _gir_includes = $(foreach include,$($(_gir_name)_INCLUDES),--include=$(include)) _gir_export_packages = $(foreach pkg,$($(_gir_name)_EXPORT_PACKAGES),--pkg-export=$(pkg)) _gir_c_includes = $(foreach include,$($(_gir_name)_C_INCLUDES),--c-include=$(include)) +_gir_doc_format = $(if $($(_gir_name)_DOC_FORMAT),--doc-format=$($(_gir_name)_DOC_FORMAT)) # Reuse the LIBTOOL variable from automake if it's set _gir_libtool = $(if $(LIBTOOL),--libtool="$(LIBTOOL)") @@ -116,6 +117,7 @@ _gir_default_scanner_env = CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$( # By default the names in the PACKAGES variable will be used. # C_INCLUDES - List of public C headers which need to be included by # consumers at compile time to make use of the API +# DOC_FORMAT - Format of the inline documentation of the API # define introspection-scanner @@ -141,6 +143,7 @@ $(1): $$($(_gir_name)_FILES) $(_gir_includes) \ $(_gir_export_packages) \ $(_gir_c_includes) \ + $(_gir_doc_format) \ $(_gir_program) \ $(_gir_libraries) \ $($(_gir_name)_SCANNERFLAGS) \ diff --git a/docs/gir-1.2.rnc b/docs/gir-1.2.rnc index 57e7baf7..1f224a4a 100644 --- a/docs/gir-1.2.rnc +++ b/docs/gir-1.2.rnc @@ -19,7 +19,8 @@ grammar { (Include* & CInclude* & Package* - & Namespace*) + & Namespace* + & DocFormat*) } ## Namespace which maps metadata entries to C functionality. This a similar concept to namespace in C++, but for GObject-based C libraries @@ -71,6 +72,15 @@ grammar { empty } + DocFormat = + ## Format used for the included documentation. + element doc:format { + ## Name of the documentation format. For example, 'gi-docgen' or 'gtk-doc'. + attribute name { xsd:string }, + + empty + } + Include = ## Dependant namespace to include with the current namespace. For example, Gtk will need the namespace GLib element include { diff --git a/docs/website/tools/g-ir-scanner.rst b/docs/website/tools/g-ir-scanner.rst index 15fe401d..12a14fcb 100644 --- a/docs/website/tools/g-ir-scanner.rst +++ b/docs/website/tools/g-ir-scanner.rst @@ -83,6 +83,10 @@ OPTIONS Headers which should be included in C programs. This option can be specified multiple times to include more than one header. +--doc-format=DOC_FORMAT + The format of the inline documentation. This option can either be gtk-doc + or gi-docgen. + -n, --namespace=NAME The namespace name. This name should be capitalized, eg the first letter should be upper case. Examples: Gtk, Clutter, WebKit. diff --git a/examples/library/Makefile.am b/examples/library/Makefile.am index e0c77cd5..b8c026e6 100644 --- a/examples/library/Makefile.am +++ b/examples/library/Makefile.am @@ -29,6 +29,7 @@ GISample_1_0_gir_FILES = $(source_c) $(source_h) GISample_1_0_gir_CFLAGS = -I$(top_srcdir) -I$(top_builddir) $(GISAMPLE_CFLAGS) GISample_1_0_gir_INCLUDES = GObject-2.0 GISample_1_0_gir_SCANNERFLAGS = --warn-all --symbol-prefix=gi_sample +GISample_1_0_gir_DOC_FORMAT = gtk-doc girdir = $(datadir)/gir-1.0 dist_gir_DATA = GISample-1.0.gir diff --git a/examples/library/meson.build b/examples/library/meson.build index 2313ffd6..5ea26e78 100644 --- a/examples/library/meson.build +++ b/examples/library/meson.build @@ -21,4 +21,5 @@ gnome.generate_gir( identifier_prefix : 'GISample', includes : ['GObject-2.0'], install : true, + extra_args : ['--doc-format=gtk-doc'], ) diff --git a/girepository/girparser.c b/girepository/girparser.c index 3edeac34..31ba5839 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -97,7 +97,8 @@ typedef enum STATE_ALIAS, STATE_TYPE, STATE_ATTRIBUTE, - STATE_PASSTHROUGH + STATE_PASSTHROUGH, + STATE_DOC_FORMAT /* 35 */ } ParseState; typedef struct _ParseContext ParseContext; @@ -2918,6 +2919,11 @@ start_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_PASSTHROUGH); goto out; } + else if (strcmp (element_name, "doc:format") == 0) + { + state_switch (ctx, STATE_DOC_FORMAT); + goto out; + } break; case 'e': @@ -3593,6 +3599,13 @@ end_element_handler (GMarkupParseContext *context, if (ctx->unknown_depth == 0) state_switch (ctx, ctx->prev_state); break; + + case STATE_DOC_FORMAT: + if (require_end_element (context, ctx, "doc:format", element_name, error)) + { + state_switch (ctx, STATE_REPOSITORY); + } + break; default: g_error ("Unhandled state %d in end_element_handler\n", ctx->state); } diff --git a/giscanner/ast.py b/giscanner/ast.py index ad94f437..be8e1e01 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -402,6 +402,7 @@ class Namespace(object): self.shared_libraries = [] # str self.c_includes = [] # str self.exported_packages = [] # str + self.doc_format = None def type_from_name(self, name, ctype=None): """Backwards compatibility method for older .gir files, which diff --git a/giscanner/girparser.py b/giscanner/girparser.py index b652f2d6..23536c81 100644 --- a/giscanner/girparser.py +++ b/giscanner/girparser.py @@ -29,6 +29,7 @@ from .message import Position CORE_NS = "http://www.gtk.org/introspection/core/1.0" C_NS = "http://www.gtk.org/introspection/c/1.0" +DOC_NS = "http://www.gtk.org/introspection/doc/1.0" GLIB_NS = "http://www.gtk.org/introspection/glib/1.0" @@ -44,6 +45,10 @@ def _cns(tag): return '{%s}%s' % (C_NS, tag) +def _docns(tag): + return '{%s}%s' % (DOC_NS, tag) + + class GIRParser(object): def __init__(self, types_only=False): @@ -65,6 +70,7 @@ class GIRParser(object): self._pkgconfig_packages = set() self._includes = set() self._c_includes = set() + self._doc_format = None self._c_prefix = None self._parse_api(tree.getroot()) @@ -110,6 +116,8 @@ class GIRParser(object): self._parse_pkgconfig_package(node) elif node.tag == _cns('include'): self._parse_c_include(node) + elif node.tag == _docns('format'): + self._parse_doc_format(node) ns = root.find(_corens('namespace')) assert ns is not None @@ -127,6 +135,7 @@ class GIRParser(object): self._namespace.shared_libraries = ns.attrib['shared-library'].split(',') self._namespace.includes = self._includes self._namespace.c_includes = self._c_includes + self._namespace.doc_format = self._doc_format self._namespace.exported_packages = self._pkgconfig_packages parser_methods = { @@ -166,6 +175,9 @@ class GIRParser(object): def _parse_c_include(self, node): self._c_includes.add(node.attrib['name']) + def _parse_doc_format(self, node): + self._doc_format = node.attrib['name'] + def _parse_alias(self, node): typeval = self._parse_type(node) alias = ast.Alias(node.attrib['name'], typeval, node.attrib.get(_cns('type'))) diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index db4dccb4..21197e5a 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -53,6 +53,8 @@ class GIRWriter(XMLWriter): self._write_pkgconfig_pkg(pkg) for c_include in sorted(set(namespace.c_includes)): self._write_c_include(c_include) + if namespace.doc_format: + self._write_doc_format(namespace.doc_format) self._namespace = namespace self._write_namespace(namespace) self._namespace = None @@ -69,6 +71,10 @@ class GIRWriter(XMLWriter): attrs = [('name', c_include)] self.write_tag('c:include', attrs) + def _write_doc_format(self, doc_format): + attrs = [('name', doc_format)] + self.write_tag('doc:format', attrs) + def _write_namespace(self, namespace): attrs = [('name', namespace.name), ('version', namespace.version), diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py index 1d39ab84..186bfd07 100644 --- a/giscanner/scannermain.py +++ b/giscanner/scannermain.py @@ -220,6 +220,10 @@ match the namespace prefix.""") parser.add_option("", "--compiler", action="store", dest="compiler", default=None, help="the C compiler to use internally") + parser.add_option("", "--doc-format", + action="store", dest="doc_format", + help=("name of the documentation format used in the project, " + "should be on of gtk-doc or gi-docgen")) group = get_preprocessor_option_group(parser) parser.add_option_group(group) @@ -580,6 +584,9 @@ def scanner_main(args): or options.header_only): _error("Must specify --program or --library") + if options.doc_format and options.doc_format != 'gtk-doc' and options.doc_format != 'gi-docgen': + _error("Unknown doc-type: %s" % (options.doc_format, )) + namespace = create_namespace(options) logger = message.MessageLogger.get(namespace=namespace) if options.warn_all: @@ -638,6 +645,7 @@ def scanner_main(args): transformer.namespace.c_includes = options.c_includes transformer.namespace.exported_packages = exported_packages + transformer.namespace.doc_format = options.doc_format sources_top_dirs = get_source_root_dirs(options, filenames) writer = Writer(transformer.namespace, sources_top_dirs) diff --git a/tests/scanner/meson.build b/tests/scanner/meson.build index e77c2de0..f3c6700c 100644 --- a/tests/scanner/meson.build +++ b/tests/scanner/meson.build @@ -134,6 +134,7 @@ if (glib_dep.type_name() == 'pkgconfig' and '--pkg=gobject-2.0', '--library=typedef-1.0', '--c-include=typedefs.h', + '--doc-format=gtk-doc', '-L', meson.current_build_dir(), '-I', meson.current_source_dir(), '-I', join_paths(meson.current_source_dir(), '..'), @@ -171,6 +172,7 @@ if (glib_dep.type_name() == 'pkgconfig' and '--pkg=gobject-2.0', '--library=barapp-1.0', '--accept-unprefixed', + '--doc-format=gi-docgen', '-L', meson.current_build_dir(), '-L', join_paths(build_root, 'girepository'), '-I', meson.current_source_dir(), -- cgit v1.2.1