SDL

Форк
0
/
check_stdlib_usage.py 
261 строка · 5.8 Кб
1
#!/usr/bin/env python3
2
#
3
#  Simple DirectMedia Layer
4
#  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
5
#
6
#  This software is provided 'as-is', without any express or implied
7
#  warranty.  In no event will the authors be held liable for any damages
8
#  arising from the use of this software.
9
#
10
#  Permission is granted to anyone to use this software for any purpose,
11
#  including commercial applications, and to alter it and redistribute it
12
#  freely, subject to the following restrictions:
13
#
14
#  1. The origin of this software must not be misrepresented; you must not
15
#     claim that you wrote the original software. If you use this software
16
#     in a product, an acknowledgment in the product documentation would be
17
#     appreciated but is not required.
18
#  2. Altered source versions must be plainly marked as such, and must not be
19
#     misrepresented as being the original software.
20
#  3. This notice may not be removed or altered from any source distribution.
21
#
22
# This script detects use of stdlib function in SDL code
23

24
import argparse
25
import os
26
import pathlib
27
import re
28
import sys
29

30
SDL_ROOT = pathlib.Path(__file__).resolve().parents[1]
31

32
words = [
33
    'abs',
34
    'acos',
35
    'acosf',
36
    'asin',
37
    'asinf',
38
    'asprintf',
39
    'atan',
40
    'atan2',
41
    'atan2f',
42
    'atanf',
43
    'atof',
44
    'atoi',
45
    'bsearch',
46
    'calloc',
47
    'ceil',
48
    'ceilf',
49
    'copysign',
50
    'copysignf',
51
    'cos',
52
    'cosf',
53
    'crc32',
54
    'exp',
55
    'expf',
56
    'fabs',
57
    'fabsf',
58
    'floor',
59
    'floorf',
60
    'fmod',
61
    'fmodf',
62
    'free',
63
    'getenv',
64
    'isalnum',
65
    'isalpha',
66
    'isblank',
67
    'iscntrl',
68
    'isdigit',
69
    'isgraph',
70
    'islower',
71
    'isprint',
72
    'ispunct',
73
    'isspace',
74
    'isupper',
75
    'isxdigit',
76
    'itoa',
77
    'lltoa',
78
    'log10',
79
    'log10f',
80
    'logf',
81
    'lround',
82
    'lroundf',
83
    'ltoa',
84
    'malloc',
85
    'memalign',
86
    'memcmp',
87
    'memcpy',
88
    'memcpy4',
89
    'memmove',
90
    'memset',
91
    'pow',
92
    'powf',
93
    'qsort',
94
    'qsort_r',
95
    'qsort_s',
96
    'realloc',
97
    'round',
98
    'roundf',
99
    'scalbn',
100
    'scalbnf',
101
    'setenv',
102
    'sin',
103
    'sinf',
104
    'snprintf',
105
    'sqrt',
106
    'sqrtf',
107
    'sscanf',
108
    'strcasecmp',
109
    'strchr',
110
    'strcmp',
111
    'strdup',
112
    'strlcat',
113
    'strlcpy',
114
    'strlen',
115
    'strlwr',
116
    'strncasecmp',
117
    'strncmp',
118
    'strrchr',
119
    'strrev',
120
    'strstr',
121
    'strtod',
122
    'strtokr',
123
    'strtol',
124
    'strtoll',
125
    'strtoul',
126
    'strupr',
127
    'tan',
128
    'tanf',
129
    'tolower',
130
    'toupper',
131
    'trunc',
132
    'truncf',
133
    'uitoa',
134
    'ulltoa',
135
    'ultoa',
136
    'utf8strlcpy',
137
    'utf8strlen',
138
    'vasprintf',
139
    'vsnprintf',
140
    'vsscanf',
141
    'wcscasecmp',
142
    'wcscmp',
143
    'wcsdup',
144
    'wcslcat',
145
    'wcslcpy',
146
    'wcslen',
147
    'wcsncasecmp',
148
    'wcsncmp',
149
    'wcsstr' ]
150

151

152
reg_comment_remove_content = re.compile('\/\*.*\*/')
153
reg_comment_remove_content2 = re.compile('".*"')
154
reg_comment_remove_content3 = re.compile(':strlen')
155
reg_comment_remove_content4 = re.compile('->free')
156

157
def find_symbols_in_file(file, regex):
158

159
    allowed_extensions = [ ".c", ".cpp", ".m", ".h",  ".hpp", ".cc" ]
160

161
    excluded_paths = [
162
        "src/stdlib",
163
        "src/libm",
164
        "src/hidapi",
165
        "src/video/khronos",
166
        "include/SDL3",
167
        "build-scripts/gen_audio_resampler_filter.c",
168
        "build-scripts/gen_audio_channel_conversion.c" ]
169

170
    filename = pathlib.Path(file)
171

172
    for ep in excluded_paths:
173
        if ep in filename.as_posix():
174
            # skip
175
            return
176

177
    if filename.suffix not in allowed_extensions:
178
        # skip
179
        return
180

181
    # print("Parse %s" % file)
182

183
    try:
184
        with file.open("r", encoding="UTF-8", newline="") as rfp:
185
            parsing_comment = False
186
            for l in rfp:
187
                l = l.strip()
188

189
                # Get the comment block /* ... */ across several lines
190
                match_start = "/*" in l
191
                match_end = "*/" in l
192
                if match_start and match_end:
193
                    continue
194
                if match_start:
195
                    parsing_comment = True
196
                    continue
197
                if match_end:
198
                    parsing_comment = False
199
                    continue
200
                if parsing_comment:
201
                    continue
202

203
                if regex.match(l):
204

205
                    # free() allowed here
206
                    if "This should NOT be SDL_" in l:
207
                        continue
208

209
                    # double check
210
                    # Remove one line comment /* ... */
211
                    # eg: extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */);
212
                    l = reg_comment_remove_content.sub('', l)
213

214
                    # Remove strings " ... "
215
                    l = reg_comment_remove_content2.sub('', l)
216

217
                    # :strlen
218
                    l = reg_comment_remove_content3.sub('', l)
219

220
                    # ->free
221
                    l = reg_comment_remove_content4.sub('', l)
222

223
                    if regex.match(l):
224
                        print("File %s" % filename)
225
                        print("        %s" % l)
226
                        print("")
227

228
    except UnicodeDecodeError:
229
        print("%s is not text, skipping" % file)
230
    except Exception as err:
231
        print("%s" % err)
232

233
def find_symbols_in_dir(path, regex):
234

235
    for entry in path.glob("*"):
236
        if entry.is_dir():
237
            find_symbols_in_dir(entry, regex)
238
        else:
239
            find_symbols_in_file(entry, regex)
240

241
def main():
242
    str = ".*\\b("
243
    for w in words:
244
        str += w + "|"
245
    str = str[:-1]
246
    str += ")\("
247
    regex = re.compile(str)
248
    find_symbols_in_dir(SDL_ROOT, regex)
249

250
if __name__ == "__main__":
251

252
    parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
253
    args = parser.parse_args()
254

255
    try:
256
        main()
257
    except Exception as e:
258
        print(e)
259
        exit(-1)
260

261
    exit(0)
262

263

264

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.