Codebase list gtk-doc / 390d656
Merge upstream snapshot from git master into debian/experimental Simon McVittie 3 years ago
33 changed file(s) with 208 addition(s) and 514 deletion(s). Raw diff Collapse all Expand all
55 install_dir: bindir,
66 )
77
8 custom_target(
9 'gtk-doc.flat.make',
10 input: 'gtk-doc.make',
11 output: 'gtk-doc.flat.make',
12 install: true,
13 install_dir: pkgdatadir,
14 capture: true,
15 command: [
16 'sed',
17 '-e',
18 's/EXTRA_DIST =/EXTRA_DIST +=/',
19 '@INPUT@',
20 ]
21 )
8 foreach mode : ['', 'no-xslt']
9 if mode == ''
10 nested = ''
11 flat = '.flat'
12 else
13 nested = '.' + mode
14 flat = nested + '-flat'
15 endif
16
17 custom_target(
18 'gtk-doc' + flat + '.make',
19 input: 'gtk-doc' + nested + '.make',
20 output: 'gtk-doc' + flat + '.make',
21 install: true,
22 install_dir: pkgdatadir,
23 capture: true,
24 command: [
25 'sed',
26 '-e',
27 's/EXTRA_DIST =/EXTRA_DIST +=/',
28 '@INPUT@',
29 ]
30 )
31
32 install_data(
33 ['gtk-doc' + nested + '.make'],
34 install_dir: pkgdatadir,
35 )
36 endforeach
2237
2338 custom_target(
2439 'gtk-doc.m4',
3348 '@OUTPUT@',
3449 ],
3550 )
36
37 install_data(
38 ['gtk-doc.make'],
39 install_dir: pkgdatadir,
40 )
0 gtk-doc (1.32.1~git20200821.9e7c273-1) UNRELEASED; urgency=medium
1
2 * New upstream snapshot
3
4 -- Simon McVittie <smcv@debian.org> Tue, 25 Aug 2020 10:49:34 +0100
5
06 gtk-doc (1.32+git20200421.gtk4.4b737b1e-1) experimental; urgency=medium
17
28 * Team upload
2727 it under the terms of the GNU General Public License as published by
2828 the Free Software Foundation, either version 3 of the License, or
2929 (at your option) any later version.
30 .
30 .
3131 This program is distributed in the hope that it will be useful,
3232 but WITHOUT ANY WARRANTY; without even the implied warranty of
3333 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00 [DEFAULT]
11 pristine-tar = True
22 debian-branch = debian/experimental
3 upstream-branch = upstream/gtk-doc-for-gtk4
3 upstream-branch = upstream/latest
44
55 [buildpackage]
66 sign-tags = True
11 Date: Thu, 22 Aug 2019 09:31:19 +0100
22 Subject: Implement a simple tree structure without using anytree
33
4 anytree isn't currently available in Debian or Ubuntu, and seems like a
5 lot of code just to get a tree data structure. NIH just the bits we need.
4 anytree isn't currently available in Debian or Ubuntu, and seems like
5 a lot of code just to get a tree data structure. Reimplement just the
6 bits we need, with a compatible API.
7
8 Forwarded: https://gitlab.gnome.org/GNOME/gtk-doc/-/merge_requests/56
9 Signed-off-by: Simon McVittie <smcv@debian.org>
610 ---
711 gtkdoc/mkhtml2.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
812 tests/mkhtml2.py | 2 +-
+0
-76
debian/patches/meson-Install-no-xslt-variants-of-Autotools-Makefile-frag.patch less more
0 From: Simon McVittie <smcv@debian.org>
1 Date: Wed, 6 May 2020 14:09:46 +0100
2 Subject: meson: Install no-xslt variants of Autotools Makefile fragment
3
4 Previously, these were installed when building with Autotools but not
5 when building with Meson.
6
7 Signed-off-by: Simon McVittie <smcv@debian.org>
8 Forwarded: https://gitlab.gnome.org/GNOME/gtk-doc/-/merge_requests/48
9 ---
10 buildsystems/autotools/meson.build | 48 +++++++++++++++++++++++---------------
11 1 file changed, 29 insertions(+), 19 deletions(-)
12
13 diff --git a/buildsystems/autotools/meson.build b/buildsystems/autotools/meson.build
14 index c39d3fb..17bbcbd 100644
15 --- a/buildsystems/autotools/meson.build
16 +++ b/buildsystems/autotools/meson.build
17 @@ -6,20 +6,35 @@ configure_file(
18 install_dir: bindir,
19 )
20
21 -custom_target(
22 - 'gtk-doc.flat.make',
23 - input: 'gtk-doc.make',
24 - output: 'gtk-doc.flat.make',
25 - install: true,
26 - install_dir: pkgdatadir,
27 - capture: true,
28 - command: [
29 - 'sed',
30 - '-e',
31 - 's/EXTRA_DIST =/EXTRA_DIST +=/',
32 - '@INPUT@',
33 - ]
34 -)
35 +foreach mode : ['', 'no-xslt']
36 + if mode == ''
37 + nested = ''
38 + flat = '.flat'
39 + else
40 + nested = '.' + mode
41 + flat = nested + '-flat'
42 + endif
43 +
44 + custom_target(
45 + 'gtk-doc' + flat + '.make',
46 + input: 'gtk-doc' + nested + '.make',
47 + output: 'gtk-doc' + flat + '.make',
48 + install: true,
49 + install_dir: pkgdatadir,
50 + capture: true,
51 + command: [
52 + 'sed',
53 + '-e',
54 + 's/EXTRA_DIST =/EXTRA_DIST +=/',
55 + '@INPUT@',
56 + ]
57 + )
58 +
59 + install_data(
60 + ['gtk-doc' + nested + '.make'],
61 + install_dir: pkgdatadir,
62 + )
63 +endforeach
64
65 custom_target(
66 'gtk-doc.m4',
67 @@ -34,8 +49,3 @@ custom_target(
68 '@OUTPUT@',
69 ],
70 )
71 -
72 -install_data(
73 - ['gtk-doc.make'],
74 - install_dir: pkgdatadir,
75 -)
+0
-22
debian/patches/meson-Use-the-same-name-for-the-manual-as-in-Autotools.patch less more
0 From: Simon McVittie <smcv@debian.org>
1 Date: Wed, 6 May 2020 14:10:35 +0100
2 Subject: meson: Use the same name for the manual as in Autotools
3
4 Signed-off-by: Simon McVittie <smcv@debian.org>
5 Forwarded: https://gitlab.gnome.org/GNOME/gtk-doc/-/merge_requests/48
6 ---
7 help/manual/meson.build | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10 diff --git a/help/manual/meson.build b/help/manual/meson.build
11 index 6f8ec2c..7e59ab0 100644
12 --- a/help/manual/meson.build
13 +++ b/help/manual/meson.build
14 @@ -4,6 +4,6 @@ gtkdoc_help_sources = [
15 ]
16
17 gnome.yelp(
18 - package_name,
19 + package_name + '-manual',
20 sources: gtkdoc_help_sources,
21 )
1010 1 file changed, 2 insertions(+), 2 deletions(-)
1111
1212 diff --git a/gtkdoc/scan.py b/gtkdoc/scan.py
13 index 87809d2..8bfbeb3 100644
13 index 6c6534a..341939a 100644
1414 --- a/gtkdoc/scan.py
1515 +++ b/gtkdoc/scan.py
16 @@ -990,8 +990,8 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
16 @@ -978,8 +978,8 @@ def ScanHeaderContent(input_lines, decl_list, get_types, options):
1717 logging.info('struct/union level : %d', level)
1818
1919 # here we want in_declaration=='', otherwise we have a partial declaration
0 From: Simon McVittie <smcv@debian.org>
1 Date: Fri, 21 Aug 2020 15:02:25 +0100
2 Subject: scangobj: Don't sort an absence of signals/properties
3
4 qsort (NULL, 0, ...) is formally considered to be undefined behaviour,
5 and is diagnosed as such by the undefined behaviour sanitizer.
6
7 Bug: https://gitlab.gnome.org/GNOME/gtk-doc/-/issues/125
8 Forwarded: https://gitlab.gnome.org/GNOME/gtk-doc/-/merge_requests/53
9 Signed-off-by: Simon McVittie <smcv@debian.org>
10 ---
11 gtkdoc/scangobj.py | 6 ++++--
12 1 file changed, 4 insertions(+), 2 deletions(-)
13
14 diff --git a/gtkdoc/scangobj.py b/gtkdoc/scangobj.py
15 index 7434ec1..003c517 100644
16 --- a/gtkdoc/scangobj.py
17 +++ b/gtkdoc/scangobj.py
18 @@ -182,7 +182,8 @@ output_object_signals (FILE *fp, GType object_type)
19 object_class_name = g_type_name (object_type);
20
21 signals = g_signal_list_ids (object_type, &n_signals);
22 - qsort (signals, n_signals, sizeof (guint), compare_signals);
23 + if (n_signals > 0)
24 + qsort (signals, n_signals, sizeof (guint), compare_signals);
25
26 for (sig = 0; sig < n_signals; sig++) {
27 output_object_signal (fp, object_class_name, signals[sig]);
28 @@ -1095,7 +1096,8 @@ output_object_args (FILE *fp, GType object_type)
29 style_prop = FALSE;
30
31 while (TRUE) {
32 - qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
33 + if (n_properties > 0)
34 + qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
35 for (arg = 0; arg < n_properties; arg++) {
36 GParamSpec *spec = properties[arg];
37 const gchar *nick, *blurb, *dot;
00 Implement-a-simple-tree-structure-without-using-anytree.patch
11 revert_fix_build.patch
2 meson-Install-no-xslt-variants-of-Autotools-Makefile-frag.patch
3 meson-Use-the-same-name-for-the-manual-as-in-Autotools.patch
2 scangobj-Don-t-sort-an-absence-of-signals-properties.patch
4040 <xsl:param name="html.ext" select="'.html'"/>
4141 <xsl:param name="refentry.generate.name" select="0"/>
4242 <xsl:param name="refentry.generate.title" select="1"/>
43 <xsl:param name="abstract.notitle.enabled" select="1"/>
4443 <!-- don't generate all those link tags (very slow and hardly used)
4544 it does not show much effect as we have a user.head.content template
4645 <xsl:param name="html.extra.head.links" select="0" />
399398 <xsl:variable name="sect_derived_interfaces" select="./refsect1[@role='derived_interfaces']"/>
400399 <xsl:variable name="sect_implementations" select="./refsect1[@role='implementations']"/>
401400 <xsl:variable name="sect_properties" select="./refsect1[@role='properties']"/>
402 <xsl:variable name="sect_actions" select="./refsect1[@role='actions']"/>
403401 <xsl:variable name="sect_child_properties" select="./refsect1[@role='child_properties']"/>
404402 <xsl:variable name="sect_style_properties" select="./refsect1[@role='style_properties']"/>
405403 <xsl:variable name="sect_signal_proto" select="./refsect1[@role='signal_proto']"/>
480478 <span id="nav_signals">&#160;&#160;<span class="dim">|</span>&#160;
481479 <a href="#{$section_id}.signals" class="shortcut">
482480 <xsl:value-of select="./refsect1[@role='signal_proto']/title"/>
483 </a></span>
484 </xsl:if>
485 <xsl:if test="count($sect_actions) > 0">
486 <span id="nav_properties">&#160;&#160;<span class="dim">|</span>&#160;
487 <a href="#{$section_id}.actions" class="shortcut">
488 <xsl:value-of select="./refsect1[@role='actions']/title"/>
489481 </a></span>
490482 </xsl:if>
491483 </xsl:when>
5555 ArgBlurbs = [] # Docstring of the Arg.
5656 ArgDefaults = [] # Default value of the Arg.
5757 ArgRanges = [] # The range of the Arg type
58
59 ActionObjects = []
60 ActionNames = []
61 ActionParams = []
62 ActionProperties = []
6358
6459 # These global hashes store declaration info keyed on a symbol name.
6560 Declarations = {}
211206 <refpurpose>${short_desc}</refpurpose>
212207 </refnamediv>
213208 ${stability}
214 ${functions_synop}${args_synop}${signals_synop}${actions_synop}${object_anchors}${other_synop}${hierarchy}${prerequisites}${derived}${interfaces}${implementations}
209 ${functions_synop}${args_synop}${signals_synop}${object_anchors}${other_synop}${hierarchy}${prerequisites}${derived}${interfaces}${implementations}
215210 ${include_output}
216211 <refsect1 id="${section_id}.description" role="desc">
217212 <title role="desc.title">Description</title>
221216 <title role="details.title">Functions</title>
222217 ${functions_details}
223218 </refsect1>
224 ${other_desc}${args_desc}${signals_desc}${actions_desc}${see_also}
219 ${other_desc}${args_desc}${signals_desc}${see_also}
225220 </refentry>
226221 ''')
227222
289284 ReadKnownSymbols(os.path.join(ROOT_DIR, MODULE + "-sections.txt"))
290285 ReadSignalsFile(os.path.join(ROOT_DIR, MODULE + ".signals"))
291286 ReadArgsFile(os.path.join(ROOT_DIR, MODULE + ".args"))
292 ReadActionsFile(os.path.join(ROOT_DIR, MODULE + ".actions"))
293287 obj_tree = ReadObjectHierarchy(os.path.join(ROOT_DIR, MODULE + ".hierarchy"))
294288 ReadInterfaces(os.path.join(ROOT_DIR, MODULE + ".interfaces"))
295289 ReadPrerequisites(os.path.join(ROOT_DIR, MODULE + ".prerequisites"))
313307 suffix_list = ['.c', '.h']
314308
315309 source_dirs = options.source_dir
316 ignore_files = options.ignore_files and options.ignore_files.split(' ') or []
317 logging.info("Ignored files: " + options.ignore_files)
318
310 ignore_files = options.ignore_files
311 logging.info(" ignore files: " + ignore_files)
319312 for sdir in source_dirs:
320 abs_ignored_files = [os.path.join(sdir, x) for x in ignore_files]
321 ReadSourceDocumentation(sdir, suffix_list, abs_ignored_files)
313 ReadSourceDocumentation(sdir, suffix_list, source_dirs, ignore_files)
322314
323315 logging.info("Sources scanned")
324316
520512 args_desc = ''
521513 child_args_desc = ''
522514 style_args_desc = ''
523 actions_synop = ''
524 actions_desc = ''
525515 hierarchy_str = ''
526516 hierarchy = []
527517 interfaces = ''
636626 args_desc += make_refsect1_desc(style_args_desc, 'Style Property Details',
637627 section_id, 'style-property-details')
638628
639 actions_synop = re.sub(r'^\n*', '', actions_synop)
640 actions_synop = re.sub(r'\n+$', '\n', actions_synop)
641 if actions_synop != '':
642 actions_synop = '''<refsect1 id="%s.actions" role="actions">
643 <title role="actions.title">Actions</title>
644 <informaltable frame="none">
645 <tgroup cols="3">
646 <colspec colname="actions_none" colwidth="150px"/>
647 <colspec colname="actions_name" colwidth="300px"/>
648 <colspec colname="actions_param" colwidth="200px"/>
649 <tbody>
650 %s
651 </tbody>
652 </tgroup>
653 </informaltable>
654 </refsect1>
655 ''' % (section_id, actions_synop)
656 actions_desc = trim_leading_and_trailing_nl(actions_desc)
657 actions_desc = '''<refsect1 id="%s.action-details" role="action_details">
658 <title role="action_details.title">Action Details</title>
659 %s
660 </refsect1>
661 ''' % (section_id, actions_desc)
662
663629 hierarchy_str = AddTreeLineArt(hierarchy)
664630 if hierarchy_str != '':
665631 hierarchy_str = make_refsect1_desc('<screen>' + hierarchy_str + '\n</screen>',
690656 functions_details, other_desc,
691657 signals_synop, signals_desc,
692658 args_synop, args_desc,
693 actions_synop, actions_desc,
694659 hierarchy_str, interfaces,
695660 implementations,
696661 prerequisites, derived,
717682 args_desc = ''
718683 child_args_desc = ''
719684 style_args_desc = ''
720 actions_synop = ''
721 actions_desc = ''
722685 hierarchy_str = ''
723686 hierarchy = []
724687 interfaces = ''
757720 sig_synop, sig_desc = GetSignals(symbol)
758721 arg_synop, child_arg_synop, style_arg_synop, arg_desc, child_arg_desc, style_arg_desc = GetArgs(
759722 symbol)
760 action_synop, action_desc = GetActions(symbol)
761723 ifaces = GetInterfaces(symbol)
762724 impls = GetImplementations(symbol)
763725 prereqs = GetPrerequisites(symbol)
772734 args_desc += arg_desc
773735 child_args_desc += child_arg_desc
774736 style_args_desc += style_arg_desc
775 actions_synop += action_synop
776 actions_desc += action_desc
777737 interfaces += ifaces
778738 implementations += impls
779739 prerequisites += prereqs
944904 logging.info("trying symbol %s", symbol)
945905 m1 = re.search(r'(.*)::(.*)', symbol)
946906 m2 = re.search(r'(.*):(.*)', symbol)
947 m3 = re.search(r'(.*)\|(.*)', symbol)
948907 if m1:
949908 oname = m1.group(1)
950909 osym = m1.group(2)
969928 symbol_section = SymbolSection[oname]
970929 symbol_section_id = SymbolSectionId[oname]
971930 break
972 elif m3:
973 oname = m3.group(1)
974 osym = m3.group(2)
975 logging.info(" trying action %s|%s in %d actions", oname, osym, len(ActionNames))
976 for name in ActionNames:
977 logging.info(" " + name)
978 if name == osym:
979 symbol_type = "action"
980 if oname in SymbolSection:
981 symbol_section = SymbolSection[oname]
982 symbol_section_id = SymbolSectionId[oname]
983 break
984931 else:
985932 if symbol in SymbolSection:
986933 symbol_section = SymbolSection[symbol]
11751122 """
11761123
11771124 dtype = DeclarationTypes[symbol]
1178 logging.info('Output Symbol: "%s" "%s"', symbol, dtype)
11791125 if dtype == 'MACRO':
11801126 return OutputMacro(symbol, declaration)
11811127 elif dtype == 'TYPEDEF':
21042050 return str(stability)
21052051
21062052
2107 def OutputDBFile(file, title, section_id, includes, functions_synop, other_synop, functions_details, other_desc, signals_synop, signals_desc, args_synop, args_desc, actions_synop, actions_desc, hierarchy, interfaces, implementations, prerequisites, derived, file_objects, default_stability):
2053 def OutputDBFile(file, title, section_id, includes, functions_synop, other_synop, functions_details, other_desc, signals_synop, signals_desc, args_synop, args_desc, hierarchy, interfaces, implementations, prerequisites, derived, file_objects, default_stability):
21082054 """Outputs the final DocBook file for one section.
21092055
21102056 Args:
21212067 signal_desc (str): the DocBook for the Signal Description part
21222068 args_synop (str): the DocBook for the Arg Synopsis part
21232069 args_desc (str): the DocBook for the Arg Description part
2124 actions_synop (str): the DocBook for the Action Synopsis part
2125 actions_desc (str): the DocBook for the Action Description part
21262070 hierarchy (str): the DocBook for the Object Hierarchy part
21272071 interfaces (str): the DocBook for the Interfaces part
21282072 implementations (str): the DocBook for the Known Implementations part
22422186 # "<refentry id="$section_id" revision="$mday $month $year">"
22432187
22442188 OUTPUT.write(DB_REFENTRY.substitute({
2245 'actions_desc': actions_desc,
2246 'actions_synop': actions_synop,
22472189 'args_desc': args_desc,
22482190 'args_synop': args_synop,
22492191 'derived': derived,
36583600 return (synop, child_synop, style_synop, desc, child_desc, style_desc)
36593601
36603602
3661 def GetActions(gobject):
3662 """Generate action docs.
3663
3664 Returns the synopsis and detailed description DocBook output
3665 for the actions of a given GtkWidget subclass.
3666
3667 Args:
3668 object (str): the GObject subclass, e.g. 'GtkButton'.
3669
3670 Returns:
3671 str: action docs
3672 """
3673 synop = ''
3674 desc = ''
3675
3676 for i in range(len(ActionObjects)):
3677 if ActionObjects[i] == gobject:
3678 logging.info("Found action: %s", ActionNames[i])
3679 name = ActionNames[i]
3680 params = ActionParams[i]
3681 prop = ActionProperties[i]
3682
3683 # Remember: pipe, so we don't clash with signals.
3684 symbol = '%s|%s' % (gobject, name)
3685 sid = common.CreateValidSGMLID(symbol)
3686
3687 AllSymbols[symbol] = 1
3688 blurb = ''
3689 if symbol in SymbolDocs and not IsEmptyDoc(SymbolDocs[symbol]):
3690 blurb = ConvertMarkDown(symbol, SymbolDocs[symbol])
3691 logging.info(".. [%s][%s]", SymbolDocs[symbol], blurb)
3692 AllDocumentedSymbols[symbol] = 1
3693
3694 else:
3695 # FIXME: print a warning?
3696 logging.info(".. no description")
3697
3698 pad1 = ''
3699 if len(name) < 24:
3700 pad1 = " " * (24 - len(name))
3701
3702 action_synop = "<row><entry></entry><entry role=\"action_name\"><link linkend=\"%s\">%s</link></entry><entry role=\"parameter_type\">%s</entry></row>\n" % (
3703 sid, name, params)
3704 action_desc = u"<refsect2 id=\"%s\" role=\"action\"><title>The <literal>“%s”</literal> action</title>\n" % (
3705 sid, name)
3706 action_desc += MakeIndexterms(symbol, sid)
3707 action_desc += "\n"
3708 action_desc += OutputSymbolExtraLinks(symbol)
3709 if blurb != '':
3710 action_desc += blurb
3711 elif prop != '':
3712 action_desc += "<para>The %s action sets the %s property.</para>\n" % (name, MakeHashXRef (gobject + ':' + prop, "type"))
3713 action_desc += MakeDeprecationNote(symbol)
3714
3715 if params != '':
3716 action_desc += "<para>Parameter type: %s</para>\n" % params
3717
3718 action_desc += OutputParamDescriptions("ACTION", symbol, None)
3719 action_desc += OutputSymbolTraits(symbol)
3720 action_desc += "</refsect2>\n"
3721
3722 synop += action_synop
3723 desc += action_desc
3724
3725 return (synop, desc)
3726
37273603 def IgnorePath(path, source_dirs, ignore_files):
37283604 for sdir in source_dirs:
37293605 # Cut off base directory
37413617 return False
37423618
37433619
3744 def ReadSourceDocumentation(source_dir, suffix_list, ignore_files):
3620 def ReadSourceDocumentation(source_dir, suffix_list, source_dirs, ignore_files):
37453621 """Read the documentation embedded in comment blocks in the source code.
37463622
37473623 It recursively descends the source directory looking for source files and
37503626 Args:
37513627 source_dir (str): the directory to scan.
37523628 suffix_list (list): extensions to check
3753 ignore_files (list): a list of ignored paths under source_dir
3754 """
3629 """
3630 if IgnorePath(source_dir, source_dirs, ignore_files):
3631 return
3632
37553633 logging.info("Scanning source directory: %s", source_dir)
37563634
37573635 # This array holds any subdirectories found.
37643642 fname = os.path.join(source_dir, ifile)
37653643 if os.path.isdir(fname):
37663644 subdirs.append(fname)
3767 elif fname in ignore_files:
3768 logging.info(f"File {fname} matches ignored files")
37693645 else:
37703646 for suffix in suffix_list:
37713647 if ifile.endswith(suffix):
3772 ScanSourceFile(fname, ignore_files)
3773 break
3648 if not IgnorePath(fname, source_dirs, ignore_files):
3649 ScanSourceFile(fname, ignore_files)
3650 break
37743651
37753652 # Now recursively scan the subdirectories.
37763653 for sdir in subdirs:
3777 if sdir in ignore_files:
3778 logging.info(f"Directory {sdir} matches ignored files")
3779 continue
3780 ReadSourceDocumentation(sdir, suffix_list, ignore_files)
3654 ReadSourceDocumentation(sdir, suffix_list, source_dirs, ignore_files)
37813655
37823656
37833657 def ScanSourceFile(ifile, ignore_files):
37963670 common.LogWarning(ifile, 1, "Can't find basename for this filename.")
37973671 basename = ifile
37983672
3799 # Check if the filename is in the list of files to ignore.
3800 if ifile in ignore_files:
3673 # Check if the basename is in the list of files to ignore.
3674 if re.search(r'(\s|^)%s(\s|$)' % re.escape(basename), ignore_files):
38013675 logging.info("Skipping source file: %s", ifile)
38023676 return
38033677
38883762 logging.info("scanning[%s] :%s", in_part, line.strip())
38893763
38903764 # If we haven't found the symbol name yet, look for it.
3891 # We need to allow for the following cases:
3892 # function:
3893 # Class::signal:
3894 # Class:property:
3895 # Class|action:
3896 # Signal and property names can contain dashes, action names
3897 # can contain period.
3898 # In all cases, there might be annotations in parentheses
3899 # following the symbol name.
39003765 if not symbol:
39013766 m1 = re.search(r'^\s*((SECTION|PROGRAM):\s*\S+)', line)
3902 m2 = re.search(r'^\s*([\w:.|-]*\w)\s*:?\s*(\(.+?\)\s*)*$', line)
3767 m2 = re.search(r'^\s*([\w:-]*\w)\s*:?\s*(\(.+?\)\s*)*$', line)
39033768 if m1:
39043769 symbol = m1.group(1)
39053770 logging.info("docs found in source for : '%s'", symbol)
47984663
47994664 INPUT.close()
48004665
4801 def ReadActionsFile(ifile):
4802 """Reads information about object actions
4803
4804 It creates the arrays ActionObjects, ActionNames, ActionParams
4805 and ActionProperties containing info on the actions.
4806
4807 Args:
4808 ifile (str): the input filename.
4809 """
4810 in_action = False
4811 action_object = None
4812 action_name = None
4813 action_param = None
4814 action_prop = None
4815
4816 # Reset the args info.
4817 ActionObjects[:] = []
4818 ActionNames[:] = []
4819 ActionParams[:] = []
4820 ActionProperties[:] = []
4821
4822 if not os.path.isfile(ifile):
4823 return
4824
4825 INPUT = open(ifile, 'r', encoding='utf-8')
4826 line_number = 0
4827 for line in INPUT:
4828 line_number += 1
4829 if not in_action:
4830 if line.startswith('<ACTION>'):
4831 in_action = True
4832 action_object = ''
4833 action_name = ''
4834 action_param = ''
4835 action_prop = ''
4836
4837 else:
4838 m1 = re.search(r'^<NAME>(.*)</NAME>', line)
4839 m2 = re.search(r'^<PARAMETER>(.*)</PARAMETER>', line)
4840 m3 = re.search(r'^<PROPERTY>(.*)</PROPERTY>', line)
4841 if m1:
4842 action_name = m1.group(1)
4843 m1_1 = re.search(r'^(.*):::(.*)$', action_name)
4844 if m1_1:
4845 action_object = m1_1.group(1)
4846 action_name = m1_1.group(2).replace('_', '-')
4847 logging.info("Found action: %s", action_name)
4848 else:
4849 common.LogWarning(ifile, line_number, "Invalid action name: " + action_name)
4850
4851 elif m2:
4852 action_param = m2.group(1)
4853 elif m3:
4854 action_prop = m3.group(1)
4855 elif re.search(r'^</ACTION>', line):
4856 logging.info("Found end of action: %s::%s", action_object, action_name)
4857 ActionObjects.append(action_object)
4858 ActionNames.append(action_name)
4859 ActionParams.append(action_param)
4860 ActionProperties.append(action_prop)
4861 in_action = False
4862
4863 INPUT.close()
4864
48654666
48664667 def AddTreeLineArt(tree):
48674668 """Generate a line art tree.
110110 \s*\=""" % VAR_TYPE_MODIFIER, re.VERBOSE),
111111 # 17: G_DECLARE_*
112112 re.compile(
113 r""".*(G_DECLARE_|GDK_DECLARE_)
114 (FINAL_TYPE|DERIVABLE_TYPE|INTERNAL_TYPE|INTERFACE) # 1: variant
113 r""".*G_DECLARE_
114 (FINAL_TYPE|DERIVABLE_TYPE|INTERFACE) # 1: variant
115115 \s*\(""", re.VERBOSE),
116116 # 18-21: FUNCTIONS
117117 None, # in InitScanner()
178178 get_types = []
179179
180180 # do not read files twice; checking it here permits to give both srcdir and
181 # builddir as --source-dir without fear of duplicates
181 # builddir as --source-dir without fear of duplicities
182182 seen_headers = {}
183183
184 # split all the ignored files and directories
185 ignored_headers = options.ignore_headers and options.ignore_headers.split(' ') or []
186
187184 for file in options.headers:
188 # We assume that the specific headers we have been told to scan
189 # are not going to be placed in a blocklist
190 ScanHeader(file, section_list, decl_list, get_types, seen_headers, [], options)
185 ScanHeader(file, section_list, decl_list, get_types, seen_headers, options)
191186
192187 for dir in options.source_dir:
193 # Ignored headers are relative to a source directory; since we
194 # pass the full path of each header to ScanHeader(), we need to
195 # build a list of absolute paths from the ignored headers list
196 src_ignored_headers = [os.path.join(dir, x) for x in ignored_headers]
197 ScanHeaders(dir, section_list, decl_list, get_types, seen_headers, src_ignored_headers, options)
188 ScanHeaders(dir, section_list, decl_list, get_types, seen_headers, options)
198189
199190 with open(new_decl_list, 'w', encoding='utf-8') as f:
200191 for section in sorted(section_list.keys()):
338329 ]
339330
340331
341 def ScanHeaders(source_dir, section_list, decl_list, get_types, seen_headers, ignored_headers, options):
332 def ScanHeaders(source_dir, section_list, decl_list, get_types, seen_headers, options):
342333 """Scans a directory tree looking for header files.
343334
344335 Args:
345336 source_dir (str): the directory to scan.
346337 section_list (dict): map of section to filenames.
347 decl_list (list): list of declarations
348 get_types (list): list of symbols that have a get_type function
349338 seen_headers (set): set to avoid scanning headers twice
350 ignored_headers (list): list of ignored headers
351 options: command line options
352339 """
353340
354341 logging.info('Scanning source directory: %s', source_dir)
356343 # This array holds any subdirectories found.
357344 subdirs = []
358345
359 for filename in sorted(os.listdir(source_dir)):
360 if filename.startswith('.'):
346 for file in sorted(os.listdir(source_dir)):
347 if file.startswith('.'):
361348 continue
362 fullname = os.path.join(source_dir, filename)
349 fullname = os.path.join(source_dir, file)
363350 if os.path.isdir(fullname):
364 subdirs.append(fullname)
365 elif filename.endswith('.h'):
366 if fullname in ignored_headers:
367 logging.info(f"File {fullname} matches ignored headers")
368 continue
351 subdirs.append(file)
352 elif file.endswith('.h'):
369353 ScanHeader(fullname, section_list, decl_list, get_types,
370 seen_headers, ignored_headers, options)
354 seen_headers, options)
371355
372356 # Now recursively scan the subdirectories.
373 for d in subdirs:
374 if d in ignored_headers:
375 logging.info(f"Directory {d} matches ignored headers")
357 for dir in subdirs:
358 matchstr = r'(\s|^)' + re.escape(dir) + r'(\s|$)'
359 if re.search(matchstr, options.ignore_headers):
376360 continue
377 ScanHeaders(d, section_list, decl_list,
378 get_types, seen_headers, ignored_headers, options)
379
380
381 def ScanHeader(input_file, section_list, decl_list, get_types, seen_headers, ignored_headers, options):
361 ScanHeaders(os.path.join(source_dir, dir), section_list, decl_list,
362 get_types, seen_headers, options)
363
364
365 def ScanHeader(input_file, section_list, decl_list, get_types, seen_headers, options):
382366 """Scan a header file for doc commants.
383367
384368 Look for doc comments and extract them. Parse each doc comments and the
388372 input_file (str): the header file to scan.
389373 section_list (dict): a map of section per filename
390374 decl_list (list): a list of declarations
391 get_types (list): list of symbols that have a get_type function
392375 seen_headers (set): set to avoid scanning headers twice
393 ignored_headers (list): a list of ignored headers
394 options: command line options
395376 """
396
397 # Skip ignored headers
398 if input_file in ignored_headers:
399 logging.info(f"File {input_file} matches ignored headers")
400 return
401377
402378 # Don't scan headers twice
403379 canonical_input_file = os.path.realpath(input_file)
409385
410386 file_basename = os.path.split(input_file)[1][:-2] # filename ends in .h
411387
388 # Check if the basename is in the list of headers to ignore.
389 matchstr = r'(\s|^)' + re.escape(file_basename) + r'\.h(\s|$)'
390 if re.search(matchstr, options.ignore_headers):
391 logging.info('File ignored: %s', input_file)
392 return
393
394 # Check if the full name is in the list of headers to ignore.
395 matchstr = r'(\s|^)' + re.escape(input_file) + r'(\s|$)'
396 if re.search(matchstr, options.ignore_headers):
397 logging.info('File ignored: %s', input_file)
398 return
399
412400 if not os.path.exists(input_file):
413401 logging.warning('File does not exist: %s', input_file)
414402 return
438426 Args:
439427 input_lines (list):
440428 decl_list (list): symbols declarations
441 get_types (list): list of symbols that have a get_type function
429 get_types (list): lst of symbols that have a get_type function
442430 options: commandline options
443431
444432 Returns:
744732
745733 elif cm[17]:
746734 in_declaration = 'g-declare'
747 symbol = cm[17].group(1) + cm[17].group(2)
735 symbol = 'G_DECLARE_' + cm[17].group(1)
748736 decl = line[cm[17].end():]
749737
750738 # FUNCTIONS
9999 const gchar *interfaces_filename = "${new_interfaces_filename}";
100100 const gchar *prerequisites_filename = "${new_prerequisites_filename}";
101101 const gchar *args_filename = "${new_args_filename}";
102 const gchar *actions_filename = "${new_actions_filename}";
103102
104103 static void output_signals (void);
105104 static void output_object_signals (FILE *fp,
125124 static void output_args (void);
126125 static void output_object_args (FILE *fp, GType object_type);
127126
128 static void output_actions (void);
129 static void output_object_actions (FILE *fp, GType object_type);
130
131127 int
132128 main (${main_func_params})
133129 {
140136 output_object_interfaces ();
141137 output_interface_prerequisites ();
142138 output_args ();
143 output_actions ();
144139
145140 return 0;
146141 }
565560 output_prerequisites (fp, children[i]);
566561
567562 g_free (children);
568 #endif
569 }
570
571 static void
572 output_actions (void)
573 {
574 FILE *fp;
575 gint i;
576
577 fp = fopen (actions_filename, "w");
578 if (fp == NULL) {
579 g_warning ("Couldn't open output file: %s : %s", actions_filename, g_strerror(errno));
580 return;
581 }
582
583 for (i = 0; object_types[i]; i++) {
584 output_object_actions (fp, object_types[i]);
585 }
586
587 fclose (fp);
588 }
589
590 static void
591 output_object_actions (FILE *fp, GType object_type)
592 {
593 gpointer class;
594
595 if (!G_TYPE_IS_OBJECT (object_type))
596 return;
597
598 class = g_type_class_peek (object_type);
599 if (!class)
600 return;
601
602 #ifdef GTK_IS_WIDGET_CLASS
603 #if GTK_CHECK_VERSION(3,96,0)
604 if (GTK_IS_WIDGET_CLASS (class)) {
605 guint i = 0;
606 const char *action_name;
607 GType owner;
608 const GVariantType *parameter_type;
609 const char *property_name;
610 const gchar *object_class_name;
611
612 object_class_name = g_type_name (object_type);
613 while (gtk_widget_class_query_action (GTK_WIDGET_CLASS (class),
614 i,
615 &owner,
616 &action_name,
617 &parameter_type,
618 &property_name)) {
619 i++;
620 if (owner == G_TYPE_FROM_CLASS (class))
621 fprintf (fp, "<ACTION>\\n"
622 "<NAME>%s:::%s</NAME>\\n"
623 "<PARAMETER>%s</PARAMETER>\\n"
624 "<PROPERTY>%s</PROPERTY>\\n"
625 "</ACTION>\\n\\n",
626 object_class_name,
627 action_name,
628 parameter_type ? g_variant_type_peek_string (parameter_type) : "",
629 property_name ? property_name : "");
630 }
631 }
632 #endif
633563 #endif
634564 }
635565
12921222 new_prerequisites_filename = base_filename + '.prerequisites.new'
12931223 old_args_filename = base_filename + '.args'
12941224 new_args_filename = base_filename + '.args.new'
1295 old_actions_filename = base_filename + '.actions'
1296 new_actions_filename = base_filename + '.actions.new'
12971225
12981226 # generate a C program to scan the types
12991227
14041332 common.UpdateFileIfChanged(old_interfaces_filename, new_interfaces_filename, False)
14051333 common.UpdateFileIfChanged(old_prerequisites_filename, new_prerequisites_filename, False)
14061334 common.UpdateFileIfChanged(old_args_filename, new_args_filename, False)
1407 common.UpdateFileIfChanged(old_actions_filename, new_actions_filename, False)
14081335
14091336 return 0
33 ]
44
55 gnome.yelp(
6 package_name,
6 package_name + '-manual',
77 sources: gtkdoc_help_sources,
88 )
00 project('gtk-doc', 'c',
1 version: '1.99', # so we can depend on this branch in gtk
1 version: '1.32.1',
22 license: 'GPL2+',
33 meson_version: '>= 0.50.0', # needed for https://mesonbuild.com/Python-module.html#path
44 )
9898 binary_in.set('datadir', '${datarootdir}')
9999
100100 binary_in.set('PACKAGE', package_name)
101
101 binary_in.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/gtk-doc/issues')
102 binary_in.set('PACKAGE_NAME', package_name)
103 binary_in.set('PACKAGE_STRING', package_name)
104 binary_in.set('PACKAGE_TARNAME', package_name)
105 binary_in.set('PACKAGE_URL', 'https://gitlab.gnome.org/GNOME/gtk-doc')
106 binary_in.set('PACKAGE_VERSION', version)
102107 binary_in.set('VERSION', version)
103108
104109 foreach binary: gtkdoc_binaires
77 type: 'boolean', value: true,
88 description: 'Build the user manual (requires yelp-tools)')
99 option('tests',
10 type: 'boolean', value: false,
10 type: 'boolean', value: true,
1111 description: 'Build the test suite (requires glib)')
140140 border: solid 1px #babdb6;
141141 padding: 3px;
142142 vertical-align: top;
143 }
144
145 div.table table tr.subhead
146 {
147 /* tango:aluminium 2 */
148 background-color: #d3d7cf;
149 font-weight: bold;
150143 }
151144
152145 div.table table th
1919 )
2020
2121 annotations_test_html_data = []
22
23 subdir('xml')
2224
2325 test(
2426 'test-annotations-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
1919 )
2020
2121 bugs_test_html_data = []
22
23 subdir('xml')
24
25 configure_file(
26 input: join_paths(bugs_test_docs_dir, 'tester-sections.txt'),
27 output: 'tester-sections.txt',
28 copy: true,
29 )
2230
2331 test(
2432 'test-bugs-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
1919 )
2020
2121 empty_test_html_data = []
22
23 subdir('xml')
2224
2325 test(
2426 'test-empty-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
1919 )
2020
2121 fail_test_html_data = []
22
23 subdir('xml')
2224
2325 test(
2426 'test-fail-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
1919 )
2020
2121 gobject_test_html_data = []
22
23 subdir('xml')
24
25 configure_file(
26 input: join_paths(gobject_test_docs_dir, 'tester-sections.txt'),
27 output: 'tester-sections.txt',
28 copy: true,
29 )
2230
2331 test(
2432 'test-gobject-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
0 <!ENTITY package "${PACKAGE}">
1 <!ENTITY package_bugreport "${PACKAGE_BUGREPORT}">
2 <!ENTITY package_name "${PACKAGE_NAME}">
3 <!ENTITY package_string "${PACKAGE_STRING}">
4 <!ENTITY package_tarname "${PACKAGE_TARNAME}">
5 <!ENTITY package_url "${PACKAGE_URL}">
6 <!ENTITY package_version "${PACKAGE_VERSION}">
6565 """).splitlines(keepends=True))
6666 self.assertEqual({'symbol': 'Description.\n'}, mkdb.SourceSymbolDocs)
6767
68 def test_FindsDocCommentForSignal(self):
69 mkdb.SourceSymbolDocs = {}
70 mkdb.ParseCommentBlock(textwrap.dedent("""\
71 Class::signal-with-dashes:
72
73 Description.
74 """).splitlines(keepends=True))
75 self.assertEqual({'Class::signal-with-dashes': 'Description.\n'}, mkdb.SourceSymbolDocs)
76
77 def test_FindsDocCommentForProperty(self):
78 mkdb.SourceSymbolDocs = {}
79 mkdb.ParseCommentBlock(textwrap.dedent("""\
80 Class:property-with-dashes:
81
82 Description.
83 """).splitlines(keepends=True))
84 self.assertEqual({'Class:property-with-dashes': 'Description.\n'}, mkdb.SourceSymbolDocs)
85
86 def test_FindsDocCommentForActions(self):
87 mkdb.SourceSymbolDocs = {}
88 mkdb.ParseCommentBlock(textwrap.dedent("""\
89 Class|action.with.dots-and-dashes:
90
91 Description.
92 """).splitlines(keepends=True))
93 self.assertEqual({'Class|action.with.dots-and-dashes': 'Description.\n'}, mkdb.SourceSymbolDocs)
94
9568 def test_FindsDocCommentWithParam(self):
96 mkdb.SourceSymbolDocs = {}
9769 mkdb.ParseCommentBlock(textwrap.dedent("""\
9870 symbol:
9971 @par: value
10577 self.assertEqual({'par': 'value\n'}, mkdb.SourceSymbolParams['symbol'])
10678
10779 def test_FindsDocCommentWithMultilineParam(self):
108 mkdb.SourceSymbolDocs = {}
10980 mkdb.ParseCommentBlock(textwrap.dedent("""\
11081 symbol:
11182 @par: value docs with
11889 self.assertEqual({'par': 'value docs with\ntwo lines\n'}, mkdb.SourceSymbolParams['symbol'])
11990
12091 def test_FindsDocCommentWithReturns(self):
121 mkdb.SourceSymbolDocs = {}
12292 mkdb.ParseCommentBlock(textwrap.dedent("""\
12393 symbol:
12494
133103 self.assertEqual({'Returns': ' result\n'}, mkdb.SourceSymbolParams['symbol'])
134104
135105 def test_FindsDocCommentWithSince(self):
136 mkdb.SourceSymbolDocs = {}
137106 mkdb.ParseCommentBlock(textwrap.dedent("""\
138107 symbol:
139108
143112 self.assertEqual('0.1', mkdb.Since['symbol'])
144113
145114 def test_FindsDocCommentWithDeprecated(self):
146 mkdb.SourceSymbolDocs = {}
147115 mkdb.ParseCommentBlock(textwrap.dedent("""\
148116 symbol:
149117
154122 self.assertEqual(' use function() instead\n', mkdb.Deprecated['symbol'])
155123
156124 def test_FindsDocCommentWithStability(self):
157 mkdb.SourceSymbolDocs = {}
158125 mkdb.ParseCommentBlock(textwrap.dedent("""\
159126 symbol:
160127
164131 self.assertEqual('Stable', mkdb.StabilityLevel['symbol'])
165132
166133 def test_HandlesHTMLEntities(self):
167 mkdb.SourceSymbolDocs = {}
168134 mkdb.ParseCommentBlock(textwrap.dedent("""\
169135 symbol:
170136
1919 )
2020
2121 program_test_html_data = []
22
23 subdir('xml')
2224
2325 test(
2426 'test-program-scan',
0 configure_file(
1 input: join_paths(srcdir, 'tests', 'gtkdocentities.ent.in'),
2 output: 'gtkdocentities.ent',
3 configuration: binary_in,
4 )
1919 )
2020
2121 repro_test_html_data = []
22
23 subdir('xml')
2224
2325 test(
2426 'test-repro-scan',