1#!/usr/bin/env python3
2#
3# Arm SCP/MCP Software
4# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
5#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8
9import re
10import sys
11import argparse
12from argparse import RawDescriptionHelpFormatter
13from collections import namedtuple
14
15"""
16Filters out cmock and cmsis from coverage report so that only actual SCP
17code is evaluated. A report can have their own filter by appending
18the 'regex_list'.
19"""
20
21default_regex = [re.compile(r"contrib/cmock/"),
22                 re.compile(r"contrib/cmsis/")]
23
24# Append specific files filter.
25regex_list = {
26    'scp_v2_fwk_test_coverage.info': [re.compile(r"framework/test/")],
27    'scp_v2_unit_test_coverage.info': [re.compile(r"contrib/cmock/"),
28                                       re.compile(r"module/.*/test"),
29                                       re.compile(r"unit_test/")],
30    'scp_v2_product_test_coverage.info': [re.compile(r"contrib/cmock/"),
31                                          re.compile(r"framework/"),
32                                          re.compile(r"product/.*/test"),
33                                          re.compile(r"unit_test/")],
34}
35
36STARTER = "SF:"
37ENDED = "end_of_record"
38
39
40def get_filtered_info(filename):
41    within = False
42    filter = False
43    dump_lines = []
44    regexes = regex_list.get(filename, default_regex)
45    out_filename = filename.replace('.info', '_filtered.info')
46
47    with open(out_filename, "w") as fd:
48        with open(filename, "r") as fd_in:
49            for line in fd_in.readlines():
50
51                if STARTER in line:
52                    within = True
53
54                    if any(regex.search(line) for regex in regexes):
55                        filter = True
56
57                if within or "TN:" in line:
58                    dump_lines.append(line)
59
60                if ENDED in line:
61                    if not filter:
62                        fd.writelines(dump_lines)
63
64                    dump_lines = []
65                    within = False
66                    filter = False
67    return True
68
69
70def parse_args(argv, prog_name):
71    parser = argparse.ArgumentParser(
72        prog=prog_name,
73        description='Filters out cmock and cmsis from coverage report\n'
74                    'To filter specific regex for a report, please append '
75                    'the regex list in this script.',
76        formatter_class=RawDescriptionHelpFormatter)
77
78    parser.add_argument('-f', '--filename', dest='filename', required=True,
79                        type=str, action='store', help=f'Required argument.\
80                        Filename of the coverage report to be filtered.')
81
82    return parser.parse_args(argv)
83
84
85def main(argv=[], prog_name=''):
86    args = parse_args(argv, prog_name)
87    return 0 if get_filtered_info(args.filename) else 1
88
89
90if __name__ == '__main__':
91    sys.exit(main(sys.argv[1:], sys.argv[0]))
92