for (pain, d) in results:
print '%(cov)5.2f (%(lines)6d): %(file)s' % d
+class Chunk:
+ def __init__ (self, range, coverage_count, all_lines, file):
+ assert coverage_count >= 0
+ assert type (range) == type (())
+
+ self.coverage_count = coverage_count
+ self.range = range
+ self.all_lines = all_lines
+ self.file = file
+
+ def length (self):
+ return self.range[1] - self.range[0]
+ def text (self):
+ return ''.join ([l[2] for l in self.lines()])
+
+ def lines (self):
+ return self.all_lines[self.range[0]:
+ self.range[1]]
+ def widen (self):
+ self.range = (min (self.range[0] -1, 0),
+ self.range[0] +1)
+ def write (self):
+ print 'chunk in', self.file
+ for (c, n, l) in self.lines ():
+ cov = '%d' % c
+ if c == 0:
+ cov = '#######'
+ elif c < 0:
+ cov = ''
+ sys.stdout.write ('%8s:%8d:%s' % (cov, n, l))
+
+ def uncovered_score (self):
+ return self.length ()
+
+class SchemeChunk (Chunk):
+ def uncovered_score (self):
+ text = self.text ()
+ if (text.startswith ('(define ')
+ and not text.startswith ('(define (')):
+ return 0
+
+ if text.startswith ('(use-modules '):
+ return 0
+
+ if (text.startswith ('(define-public ')
+ and not text.startswith ('(define-public (')):
+ return 0
+
+ return len ([l for (c,n,l) in self.lines() if (c == 0)])
def read_gcov (f):
ls = []
in_lines = [l for l in open (f).readlines ()]
- (count_len, line_num_len) = tuple (map (len, in_lines[0].split( ':')[:2]))
+ (count_len, line_num_len) = tuple (map (len, in_lines[0].split (':')[:2]))
for l in in_lines:
c = l[:count_len].strip ()
if n == 0:
continue
+
+ if '#' in c:
+ c = 0
+ elif c == '-':
+ c = -1
+ else:
+ c = int (c)
l = l[line_num_len+1:]
return ls
-def get_chunks (ls):
+def get_c_chunks (ls, file):
chunks = []
chunk = []
- for (c,n,l) in ls:
- if '#' in c:
- chunk.append ((n,l))
- elif c.strip () != '-' or l == '}\n':
- if chunk:
- chunks.append (chunk)
+
+ last_c = -1
+ for (c, n, l) in ls:
+ if not (c == last_c or c < 0 and l != '}\n'):
+ if chunk and last_c >= 0:
+ nums = [n-1 for (n, l) in chunk]
+ chunks.append (Chunk ((min (nums), max (nums)+1),
+ last_c, ls, file))
chunk = []
+
+ chunk.append ((n,l))
+ if c >= 0:
+ last_c = c
return chunks
-def is_exception_chunk (ch):
- for (n,l) in ch:
- for stat in ('warning', 'error'):
- if stat in l:
- return True
- return False
+def get_scm_chunks (ls, file):
+ chunks = []
+ chunk = []
+
+ def new_chunk ():
+ if chunk:
+ nums = [n-1 for (n, l) in chunk]
+ chunks.append (SchemeChunk ((min (nums), max (nums)+1),
+ max (last_c, 0), ls, file))
+ chunk[:] = []
+
+ last_c = -1
+ for (cov_count, line_number, line) in ls:
+ if line.startswith ('('):
+ new_chunk ()
+ last_c = -1
+
+ chunk.append ((line_number, line))
+ if cov_count >= 0:
+ last_c = cov_count
+
+ return chunks
def widen_chunk (ch, ls):
- nums = [n-1 for (n, l) in ch]
- (a, b) = (min (nums), max (nums)+1)
a -= 1
b += 1
return [(n, l) for (c, n, l) in ls[a:b]]
-def is_inspection_chunk (ch):
- for (n,l) in ch:
- for stat in ('::print',):
- if stat in l:
- return True
- return False
-
-def print_chunk (ch, lines):
- nums = [n-1 for (n, l) in ch]
- (a, b) = (min (nums), max (nums)+1)
- a -= 1
- b += 1
- for (c, n, l) in lines[a:b]:
- sys.stdout.write ('%8s:%8d:%s' % (c,n,l))
-
-
-def extract_uncovered (file):
+def extract_chunks (file):
try:
ls = read_gcov (file)
except IOError, s :
print s
- return
+ return []
- cs = get_chunks (ls)
- cs = [widen_chunk(c, ls) for c in cs]
- cs = [c for c in cs if not is_exception_chunk (c)]
- cs = [c for c in cs if not is_inspection_chunk (c)]
- for c in cs:
- print 'Uncovered chunk in', file
- print_chunk (c, ls)
- print '\n\n: '
+ cs = []
+ if 'scm' in file:
+ cs = get_scm_chunks (ls, file)
+ else:
+ cs = get_c_chunks (ls, file)
+ return cs
+
+
+def filter_uncovered (chunks):
+ def interesting (c):
+ if c.coverage_count > 0:
+ return False
+
+ t = c.text()
+ for stat in ('warning', 'error', 'print', 'scm_gc_mark'):
+ if stat in t:
+ return False
+ return True
+
+ return [c for c in chunks if interesting (c)]
def main ():
default=False,
dest="summary")
+ p.add_option ("--hotspots",
+ default=False,
+ action='store_true',
+ dest="hotspots")
+
p.add_option ("--uncovered",
default=False,
action='store_true',
if options.summary:
summary (['%s.gcov-summary' % s for s in args])
- if options.uncovered:
+ if options.uncovered or options.hotspots:
+ chunks = []
for a in args:
- extract_uncovered ('%s.gcov' % a)
-
+ name = a
+ if name.endswith ('scm'):
+ name += '.cov'
+ else:
+ name += '.gcov'
+
+ chunks += extract_chunks (name)
+
+ if options.uncovered:
+ chunks = filter_uncovered (chunks)
+ chunks = [(c.uncovered_score (), c) for c in chunks if c.uncovered_score() > 0]
+ elif options.hotspots:
+ chunks = [((c.coverage_count, -c.length()), c) for c in chunks]
+
+
+ chunks.sort ()
+ chunks.reverse ()
+ for (score, c) in chunks:
+ c.write ()
+
+
if __name__ == '__main__':
main ()