mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 01:34:38 +00:00 
			
		
		
		
	Fix some issues caught by check_stdlib_usage.py
This commit is contained in:
		
							
								
								
									
										260
									
								
								build-scripts/check_stdlib_usage.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										260
									
								
								build-scripts/check_stdlib_usage.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
#
 | 
			
		||||
#  Simple DirectMedia Layer
 | 
			
		||||
#  Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
 | 
			
		||||
#
 | 
			
		||||
#  This software is provided 'as-is', without any express or implied
 | 
			
		||||
#  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
#  arising from the use of this software.
 | 
			
		||||
#
 | 
			
		||||
#  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
#  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
#  freely, subject to the following restrictions:
 | 
			
		||||
#
 | 
			
		||||
#  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
#     claim that you wrote the original software. If you use this software
 | 
			
		||||
#     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
#     appreciated but is not required.
 | 
			
		||||
#  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
#     misrepresented as being the original software.
 | 
			
		||||
#  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
#
 | 
			
		||||
# This script detects use of stdlib function in SDL code
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
import os
 | 
			
		||||
import pathlib
 | 
			
		||||
import re
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
SDL_ROOT = pathlib.Path(__file__).resolve().parents[1]
 | 
			
		||||
 | 
			
		||||
words = [
 | 
			
		||||
    'abs',
 | 
			
		||||
    'acos',
 | 
			
		||||
    'acosf',
 | 
			
		||||
    'asin',
 | 
			
		||||
    'asinf',
 | 
			
		||||
    'asprintf',
 | 
			
		||||
    'atan',
 | 
			
		||||
    'atan2',
 | 
			
		||||
    'atan2f',
 | 
			
		||||
    'atanf',
 | 
			
		||||
    'atof',
 | 
			
		||||
    'atoi',
 | 
			
		||||
    'calloc',
 | 
			
		||||
    'ceil',
 | 
			
		||||
    'ceilf',
 | 
			
		||||
    'copysign',
 | 
			
		||||
    'copysignf',
 | 
			
		||||
    'cos',
 | 
			
		||||
    'cosf',
 | 
			
		||||
    'crc32',
 | 
			
		||||
    'exp',
 | 
			
		||||
    'expf',
 | 
			
		||||
    'fabs',
 | 
			
		||||
    'fabsf',
 | 
			
		||||
    'floor',
 | 
			
		||||
    'floorf',
 | 
			
		||||
    'fmod',
 | 
			
		||||
    'fmodf',
 | 
			
		||||
    'free',
 | 
			
		||||
    'getenv',
 | 
			
		||||
    'isalnum',
 | 
			
		||||
    'isalpha',
 | 
			
		||||
    'isblank',
 | 
			
		||||
    'iscntrl',
 | 
			
		||||
    'isdigit',
 | 
			
		||||
    'isgraph',
 | 
			
		||||
    'islower',
 | 
			
		||||
    'isprint',
 | 
			
		||||
    'ispunct',
 | 
			
		||||
    'isspace',
 | 
			
		||||
    'isupper',
 | 
			
		||||
    'isxdigit',
 | 
			
		||||
    'itoa',
 | 
			
		||||
    'lltoa',
 | 
			
		||||
    'log10',
 | 
			
		||||
    'log10f',
 | 
			
		||||
    'logf',
 | 
			
		||||
    'lround',
 | 
			
		||||
    'lroundf',
 | 
			
		||||
    'ltoa',
 | 
			
		||||
    'malloc',
 | 
			
		||||
    'memalign',
 | 
			
		||||
    'memcmp',
 | 
			
		||||
    'memcpy',
 | 
			
		||||
    'memcpy4',
 | 
			
		||||
    'memmove',
 | 
			
		||||
    'memset',
 | 
			
		||||
    'pow',
 | 
			
		||||
    'powf',
 | 
			
		||||
    'qsort',
 | 
			
		||||
    'realloc',
 | 
			
		||||
    'round',
 | 
			
		||||
    'roundf',
 | 
			
		||||
    'scalbn',
 | 
			
		||||
    'scalbnf',
 | 
			
		||||
    'setenv',
 | 
			
		||||
    'sin',
 | 
			
		||||
    'sinf',
 | 
			
		||||
    'snprintf',
 | 
			
		||||
    'sqrt',
 | 
			
		||||
    'sqrtf',
 | 
			
		||||
    'sscanf',
 | 
			
		||||
    'strcasecmp',
 | 
			
		||||
    'strchr',
 | 
			
		||||
    'strcmp',
 | 
			
		||||
    'strdup',
 | 
			
		||||
    'strlcat',
 | 
			
		||||
    'strlcpy',
 | 
			
		||||
    'strlen',
 | 
			
		||||
    'strlwr',
 | 
			
		||||
    'strncasecmp',
 | 
			
		||||
    'strncmp',
 | 
			
		||||
    'strrchr',
 | 
			
		||||
    'strrev',
 | 
			
		||||
    'strstr',
 | 
			
		||||
    'strtod',
 | 
			
		||||
    'strtokr',
 | 
			
		||||
    'strtol',
 | 
			
		||||
    'strtoll',
 | 
			
		||||
    'strtoul',
 | 
			
		||||
    'strupr',
 | 
			
		||||
    'tan',
 | 
			
		||||
    'tanf',
 | 
			
		||||
    'tolower',
 | 
			
		||||
    'toupper',
 | 
			
		||||
    'trunc',
 | 
			
		||||
    'truncf',
 | 
			
		||||
    'uitoa',
 | 
			
		||||
    'ulltoa',
 | 
			
		||||
    'ultoa',
 | 
			
		||||
    'utf8strlcpy',
 | 
			
		||||
    'utf8strlen',
 | 
			
		||||
    'vasprintf',
 | 
			
		||||
    'vsnprintf',
 | 
			
		||||
    'vsscanf',
 | 
			
		||||
    'wcscasecmp',
 | 
			
		||||
    'wcscmp',
 | 
			
		||||
    'wcsdup',
 | 
			
		||||
    'wcslcat',
 | 
			
		||||
    'wcslcpy',
 | 
			
		||||
    'wcslen',
 | 
			
		||||
    'wcsncasecmp',
 | 
			
		||||
    'wcsncmp',
 | 
			
		||||
    'wcsstr' ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
reg_comment_remove_content = re.compile('\/\*.*\*/')
 | 
			
		||||
reg_comment_remove_content2 = re.compile('".*"')
 | 
			
		||||
reg_comment_remove_content3 = re.compile(':strlen')
 | 
			
		||||
reg_comment_remove_content4 = re.compile('->free')
 | 
			
		||||
 | 
			
		||||
def find_symbols_in_file(file, regex):
 | 
			
		||||
 | 
			
		||||
    allowed_extensions = [ ".c", ".cpp", ".m", ".h",  ".hpp", ".cc" ]
 | 
			
		||||
 | 
			
		||||
    excluded_paths = [
 | 
			
		||||
        "src/stdlib",
 | 
			
		||||
        "src/libm",
 | 
			
		||||
        "src/hidapi",
 | 
			
		||||
        "src/video/khronos",
 | 
			
		||||
        "include/SDL3",
 | 
			
		||||
        "build-scripts/gen_audio_resampler_filter.c",
 | 
			
		||||
        "build-scripts/gen_audio_channel_conversion.c" ]
 | 
			
		||||
 | 
			
		||||
    filename = pathlib.Path(file)
 | 
			
		||||
 | 
			
		||||
    for ep in excluded_paths:
 | 
			
		||||
        if ep in filename.as_posix():
 | 
			
		||||
            # skip
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
    if filename.suffix not in allowed_extensions:
 | 
			
		||||
        # skip
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # print("Parse %s" % file)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        with file.open("r", encoding="UTF-8", newline="") as rfp:
 | 
			
		||||
            parsing_comment = False
 | 
			
		||||
            for l in rfp:
 | 
			
		||||
                l = l.strip()
 | 
			
		||||
 | 
			
		||||
                # Get the comment block /* ... */ across several lines
 | 
			
		||||
                match_start = "/*" in l
 | 
			
		||||
                match_end = "*/" in l
 | 
			
		||||
                if match_start and match_end:
 | 
			
		||||
                    continue
 | 
			
		||||
                if match_start:
 | 
			
		||||
                    parsing_comment = True
 | 
			
		||||
                    continue
 | 
			
		||||
                if match_end:
 | 
			
		||||
                    parsing_comment = False
 | 
			
		||||
                    continue
 | 
			
		||||
                if parsing_comment:
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                if regex.match(l):
 | 
			
		||||
 | 
			
		||||
                    # free() allowed here
 | 
			
		||||
                    if "This should NOT be SDL_" in l:
 | 
			
		||||
                        continue
 | 
			
		||||
 | 
			
		||||
                    # double check
 | 
			
		||||
                    # Remove one line comment /* ... */
 | 
			
		||||
                    # eg: extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */);
 | 
			
		||||
                    l = reg_comment_remove_content.sub('', l)
 | 
			
		||||
 | 
			
		||||
                    # Remove strings " ... "
 | 
			
		||||
                    l = reg_comment_remove_content2.sub('', l)
 | 
			
		||||
 | 
			
		||||
                    # :strlen
 | 
			
		||||
                    l = reg_comment_remove_content3.sub('', l)
 | 
			
		||||
 | 
			
		||||
                    # ->free
 | 
			
		||||
                    l = reg_comment_remove_content4.sub('', l)
 | 
			
		||||
 | 
			
		||||
                    if regex.match(l):
 | 
			
		||||
                        print("File %s" % filename)
 | 
			
		||||
                        print("        %s" % l)
 | 
			
		||||
                        print("")
 | 
			
		||||
 | 
			
		||||
    except UnicodeDecodeError:
 | 
			
		||||
        print("%s is not text, skipping" % file)
 | 
			
		||||
    except Exception as err:
 | 
			
		||||
        print("%s" % err)
 | 
			
		||||
 | 
			
		||||
def find_symbols_in_dir(path, regex):
 | 
			
		||||
 | 
			
		||||
    for entry in path.glob("*"):
 | 
			
		||||
        if entry.is_dir():
 | 
			
		||||
            find_symbols_in_dir(entry, regex)
 | 
			
		||||
        else:
 | 
			
		||||
            find_symbols_in_file(entry, regex)
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    str = ".*\\b("
 | 
			
		||||
    for w in words:
 | 
			
		||||
        str += w + "|"
 | 
			
		||||
    str = str[:-1]
 | 
			
		||||
    str += ")\("
 | 
			
		||||
    regex = re.compile(str)
 | 
			
		||||
    find_symbols_in_dir(SDL_ROOT, regex)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
 | 
			
		||||
    parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        main()
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(e)
 | 
			
		||||
        exit(-1)
 | 
			
		||||
 | 
			
		||||
    exit(0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user