Merge branch 'tap-out-phase-1' into 'main'
[tor.git] / scripts / maint / locatemissingdoxygen.py
bloba2844346d64994d71dafe3eadc144bef9a4734d9
1 #!/usr/bin/env python
3 """
4 This script parses the stderr output of doxygen and looks for undocumented
5 stuff. By default, it just counts the undocumented things per file. But with
6 the -A option, it rewrites the files to stick in /*DOCDOC*/ comments
7 to highlight the undocumented stuff.
8 """
10 # Future imports for Python 2.7, mandatory in 3.0
11 from __future__ import division
12 from __future__ import print_function
13 from __future__ import unicode_literals
15 import os
16 import re
17 import shutil
18 import sys
20 warning_pattern = re.compile(r'^([^:]+):(\d+): warning: (.*) is not documented')
22 def readDoxygenOutput(f):
23 " yields (cfilename, lineno, thingname) "
24 for line in f:
25 m = warning_pattern.match(line)
26 if m:
27 yield m.groups()
29 warnings = {}
31 def buildWarnings():
32 for fn, lineno, what in list(readDoxygenOutput(sys.stdin)):
33 warnings.setdefault(fn, []).append( (int(lineno), what) )
35 def count(fn):
36 if os.path.abspath(fn) not in warnings:
37 print("0\t%s"%fn)
38 else:
39 n = len(warnings[os.path.abspath(fn)])
40 print("%d\t%s"%(n,fn))
42 def getIndentation(line):
43 s = line.lstrip()
44 return line[:len(line)-len(s)]
46 def annotate(filename):
47 if os.path.abspath(filename) not in warnings:
48 return
49 with open(filename) as f:
50 lines = f.readlines()
51 w = warnings[os.path.abspath(filename)][:]
52 w.sort()
53 w.reverse()
55 for lineno, what in w:
56 lineno -= 1 # list is 0-indexed.
57 if 'DOCDOC' in lines[lineno]:
58 continue
59 ind = getIndentation(lines[lineno])
60 lines.insert(lineno, "%s/* DOCDOC %s */\n"%(ind,what))
62 shutil.copy(filename, filename+".orig")
63 with open(filename, 'w') as f:
64 for l in lines:
65 f.write(l)
68 if __name__ == '__main__':
69 if len(sys.argv) == 1:
70 print("Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log")
71 sys.exit(1)
72 buildWarnings()
73 if sys.argv[1] == '-A':
74 del sys.argv[1]
75 func = annotate
76 else:
77 func = count
78 for fname in sys.argv[1:]:
79 func(fname)