blob: 77a46eacadfc4406e68a033f561398669bffb574 [file] [log] [blame]
#!/usr/bin/python
import os
from glob import glob
from collections import defaultdict
#
# gcov *.c is buggy, so getting a nice coverage report for .h files
# requires more steps:
#
# (1) for file in *.c; do gcov -l $file; done
#
# (2) generate a cumulative coverage for each .h file
#
# Tested with gcc/gcov 4.4.3.
#
NOCOV_EXPECTED = ['constants.c', 'bench.c']
def update_count(line, results):
first, rest = line.split(':', 1)
first = first.lstrip()
try:
results['count'] += int(first)
except ValueError:
results[first] += 1
return first, rest
d = defaultdict(list)
for filename in glob("*##*.h.gcov"):
k = filename.split('##')[1]
d[k].append(filename)
for outfile, lst in d.items():
files = [open(x) for x in lst]
out = open(outfile, "w")
for line in files[0]:
results = {'-': 0, '#####': 0, 'count': 0}
first, rest = update_count(line, results)
for f in files[1:]:
fst, rst = update_count(f.readline(), results)
if rst != rest and not 'gcda' in rest and not 'gcno' in rest \
and not ':Runs:' in rest and not ':Programs:' in rest:
print(line.rstrip(), rst.rstrip(), rest.rstrip())
if results['count'] > 0:
first = results['count']
elif results['#####'] > 0:
first = '#####'
else:
first = '-'
first = format(str(first), ">10.10")
out.write(':'.join((first, rest)))
out.close()
for f in files:
f.close()
def update_total(line, results):
first, rest = line.split(':', 1)
first = first.lstrip()
try:
int(first)
results['count'] += 1
except ValueError:
if 'GCOV_NOT_REACHED' in rest:
results['not_reached'] += 1
elif 'GCOV_UNLIKELY' in rest:
results['unlikely'] += 1
else:
#if '####' in first:
# print(first, rest)
results[first] += 1
return first, rest
print("\n%19s%19s%19s%19s\n" %
("file name:", "lines:", "not executed:", "unaccounted for:"))
for filename in glob("*.h.gcov"):
if '##' in filename: continue
with open(filename) as f:
results = {'-': 0, '#####': 0, 'not_reached': 0, 'unlikely': 0,
'count': 0}
for line in f:
update_total(line, results)
print("%19s%19d%19d%19d" % (filename.split('.gcov')[0], results['count'],
results['not_reached']+results['unlikely']+
results['#####'], results['#####']))
print("")
for filename in glob("*.c.gcov"):
if '##' in filename: continue
with open(filename) as f:
results = {'-': 0, '#####': 0, 'not_reached': 0, 'unlikely': 0, 'count': 0}
for line in f:
update_total(line, results)
print("%19s%19d%19d%19d" % (filename.split('.gcov')[0], results['count'],
results['not_reached']+results['unlikely']+
results['#####'], results['#####']))
print("\n\n%19s\n" % "no coverage:")
for filename in glob("*.h"):
s = filename + '.gcov'
if not os.path.isfile(s):
with open(filename) as f:
for line in f:
if 'static inline' in line:
print("%19s" % filename)
break
for filename in glob("*.c"):
s = filename + '.gcov'
if not os.path.isfile(s) and not filename in NOCOV_EXPECTED:
print("%19s" % filename)
print("")