1#!/usr/bin/env python3
2#
3# Arm SCP/MCP Software
4# Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
5#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8
9"""
10    Check for usage of banned API (banned_api.lst).
11"""
12
13import argparse
14import os
15import re
16import shutil
17import subprocess
18import sys
19import tempfile
20import fnmatch
21
22BANNED_LIST = './tools/banned_api.lst'
23BANNED_API = list()
24
25#
26# Directories to exclude
27#
28EXCLUDE_DIRECTORIES = [
29    '.git',
30    'build',
31    'tools',
32    'contrib/cmsis/git',
33    "contrib/run-clang-format/git",
34    'product/rcar/src/CMSIS-FreeRTOS',
35]
36
37#
38# Exclude patterns (applied to files only)
39#
40EXCLUDE = [
41    '*.html',
42    '*.xml',
43    '*.css',
44    '*.gif',
45    '*.dat',
46    '*.pyc',
47    '*.jar',
48    '*.md',
49    '*.swp',
50    '*.a',
51    '*.pdf',
52]
53
54#
55# File types to check
56#
57FILE_TYPES = [
58    '*.c',
59    '*.h',
60]
61
62
63def is_valid_type(filename):
64    for file_type in FILE_TYPES:
65        if fnmatch.fnmatch(filename, file_type):
66            return True
67
68    return False
69
70
71def main(argv=[], prog_name=''):
72    print('Checking for usage of banned APIs...')
73
74    illegal_use = 0
75
76    with open(BANNED_LIST) as file:
77        for fname in file:
78            if fname[0] == '#':
79                continue
80            BANNED_API.append(fname.rstrip())
81
82        print("\tBanned API list: {}".format(BANNED_API))
83
84    cwd = os.getcwd()
85
86    for i, directory in enumerate(EXCLUDE_DIRECTORIES):
87        EXCLUDE_DIRECTORIES[i] = os.path.abspath(directory)
88        print("\tAdding to the exclude list: {}"
89              .format(EXCLUDE_DIRECTORIES[i]))
90
91    for root, dirs, files in os.walk(cwd, topdown=True):
92        #
93        # Exclude directories based on the EXCLUDE_DIRECTORIES pattern list
94        #
95        dirs[:] = [d for d in dirs
96                   if os.path.join(root, d) not in EXCLUDE_DIRECTORIES]
97
98        #
99        # Exclude files based on the EXCLUDE pattern list
100        #
101        matches = list()
102        for filename in files:
103            for file_pattern in EXCLUDE:
104                if fnmatch.fnmatch(filename, file_pattern):
105                    matches.append(filename)
106                    break
107
108        for match in matches:
109            files.remove(match)
110
111        #
112        # Check files
113        #
114        for filename in files:
115            path = os.path.join(root, filename)
116            content = ''
117            with open(path, encoding="utf-8") as file:
118                for line, string in enumerate(file):
119                    for fname in BANNED_API:
120                        if fname in string:
121                            print("{}:{}:{}".format(path, line + 1, fname),
122                                  file=sys.stderr)
123
124
125if __name__ == '__main__':
126    sys.exit(main(sys.argv[1:], sys.argv[0]))
127