From 5ebac8799f2b8f42c4e63272ca220b9c48ee4647 Mon Sep 17 00:00:00 2001 From: Catania Date: Mon, 19 Jan 2026 15:14:19 +0100 Subject: [PATCH] Added new file and directories filter tags --- src/rcore.c | 170 ++++++++-------------------------------------------- 1 file changed, 25 insertions(+), 145 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index b719c5fa0..08acd6874 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -267,9 +267,15 @@ #define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record #endif -#ifndef DIRECTORY_FILTER_TAG - #define DIRECTORY_FILTER_TAG "DIR" // Name tag used to request directory inclusion on directory scan -#endif // NOTE: Used in ScanDirectoryFiles(), ScanDirectoryFilesRecursively() and LoadDirectoryFilesEx() +#ifndef FILE_FILTER_TAG_ALL + #define FILE_FILTER_TAG_ALL "*.*" // Filter to include all file types and directories on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() +#ifndef FILE_FILTER_TAG_FILE_ONLY + #define FILE_FILTER_TAG_FILE_ONLY "FILES*" // Filter to include all file types on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() +#ifndef FILE_FILTER_TAG_DIR_ONLY + #define FILE_FILTER_TAG_DIR_ONLY "DIR*" // Filter to include directories on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() // Flags operation macros #define FLAG_SET(n, f) ((n) |= (f)) @@ -505,8 +511,7 @@ extern void ClosePlatform(void); // Close platform static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) static void SetupViewport(int width, int height); // Set viewport for a provided width and height -static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter, unsigned int fileCount); // Scan all files and directories in a base path -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *list, const char *filter, unsigned int fileCount); // Scan all files and directories recursively from a base path +static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter, unsigned int fileCount, bool scanSubdirs); // Scan all files and directories in a base path #if defined(SUPPORT_AUTOMATION_EVENTS) static void RecordAutomationEvent(void); // Record frame events (to internal events array) @@ -2753,31 +2758,7 @@ const char *GetApplicationDirectory(void) // No recursive scanning is done! FilePathList LoadDirectoryFiles(const char *dirPath) { - FilePathList files = { 0 }; - - if (DirectoryExists(dirPath)) // It's a directory - { - // SCAN 1: Count files - unsigned int fileCounter = GetDirectoryFileCount(dirPath); - - // Memory allocation for dirFileCount - files.paths = (char **)RL_CALLOC(fileCounter, sizeof(char *)); - for (unsigned int i = 0; i < fileCounter; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - - // SCAN 2: Read filepaths - // NOTE: Directory paths are also registered - ScanDirectoryFiles(dirPath, &files, NULL, fileCounter); - - // Security check: read files.count should match fileCounter - if (files.count != fileCounter) - { - TRACELOG(LOG_WARNING, "FILEIO: Read files count (%u) does not match capacity allocated (%u)", files.count, fileCounter); - files.count = fileCounter; // Avoid memory leak when unloading this FilePathList - } - } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... - - return files; + return LoadDirectoryFilesEx(dirPath, FILE_FILTER_TAG_ALL, false); } // Load directory filepaths with extension filtering and recursive directory scan @@ -2797,8 +2778,7 @@ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool // SCAN 2: Read filepaths // WARNING: basePath is always prepended to scanned paths - if (scanSubdirs) ScanDirectoryFilesRecursively(basePath, &files, filter, fileCounter); - else ScanDirectoryFiles(basePath, &files, filter, fileCounter); + ScanDirectoryFiles(basePath, &files, filter, fileCounter, scanSubdirs); // Security check: read files.count should match fileCounter if (files.count != fileCounter) @@ -2807,7 +2787,7 @@ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool files.count = fileCounter; // Avoid memory leak when unloading this FilePathList } } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... return files; } @@ -2977,43 +2957,10 @@ void UnloadDroppedFiles(FilePathList files) // Get the file count in a directory unsigned int GetDirectoryFileCount(const char *dirPath) { - unsigned int fileCounter = 0; - - static char path[MAX_FILEPATH_LENGTH] = { 0 }; - memset(path, 0, MAX_FILEPATH_LENGTH); - - struct dirent *entity; - DIR *dir = opendir(dirPath); - - if (dir != NULL) // It's a directory - { - while ((entity = readdir(dir)) != NULL) - { - // NOTE: We skip '.' (current dir) and '..' (parent dir) filepaths - if ((strcmp(entity->d_name, ".") != 0) && (strcmp(entity->d_name, "..") != 0)) - { - // Construct new path from our base path - #if defined(_WIN32) - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", dirPath, entity->d_name); - #else - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", dirPath, entity->d_name); - #endif - // Don't add to count if path too long - if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) - { - TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, dirPath); - } - else fileCounter++; - } - } - - closedir(dir); - } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... - return fileCounter; + return GetDirectoryFileCountEx(dirPath, FILE_FILTER_TAG_ALL, false); } -// Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result +// Get the file count in a directory with extension filtering and recursive directory scan. Use 'FILE_FILTER_TAG_DIR_ONLY' in the filter string to include directories in the result unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, bool scanSubdirs) { unsigned int fileCounter = 0; @@ -3045,17 +2992,18 @@ unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, b } else if (IsPathFile(path)) { - if (filter == NULL || IsFileExtension(path, filter)) fileCounter++; + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) fileCounter++; } else { - if ((filter != NULL) && (strstr(filter, DIRECTORY_FILTER_TAG) != NULL)) fileCounter++; + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || (strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL))) fileCounter++; if (scanSubdirs) fileCounter += GetDirectoryFileCountEx(path, filter, scanSubdirs); } } } } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... return fileCounter; } @@ -4322,68 +4270,7 @@ void SetupViewport(int width, int height) // Scan all files and directories in a base path // WARNING: files.paths[] must be previously allocated and // contain enough space to store all required paths -static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter, unsigned int fileCount) -{ - static char path[MAX_FILEPATH_LENGTH] = { 0 }; - memset(path, 0, MAX_FILEPATH_LENGTH); - - struct dirent *dp = NULL; - DIR *dir = opendir(basePath); - - if (dir != NULL) - { - while (((dp = readdir(dir)) != NULL) && (files->count < fileCount)) - { - if ((strcmp(dp->d_name, ".") != 0) && - (strcmp(dp->d_name, "..") != 0)) - { - // Construct new path from our base path - #if defined(_WIN32) - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, dp->d_name); - #else - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, dp->d_name); - #endif - - if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) - { - TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, basePath); - } - else if (filter != NULL) - { - if (IsPathFile(path)) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else - { - if (strstr(filter, DIRECTORY_FILTER_TAG) != NULL) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - else - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - - closedir(dir); - } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); -} - -// Scan all files and directories recursively from a base path -// WARNING: files.paths[] must be previously allocated and -// contain enough space to store all required paths -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter, unsigned int fileCount) +static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter, unsigned int fileCount, bool scanSubdirs) { // WARNING: Path can not be static or it will be reused between recursive function calls! char path[MAX_FILEPATH_LENGTH] = { 0 }; @@ -4411,15 +4298,8 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi } else if (IsPathFile(path)) { - if (filter != NULL) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; @@ -4427,20 +4307,20 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi } else { - if ((filter != NULL) && (strstr(filter, DIRECTORY_FILTER_TAG) != NULL)) + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL))) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } - ScanDirectoryFilesRecursively(path, files, filter, fileCount); + if (scanSubdirs) ScanDirectoryFiles(path, files, filter, fileCount, scanSubdirs); } } } closedir(dir); } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... } #if defined(SUPPORT_AUTOMATION_EVENTS)