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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
#!/usr/bin/env python
# Eclass-EAPI matrix
# (c) 2018 Michał Górny
# Licensed under the terms of the 2-clause BSD license
import math
import os
import os.path
import re
import sys
STATS_LINE_RE = re.compile(r'EAPI=(?P<eapi>\w+) count: (?P<count>\d+)')
SUPP_LINE_RE = re.compile(r'EAPIs declared supported by eclass: (.*)')
def collect_data(work_dir):
"""
Collect data about supported and used EAPIs from work_dir.
work_dir: directory with eapi-per-eclass stats
Returns dict of {eclass: (supported_eapis, {eapi: count, ...}), ...}
"""
data = {}
for eclass in os.listdir(work_dir):
if not eclass.endswith('.eclass'):
continue
with open(os.path.join(work_dir, eclass, 'STATS.txt')) as f:
eapis = {}
supp_eapis = None
for l in f:
m = STATS_LINE_RE.match(l)
if m is not None:
eapis[m.group('eapi')] = int(m.group('count'))
continue
m = SUPP_LINE_RE.match(l)
if m is not None:
supp_eapis = m.group(1).split()
data[eclass[:-7]] = (supp_eapis, eapis)
return data
def format_table(data):
"""
Pretty-format table of eclass-EAPI data.
"""
ret = ''
max_eclass_length = max(len(k) for k in data)
max_count = max(v for supp, eapis in data.values()
for v in eapis.values())
max_count_length = math.ceil(math.log10(max_count))
all_eapis = sorted(frozenset(v for supp, eapis in data.values()
for v in eapis))
# format strings
format_str = '{{eclass:>{}}}'.format(max_eclass_length)
for eapi in all_eapis:
format_str += ' {{eapi_{}:>{}}}'.format(eapi, max_count_length)
format_str += '\n'
# header
hdr = {'eclass': 'eclass / EAPI'}
for eapi in all_eapis:
hdr['eapi_'+eapi] = eapi
ret += format_str.format(**hdr)
# ruler
rule = {'eclass': max_eclass_length * '-'}
for eapi in all_eapis:
rule['eapi_'+eapi] = max_count_length * '-'
ret += format_str.format(**rule)
# data
for eclass, ecl_data in sorted(data.items()):
line = {'eclass': eclass}
supp_eapis, eapis = ecl_data
for eapi in all_eapis:
if supp_eapis is not None and eapi not in supp_eapis:
if eapis.get(eapi, 0) > 0:
line['eapi_'+eapi] = '%d?!' % eapis[eapi]
else:
line['eapi_'+eapi] = 'xx'
else:
line['eapi_'+eapi] = eapis.get(eapi, 0)
ret += format_str.format(**line)
return ret
def main(work_dir):
data = collect_data(work_dir)
out = format_table(data)
with open(os.path.join(work_dir, 'matrix.txt'), 'w') as f:
f.write(out)
if __name__ == '__main__':
main(*sys.argv[1:])
|