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
37 def grep(regexp, filename, what):
38 pattern = re.compile(regexp)
39 with open(filename) as f:
41 for match in re.finditer(pattern, line):
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())
50 print("%s:1:E: %d %st\n" % (filename, count, what))
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()
60 for include in glob('xml/*.xml'):
62 next(line for line in lines if include in line)
65 print('% doesn\'t appear to include "%s"' % (filename, xml_file))
73 parser = argparse.ArgumentParser(description='gtkdoc-check version @VERSION@ - run documentation unit tests')
74 parser.add_argument('--version', action='version', version='@VERSION@')
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):
83 # For historic reasons tests are launched in srcdir
84 srcdir = os.environ.get('SRCDIR', None)
85 builddir = os.environ.get('BUILDDIR', None)
90 doc_module = os.environ.get('DOC_MODULE', None)
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)
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
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__':