blob: ce1449fc3edbf058278417a9b618fd2d286387a5 [file] [log] [blame]
"""Filters LCOV tracefiles
- Arguments are filepath prefixes to keep (or drop if prefixed with '-')
- A path is kept if it matches at least one include and no excludes
- If no includes are specified then everything not excluded is included
- Input tracefile comes from stdin
- Output tracefiles goes to stdout
"""
import sys
def read_lcov():
file_line_cov = {} # map[test][file][line] = covered
current_sf = None
current_tn = None
for line in sys.stdin:
line = line.strip()
if line[:3] == "TN:":
current_tn = line[3:]
if current_tn not in file_line_cov:
file_line_cov[current_tn] = {}
elif line[:3] == "SF:":
current_sf = line[3:]
file_line_cov[current_tn][current_sf] = {}
elif line[:3] == "DA:":
[num, hit] = line[3:].split(",")
file_line_cov[current_tn][current_sf][int(num)] = hit != "0" # convert to bool
else:
pass
return file_line_cov
def is_excluded(path, excludes):
# if no excludes are specified then this is skipped and nothing is excluded
for e in excludes:
if path.startswith(e):
# matched an excluded prefix so finished with excludes
return True
return False
def is_included(path, includes):
for i in includes:
if path.startswith(i):
# matched an included prefix so finished with includes
return True
return False
def write_lcov(filtered_cov):
for tn in sorted(filtered_cov):
for filepath in sorted(filtered_cov[tn]):
sys.stdout.write('TN:{}\n'.format(tn))
sys.stdout.write('SF:{}\n'.format(filepath))
for line in sorted(filtered_cov[tn][filepath]):
sys.stdout.write('DA:{},{}\n'.format(line, int(filtered_cov[tn][filepath][line])))
sys.stdout.write('end_of_record\n')
def main():
prefixes = sys.argv[1:]
includes = [x for x in prefixes if not x.startswith("-")]
excludes = [x[1:] for x in prefixes if x.startswith("-")]
file_line_cov = read_lcov()
after_excludes = {}
for tn in file_line_cov:
after_excludes[tn] = {f: file_line_cov[tn][f] for f in file_line_cov[tn] if not is_excluded(f, excludes)}
filtered = after_excludes # by default include everything
if len(includes) > 0: # but if there are explicit includes then only include those
filtered = {}
for tn in after_excludes:
filtered[tn] = {f: after_excludes[tn][f] for f in after_excludes[tn] if is_included(f, includes)}
write_lcov(filtered)
if __name__ == '__main__':
main()