diff --git a/include/SDL3/SDL_filesystem.h b/include/SDL3/SDL_filesystem.h index 40df39b0da..30bfea0fca 100644 --- a/include/SDL3/SDL_filesystem.h +++ b/include/SDL3/SDL_filesystem.h @@ -264,11 +264,42 @@ typedef Uint32 SDL_GlobFlags; */ extern SDL_DECLSPEC bool SDLCALL SDL_CreateDirectory(const char *path); -/* Callback for directory enumeration. Return 1 to keep enumerating, - 0 to stop enumerating (no error), -1 to stop enumerating and - report an error. `dirname` is the directory being enumerated, - `fname` is the enumerated entry. */ -typedef int (SDLCALL *SDL_EnumerateDirectoryCallback)(void *userdata, const char *dirname, const char *fname); +/** + * Possible results from an enumeration callback. + * + * \since This enum is available since SDL 3.0.0. + * + * \sa SDL_EnumerateDirectoryCallback + */ +typedef enum SDL_EnumerationResult +{ + SDL_ENUM_CONTINUE, /**< Value that requests that enumeration continue. */ + SDL_ENUM_SUCCESS, /**< Value that requests that enumeration stop, successfully. */ + SDL_ENUM_FAILURE /**< Value that requests that enumeration stop, as a failure. */ +} SDL_EnumerationResult; + +/** + * Callback for directory enumeration. + * + * Enumeration of directory entries will continue until either all entries + * have been provided to the callback, or the callback has requested a stop + * through its return value. + * + * Returning SDL_ENUM_CONTINUE will let enumeration proceed, calling the + * callback with further entries. SDL_ENUM_SUCCESS and SDL_ENUM_FAILURE will + * terminate the enumeration early, and dictate the return value of the + * enumeration function itself. + * + * \param userdata an app-controlled pointer that is passed to the callback. + * \param dirname the directory that is being enumerated. + * \param fname the next entry in the enumeration. + * \returns how the enumeration should proceed. + * + * \since This datatype is available since SDL 3.0.0. + * + * \sa SDL_EnumerateDirectory + */ +typedef SDL_EnumerationResult (SDLCALL *SDL_EnumerateDirectoryCallback)(void *userdata, const char *dirname, const char *fname); /** * Enumerate a directory through a callback function. diff --git a/src/filesystem/SDL_filesystem.c b/src/filesystem/SDL_filesystem.c index 05f184d359..2f2b66c94a 100644 --- a/src/filesystem/SDL_filesystem.c +++ b/src/filesystem/SDL_filesystem.c @@ -290,7 +290,7 @@ typedef struct GlobDirCallbackData SDL_IOStream *string_stream; } GlobDirCallbackData; -static int SDLCALL GlobDirectoryCallback(void *userdata, const char *dirname, const char *fname) +static SDL_EnumerationResult SDLCALL GlobDirectoryCallback(void *userdata, const char *dirname, const char *fname) { SDL_assert(userdata != NULL); SDL_assert(dirname != NULL); @@ -305,14 +305,14 @@ static int SDLCALL GlobDirectoryCallback(void *userdata, const char *dirname, co char *fullpath = NULL; if (SDL_asprintf(&fullpath, "%s/%s", dirname, fname) < 0) { - return -1; + return SDL_ENUM_FAILURE; } char *folded = NULL; if (data->flags & SDL_GLOB_CASEINSENSITIVE) { folded = CaseFoldUtf8String(fullpath); if (!folded) { - return -1; + return SDL_ENUM_FAILURE; } } @@ -326,18 +326,18 @@ static int SDLCALL GlobDirectoryCallback(void *userdata, const char *dirname, co const size_t slen = SDL_strlen(subpath) + 1; if (SDL_WriteIO(data->string_stream, subpath, slen) != slen) { SDL_free(fullpath); - return -1; // stop enumerating, return failure to the app. + return SDL_ENUM_FAILURE; // stop enumerating, return failure to the app. } data->num_entries++; } - int result = 1; // keep enumerating by default. + SDL_EnumerationResult result = SDL_ENUM_CONTINUE; // keep enumerating by default. if (matched_to_dir) { SDL_PathInfo info; if (data->getpathinfo(fullpath, &info, data->fsuserdata) && (info.type == SDL_PATHTYPE_DIRECTORY)) { //SDL_Log("GlobDirectoryCallback: Descending into subdir '%s'", fname); if (!data->enumerator(fullpath, GlobDirectoryCallback, data, data->fsuserdata)) { - result = -1; + result = SDL_ENUM_FAILURE; } } } diff --git a/src/filesystem/posix/SDL_sysfsops.c b/src/filesystem/posix/SDL_sysfsops.c index 5b199c7f84..36f539257d 100644 --- a/src/filesystem/posix/SDL_sysfsops.c +++ b/src/filesystem/posix/SDL_sysfsops.c @@ -36,7 +36,7 @@ bool SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_EnumerateDirectoryCallback cb, void *userdata) { - int result = 1; + SDL_EnumerationResult result = SDL_ENUM_CONTINUE; DIR *dir = opendir(path); if (!dir) { @@ -45,7 +45,7 @@ bool SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_Enume } struct dirent *ent; - while ((result == 1) && ((ent = readdir(dir)) != NULL)) + while ((result == SDL_ENUM_CONTINUE) && ((ent = readdir(dir)) != NULL)) { const char *name = ent->d_name; if ((SDL_strcmp(name, ".") == 0) || (SDL_strcmp(name, "..") == 0)) { @@ -56,7 +56,7 @@ bool SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_Enume closedir(dir); - return (result >= 0); + return (result != SDL_ENUM_FAILURE); } bool SDL_SYS_RemovePath(const char *path) diff --git a/src/filesystem/windows/SDL_sysfsops.c b/src/filesystem/windows/SDL_sysfsops.c index b782b660d0..a8f3759ee6 100644 --- a/src/filesystem/windows/SDL_sysfsops.c +++ b/src/filesystem/windows/SDL_sysfsops.c @@ -31,11 +31,11 @@ bool SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_EnumerateDirectoryCallback cb, void *userdata) { - int result = 1; + SDL_EnumerationResult result = SDL_ENUM_CONTINUE; if (*path == '\0') { // if empty (completely at the root), we need to enumerate drive letters. const DWORD drives = GetLogicalDrives(); char name[3] = { 0, ':', '\0' }; - for (int i = 'A'; (result == 1) && (i <= 'Z'); i++) { + for (int i = 'A'; (result == SDL_ENUM_CONTINUE) && (i <= 'Z'); i++) { if (drives & (1 << (i - 'A'))) { name[0] = (char) i; result = cb(userdata, dirname, name); @@ -78,17 +78,17 @@ bool SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_Enume char *utf8fn = WIN_StringToUTF8W(fn); if (!utf8fn) { - result = -1; + result = SDL_ENUM_FAILURE; } else { result = cb(userdata, dirname, utf8fn); SDL_free(utf8fn); } - } while ((result == 1) && (FindNextFileW(dir, &entw) != 0)); + } while ((result == SDL_ENUM_CONTINUE) && (FindNextFileW(dir, &entw) != 0)); FindClose(dir); } - return (result >= 0); + return (result != SDL_ENUM_FAILURE); } bool SDL_SYS_RemovePath(const char *path) diff --git a/test/testfilesystem.c b/test/testfilesystem.c index 848d6bbe1c..3a068a0f2b 100644 --- a/test/testfilesystem.c +++ b/test/testfilesystem.c @@ -15,7 +15,7 @@ #include #include -static int SDLCALL enum_callback(void *userdata, const char *origdir, const char *fname) +static SDL_EnumerationResult SDLCALL enum_callback(void *userdata, const char *origdir, const char *fname) { SDL_PathInfo info; char *fullpath = NULL; @@ -29,7 +29,7 @@ static int SDLCALL enum_callback(void *userdata, const char *origdir, const char if (SDL_asprintf(&fullpath, "%s%s%s", origdir, *origdir ? pathsep : "", fname) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); - return -1; + return SDL_ENUM_FAILURE; } if (!SDL_GetPathInfo(fullpath, &info)) { @@ -54,7 +54,7 @@ static int SDLCALL enum_callback(void *userdata, const char *origdir, const char } SDL_free(fullpath); - return 1; /* keep going */ + return SDL_ENUM_CONTINUE; /* keep going */ }