MAINTAINERS: fix my last name
[gtk-doc.git] / gtkdoc-check.in
blob40d1e5ac9390721c95832d191499e22378c2f781
1 #!@PYTHON@
2 # -*- python; coding: utf-8 -*-
4 # gtk-doc - GTK DocBook documentation generator.
5 # Copyright (C) 2007  David Nečas
6 #               2007-2017  Stefan Sauer
8 # This program is free scperlonoftware; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #############################################################################
24 # Script      : gtkdoc-check
25 # Description : Runs various checks on built documentation and outputs test
26 #                results. Can be run druring make check, by adding this to the
27 #                documentations Makefile.am: TESTS = $(GTKDOC_CHECK)
28 #############################################################################
30 # Support both Python 2 and 3
31 from __future__ import print_function
33 import os, re, sys, argparse, subprocess
34 from glob import glob
37 def grep(regexp, filename, what):
38     pattern = re.compile(regexp)
39     with open(filename) as f:
40         for line in f:
41             for match in re.finditer(pattern, line):
42                 return match.group(1)
43     sys.exit("Cannot find %s in %s" % (what, filename));
46 def check_empty(filename, what):
47     with open(filename) as f:
48         count = sum(1 for line in f if line.strip())
49         if count:
50             print("%s:1:E: %d %st\n" % (filename, count, what))
51             return count
52     return 0
55 def check_includes(filename):
56     # Check that each XML file in the xml directory is included in doc_main_file
57     with open(filename) as f:
58         lines = f.read().splitlines()
59         num_missing = 0;
60         for include in glob('xml/*.xml'):
61             try:
62                 next(line for line in lines if include in line)
63             except StopIteration:
64                 num_missing += 1;
65                 print('% doesn\'t appear to include "%s"' % (filename, xml_file))
67     return num_missing
70 def run():
71     checks = 4
73     parser = argparse.ArgumentParser(description='gtkdoc-check version @VERSION@ - run documentation unit tests')
74     parser.add_argument('--version', action='version', version='@VERSION@')
75     parser.parse_args()
77     # Get parameters from test env, if not there try to grab them from the makefile
78     # We like Makefile.am more but builddir does not necessarily contain one.
79     makefile = 'Makefile.am'
80     if not os.path.exists(makefile):
81         makefile = 'Makefile'
83     # For historic reasons tests are launched in srcdir
84     srcdir = os.environ.get('SRCDIR', None)
85     builddir = os.environ.get('BUILDDIR', None)
86     workdir = '.'
87     if builddir:
88         workdir = builddir
90     doc_module = os.environ.get('DOC_MODULE', None)
91     if not doc_module:
92         doc_module = grep(r'^\s*DOC_MODULE\s*=\s*(\S+)', makefile, 'DOC_MODULE')
94     doc_main_file = os.environ.get('DOC_MAIN_SGML_FILE', None)
95     if not doc_main_file:
96         doc_main_file = grep(r'^\s*DOC_MAIN_SGML_FILE\s*=\s*(\S+)', makefile, 'DOC_MAIN_SGML_FILE')
97         doc_main_file = doc_main_file.replace('$(DOC_MODULE)', doc_module)
100     print('Running suite(s): gtk-doc-doc_module')
102     undocumented = int(grep(r'^(\d+)\s+not\s+documented\.\s*$',
103                             os.path.join(workdir, doc_module + '-undocumented.txt'),
104                             'number of undocumented symbols'))
105     incomplete = int(grep(r'^(\d+)\s+symbols?\s+incomplete\.\s*$',
106                           os.path.join(workdir, doc_module + '-undocumented.txt'),
107                           'number of incomplete symbols'))
108     total = undocumented + incomplete
109     if total:
110         print('doc_module-undocumented.txt:1:E: %d undocumented or incomplete symbols' % total)
112     undeclared = check_empty(os.path.join(workdir, doc_module + '-undeclared.txt'),
113                              'undeclared symbols')
114     unused = check_empty(os.path.join(workdir, doc_module + '-unused.txt'),
115                          'unused documentation entries')
117     missing_includes = check_includes(os.path.join(workdir, doc_main_file))
119     failed = (total > 0) + (undeclared != 0) + (unused != 0) + (missing_includes != 0)
120     rate = 100.0 * (checks - failed) / checks
121     print("%.1f%%: Checks %d, Failures: %d" % (rate, checks, failed))
122     sys.exit(failed != 0)
125 if __name__== '__main__':
126     run()