]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/coverage.py
updates for coverage scripts
[lilypond.git] / buildscripts / coverage.py
1 #!/bin/sh
2 import os
3 import glob
4 import re
5 import sys
6 import optparse
7
8 #File 'accidental-engraver.cc'
9 #Lines executed:87.70% of 252
10
11 def summary (args):
12     results = []
13     for f in args:
14         str = open (f).read ()
15         m = re.search ("File '([^']+.cc)'\s*Lines executed:([0-9.]+)% of ([0-9]+)", str)
16
17         if m and '/usr/lib' in m.group (1):
18             continue
19
20         if m:
21             cov = float (m.group (2))
22             lines = int (m.group (3))
23             pain = lines * (100.0 - cov)
24             file = m.group (1)
25             tup = (pain, locals ().copy())
26
27             results.append(tup)
28
29     results.sort ()
30     results.reverse()
31
32     print 'files sorted by number of untested lines (decreasing)'
33     print
34     print '%5s (%6s): %s' % ('cov %', 'lines', 'file')
35     print '----------------------------------------------'
36
37     for (pain, d) in results:
38         print '%(cov)5.2f (%(lines)6d): %(file)s' % d
39
40
41
42 def read_gcov (f):
43     ls = []
44
45     in_lines = [l for l in open (f).readlines ()]
46     (count_len, line_num_len) = tuple (map (len, in_lines[0].split( ':')[:2]))
47     
48     for l in in_lines:
49         c = l[:count_len].strip ()
50         l = l[count_len+1:]
51         n = int (l[:line_num_len].strip ())
52
53         if n == 0:
54             continue
55         
56         l = l[line_num_len+1:]
57
58         ls.append ((c,n,l))
59         
60     return ls
61
62 def get_chunks (ls):
63     chunks = []
64     chunk = []
65     for (c,n,l) in ls:
66         if '#' in c:
67             chunk.append ((n,l))
68         elif c.strip () != '-' or l == '}\n':
69             if chunk:
70                 chunks.append (chunk)
71                 chunk = []
72             
73     return chunks
74
75 def is_exception_chunk (ch):
76     for (n,l) in ch:
77         for stat in  ('warning', 'error'):
78             if stat in l:
79                 return True
80     return False
81
82 def print_chunk (ch, lines):
83     nums = [n-1 for (n, l) in ch]
84     for (c, n, l) in lines[min (nums):max (nums)+1]:
85         sys.stdout.write ('%8s:%8d:%s' % (c,n,l))
86
87
88 def extract_uncovered (file):
89     try:
90         ls = read_gcov (file)
91     except IOError, s :
92         print s
93         return
94         
95     cs = get_chunks (ls)
96     cs = [c for c in cs if not is_exception_chunk (c)]
97     print '\n'.join (['%d' % x for (a,x,b) in ls])
98     for c in cs:
99         print 'Uncovered chunk in', file
100         print_chunk (c, ls)
101         print '\n\n: '
102     
103
104 def main ():
105     p = optparse.OptionParser (usage="usage coverage.py [options] files",
106                                description="")
107     p.add_option ("--summary",
108                   action='store_true',
109                   default=False,
110                   dest="summary")
111     
112     p.add_option ("--uncovered",
113                   default=False,
114                   action='store_true',
115                   dest="uncovered")
116
117     
118     (options, args) = p.parse_args ()
119     
120
121     if options.summary:
122         summary (['%s.gcov-summary' % s for s in args])
123
124     if options.uncovered:
125         for a in args:
126             extract_uncovered ('%s.gcov' % a)
127         
128         
129 if __name__ == '__main__':
130     main ()