1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import sys
27 import os
28 import re
29 import copy
30 import glob
31 import types
32
33 try:
34 import mbuild
35 except:
36 s = "\nXED ERROR: mfile.py could not find mbuild." + \
37 " Should be a sibling of the xed2 directory.\n\n"
38 sys.stderr.write(s)
39 sys.exit(1)
40
41
42
43
44
45
47 values = s.split('.')
48
49 maj =int(values[0])
50 minor = int(values[1])
51 fix = 0
52 if len(values) > 2:
53
54
55 values[2] = re.sub(r'-.*$','',values[2])
56 try:
57 fix = int(values[2])
58 except ValueError:
59 pass
60 if (maj > 1) or \
61 (maj == want_major and minor > want_minor) or \
62 (maj == want_major and minor == want_minor and fix >= want_fix):
63 return True
64 return False
65
67 """Find the right version of doxygen. Return a tuple of the
68 command name and a boolean indicating whether or not the version
69 checked out."""
70
71 if env['doxygen_cmd'] == '':
72 doxygen_cmd_intel = "/usr/intel/bin/doxygen"
73 doxygen_cmd_cygwin = "C:/cygwin/bin/doxygen"
74 doxygen_cmd_mac = \
75 "/Applications/Doxygen.app/Contents/Resources/doxygen"
76 doxygen_cmd = "doxygen"
77
78 if env['build_os'] == 'win':
79 if os.path.exists(doxygen_cmd_cygwin):
80 doxygen_cmd = doxygen_cmd_cygwin
81 else:
82 mbuild.msgb('DOXYGEN',"Could not find cygwin's doxygen," +
83 "trying doxygen from PATH")
84 elif env['build_os'] == 'lin':
85 if mbuild.verbose(1):
86 mbuild.msgb("CHECKING FOR", doxygen_cmd_intel)
87 if os.path.exists(doxygen_cmd_intel):
88 doxygen_cmd = doxygen_cmd_intel
89 elif env['build_os'] == 'mac':
90 if mbuild.verbose(1):
91 mbuild.msgb("CHECKING FOR", doxygen_cmd_mac)
92 if os.path.exists(doxygen_cmd_mac):
93 doxygen_cmd = doxygen_cmd_mac
94 else:
95 doxygen_cmd = env['doxygen_cmd']
96
97 doxygen_cmd = env.escape_string(doxygen_cmd)
98 doxygen_okay = False
99 if mbuild.verbose(1):
100 mbuild.msgb('Checking doxygen version','...')
101 if mbuild.check_python_version(2,4):
102 try:
103 (retval, output, error_output) = \
104 mbuild.run_command(doxygen_cmd + " --version")
105 if retval==0:
106 if len(output) > 0:
107 first_line = output[0].strip()
108 if mbuild.verbose(1):
109 mbuild.msgb("Doxygen version", first_line)
110 doxygen_okay = _doxygen_version_okay(first_line, 1,4,6)
111 else:
112 for o in output:
113 mbuild.msgb("Doxygen-version-check STDOUT", o)
114 if error_output:
115 for line in error_output:
116 mbuild.msgb("STDERR ",line.rstrip())
117 except:
118 mbuild.die("Doxygen required by the command line options " +
119 "but no doxygen found")
120
121 return (doxygen_cmd, doxygen_okay)
122
123
125 """This is a lame way of avoiding regular expression backslashing
126 issues"""
127 x1= mtch.start(group_name)
128 x2= mtch.end(group_name)
129 ostring = istring[0:x1] + newstring + istring[x2:]
130 return ostring
131
132
134
135 """Change the $(*) strings to the proper value in the config file.
136 Returns True on success"""
137
138
139 for k,s in subs.iteritems():
140 if re.search(' ',s):
141 if not re.search('^".*"$',s):
142 mbuild.die("Doxygen requires quotes around strings with spaces: [%s]->[%s]" %
143 ( k,s))
144 return False
145
146
147 try:
148 lines = file(env['doxygen_config']).readlines()
149 except:
150 mbuild.msgb("Could not open input file: " + env['doxygen_config'])
151 return False
152
153 env['doxygen_config_customized'] = \
154 env.build_dir_join(os.path.basename(env['doxygen_config']) + '.customized')
155 try:
156 ofile = open(env['doxygen_config_customized'],'w')
157 except:
158 mbuild.msgb("Could not open output file: " + env['doxygen_config_customized'])
159 return False
160
161
162 rsubs = {}
163 for k,v in subs.iteritems():
164 rsubs[k]=re.compile(r'(?P<tag>[$][(]' + k + '[)])')
165
166 olines = []
167 for line in lines:
168 oline = line
169 for k,p in rsubs.iteritems():
170
171 m = p.search(oline)
172 while m:
173
174 oline = _replace_match(oline, m, subs[k], 'tag')
175 m = p.search(oline)
176 olines.append(oline)
177
178
179 try:
180 for line in olines:
181 ofile.write(line)
182 except:
183 ofile.close()
184 mbuild.msgb("Could not write output file: " + env['doxygen_config_customized'])
185 return False
186
187 ofile.close()
188 return True
189
190 -def _build_doxygen_main(args, env):
191 """Customize the doxygen input file. Run the doxygen command, copy
192 in any images, and put the output in the right place."""
193
194 if type(args) is types.ListType:
195 if len(args) < 2:
196 mbuild.die("Need subs dictionary and dummy file arg for the doxygen command " +
197 "to indicate its processing")
198 else:
199 mbuild.die("Need a list for _build_doxygen_main with the subs " +
200 "dictionary and the dummy file name")
201
202 (subs,dummy_file) = args
203
204 (doxygen_cmd, doxygen_okay) = _find_doxygen(env)
205 if not doxygen_okay:
206 msg = 'No good doxygen available on this system; ' + \
207 'Your command line arguments\n\trequire it to be present. ' + \
208 'Consider dropping the "doc" and "doc-build" options\n\t or ' + \
209 'specify a path to doxygen with the --doxygen knob.\n\n\n'
210 return (1, [msg])
211 else:
212 env['DOXYGEN'] = doxygen_cmd
213
214 try:
215 okay = _customize_doxygen_file(env, subs)
216 except:
217 mbuild.die("CUSTOMIZE DOXYGEN INPUT FILE FAILED")
218 if not okay:
219 return (1, ['Doxygen customization failed'])
220
221 cmd = env['DOXYGEN'] + ' ' + \
222 env.escape_string(env['doxygen_config_customized'])
223 if mbuild.verbose(1):
224 mbuild.msgb("RUN DOXYGEN", cmd)
225 (retval, output, error_output) = mbuild.run_command(cmd)
226
227 for line in output:
228 mbuild.msgb("DOX",line.rstrip())
229 if error_output:
230 for line in error_output:
231 mbuild.msgb("DOX-ERROR",line.rstrip())
232 if retval != 0:
233 mbuild.msgb("DOXYGEN FAILED")
234 mbuild.die("Doxygen run failed. Retval=", str(retval))
235 mbuild.touch(dummy_file)
236 mbuild.msgb("DOXYGEN","succeeded")
237 return (0, [])
238
239
240
241
242
244 """return True if the directory d does not exist or if it contains no
245 files/subdirectories."""
246 if not os.path.exists(d):
247 return True
248 for (root, subdirs, subfiles) in os.walk(d):
249 if len(subfiles) or len(subdirs):
250 return False
251 return True
252
255 """Install the doxygen reference manual the doyxgen_output_dir
256 directory. doxygen_inputs is a list of files """
257
258 dox_dag = mbuild.dag_t(hash_file_name,env=env)
259
260
261 dirs = {}
262 for f in doxygen_inputs:
263 dirs[os.path.dirname(f)]=True
264 for d in dirs.iterkeys():
265 env.add_include_dir(d)
266
267
268 doxygen_inputs.append(env['doxygen_config'])
269 doxygen_inputs.append(env['doxygen_top_src'])
270
271 dummy = env.build_dir_join('dummy-doxygen-' + hash_file_name)
272
273
274 run_always = False
275 if _empty_dir(env['doxygen_install']):
276 run_always = True
277
278 if run_always:
279 _build_doxygen_main([subs,dummy], env)
280 else:
281 c1 = mbuild.plan_t(command=_build_doxygen_main,
282 args= [subs,dummy],
283 env= env,
284 input= doxygen_inputs,
285 output= dummy)
286 dox1 = dox_dag.add(env,c1)
287
288 okay = work_queue.build(dag=dox_dag)
289 phase = "DOXYGEN"
290 if not okay:
291 mbuild.die("[%s] failed. dying..." % phase)
292 if mbuild.verbose(1):
293 mbuild.msgb(phase, "build succeeded")
294
295
296
297
299 """Add the doxygen variables to the environment"""
300 doxygen_defaults = dict( doxygen_config='',
301 doxygen_top_src='',
302 doxygen_install='',
303 doxygen_cmd='' )
304 env.update_dict(doxygen_defaults)
305
307 """Add the knobs to the command line knobs parser"""
308
309 env.parser.add_option("--doxygen-install",
310 dest="doxygen_install",
311 action="store",
312 default='',
313 help="Doxygen installation directory")
314
315 env.parser.add_option("--doxygen-config",
316 dest="doxygen_config",
317 action="store",
318 default='',
319 help="Doxygen config file")
320
321 env.parser.add_option("--doxygen-top-src",
322 dest="doxygen_top_src",
323 action="store",
324 default='',
325 help="Doxygen top source file")
326
327 env.parser.add_option("--doxygen-cmd",
328 dest="doxygen_cmd",
329 action="store",
330 default='',
331 help="Doxygen command name")
332
333
334 -def doxygen_run(env, inputs, subs, work_queue, hash_file_name='dox'):
335 """Run doxygen assuming certain values are in the environment env.
336
337 @type env: env_t
338 @param env: the environment
339
340 @type inputs: list
341 @param inputs: list of input files to scan for dependences
342
343 @type subs: dictionary
344 @param subs: replacements in the config file
345
346 @type work_queue: work_queue_t
347 @param work_queue: a work queue for the build
348
349 @type hash_file_name: string
350 @param hash_file_name: used for the dummy file and mbuild hash suffix
351 """
352 _make_doxygen_reference_manual(env, inputs, subs, work_queue, hash_file_name)
353