blob: ac9b754259f008fbc9508dc1393ef014081a0728 [file] [log] [blame]
Fred Drake34a05f72002-04-16 21:27:17 +00001#! /usr/bin/env python
2
3import errno
4import os
Fred Drake56aa6282002-05-01 17:25:04 +00005import re
Fred Drake34a05f72002-04-16 21:27:17 +00006import sys
7
8if __name__ == "__main__":
9 _base = sys.argv[0]
10else:
11 _base = __file__
12
13_script_home = os.path.abspath(os.path.dirname(_base))
14
15srcdir = os.path.dirname(os.path.dirname(_script_home))
16
17EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h",
18 "longintrepr.h", "metagrammar.h",
19 "node.h", "opcode.h", "osdefs.h", "pgenheaders.h",
20 "py_curses.h", "parsetok.h", "symtable.h", "token.h"]
21
22
23def list_headers():
24 """Return a list of headers."""
25 incdir = os.path.join(srcdir, "Include")
26 return [fn for fn in os.listdir(incdir)
27 if fn.endswith(".h") and fn not in EXCLUDES]
28
Fred Drake56aa6282002-05-01 17:25:04 +000029
30def matcher(pattern):
31 return re.compile(pattern).match
32
33MATCHERS = [
34 matcher(r"\\begin\{cfuncdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
35 matcher(r"\\cfuncline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
36 matcher(r"\\begin\{ctypedesc\}(\[[^{]*\])?\{(?P<sym>[^{]*)\}"),
37 matcher(r"\\begin\{cvardesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
38 matcher(r"\\begin\{cmemberdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
39 matcher(r"\\cmemberline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
40 matcher(r"\\begin\{csimplemacrodesc\}\{(?P<sym>[^{]*)\}"),
41 ]
42
43
Fred Drake34a05f72002-04-16 21:27:17 +000044def list_documented_items():
45 """Return a list of everything that's already documented."""
Fred Drake56aa6282002-05-01 17:25:04 +000046 apidir = os.path.join(srcdir, "Doc", "api")
47 files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")]
48 L = []
49 for fn in files:
50 fullname = os.path.join(apidir, fn)
51 for line in open(fullname):
52 line = line.lstrip()
53 if not line.startswith("\\"):
54 continue
55 for matcher in MATCHERS:
56 m = matcher(line)
57 if m:
58 L.append(m.group("sym"))
59 break
60 return L
Fred Drake34a05f72002-04-16 21:27:17 +000061
62def split_documented(all, documented):
63 """Split the list of all symbols into documented and undocumented
64 categories."""
65 doc = []
66 undoc = []
67 for t in all:
68 if t[0] in documented:
69 doc.append(t)
70 else:
71 undoc.append(t)
72 return doc, undoc
73
74def print_list(L, title=None):
75 """Dump a list to stdout."""
76 if title:
77 print title + ":"
78 print "-" * (len(title) + 1)
79 w = 0
80 for sym, filename in L:
81 w = max(w, len(sym))
82 if w % 4 == 0:
83 w += 4
84 else:
85 w += (4 - (w % 4))
86 for sym, filename in L:
87 print "%-*s%s" % (w, sym, filename)
88
89
90_spcjoin = ' '.join
91
92def main():
93 args = sys.argv[1:]
94 if args:
95 headers = args
96 documented = []
97 else:
98 os.chdir(os.path.join(srcdir, "Include"))
99 headers = list_headers()
100 documented = list_documented_items()
101
Fred Drake56aa6282002-05-01 17:25:04 +0000102 cmd = ("ctags -f - --file-scope=no --c-types=dgpstux "
103 "-Istaticforward -Istatichere=static "
Fred Drake34a05f72002-04-16 21:27:17 +0000104 + _spcjoin(headers))
105 fp = os.popen(cmd)
106 L = []
107 prevsym = None
108 while 1:
109 line = fp.readline()
110 if not line:
111 break
112 sym, filename = line.split()[:2]
113 if sym == prevsym:
114 continue
115 if not sym.endswith("_H"):
116 L.append((sym, filename))
117 prevsym = sym
118 L.sort()
119 fp.close()
120
121 try:
122 if documented:
123 documented, undocumented = split_documented(L, documented)
124 print_list(documented, "Documented symbols")
125 if undocumented:
126 print
127 print_list(undocumented, "Undocumented symbols")
128 else:
129 print_list(L)
130 except IOError, e:
131 if e.errno != errno.EPIPE:
132 raise
133
134
135if __name__ == "__main__":
136 main()