#!/usr/bin/env python3 import argparse import json from collections import defaultdict def lines2phabricator(filename, lines): ret = "" numlines = 0 with open(filename) as f: for row in f: numlines += 1 for i in range(1, numlines + 1): if i not in lines: ret += "N" elif lines[i] == 0: ret += "U" else: ret += "C" return ret parser = argparse.ArgumentParser(description='Parse llvm-cov export data.') parser.add_argument('input', help='input file') parser.add_argument('coverage', help='coverage output file') parser.add_argument('summary', help='summary output file') parser.add_argument('files', nargs='+', help='files to process') args = parser.parse_args() # for specification of the format see: # https://github.com/llvm-mirror/llvm/blob/master/tools/llvm-cov/CoverageExporterJson.cpp data = json.load(open(args.input, "r")) totals = defaultdict(lambda: defaultdict(int)) sources = defaultdict(lambda: defaultdict(int)) for export in data["data"]: for cfile in export["files"]: for segment in cfile["segments"]: filename = cfile["filename"] if filename not in args.files: continue line, col, count, has_count, is_region_entry, is_gap_region = \ segment sources[filename][line] += count for function in export["functions"]: for region in function["regions"]: line_start, column_start, line_end, column_end, execution_count, \ file_id, expanded_file_id, kind = region filename = function["filenames"][file_id] if filename not in args.files: continue for i in range(line_start, line_end + 1): sources[filename][i] += execution_count for total, values in export["totals"].items(): for key, value in values.items(): totals[total][key] += value coverage = {} for filename, lines in sources.items(): path = "/".join(filename.split("/")[3:]) coverage[path] = lines2phabricator(filename, lines) with open(args.coverage, "w") as f: json.dump(coverage, f) summary = """
Coverage | Total |
---|---|
{name} | {covered} / {count} ({percent:.2%}) |