958bc870b3
* GCC_VERSION=10.2.0 * BINUTILS_VERSION=2.35.1 * GDB_VERSION=10.1 (except centos-7 8.3) * CMAKE_VERSION=3.18.4 * CPPCHECK_VERSION=2.2 * LLVM_VERSION=11.0.0 * SWIG_VERSION=4.0.2
82 lines
2.6 KiB
Python
Executable File
82 lines
2.6 KiB
Python
Executable File
#!/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 = """<!DOCTYPE html>
|
|
<h1>Code coverage</h1>
|
|
<table>
|
|
<tr><th>Coverage</th><th>Total</th></tr>
|
|
"""
|
|
ROW = "<tr><td>{name}</td><td>{covered} / {count} ({percent:.2%})</td></tr>\n"
|
|
for what in ["functions", "instantiations", "lines", "regions"]:
|
|
now = totals[what]
|
|
now["percent"] = now["covered"] / now["count"]
|
|
summary += ROW.format(**dict(totals[what], name=what.capitalize()))
|
|
summary += "</table>\n"
|
|
|
|
with open(args.summary, "w") as f:
|
|
f.write(summary)
|