#!/usr/bin/env python """ Summarize the information in the given coverage files. Emits the number of rules covered or the percentage of rules covered depending on whether --num-rules has been used to specify the total number of rules. """ from __future__ import print_function import argparse import struct class FileFormatError(Exception): pass def backend_int_pair(s): backend, sep, value = s.partition("=") if sep is None: raise argparse.ArgumentTypeError("'=' missing, expected name=value") if not backend: raise argparse.ArgumentTypeError("Expected name=value") if not value: raise argparse.ArgumentTypeError("Expected name=value") return backend, int(value) def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("input", nargs="+") parser.add_argument( "--num-rules", type=backend_int_pair, action="append", metavar="BACKEND=NUM", help="Specify the number of rules for a backend", ) args = parser.parse_args() covered_rules = {} for input_filename in args.input: with open(input_filename, "rb") as input_fh: data = input_fh.read() pos = 0 while data: backend, _, data = data.partition("\0") pos += len(backend) pos += 1 if len(backend) == 0: raise FileFormatError() (backend,) = struct.unpack("%ds" % len(backend), backend) while data: if len(data) < 8: raise FileFormatError() (rule_id,) = struct.unpack("Q", data[:8]) pos += 8 data = data[8:] if rule_id == (2**64) - 1: break covered_rules[backend] = covered_rules.get(backend, {}) covered_rules[backend][rule_id] = ( covered_rules[backend].get(rule_id, 0) + 1 ) num_rules = dict(args.num_rules) for backend, rules_for_backend in covered_rules.items(): if backend in num_rules: print( "%s: %3.2f%% of rules covered" % (backend, float(len(rules_for_backend)) / num_rules[backend]) * 100 ) else: print("%s: %d rules covered" % (backend, len(rules_for_backend))) if __name__ == "__main__": main()