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