1169691Skan#!/usr/bin/python
2169691Skan
3169691Skanimport string
4169691Skanimport sys
5169691Skanimport re
6169691Skanimport os
7169691Skanimport platform
8169691Skanimport commands
9169691Skanfrom Numeric import *
10169691Skanfrom pychart import *
11169691Skanfrom xml.dom import minidom
12169691Skan
13169691Skanclass exception:
14169691Skan	pass
15169691Skan
16169691Skan
17169691Skandef comp_platform_info(compiler):
18169691Skan	ret = '<ul>\n'
19169691Skan	so = commands.getstatusoutput('cat /proc/cpuinfo | grep \'cpu MHz\'')
20169691Skan	if so[0] == 0:
21169691Skan		ret += '<li>CPU speed - %s</li>\n' % so[1]
22169691Skan	so = commands.getstatusoutput('cat /proc/meminfo | grep \'MemTotal\'')
23169691Skan	if so[0] == 0:
24169691Skan		ret += '<li>Memory - %s</li>\n' % so[1]
25169691Skan	ret += '<li>Platform - %s</li>\n' % platform.platform()
26169691Skan	so = commands.getstatusoutput(compiler + ' --version')
27169691Skan	if so[0] == 0:
28169691Skan		ret += '<li>Compiler - %s</li>\n' % so[1]
29169691Skan	ret += '</ul>\n'
30169691Skan	return ret
31169691Skan
32169691Skan
33169691Skanclass res:
34169691Skan	"""
35169691Skan	A 'structure' representing the results of a test.
36169691Skan	"""
37169691Skan	def __init__(self, x_label, y_label, cntnr_list, cntnr_descs, res_sets):
38169691Skan		self.x_label = x_label
39169691Skan		self.y_label = y_label
40169691Skan		self.cntnr_list = cntnr_list
41169691Skan		self.cntnr_descs = cntnr_descs
42169691Skan		self.res_sets = res_sets
43169691Skan
44169691Skan
45169691Skanclass res_getter:
46169691Skan	"""
47169691Skan	This class returns a res object for some test.
48169691Skan	"""
49169691Skan	class __sorter:
50169691Skan		def __accum(self, results):
51169691Skan			total = 0
52169691Skan			for result in results:
53169691Skan				total = total + result[1]
54169691Skan			return total
55169691Skan
56169691Skan		def sort(self, cntnr_list, res_sets):
57169691Skan			cntnrs_and_totals = []
58169691Skan			for cntnr in cntnr_list:
59169691Skan				results = res_sets[cntnr]
60169691Skan				total = self.__accum(results)
61169691Skan				cntnrs_and_totals.append((cntnr, total))
62169691Skan			by_total = lambda x,y: x[1] > y[1] and -1 or 1
63169691Skan			cntnrs_and_totals.sort(by_total)
64169691Skan			ret = []
65169691Skan			for cntnr_and_total in cntnrs_and_totals:
66169691Skan				cntnr = cntnr_and_total[0]
67169691Skan				ret.append(cntnr)
68169691Skan			return ret
69169691Skan
70169691Skan	def __init__(self, test_infos_f_name):
71169691Skan		self.__test_to_container_res_sets = {}
72169691Skan		self.__test_to_f_names = {}
73169691Skan		tests_dat = minidom.parse(test_infos_f_name)
74169691Skan		for test in tests_dat.getElementsByTagName('test'):
75169691Skan			test_name = test.attributes['name'].value
76169691Skan			self.__test_to_f_names[test_name] = test.getElementsByTagName('file')[0].attributes['name'].value
77169691Skan			cntnr_list = []
78169691Skan			for cntnr in test.getElementsByTagName('cntnr'):
79169691Skan				cntnr_list.append(cntnr.attributes['name'].value)
80169691Skan			self.__test_to_container_res_sets[test_name] = cntnr_list
81169691Skan
82169691Skan	def __get_label(self, tst_dat, label_name):
83169691Skan		label = tst_dat.getElementsByTagName(label_name)[0].firstChild.data
84169691Skan		label = string.strip(label, '\n')
85169691Skan		label = string.strip(label)
86169691Skan		return label
87169691Skan
88169691Skan	def __parse_res_sets(self, f_name, cntnr_list):
89169691Skan		tst_dat = minidom.parse(f_name)
90169691Skan		x_label = self.__get_label(tst_dat, 'x_name')
91169691Skan		y_label = self.__get_label(tst_dat, 'y_name')
92169691Skan		parsed_container_list = tst_dat.getElementsByTagName('cntnr')
93169691Skan		res_sets = {}
94169691Skan		cntnr_descs = {}
95169691Skan		for cntnr in parsed_container_list:
96169691Skan			cntnr_name = cntnr.attributes["name"].value
97169691Skan			res_sets[cntnr_name] = []
98169691Skan		for cntnr in parsed_container_list:
99169691Skan			cntnr_name = cntnr.attributes["name"].value
100169691Skan			cntnr_desc = cntnr.getElementsByTagName('desc')
101169691Skan			if res_sets.has_key(cntnr_name):
102169691Skan				res_set = []
103169691Skan				result_list = cntnr.getElementsByTagName('result')
104169691Skan				for result in result_list:
105169691Skan					x = string.atol(result.attributes["x"].value)
106169691Skan					y = string.atof(result.attributes["y"].value)
107169691Skan					res_set.append((x, y))
108169691Skan				res_sets[cntnr_name] = res_set
109169691Skan				cntnr_descs[cntnr_name] = cntnr_desc[0]
110169691Skan		return (x_label, y_label, cntnr_descs, res_sets)
111169691Skan
112169691Skan	def get(self, res_dir, test_name):
113169691Skan		cntnr_list = self.__test_to_container_res_sets[test_name]
114169691Skan		f_name = res_dir + '/' + self.__test_to_f_names[test_name]
115169691Skan		parsed = self.__parse_res_sets(f_name, cntnr_list)
116169691Skan		x_label = parsed[0]
117169691Skan		y_label = parsed[1]
118169691Skan		cntnr_descs = parsed[2]
119169691Skan		res_sets = parsed[3]
120169691Skan		cntnr_list = self.__sorter().sort(cntnr_list, res_sets)
121169691Skan		return res(x_label, y_label, cntnr_list, cntnr_descs, res_sets)
122169691Skan
123169691Skan
124169691Skanclass png_maker:
125169691Skan	"""
126169691Skan	This class creates a png file from a result set.
127169691Skan	"""
128169691Skan	class __style_chooser:
129169691Skan		def __init__(self):
130169691Skan			self.native_re = re.compile(r'n_(?:.*?)')
131169691Skan
132169691Skan			self.native_tick_mark_0 = tick_mark.Circle(size = 4)
133169691Skan			self.native_tick_mark_1 = tick_mark.Square(size = 4)
134169691Skan			self.native_line_style_0 = line_style.T(color = color.black, width=2)
135169691Skan			self.native_line_style_1 = line_style.T(color = color.black, width=2)
136169691Skan
137169691Skan			self.mask_re = re.compile(r'mask(?:.*?)')
138169691Skan			self.mod_re = re.compile(r'mod(?:.*?)')
139169691Skan
140169691Skan			self.rb_tree_mmap_rb_tree_set_re = re.compile(r'rb_tree_mmap_rb_tree_set(?:.*?)')
141169691Skan			self.rb_tree_mmap_lu_mtf_set_re = re.compile(r'rb_tree_mmap_lu_mtf_set(?:.*?)')
142169691Skan
143169691Skan			self.splay_re = re.compile(r'splay(?:.*?)')
144169691Skan			self.rb_tree_re = re.compile(r'rb_tree(?:.*?)')
145169691Skan			self.ov_tree_re = re.compile(r'ov_tree(?:.*?)')
146169691Skan			self.splay_tree_re = re.compile(r'splay_tree(?:.*?)')
147169691Skan
148169691Skan			self.pat_trie_re = re.compile(r'pat_trie(?:.*?)')
149169691Skan
150169691Skan			self.lc_1div8_1div2_re = re.compile(r'lc_1div8_1div2(?:.*?)')
151169691Skan			self.lc_1div8_1div1_re = re.compile(r'lc_1div8_1div1(?:.*?)')
152169691Skan			self.mcolc_1div2_re = re.compile(r'mcolc_1div2(?:.*?)')
153169691Skan
154169691Skan		def choose(self, cntnr):
155169691Skan			if self.native_re.search(cntnr):
156169691Skan				if cntnr == 'n_pq_vector':
157169691Skan					return (self.native_tick_mark_1, self.native_line_style_1)
158169691Skan
159169691Skan				return (self.native_tick_mark_0, self.native_line_style_0)
160169691Skan
161169691Skan			# tick_mark predefined
162169691Skan			# square, circle3, dia, tri, dtri, star, plus5, x5, gray70dia, blackdtri, blackdia
163169691Skan			if self.mask_re.search(cntnr):
164169691Skan				clr = color.navy
165169691Skan			elif self.mod_re.search(cntnr):
166169691Skan				clr = color.green4
167169691Skan			elif self.rb_tree_mmap_rb_tree_set_re.search(cntnr):
168169691Skan				clr = color.mediumblue
169169691Skan				tm = tick_mark.square
170169691Skan			elif self.rb_tree_mmap_lu_mtf_set_re.search(cntnr) or cntnr == 'rc_binomial_heap':
171169691Skan				clr = color.gray50
172169691Skan				tm = tick_mark.dia
173169691Skan			elif self.splay_tree_re.search(cntnr) or cntnr == 'binomial_heap':
174169691Skan				clr = color.gray58
175169691Skan				tm = tick_mark.tri
176169691Skan			elif self.rb_tree_re.search(cntnr) or cntnr == 'binary_heap':
177169691Skan				clr = color.red3
178169691Skan				tm = tick_mark.dtri
179169691Skan			elif self.ov_tree_re.search(cntnr) or cntnr == 'thin_heap':
180169691Skan				clr = color.orangered1
181169691Skan				tm = tick_mark.star
182169691Skan			elif self.pat_trie_re.search(cntnr) or cntnr == 'pairing_heap':
183169691Skan				clr = color.blueviolet
184169691Skan				tm = tick_mark.plus5
185169691Skan			else:
186169691Skan				sys.stderr.write(cntnr + '\n')
187169691Skan				raise exception
188169691Skan
189169691Skan                        # mask / mod
190169691Skan                        if cntnr.find('lc_1div8_1div') <> -1:
191169691Skan				if cntnr.find('mask') <> -1:
192169691Skan					# mask
193169691Skan					if self.lc_1div8_1div2_re.search(cntnr):
194169691Skan						if cntnr.find('nsth') <> -1:
195169691Skan							tm = tick_mark.x5
196169691Skan						else:
197169691Skan							tm = tick_mark.gray70dia
198169691Skan					if self.lc_1div8_1div1_re.search(cntnr):
199169691Skan						if cntnr.find('nsth') <> -1:
200169691Skan							tm = tick_mark.dia
201169691Skan                                                else:
202169691Skan							tm = tick_mark.circle3
203169691Skan                                else:
204169691Skan                                        # mod
205169691Skan					if self.lc_1div8_1div2_re.search(cntnr):
206169691Skan						if cntnr.find('nsth') <> -1:
207169691Skan							tm = tick_mark.tri
208169691Skan						else:
209169691Skan                                                        tm = tick_mark.square
210169691Skan					if self.lc_1div8_1div1_re.search(cntnr):
211169691Skan						if cntnr.find('nsth') <> -1:
212169691Skan                                                        tm = tick_mark.dtri
213169691Skan                                                else:
214169691Skan                                                        tm = tick_mark.star
215169691Skan
216169691Skan			if self.mcolc_1div2_re.search(cntnr):
217169691Skan				tm = tick_mark.circle3
218169691Skan
219169691Skan			return (tm, line_style.T(color = clr, width = 2))
220169691Skan
221169691Skan
222169691Skan	def __init__(self):
223169691Skan		self.__sc = self.__style_chooser()
224169691Skan		self.__mmap_re = re.compile('mmap_')
225169691Skan
226169691Skan	def __container_label_name(self, cntnr):
227169691Skan		return self.__mmap_re.sub('\nmmap_\n', cntnr)
228169691Skan
229169691Skan	def make(self, res, of_name):
230169691Skan		theme.output_format = 'png'
231169691Skan		theme.output_file = of_name
232169691Skan		theme.scale_factor = 2
233169691Skan#		theme.default_font_size = 5
234169691Skan		theme.use_color = 1
235169691Skan		theme.reinitialize()
236169691Skan		y_tick_interval = self.__get_y_tics(res)
237169691Skan		xaxis = axis.X(format = '/a90/hL%d',
238169691Skan			       tic_interval = 200,
239169691Skan			       label = res.x_label)
240169691Skan		yaxis = axis.Y(format = '%.2e',
241169691Skan			       tic_interval = y_tick_interval,
242169691Skan			       label = res.y_label)
243169691Skan		legend_lines = len(res.cntnr_list)
244169691Skan		legend_vloc = 50 + (legend_lines * 10)
245169691Skan		ar = area.T(x_axis = xaxis, y_axis = yaxis,
246169691Skan			    legend = legend.T(loc=(0,-legend_vloc),
247169691Skan					      frame_line_style=None,
248169691Skan					      inter_row_sep=2),
249169691Skan			    size=(240,110))
250169691Skan		plot_list = []
251169691Skan		for cntnr in res.cntnr_list:
252169691Skan			style = self.__sc.choose(cntnr)
253169691Skan			print cntnr
254169691Skan			pl = line_plot.T(label = self.__container_label_name(cntnr),
255169691Skan				data = res.res_sets[cntnr],
256169691Skan				tick_mark = style[0],
257169691Skan				line_style = style[1])
258169691Skan			plot_list.append(pl)
259169691Skan		for plot in plot_list:
260169691Skan			ar.add_plot(plot)
261169691Skan		ar.draw()
262169691Skan
263169691Skan
264169691Skan	def __get_y_tics(self, res):
265169691Skan		mx = 0
266169691Skan		for cntnr in res.cntnr_list:
267169691Skan			m = max(d[1] for d in res.res_sets[cntnr])
268169691Skan			mx = max(m, mx)
269169691Skan		return mx / 5
270169691Skan
271169691Skan
272169691Skan
273169691Skandef make_tt(s):
274169691Skan	return '<tt>' + s + '</tt>'
275169691Skan
276169691Skandef make_b(s):
277169691Skan	return '<b>' + s + '</b>'
278169691Skan
279169691Skandef make_ttb(s):
280169691Skan	return '<tt><b>' + s + '</b></tt>'
281169691Skan
282169691Skandef make_i(s):
283169691Skan	return '<i>' + s + '</i>'
284169691Skan
285169691Skandef make_pb_ds_class_href(c_name):
286169691Skan	return '<a href = "' + c_name + '.html">' + make_tt(c_name) + '</a>\n'
287169691Skan
288169691Skandef build_value_to_pb_ds_class_href(s_desc):
289169691Skan	value = s_desc.attributes['value'].value
290169691Skan	ret = make_pb_ds_class_href(value)
291169691Skan	return ret
292169691Skan
293169691Skanclass hash_desc_to_html_builder:
294169691Skan	def build_specific_comb_hash_fn(self, s_desc):
295169691Skan		comb_hash_fn_desc = s_desc.getElementsByTagName('Comb_Hash_Fn')[0]
296169691Skan		ret = make_tt('Comb_Hash_Fn')
297169691Skan		ret = ret + ' = '
298169691Skan		ret = ret + build_value_to_pb_ds_class_href(comb_hash_fn_desc)
299169691Skan		return ret
300169691Skan
301169691Skan	def __build_nom_denom(self, s_desc):
302169691Skan		nom_denom = s_desc.attributes['nom'].value + '/' + s_desc.attributes['denom'].value
303169691Skan		return make_i(nom_denom)
304169691Skan
305169691Skan	def __build_lc_trigger_desc(self, s_desc):
306169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
307169691Skan		ret = ret + ' with ' + make_i('&alpha;<sub>min</sub>')
308169691Skan		ret = ret + ' = '  + self.__build_nom_denom(s_desc.getElementsByTagName('alpha_min')[0])
309169691Skan		ret = ret + ' and ' + make_i('&alpha;<sub>max</sub>')
310169691Skan		ret = ret + ' = '  + self.__build_nom_denom(s_desc.getElementsByTagName('alpha_max')[0])
311169691Skan		return ret
312169691Skan
313169691Skan	def build_specific_resize_policy(self, s_desc):
314169691Skan		ret = make_tt('Resize_Policy')
315169691Skan		ret = ret + ' = '
316169691Skan		resize_policy_desc = s_desc.getElementsByTagName('Resize_Policy')[0]
317169691Skan		ret = ret + build_value_to_pb_ds_class_href(resize_policy_desc)
318169691Skan		ret = ret + ' with ' + make_tt('Size_Policy')
319169691Skan		ret = ret + ' = '
320169691Skan		size_policy_desc = resize_policy_desc.getElementsByTagName('Size_Policy')[0]
321169691Skan		ret = ret + build_value_to_pb_ds_class_href(size_policy_desc)
322169691Skan		ret = ret + ', and ' + make_tt('Trigger_Policy')
323169691Skan		ret = ret + ' = '
324169691Skan		trigger_policy_desc = resize_policy_desc.getElementsByTagName('Trigger_Policy')[0]
325169691Skan		if trigger_policy_desc.attributes['value'].value == 'hash_load_check_resize_trigger':
326169691Skan			ret = ret + self.__build_lc_trigger_desc(trigger_policy_desc)
327169691Skan		else:
328169691Skan			raise exception
329169691Skan		return ret
330169691Skan
331169691Skan
332169691Skanclass cc_hash_desc_to_html_builder:
333169691Skan	def __init__(self):
334169691Skan		self.__hash_builder = hash_desc_to_html_builder()
335169691Skan
336169691Skan	def build(self, s_desc):
337169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
338169691Skan		ret = ret + 'with ' + self.__hash_builder.build_specific_comb_hash_fn(s_desc)
339169691Skan		ret = ret + ', and ' + self.__hash_builder.build_specific_resize_policy(s_desc)
340169691Skan		return ret
341169691Skan
342169691Skan
343169691Skanclass gp_hash_desc_to_html_builder:
344169691Skan	def __init__(self):
345169691Skan		self.__hash_builder = hash_desc_to_html_builder()
346169691Skan
347169691Skan	def build(self, s_desc):
348169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
349169691Skan		ret = ret + ' with ' + self.__hash_builder.build_specific_comb_hash_fn(s_desc)
350169691Skan		ret = ret + ', ' + self.__hash_builder.build_specific_resize_policy(s_desc)
351169691Skan		ret = ret + ', and ' + make_tt('Probe_Fn')
352169691Skan		ret = ret + ' = '
353169691Skan		probe_fn = s_desc.getElementsByTagName('Probe_Fn')[0].attributes['value'].value
354169691Skan		ret = ret + make_pb_ds_class_href(probe_fn)
355169691Skan		return ret
356169691Skan
357169691Skan
358169691Skanclass basic_tree_like_desc_to_html_builder:
359169691Skan	def build_tag(self, s_desc):
360169691Skan		ret = make_tt('Tag')
361169691Skan		ret = ret + ' = '
362169691Skan		tag_desc = s_desc.getElementsByTagName('Tag')[0]
363169691Skan		ret = ret + build_value_to_pb_ds_class_href(tag_desc)
364169691Skan		return ret
365169691Skan
366169691Skan	def build_node_update(self, s_desc):
367169691Skan		ret = make_tt('Node_Update')
368169691Skan		ret = ret + ' = '
369169691Skan		node_update_desc = s_desc.getElementsByTagName('Node_Update')[0]
370169691Skan		ret = ret + build_value_to_pb_ds_class_href(node_update_desc)
371169691Skan		return ret
372169691Skan
373169691Skan
374169691Skanclass basic_tree_desc_to_html_builder:
375169691Skan	def __init__(self):
376169691Skan		self.__tree_like_builder = basic_tree_like_desc_to_html_builder()
377169691Skan
378169691Skan	def build(self, s_desc):
379169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
380169691Skan		ret = ret + ' with ' + self.__tree_like_builder.build_tag(s_desc)
381169691Skan		ret = ret + ', and ' + self.__tree_like_builder.build_node_update(s_desc)
382169691Skan		return ret
383169691Skan
384169691Skan
385169691Skanclass basic_trie_desc_to_html_builder:
386169691Skan	def __init__(self):
387169691Skan		self.__tree_like_builder = basic_tree_like_desc_to_html_builder()
388169691Skan
389169691Skan	def build(self, s_desc):
390169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
391169691Skan		ret = ret + ' with ' + self.__tree_like_builder.build_tag(s_desc)
392169691Skan		ret = ret + ', and ' + self.__tree_like_builder.build_node_update(s_desc)
393169691Skan		return ret
394169691Skan
395169691Skanclass lu_desc_to_html_builder:
396169691Skan	def build(self, s_desc):
397169691Skan		ret = build_value_to_pb_ds_class_href(s_desc)
398169691Skan		ret = ret + ' with ' + make_tt('Update_Policy')
399169691Skan		ret = ret + ' = '
400169691Skan		update_policy_desc = s_desc.getElementsByTagName('Update_Policy')[0]
401169691Skan		ret = ret + build_value_to_pb_ds_class_href(update_policy_desc)
402169691Skan		return ret
403169691Skan
404169691Skan
405169691Skanclass std_desc_to_html_builder:
406169691Skan	def build(self, s_desc):
407169691Skan		value = s_desc.attributes['value'].value
408169691Skan		return make_tt(value.replace('std_', 'std::'))
409169691Skan
410169691Skan
411169691Skanclass std_tr1_desc_to_html_builder:
412169691Skan	def build(self, s_desc):
413169691Skan		value = s_desc.attributes['value'].value
414169691Skan		ret =  make_tt(value.replace('std_tr1_', 'std::tr1::'))
415169691Skan		ret = ret + ' with ' + make_tt('cache_hash_code')
416169691Skan		ret = ret + ' = '
417169691Skan		cache_hash_code = s_desc.getElementsByTagName('cache_hash_code')[0].attributes['value'].value
418169691Skan		ret = ret + make_ttb(cache_hash_code)
419169691Skan		return ret
420169691Skan
421169691Skanclass gnucxx_desc_to_html_builder:
422169691Skan	def build(self, s_desc):
423169691Skan		value = s_desc.attributes['value'].value
424169691Skan		return make_tt(value.replace('__gnucxx_', '__gnucxx::'))
425169691Skan
426169691Skanclass stdext_desc_to_html_builder:
427169691Skan	def build(self, s_desc):
428169691Skan		value = s_desc.attributes['value'].value
429169691Skan		return make_tt(value.replace('stdext_', 'stdext::'))
430169691Skan
431169691Skanclass npq_desc_to_html_builder:
432169691Skan	def build(self, vector):
433169691Skan		if vector:
434169691Skan			under = make_tt('std::vector')
435169691Skan		else:
436169691Skan			under = make_tt('std::deque')
437169691Skan
438169691Skan		return make_tt('std::priority_queue') + ' adapting ' + under
439169691Skan
440169691Skanclass binary_heap_desc_to_html_builder:
441169691Skan	def build(self, s_desc):
442169691Skan		ret = make_pb_ds_class_href('priority_queue')
443169691Skan		ret = ret + ' with ' + make_tt('Tag')
444169691Skan		ret = ret + ' = ' + make_pb_ds_class_href('binary_heap_tag')
445169691Skan		return ret
446169691Skan
447169691Skanclass thin_heap_desc_to_html_builder:
448169691Skan	def build(self, s_desc):
449169691Skan		ret = make_pb_ds_class_href('priority_queue')
450169691Skan		ret = ret + ' with ' + make_tt('Tag')
451169691Skan		ret = ret + ' = ' + make_pb_ds_class_href('thin_heap_tag')
452169691Skan		return ret
453169691Skan
454169691Skanclass binomial_heap_desc_to_html_builder:
455169691Skan	def build(self, s_desc):
456169691Skan		ret = make_pb_ds_class_href('priority_queue')
457169691Skan		ret = ret + ' with ' + make_tt('Tag')
458169691Skan		ret = ret + ' = ' + make_pb_ds_class_href('binomial_heap_tag')
459169691Skan		return ret
460169691Skan
461169691Skanclass rc_binomial_heap_desc_to_html_builder:
462169691Skan	def build(self, s_desc):
463169691Skan		ret = make_pb_ds_class_href('priority_queue')
464169691Skan		ret = ret + ' with ' + make_tt('Tag')
465169691Skan		ret = ret + ' = ' + make_pb_ds_class_href('rc_binomial_heap_tag')
466169691Skan		return ret
467169691Skan
468169691Skanclass pairing_heap_desc_to_html_builder:
469169691Skan	def build(self, s_desc):
470169691Skan		ret = make_pb_ds_class_href('priority_queue')
471169691Skan		ret = ret + ' with ' + make_tt('Tag')
472169691Skan		ret = ret + ' = ' + make_pb_ds_class_href('pairing_heap_tag')
473169691Skan		return ret
474169691Skan
475169691Skanclass legend_desc_builder:
476169691Skan	"""
477169691Skan	Returns a string corresponding to a specific container type.
478169691Skan	"""
479169691Skan	def __init__(self):
480169691Skan		self.__cc_hash_builder = cc_hash_desc_to_html_builder()
481169691Skan		self.__gp_hash_builder = gp_hash_desc_to_html_builder()
482169691Skan		self.__basic_tree_builder = basic_tree_desc_to_html_builder()
483169691Skan		self.__basic_trie_builder = basic_trie_desc_to_html_builder()
484169691Skan		self.__lu_builder = lu_desc_to_html_builder()
485169691Skan		self.__std_builder = std_desc_to_html_builder()
486169691Skan		self.__std_tr1_builder = std_tr1_desc_to_html_builder()
487169691Skan		self.__gnucxx_builder = gnucxx_desc_to_html_builder()
488169691Skan		self.__stdext_builder = stdext_desc_to_html_builder()
489169691Skan		self.__npq_builder = npq_desc_to_html_builder()
490169691Skan		self.__thin_heap_builder = thin_heap_desc_to_html_builder()
491169691Skan		self.__thin_heap_builder = thin_heap_desc_to_html_builder()
492169691Skan		self.__binary_heap_builder = binary_heap_desc_to_html_builder()
493169691Skan		self.__binomial_heap_builder = binomial_heap_desc_to_html_builder()
494169691Skan		self.__rc_binomial_heap_builder = rc_binomial_heap_desc_to_html_builder()
495169691Skan		self.__pairing_heap_builder = pairing_heap_desc_to_html_builder()
496169691Skan
497169691Skan	def __build_specific(self, s_desc):
498169691Skan		type = s_desc.attributes['value'].value
499169691Skan
500169691Skan		if type == 'thin_heap':
501169691Skan			return self.__thin_heap_builder.build(s_desc)
502169691Skan		if type == 'binary_heap':
503169691Skan			return self.__binary_heap_builder.build(s_desc)
504169691Skan		if type == 'binomial_heap':
505169691Skan			return self.__binomial_heap_builder.build(s_desc)
506169691Skan		if type == 'rc_binomial_heap':
507169691Skan			return self.__rc_binomial_heap_builder.build(s_desc)
508169691Skan		if type == 'pairing_heap':
509169691Skan			return self.__pairing_heap_builder.build(s_desc)
510169691Skan		if type == 'cc_hash_table':
511169691Skan			ret = self.__cc_hash_builder.build(s_desc)
512169691Skan		elif type == 'gp_hash_table':
513169691Skan			ret = self.__gp_hash_builder.build(s_desc)
514169691Skan		elif type == 'tree':
515169691Skan			ret = self.__basic_tree_builder.build(s_desc)
516169691Skan		elif type == 'trie':
517169691Skan			ret = self.__basic_trie_builder.build(s_desc)
518169691Skan		elif type == 'list_update':
519169691Skan			ret = self.__lu_builder.build(s_desc)
520169691Skan		elif type == 'std::priority_queue_vector':
521169691Skan			return self.__npq_builder.build(True)
522169691Skan		elif type == 'std::priority_queue_deque':
523169691Skan			return self.__npq_builder.build(False)
524169691Skan		elif type == 'std_set' or type == 'std_map' or type == 'std_multimap':
525169691Skan			return self.__std_builder.build(s_desc)
526169691Skan		elif type == 'std_tr1_unordered_set' or type == 'std_tr1_unordered_map':
527169691Skan			return self.__std_tr1_builder.build(s_desc)
528169691Skan		elif type == 'stdext_hash_set' or type == 'stdext_hash_map' or type == 'stdext_hash_multimap':
529169691Skan			return self.__stdext_builder.build(s_desc)
530169691Skan		elif type == '__gnucxx_hash_set' or type == '__gnucxx_hash_map' or type == '__gnucxx_hash_multimap':
531169691Skan			return self.__gnucxx_builder.build(s_desc)
532169691Skan		else:
533169691Skan			sys.stderr.write('cannot recognize %s\n' % type)
534169691Skan			raise exception
535169691Skan		return ret
536169691Skan
537169691Skan
538169691Skan	def build(self, desc):
539169691Skan		s_descs = desc.getElementsByTagName('type')
540169691Skan		if s_descs.length == 0:
541169691Skan			print desc.toxml()
542169691Skan			raise exception
543169691Skan		ret = ''
544169691Skan		count = 0
545169691Skan		for s_desc in s_descs:
546169691Skan			if count > 0:
547169691Skan				ret = ret + ', mapping each key to '
548169691Skan			ret = ret + self.__build_specific(s_desc)
549169691Skan			count = count + 1
550169691Skan		return ret
551169691Skan
552169691Skan
553169691Skandef main(doc_dir, res_dir, test_infos_f_name, test_name, build_name):
554169691Skan	res_gtr = res_getter(test_infos_f_name)
555169691Skan	res = res_gtr.get(res_dir, test_name)
556169691Skan	png_mkr = png_maker()
557169691Skan	png_of_name = doc_dir + '/' + test_name + '_' + build_name + '.png'
558169691Skan	print png_of_name
559169691Skan	png_mkr.make(res, png_of_name)
560169691Skan
561169691Skan
562169691Skanif __name__ == "__main__":
563169691Skan	"""
564169691Skan	This module takes 6 parameters from the command line:
565169691Skan	Docs directory
566169691Skan	Results directory
567169691Skan	Tests info XML file name
568169691Skan	Test name
569169691Skan	Build name
570169691Skan	Compiler name
571169691Skan	"""
572169691Skan	usg = "make_graph.py <doc_dir> <res_dir> <test_info_file> <test_name> <build_name>\n"
573169691Skan	if len(sys.argv) != 6:
574169691Skan		sys.stderr.write(usg)
575169691Skan		raise exception
576169691Skan	main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
577