[gtk-doc] Add support for inline program documentation
- From: Stefan Kost <stefkost src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk-doc] Add support for inline program documentation
- Date: Wed, 23 Mar 2016 21:04:20 +0000 (UTC)
commit a9864c47fdd8abfd52978f100d654d6880908d66
Author: Thomas Wood <thomas wood intel com>
Date: Wed Jul 8 14:27:46 2015 +0100
Add support for inline program documentation
Create program documentation from documentation comments in source
files.
https://bugzilla.gnome.org/show_bug.cgi?id=752126
configure.ac | 3 +
gtkdoc-mkdb.in | 214 +++++++++++++++++++++++++++++++-
tests/Makefile.am | 5 +-
tests/program.sh | 4 +
tests/program/Makefile.am | 11 ++
tests/program/docs/Makefile.am | 81 ++++++++++++
tests/program/docs/tester-docs.xml | 37 ++++++
tests/program/src/Makefile.am | 10 ++
tests/program/src/test-program.c | 19 +++
9 files changed, 381 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1046d27..7dfae29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -261,6 +261,9 @@ tests/fail/docs/Makefile
tests/empty/Makefile
tests/empty/src/Makefile
tests/empty/docs/Makefile
+tests/program/Makefile
+tests/program/src/Makefile
+tests/program/docs/Makefile
])
dnl run chmod on these after parsing them.
diff --git a/gtkdoc-mkdb.in b/gtkdoc-mkdb.in
index 8dd6d5e..40db385 100755
--- a/gtkdoc-mkdb.in
+++ b/gtkdoc-mkdb.in
@@ -2585,6 +2585,160 @@ EOF
return &UpdateFileIfChanged ($old_db_file, $new_db_file, 0);
}
+#############################################################################
+# Function : OutputProgramDBFile
+# Description : Outputs the final DocBook file for one program.
+# Arguments : $file - the name of the file.
+# $section_id - the id to use for the toplevel tag.
+#############################################################################
+
+sub OutputProgramDBFile {
+ my ($program, $section_id) = @_;
+
+ @TRACE@("Output program docbook for $program\n");
+
+ my $short_desc = $SourceSymbolDocs{"$TMPL_DIR/$program:Short_Description"};
+ if (!defined ($short_desc) || $short_desc =~ m/^\s*$/) {
+ $short_desc = "";
+ } else {
+ # Don't use ConvertMarkDown here for now since we don't want blocks
+ $short_desc = &ExpandAbbreviations("$program", $short_desc);
+ @TRACE@("Found short_desc: $short_desc");
+ }
+
+ my $synopsis = $SourceSymbolDocs{"$TMPL_DIR/$program:Synopsis"};
+ if (defined ($synopsis) && $synopsis !~ m/^\s*$/) {
+ my $i;
+ my @items = split(' ', $synopsis);
+ for ($i = 0; $i <= $#items; $i++) {
+ my $parameter = $items[$i];
+ my $choice = "plain";
+ my $rep = "";
+
+ # first parameter is the command name
+ if ($i == 0) {
+ $synopsis = "<command>$parameter</command>\n";
+ next;
+ }
+
+ # square brackets indicate optional parameters, curly brackets
+ # indicate required parameters ("plain" parameters are also
+ # mandatory, but do not get extra decoration)
+ if ($parameter =~ s/^\[(.+?)\]$/$1/) {
+ $choice = "opt";
+ } elsif ($parameter =~ s/^\{(.+?)\}$/$1/) {
+ $choice = "req";
+ }
+
+ # parameters ending in "..." are repeatable
+ if ($parameter =~ s/\.\.\.$//) {
+ $rep = " rep=\"repeat\"";
+ }
+
+ # italic parameters are replaceable parameters
+ if ($parameter =~ s/\*(.+?)\*/$1/) {
+ $parameter = "<replaceable>$parameter</replaceable>";
+ }
+
+ $synopsis .= "<arg choice=\"$choice\"$rep>";
+ $synopsis .= $parameter;
+ $synopsis .= "</arg>\n";
+ }
+
+ @TRACE@("Found synopsis: $synopsis");
+ } else {
+ $synopsis = "<command>$program</command>";
+ }
+
+ my $long_desc = $SourceSymbolDocs{"$TMPL_DIR/$program:Long_Description"};
+ if (!defined ($long_desc) || $long_desc =~ m/^\s*$/) {
+ $long_desc = "";
+ } else {
+ $long_desc = &ConvertMarkDown("$program:Long_description", $long_desc);
+ @TRACE@("Found long_desc: $long_desc");
+ }
+
+ my $options = "";
+ if (defined ($SourceSymbolDocs{"$TMPL_DIR/$program:Options"})) {
+ my @opts = @{ $SourceSymbolDocs{"$TMPL_DIR/$program:Options"} };
+ my $k;
+
+ $options = "<refsect1>\n<title>Options</title>\n<variablelist>\n";
+ for ($k = 0; $k <= $#opts; $k += 2) {
+ my $opt_desc = $opts[$k+1];
+ my @opt_names;
+ my $i;
+
+ $opt_desc =~ s/\*(.+?)\*/<replaceable>$1<\/replaceable>/g;
+
+ $options .= "<varlistentry>\n<term>";
+ @opt_names = split (',', $opts[$k]);
+ for ($i = 0; $i <= $#opt_names; $i++) {
+ my $prefix = ($i > 0) ? ", " : "";
+ $opt_names[$i] =~ s/\*(.+?)\*/<replaceable>$1<\/replaceable>/g;
+
+ $options .= "$prefix<option>$opt_names[$i]</option>\n";
+ }
+ $options .= "</term>\n";
+ $options .= "<listitem><para>$opt_desc</para></listitem>\n";
+ $options .= "</varlistentry>\n";
+ }
+ $options .= "</variablelist></refsect1>\n";
+ }
+
+ my $exit_status = $SourceSymbolDocs{"$TMPL_DIR/$program:Returns"};
+ if (defined ($exit_status) && $exit_status ne "") {
+ $exit_status = &ConvertMarkDown("$program:Returns", $exit_status);
+ $exit_status = "<refsect1 id=\"$section_id.exit-status\">\n<title>Exit
Status</title>\n$exit_status\n</refsect1>\n";
+ } else {
+ $exit_status = "";
+ }
+
+ my $see_also = $SourceSymbolDocs{"$TMPL_DIR/$program:See_Also"};
+ if (!defined ($see_also) || $see_also =~ m%^\s*(<para>)?\s*(</para>)?\s*$%) {
+ $see_also = "";
+ } else {
+ $see_also = &ConvertMarkDown("$program:See_Also", $see_also);
+ @TRACE@("Found see_also: $see_also");
+ }
+ if ($see_also) {
+ $see_also = "<refsect1 id=\"$section_id.see-also\">\n<title>See
Also</title>\n$see_also\n</refsect1>\n";
+ }
+
+ my $old_db_file = "$DB_OUTPUT_DIR/$program.xml";
+ my $new_db_file = "$DB_OUTPUT_DIR/$program.xml.new";
+
+ open (OUTPUT, ">$new_db_file")
+ || die "Can't create $new_db_file: $!";
+
+ print OUTPUT <<EOF;
+${\( MakeDocHeader ("refentry") )}
+<refentry id="$section_id">
+<refmeta>
+<refentrytitle role="top_of_page" id="$section_id.top_of_page">$program</refentrytitle>
+<manvolnum>1</manvolnum>
+<refmiscinfo>User Commands</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>$program</refname>
+<refpurpose>$short_desc</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<cmdsynopsis>$synopsis</cmdsynopsis>
+</refsynopsisdiv>
+<refsect1 id="$section_id.description" role="desc">
+<title role="desc.title">Description</title>
+$long_desc
+</refsect1>
+$options$exit_status$see_also
+</refentry>
+EOF
+ close (OUTPUT);
+
+ return &UpdateFileIfChanged ($old_db_file, $new_db_file, 0);
+}
+
+
#############################################################################
# Function : OutputExtraFile
@@ -4056,6 +4210,61 @@ sub ScanSourceFile {
$SourceSymbolSourceFile{"$TMPL_DIR/$real_symbol:Long_Description"} = $file;
$SourceSymbolSourceLine{"$TMPL_DIR/$real_symbol:Long_Description"} = $.;
#$SourceSymbolTypes{$symbol} = "SECTION";
+ } elsif ($symbol =~ m/PROGRAM:\s*(.*)/) {
+ my $real_symbol = $1;
+ my $key;
+ my $section_id;
+
+ @TRACE@("PROGRAM DOCS found in source for '$real_symbol'\n");
+ for ($k = 0; $k <= $#params; $k += $PARAM_FIELD_COUNT) {
+ @TRACE@(" '".$params[$k]."'\n");
+ $params[$k] = "\L$params[$k]";
+ undef $key;
+
+ if ($params[$k] eq "short_description") {
+ $key = "$TMPL_DIR/$real_symbol:Short_Description";
+ } elsif ($params[$k] eq "see_also") {
+ $key = "$TMPL_DIR/$real_symbol:See_Also";
+ } elsif ($params[$k] eq "section_id") {
+ $key = "$TMPL_DIR/$real_symbol:Section_Id";
+ } elsif ($params[$k] eq "synopsis") {
+ $key = "$TMPL_DIR/$real_symbol:Synopsis";
+ } elsif ($params[$k] eq "returns") {
+ $key = "$TMPL_DIR/$real_symbol:Returns";
+ } elsif ($params[$k] =~ m/^(-.*)/) {
+ $key = "$TMPL_DIR/$real_symbol:Options";
+ my $opts;
+ if (defined($SourceSymbolDocs{$key})) {
+ $opts = $SourceSymbolDocs{$key};
+ } else {
+ $opts = [];
+ }
+ push (@{ $opts }, $1);
+ push (@{ $opts }, $params[$k+1]);
+
+ $SourceSymbolDocs{$key} = $opts;
+ next;
+ }
+ if (defined($key)) {
+ $SourceSymbolDocs{$key}=$params[$k+1];
+ $SourceSymbolSourceFile{$key} = $file;
+ $SourceSymbolSourceLine{$key} = $.;
+ }
+ }
+ $SourceSymbolDocs{"$TMPL_DIR/$real_symbol:Long_Description"}=$description;
+ $SourceSymbolSourceFile{"$TMPL_DIR/$real_symbol:Long_Description"} = $file;
+ $SourceSymbolSourceLine{"$TMPL_DIR/$real_symbol:Long_Description"} = $.;
+
+ $section_id = $SourceSymbolDocs{"$TMPL_DIR/$real_symbol:Section_Id"};
+ if (defined ($section_id) && $section_id !~ m/^\s*$/) {
+ # Remove trailing blanks and use as is
+ $section_id =~ s/\s+$//;
+ } else {
+ $section_id = &CreateValidSGMLID ("$MODULE-$real_symbol");
+ }
+
+ &OutputProgramDBFile ($real_symbol, $section_id);
+
} else {
@TRACE@("SYMBOL DOCS found in source for : '$symbol' ",length($description), "\n");
$SourceSymbolDocs{$symbol} = $description;
@@ -4115,6 +4324,9 @@ sub ScanSourceFile {
if (m%^\s*(SECTION:\s*\S+)%) {
$symbol = $1;
@TRACE@("SECTION DOCS found in source for : '$symbol'\n");
+ } elsif (m%^\s*(PROGRAM:\s*\S+)%) {
+ $symbol = $1;
+ @TRACE@("PROGRAM DOCS found in source for : '$symbol'\n");
} elsif (m%^\s*([\w:-]*\w)\s*:?\s*(\([-A-Za-z0-9._() ]+?\)\s*)*$%) {
$symbol = $1;
my $annotation = $2;
@@ -4186,7 +4398,7 @@ sub ScanSourceFile {
}
# Look for a parameter name.
- if (m%^\s*@(\S+)\s*:\s*%) {
+ if (m%^\s*@(.+?)\s*:\s*%) {
my $param_name = $1;
my $param_desc = $';
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7e23744..5d1d2d6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,12 +1,13 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = gobject bugs annotations fail empty .
+SUBDIRS = gobject bugs annotations fail empty program .
if BUILD_TESTS
TESTS = \
gtkdoc-common.t gtkdoc-fixxref.t gtkdoc-mkdb.t gtkdoc-rebase.t gtkdoc-scan.t \
- tools.sh gobject.sh bugs.sh annotations.sh fail.sh empty.sh sanity.sh
+ tools.sh gobject.sh bugs.sh annotations.sh fail.sh empty.sh sanity.sh \
+ program.sh
TESTS_ENVIRONMENT = \
BUILDDIR=$(abs_builddir) \
SRCDIR=$(abs_srcdir) \
diff --git a/tests/program.sh b/tests/program.sh
new file mode 100755
index 0000000..eb5d511
--- /dev/null
+++ b/tests/program.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+gtkdoctest.sh program
+
diff --git a/tests/program/Makefile.am b/tests/program/Makefile.am
new file mode 100644
index 0000000..1653011
--- /dev/null
+++ b/tests/program/Makefile.am
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = . src docs
+
+if BUILD_TESTS
+
+check-local: clean
+
+endif
+
+-include $(top_srcdir)/git.mk
diff --git a/tests/program/docs/Makefile.am b/tests/program/docs/Makefile.am
new file mode 100644
index 0000000..7659310
--- /dev/null
+++ b/tests/program/docs/Makefile.am
@@ -0,0 +1,81 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=tester
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+DOC_SOURCE_DIR=$(top_srcdir)/tests/program/src
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+SCAN_OPTIONS=--deprecated-guards="GTKDOC_TESTER_DISABLE_DEPRECATED" \
+ --rebuild-types
+
+# Extra options to supply to gtkdoc-mkdb.
+MKDB_OPTIONS=--xml-mode
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# --html-dir=$(HTML_DIR)
+FIXXREF_OPTIONS=--extra-dir=$(glib_prefix)/share/gtk-doc/html
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+HFILE_GLOB=
+CFILE_GLOB=$(top_srcdir)/tests/program/src/*.c
+
+# Header files to ignore when scanning.
+IGNORE_HFILES=config.h
+
+# Images to copy into HTML directory.
+HTML_IMAGES =
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files =
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+GTKDOC_CFLAGS =
+GTKDOC_LIBS =
+
+# include generic part
+include $(top_srcdir)/tests/gtk-doc.notmpl.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
+
+CLEANFILES += \
+ $(DOC_MODULE)-overrides.txt \
+ $(DOC_MODULE).types
+
+if BUILD_TESTS
+TESTS_ENVIRONMENT = \
+ DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
+ PATH=$(abs_top_builddir):$(srcdir):$(PATH) \
+ PERL5LIB=$(abs_top_builddir):$(PERL5LIB)
+endif
+
+-include $(top_srcdir)/git.mk
diff --git a/tests/program/docs/tester-docs.xml b/tests/program/docs/tester-docs.xml
new file mode 100644
index 0000000..1bb342f
--- /dev/null
+++ b/tests/program/docs/tester-docs.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+ <!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
+ %gtkdocentities;
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>&package_name; Reference Manual</title>
+ <releaseinfo>
+ for &package_string;.
+ The latest version of this documentation can be found on-line at
+ <ulink role="online-location"
url="http://[SERVER]/&package_name;/index.html">http://[SERVER]/&package_name;/</ulink>.
+ </releaseinfo>
+ </bookinfo>
+
+ <chapter>
+ <title>Programs</title>
+ <xi:include href="xml/test-program.xml"/>
+ </chapter>
+
+ <index id="api-index">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+ <index id="deprecated-api-index" role="deprecated">
+ <title>Index of deprecated API</title>
+ <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+ </index>
+ <index id="api-index-0-1" role="0.1">
+ <title>Index of new API in 0.1</title>
+ <xi:include href="xml/api-index-0.1.xml"><xi:fallback /></xi:include>
+ </index>
+
+</book>
diff --git a/tests/program/docs/tester-sections.txt b/tests/program/docs/tester-sections.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/program/src/Makefile.am b/tests/program/src/Makefile.am
new file mode 100644
index 0000000..041a70c
--- /dev/null
+++ b/tests/program/src/Makefile.am
@@ -0,0 +1,10 @@
+## Process this file with automake to produce Makefile.in
+
+if BUILD_TESTS
+
+noinst_PROGRAMS = test-program
+
+endif
+
+
+-include $(top_srcdir)/git.mk
diff --git a/tests/program/src/test-program.c b/tests/program/src/test-program.c
new file mode 100644
index 0000000..fa60fef
--- /dev/null
+++ b/tests/program/src/test-program.c
@@ -0,0 +1,19 @@
+
+/**
+ * PROGRAM:test-program
+ * @short_description: A test program
+ * @synopsis: test-program [*OPTIONS*...] --arg1 *arg* *FILE*
+ * @see_also: test(1)
+ * @--arg1 *arg*: set arg1 to *arg*
+ * @-v, --version: Print the version number
+ * @-h, --help: Print the help message
+ *
+ * Long description of program.
+ *
+ * Returns: Zero on success, non-zero on failure
+ */
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]