summaryrefslogtreecommitdiff
path: root/util/find_non_exec_lines.py
blob: e88d3f61ff274692c6fb26d65095f7ca25fcaf18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env python3
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Read lcov files, and find lines that are probably not executable.

Example run:
zmake build --coverage -a && \
./util/find_non_exec_lines.py build/zephyr/all_builds.info && \
echo SUCCESS
"""

import re
import sys


BAD_COVERAGE = re.compile(r"^$|\*/\s*$")


def main() -> int:
    """Read lcov files, and find lines that are probably not executable."""
    exit_code = 0
    for input_file in sys.argv:
        with open(input_file, encoding="utf-8") as lcov:
            active_file = None
            active_line = 0
            active_name = ""
            for line in lcov:
                line = line.strip()
                if line.startswith("SF:"):
                    if active_file:
                        active_file.close()
                        active_file = None
                    active_line = 0
                    active_name = line[3:]
                    # There are several files in zephyr that have odd coverage
                    # but it seems consistent.
                    if not "src/third_party/zephyr" in active_name:
                        active_file = open(  # pylint: disable=R1732
                            active_name, encoding="utf-8"
                        )
                if active_file and line.startswith("DA:"):
                    target_line = int(line[3:].split(",", 1)[0])
                    target = "NO SUCH LINE\n"
                    while target and target_line > active_line:
                        target = active_file.readline()
                        active_line += 1
                    if target and target_line == active_line:
                        target = target.strip()
                        if BAD_COVERAGE.match(target):
                            print(f"{active_name}:{active_line}={target}")
                            exit_code = 1
            if active_file:
                active_file.close()
                active_file = None

    return exit_code


if __name__ == "__main__":
    sys.exit(main())  # next section explains the use of sys.exit