1#!/usr/bin/env python3
2
3import os, glob, json
4from . import settings
5
6class ExclusionFileListError(Exception):
7    pass
8
9
10def cppcheck_exclusion_file_list(input_file):
11    ret = []
12    excl_list = load_exclusion_file_list(input_file, "xen-analysis")
13
14    for entry in excl_list:
15        # Prepending * to the relative path to match every path where the Xen
16        # codebase could be
17        ret.append("*" + entry[0])
18
19    return ret
20
21
22# Reads the exclusion file list and returns an array containing a set where the
23# first entry is what was listed in the exclusion list file, and the second
24# entry is the absolute path of the first entry.
25# If the first entry contained a wildcard '*', the second entry will have an
26# array of the solved absolute path for that entry.
27# Returns [('path',[path,path,...]), ('path',[path,path,...]), ...]
28def load_exclusion_file_list(input_file, checker=""):
29    ret = []
30    try:
31        with open(input_file, "rt") as handle:
32            content = json.load(handle)
33            entries = content['content']
34    except json.JSONDecodeError as e:
35        raise ExclusionFileListError(
36                "JSON decoding error in file {}: {}".format(input_file, e)
37        )
38    except KeyError:
39        raise ExclusionFileListError(
40            "Malformed JSON file: content field not found!"
41        )
42    except Exception as e:
43        raise ExclusionFileListError(
44                "Can't open file {}: {}".format(input_file, e)
45        )
46
47    for entry in entries:
48        try:
49            path = entry['rel_path']
50        except KeyError:
51            raise ExclusionFileListError(
52                "Malformed JSON entry: rel_path field not found!"
53            )
54        # Check the checker field
55        try:
56            entry_checkers = entry['checkers']
57        except KeyError:
58            # If the field doesn't exists, assume that this entry is for every
59            # checker
60            entry_checkers = checker
61
62        # Check if this entry is for the selected checker
63        if checker not in entry_checkers:
64            continue
65
66        abs_path = settings.xen_dir + "/" + path
67        check_path = [abs_path]
68
69        # If the path contains wildcards, solve them
70        if '*' in abs_path:
71            check_path = glob.glob(abs_path)
72
73        # Check that the path exists
74        for filepath_object in check_path:
75            if not os.path.exists(filepath_object):
76                raise ExclusionFileListError(
77                    "Malformed path: {} refers to {} that does not exists"
78                    .format(path, filepath_object)
79                )
80
81        ret.append((path, check_path))
82
83    return ret
84