1#!/usr/bin/env python 2""" 3Summarize the information in the given coverage files. 4 5Emits the number of rules covered or the percentage of rules covered depending 6on whether --num-rules has been used to specify the total number of rules. 7""" 8 9import argparse 10import struct 11 12class FileFormatError(Exception): 13 pass 14 15def backend_int_pair(s): 16 backend, sep, value = s.partition('=') 17 if (sep is None): 18 raise argparse.ArgumentTypeError("'=' missing, expected name=value") 19 if (not backend): 20 raise argparse.ArgumentTypeError("Expected name=value") 21 if (not value): 22 raise argparse.ArgumentTypeError("Expected name=value") 23 return backend, int(value) 24 25def main(): 26 parser = argparse.ArgumentParser(description=__doc__) 27 parser.add_argument('input', nargs='+') 28 parser.add_argument('--num-rules', type=backend_int_pair, action='append', 29 metavar='BACKEND=NUM', 30 help='Specify the number of rules for a backend') 31 args = parser.parse_args() 32 33 covered_rules = {} 34 35 for input_filename in args.input: 36 with open(input_filename, 'rb') as input_fh: 37 data = input_fh.read() 38 pos = 0 39 while data: 40 backend, _, data = data.partition('\0') 41 pos += len(backend) 42 pos += 1 43 44 if len(backend) == 0: 45 raise FileFormatError() 46 backend, = struct.unpack("%ds" % len(backend), backend) 47 48 while data: 49 if len(data) < 8: 50 raise FileFormatError() 51 rule_id, = struct.unpack("Q", data[:8]) 52 pos += 8 53 data = data[8:] 54 if rule_id == (2 ** 64) - 1: 55 break 56 covered_rules[backend] = covered_rules.get(backend, {}) 57 covered_rules[backend][rule_id] = covered_rules[backend].get(rule_id, 0) + 1 58 59 num_rules = dict(args.num_rules) 60 for backend, rules_for_backend in covered_rules.items(): 61 if backend in num_rules: 62 print "%s: %3.2f%% of rules covered" % (backend, (float(len(rules_for_backend.keys())) / num_rules[backend]) * 100) 63 else: 64 print "%s: %d rules covered" % (backend, len(rules_for_backend.keys())) 65 66if __name__ == '__main__': 67 main() 68