Finish with check_docs.py.
[monky] / check_docs.py
1 #!/usr/bin/python
2 #
3 # This script will check the documentation consistency against the code.  It
4 # doesn't check the actual accuracy of the documentation, it just ensures that
5 # everything is documented and that nothing which doesn't exist in Conky
6 # appears in the documentation.
7 #
8 # This script also updates the vim and nano syntax files so it doesn't have to
9 # be done manually.
10 #
11
12 import os.path
13 import re
14 import sys
15
16 file_names = dict()
17 file_names["text_objects"]    = "src/text_object.h"
18 file_names["conky"]           = "src/conky.c"
19 file_names["vim_syntax"]      = "extras/vim/syntax/conkyrc.vim"
20 file_names["nano_syntax"]     = "extras/nano/conky.nanorc"
21 file_names["variables"]       = "doc/variables.xml"
22 file_names["config_settings"] = "doc/config_settings.xml"
23
24 for fn in file_names.values():
25         if not os.path.exists(fn) or not os.path.isfile(fn):
26                 print "'%s' doesn't exist, or isn't a file" % (fn)
27                 exit(0)
28
29 #
30 # Do all the objects first
31 #
32
33 objects = []
34
35 file = open(file_names["text_objects"], "r")
36 exp = re.compile("\s*OBJ_(\w*).*")
37 while file:
38         line = file.readline()
39         if len(line) == 0:
40                 break
41         res = exp.match(line)
42         if res:
43                 obj = res.group(1)
44                 if not re.match("color\d", obj) and obj != "text":
45                         # ignore colourN stuff
46                         objects.append(res.group(1))
47 file.close()
48
49 doc_objects = []
50 exp = re.compile("\s*<command><option>(\w*)</option></command>.*")
51 print "checking docs -> objs consistency (in %s)" % (file_names["text_objects"])
52 file = open(file_names["variables"], "r")
53 while file:
54         line = file.readline()
55         if len(line) == 0:
56                 break
57         res = exp.match(line)
58         if res:
59                 doc_objects.append(res.group(1))
60                 if doc_objects[len(doc_objects) - 1] != "templateN" and doc_objects[len(doc_objects) - 1] not in objects:
61                         print "   '%s' is documented, but doesn't seem to be an object" % (doc_objects[len(doc_objects) - 1])
62 file.close()
63 print "done\n"
64
65 print "checking objs -> docs consistency (in %s)" % (file_names["variables"])
66 for obj in objects:
67         if obj not in doc_objects:
68                 print "   '%s' seems to be undocumented" % (obj)
69 print "done\n"
70
71 #
72 # Now we'll do config settings
73 #
74
75 configs = []
76
77 file = open(file_names["conky"], "r")
78 exp1 = re.compile('\s*CONF\("(\w*)".*')
79 exp2 = re.compile('\s*CONF2\("(\w*)".*')
80 exp3 = re.compile('\s*CONF3\("(\w*)".*')
81 while file:
82         line = file.readline()
83         if len(line) == 0:
84                 break
85         res = exp1.match(line)
86         if not res:
87                 res = exp2.match(line)
88         if not res:
89                 res = exp3.match(line)
90         if res:
91                 conf = res.group(1)
92                 if re.match("color\d", conf):
93                         conf = "colorN"
94                 if configs.count(conf) == 0:
95                         configs.append(conf)
96 file.close()
97
98 doc_configs = []
99 exp = re.compile("\s*<term><command><option>(\w*)</option></command>.*")
100 print "checking docs -> configs consistency (in %s)" % (file_names["conky"])
101 file = open(file_names["config_settings"], "r")
102 while file:
103         line = file.readline()
104         if len(line) == 0:
105                 break
106         res = exp.match(line)
107         if res:
108                 doc_configs.append(res.group(1))
109                 if doc_configs[len(doc_configs) - 1] != "TEXT" and doc_configs[len(doc_configs) - 1] != "templateN" and doc_configs[len(doc_configs) - 1] not in configs:
110                         print "   '%s' is documented, but doesn't seem to be a config setting" % (doc_configs[len(doc_configs) - 1])
111 file.close()
112 print "done\n"
113
114 print "checking configs -> docs consistency (in %s)" % (file_names["config_settings"])
115 for obj in configs:
116         if obj != "text" and obj != "template" and obj not in doc_configs:
117                 print "   '%s' seems to be undocumented" % (obj)
118 print "done\n"
119
120
121
122 # Cheat and add the colour/template stuff.
123
124 for i in range(0, 10):
125         objects.append("color" + str(i))
126         configs.append("color" + str(i))
127         objects.append("template" + str(i))
128         configs.append("template" + str(i))
129
130 # Finally, sort everything.
131 objects.sort()
132 configs.sort()
133
134 #
135 # Update nano syntax stuff
136 #
137
138 print "updating nano syntax...",
139 sys.stdout.flush()
140 file = open(file_names["nano_syntax"], "rw+")
141 lines = []
142 while file:
143         line = file.readline()
144         if len(line) == 0:
145                 break
146         lines.append(line)
147
148 # find the line we want to update
149 for line in lines:
150         if re.match("color green ", line):
151                 idx = lines.index(line)
152                 lines.pop(idx) # remove old line
153                 line = 'color green "\<('
154                 for obj in configs:
155                         line += "%s|" % (obj)
156                 line = line[:len(line) - 1]
157                 line += ')\>"\n'
158                 lines.insert(idx, line)
159         if re.match("color brightblue ", line):
160                 idx = lines.index(line)
161                 lines.pop(idx) # remove old line
162                 line = 'color brightblue "\<('
163                 for obj in objects:
164                         line += "%s|" % (obj)
165                 line = line[:len(line) - 1]
166                 line += ')\>"\n'
167                 lines.insert(idx, line)
168                 break # want to ignore everything after this line
169 file.truncate(0)
170 file.seek(0)
171 file.writelines(lines)
172 file.close()
173 print "done."
174
175 #
176 # Update vim syntax stuff
177 #
178
179 print "updating vim syntax...",
180 sys.stdout.flush()
181 file = open(file_names["vim_syntax"], "rw+")
182 lines = []
183 while file:
184         line = file.readline()
185         if len(line) == 0:
186                 break
187         lines.append(line)
188
189 # find the line we want to update
190 for line in lines:
191         if re.match("syn keyword ConkyrcSetting ", line):
192                 idx = lines.index(line)
193                 lines.pop(idx) # remove old line
194                 line = 'syn keyword ConkyrcSetting '
195                 for obj in configs:
196                         line += "%s " % (obj)
197                 line = line[:len(line) - 1]
198                 line += '\n'
199                 lines.insert(idx, line)
200         if re.match("syn keyword ConkyrcVarName contained nextgroup=ConkyrcNumber,ConkyrcColour skipwhite ", line):
201                 idx = lines.index(line)
202                 lines.pop(idx) # remove old line
203                 line = 'syn keyword ConkyrcVarName contained nextgroup=ConkyrcNumber,ConkyrcColour skipwhite '
204                 for obj in objects:
205                         line += "%s " % (obj)
206                 line = line[:len(line) - 1]
207                 line += '\n'
208                 lines.insert(idx, line)
209                 break # want to ignore everything after this line
210 file.truncate(0)
211 file.seek(0)
212 file.writelines(lines)
213 file.close()
214 print "done."