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