parent
810656962c
commit
764207d873
|
@ -272,7 +272,11 @@ extern DECLSPEC int SDLCALL SDL_CreateDirectory(const char *path);
|
|||
typedef int (SDLCALL *SDL_EnumerateDirectoryCallback)(void *userdata, const char *dirname, const char *fname);
|
||||
|
||||
/**
|
||||
* Enumerate a directory.
|
||||
* Enumerate a directory through a callback function.
|
||||
*
|
||||
* This function provides every directory entry through an app-provided
|
||||
* callback, called once for each directory entry, until all results have
|
||||
* been provided or the callback returns <= 0.
|
||||
*
|
||||
* \param path the path of the directory to enumerate
|
||||
* \param callback a function that is called for each entry in the directory
|
||||
|
@ -320,6 +324,42 @@ extern DECLSPEC int SDLCALL SDL_RenamePath(const char *oldpath, const char *newp
|
|||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetPathInfo(const char *path, SDL_PathInfo *info);
|
||||
|
||||
|
||||
#define SDL_GLOBDIR_CASEINSENSITIVE (1 << 0)
|
||||
|
||||
/**
|
||||
* Enumerate a directory tree, filtered by pattern, and return a list.
|
||||
*
|
||||
* Files are filtered out if they don't match the string in `pattern`, which
|
||||
* may contain wildcard characters '*' (match everything) and '?' (match one
|
||||
* character). If pattern is NULL, no filtering is done and all results are
|
||||
* returned. Subdirectories are permitted, and are specified with a path
|
||||
* separator of '/'. Wildcard characters '*' and '?' never match a path
|
||||
* separator.
|
||||
*
|
||||
* `flags` may be set to SDL_GLOBDIR_CASEINSENSITIVE to make the pattern
|
||||
* matching case-insensitive.
|
||||
*
|
||||
* The returned array is always NULL-terminated, for your iterating
|
||||
* convenience, but if `count` is non-NULL, on return it will contain the
|
||||
* number of items in the array, not counting the NULL terminator.
|
||||
*
|
||||
* You must free the returned pointer with SDL_free() when done with it.
|
||||
*
|
||||
* \param path the path of the directory to enumerate
|
||||
* \param pattern the pattern that files in the directory must match. Can be NULL.
|
||||
* \param flags `SDL_GLOBDIR_*` bitflags that affect this search.
|
||||
* \param count on return, will be set to the number of items in the returned array. Can be NULL.
|
||||
* \returns an array of strings on success or NULL on failure; call
|
||||
* SDL_GetError() for more information. The caller should pass the
|
||||
* returned pointer to SDL_free when done with it.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*/
|
||||
extern DECLSPEC char **SDLCALL SDL_GlobDirectory(const char *path, const char *pattern, Uint32 flags, int *count);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -268,7 +268,11 @@ extern DECLSPEC int SDL_WriteStorageFile(SDL_Storage *storage, const char *path,
|
|||
extern DECLSPEC int SDLCALL SDL_CreateStorageDirectory(SDL_Storage *storage, const char *path);
|
||||
|
||||
/**
|
||||
* Enumerate a directory in a storage container.
|
||||
* Enumerate a directory in a storage container through a callback function.
|
||||
*
|
||||
* This function provides every directory entry through an app-provided
|
||||
* callback, called once for each directory entry, until all results have
|
||||
* been provided or the callback returns <= 0.
|
||||
*
|
||||
* \param storage a storage container
|
||||
* \param path the path of the directory to enumerate
|
||||
|
@ -341,6 +345,40 @@ extern DECLSPEC int SDLCALL SDL_GetStoragePathInfo(SDL_Storage *storage, const c
|
|||
*/
|
||||
extern DECLSPEC Uint64 SDLCALL SDL_GetStorageSpaceRemaining(SDL_Storage *storage);
|
||||
|
||||
/**
|
||||
* Enumerate a directory tree, filtered by pattern, and return a list.
|
||||
*
|
||||
* Files are filtered out if they don't match the string in `pattern`, which
|
||||
* may contain wildcard characters '*' (match everything) and '?' (match one
|
||||
* character). If pattern is NULL, no filtering is done and all results are
|
||||
* returned. Subdirectories are permitted, and are specified with a path
|
||||
* separator of '/'. Wildcard characters '*' and '?' never match a path
|
||||
* separator.
|
||||
*
|
||||
* `flags` may be set to SDL_GLOBDIR_CASEINSENSITIVE to make the pattern
|
||||
* matching case-insensitive.
|
||||
*
|
||||
* The returned array is always NULL-terminated, for your iterating
|
||||
* convenience, but if `count` is non-NULL, on return it will contain the
|
||||
* number of items in the array, not counting the NULL terminator.
|
||||
*
|
||||
* You must free the returned pointer with SDL_free() when done with it.
|
||||
*
|
||||
* \param storage a storage container
|
||||
* \param path the path of the directory to enumerate
|
||||
* \param pattern the pattern that files in the directory must match. Can be NULL.
|
||||
* \param flags `SDL_GLOBDIR_*` bitflags that affect this search.
|
||||
* \param count on return, will be set to the number of items in the returned array. Can be NULL.
|
||||
* \returns an array of strings on success or NULL on failure; call
|
||||
* SDL_GetError() for more information. The caller should pass the
|
||||
* returned pointer to SDL_free when done with it.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, assuming the `storage` object is thread-safe.
|
||||
*/
|
||||
extern DECLSPEC char **SDLCALL SDL_GlobStorageDirectory(SDL_Storage *storage, const char *path, const char *pattern, Uint32 flags, int *count);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -481,6 +481,8 @@ SDL3_0.0.0 {
|
|||
SDL_GetWindowSizeInPixels;
|
||||
SDL_GetWindowSurface;
|
||||
SDL_GetWindowTitle;
|
||||
SDL_GlobDirectory;
|
||||
SDL_GlobStorageDirectory;
|
||||
SDL_HapticEffectSupported;
|
||||
SDL_HapticRumbleSupported;
|
||||
SDL_HasARMSIMD;
|
||||
|
|
|
@ -506,6 +506,8 @@
|
|||
#define SDL_GetWindowSizeInPixels SDL_GetWindowSizeInPixels_REAL
|
||||
#define SDL_GetWindowSurface SDL_GetWindowSurface_REAL
|
||||
#define SDL_GetWindowTitle SDL_GetWindowTitle_REAL
|
||||
#define SDL_GlobDirectory SDL_GlobDirectory_REAL
|
||||
#define SDL_GlobStorageDirectory SDL_GlobStorageDirectory_REAL
|
||||
#define SDL_HapticEffectSupported SDL_HapticEffectSupported_REAL
|
||||
#define SDL_HapticRumbleSupported SDL_HapticRumbleSupported_REAL
|
||||
#define SDL_HasARMSIMD SDL_HasARMSIMD_REAL
|
||||
|
|
|
@ -537,6 +537,8 @@ SDL_DYNAPI_PROC(int,SDL_GetWindowSize,(SDL_Window *a, int *b, int *c),(a,b,c),re
|
|||
SDL_DYNAPI_PROC(int,SDL_GetWindowSizeInPixels,(SDL_Window *a, int *b, int *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(SDL_Surface*,SDL_GetWindowSurface,(SDL_Window *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetWindowTitle,(SDL_Window *a),(a),return)
|
||||
SDL_DYNAPI_PROC(char**,SDL_GlobDirectory,(const char *a, const char *b, Uint32 c, int *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(char**,SDL_GlobStorageDirectory,(SDL_Storage *a, const char *b, const char *c, Uint32 d, int *e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HapticEffectSupported,(SDL_Haptic *a, const SDL_HapticEffect *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HapticRumbleSupported,(SDL_Haptic *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HasARMSIMD,(void),(),return)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "SDL_internal.h"
|
||||
#include "SDL_sysfilesystem.h"
|
||||
#include "../stdlib/SDL_sysstdlib.h"
|
||||
|
||||
int SDL_RemovePath(const char *path)
|
||||
{
|
||||
|
@ -74,3 +75,279 @@ int SDL_GetPathInfo(const char *path, SDL_PathInfo *info)
|
|||
|
||||
return SDL_SYS_GetPathInfo(path, info);
|
||||
}
|
||||
|
||||
static SDL_bool EverythingMatch(const char *pattern, const char *str, SDL_bool *matched_to_dir)
|
||||
{
|
||||
SDL_assert(pattern == NULL);
|
||||
SDL_assert(str != NULL);
|
||||
SDL_assert(matched_to_dir != NULL);
|
||||
|
||||
*matched_to_dir = SDL_TRUE;
|
||||
return SDL_TRUE; // everything matches!
|
||||
}
|
||||
|
||||
// this is just '*' and '?', with '/' matching nothing.
|
||||
static SDL_bool WildcardMatch(const char *pattern, const char *str, SDL_bool *matched_to_dir)
|
||||
{
|
||||
SDL_assert(pattern != NULL);
|
||||
SDL_assert(str != NULL);
|
||||
SDL_assert(matched_to_dir != NULL);
|
||||
|
||||
const char *str_backtrack = NULL;
|
||||
const char *pattern_backtrack = NULL;
|
||||
char sch_backtrack = 0;
|
||||
char sch = *str;
|
||||
char pch = *pattern;
|
||||
|
||||
while (sch) {
|
||||
if (pch == '*') {
|
||||
str_backtrack = str;
|
||||
pattern_backtrack = ++pattern;
|
||||
sch_backtrack = sch;
|
||||
pch = *pattern;
|
||||
} else if (pch == sch) {
|
||||
if (pch == '/') {
|
||||
str_backtrack = pattern_backtrack = NULL;
|
||||
}
|
||||
sch = *(++str);
|
||||
pch = *(++pattern);
|
||||
} else if ((pch == '?') && (sch != '/')) { // end of string (checked at `while`) or path separator do not match '?'.
|
||||
sch = *(++str);
|
||||
pch = *(++pattern);
|
||||
} else if (!pattern_backtrack || (sch_backtrack == '/')) { // we didn't have a match. Are we in a '*' and NOT on a path separator? Keep going. Otherwise, fail.
|
||||
*matched_to_dir = SDL_FALSE;
|
||||
return SDL_FALSE;
|
||||
} else { // still here? Wasn't a match, but we're definitely in a '*' pattern.
|
||||
str = ++str_backtrack;
|
||||
pattern = pattern_backtrack;
|
||||
sch_backtrack = sch;
|
||||
sch = *str;
|
||||
pch = *pattern;
|
||||
}
|
||||
}
|
||||
|
||||
// '*' at the end can be ignored, they are allowed to match nothing.
|
||||
while (pch == '*') {
|
||||
pch = *(++pattern);
|
||||
}
|
||||
|
||||
*matched_to_dir = ((pch == '/') || (pch == '\0')); // end of string and the pattern is complete or failed at a '/'? We should descend into this directory.
|
||||
|
||||
return (pch == '\0'); // survived the whole pattern? That's a match!
|
||||
}
|
||||
|
||||
static char *CaseFoldUtf8String(const char *fname)
|
||||
{
|
||||
SDL_assert(fname != NULL);
|
||||
const size_t allocation = (SDL_strlen(fname) + 1) * 3;
|
||||
char *retval = (char *) SDL_malloc(allocation); // lazy: just allocating the max needed.
|
||||
if (!retval) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Uint32 codepoint;
|
||||
size_t written = 0;
|
||||
while ((codepoint = SDL_StepUTF8(&fname, 4)) != 0) {
|
||||
Uint32 folded[3];
|
||||
const int num_folded = SDL_CaseFoldUnicode(codepoint, folded);
|
||||
SDL_assert(num_folded > 0);
|
||||
SDL_assert(num_folded <= SDL_arraysize(folded));
|
||||
for (int i = 0; i < num_folded; i++) {
|
||||
SDL_assert(written < allocation);
|
||||
retval[written++] = folded[i];
|
||||
}
|
||||
}
|
||||
|
||||
SDL_assert(written < allocation);
|
||||
retval[written++] = '\0';
|
||||
|
||||
if (written < allocation) {
|
||||
void *ptr = SDL_realloc(retval, written); // shrink it down.
|
||||
if (ptr) { // shouldn't fail, but if it does, `retval` is still valid.
|
||||
retval = (char *) ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
typedef struct GlobDirCallbackData
|
||||
{
|
||||
SDL_bool (*matcher)(const char *pattern, const char *str, SDL_bool *matched_to_dir);
|
||||
const char *pattern;
|
||||
int num_entries;
|
||||
Uint32 flags;
|
||||
SDL_GlobEnumeratorFunc enumerator;
|
||||
SDL_GlobGetPathInfoFunc getpathinfo;
|
||||
void *fsuserdata;
|
||||
size_t basedirlen;
|
||||
SDL_IOStream *string_stream;
|
||||
} GlobDirCallbackData;
|
||||
|
||||
static int SDLCALL GlobDirectoryCallback(void *userdata, const char *dirname, const char *fname)
|
||||
{
|
||||
SDL_assert(userdata != NULL);
|
||||
SDL_assert(dirname != NULL);
|
||||
SDL_assert(fname != NULL);
|
||||
|
||||
//SDL_Log("GlobDirectoryCallback('%s', '%s')", dirname, fname);
|
||||
|
||||
GlobDirCallbackData *data = (GlobDirCallbackData *) userdata;
|
||||
|
||||
// !!! FIXME: if we're careful, we can keep a single buffer in `data` that we push and pop paths off the end of as we walk the tree,
|
||||
// !!! FIXME: and only casefold the new pieces instead of allocating and folding full paths for all of this.
|
||||
|
||||
char *fullpath = NULL;
|
||||
if (SDL_asprintf(&fullpath, "%s/%s", dirname, fname) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *folded = NULL;
|
||||
if (data->flags & SDL_GLOBDIR_CASEINSENSITIVE) {
|
||||
folded = CaseFoldUtf8String(fullpath);
|
||||
if (!folded) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool matched_to_dir = SDL_FALSE;
|
||||
const SDL_bool matched = data->matcher(data->pattern, (folded ? folded : fullpath) + data->basedirlen, &matched_to_dir);
|
||||
//SDL_Log("GlobDirectoryCallback: Considered %spath='%s' vs pattern='%s': %smatched (matched_to_dir=%s)", folded ? "(folded) " : "", (folded ? folded : fullpath) + data->basedirlen, data->pattern, matched ? "" : "NOT ", matched_to_dir ? "TRUE" : "FALSE");
|
||||
SDL_free(folded);
|
||||
|
||||
if (matched) {
|
||||
const char *subpath = fullpath + data->basedirlen;
|
||||
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.
|
||||
}
|
||||
data->num_entries++;
|
||||
}
|
||||
|
||||
int retval = 1; // keep enumerating by default.
|
||||
if (matched_to_dir) {
|
||||
SDL_PathInfo info;
|
||||
if ((data->getpathinfo(fullpath, &info, data->fsuserdata) == 0) && (info.type == SDL_PATHTYPE_DIRECTORY)) {
|
||||
//SDL_Log("GlobDirectoryCallback: Descending into subdir '%s'", fname);
|
||||
if (data->enumerator(fullpath, GlobDirectoryCallback, data, data->fsuserdata) < 0) {
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(fullpath);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
char **SDL_InternalGlobDirectory(const char *path, const char *pattern, Uint32 flags, int *count, SDL_GlobEnumeratorFunc enumerator, SDL_GlobGetPathInfoFunc getpathinfo, void *userdata)
|
||||
{
|
||||
int dummycount;
|
||||
if (!count) {
|
||||
count = &dummycount;
|
||||
}
|
||||
*count = 0;
|
||||
|
||||
if (!path) {
|
||||
SDL_InvalidParamError("path");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if path ends with any '/', chop them off, so we don't confuse the pattern matcher later.
|
||||
char *pathcpy = NULL;
|
||||
size_t pathlen = SDL_strlen(path);
|
||||
if (pathlen && (path[pathlen-1] == '/')) {
|
||||
pathcpy = SDL_strdup(path);
|
||||
if (!pathcpy) {
|
||||
return NULL;
|
||||
}
|
||||
char *ptr = &pathcpy[pathlen-1];
|
||||
while ((ptr >= pathcpy) && (*ptr == '/')) {
|
||||
*(ptr--) = '\0';
|
||||
}
|
||||
path = pathcpy;
|
||||
}
|
||||
|
||||
char *folded = NULL;
|
||||
if (pattern && (flags & SDL_GLOBDIR_CASEINSENSITIVE)) {
|
||||
folded = CaseFoldUtf8String(pattern);
|
||||
if (!folded) {
|
||||
SDL_free(pathcpy);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GlobDirCallbackData data;
|
||||
SDL_zero(data);
|
||||
data.string_stream = SDL_IOFromDynamicMem();
|
||||
if (!data.string_stream) {
|
||||
SDL_free(folded);
|
||||
SDL_free(pathcpy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pattern) {
|
||||
data.matcher = EverythingMatch; // no pattern? Everything matches.
|
||||
|
||||
// !!! FIXME
|
||||
//} else if (flags & SDL_GLOBDIR_GITIGNORE) {
|
||||
// data.matcher = GitIgnoreMatch;
|
||||
|
||||
} else {
|
||||
data.matcher = WildcardMatch;
|
||||
}
|
||||
|
||||
data.pattern = folded ? folded : pattern;
|
||||
data.flags = flags;
|
||||
data.enumerator = enumerator;
|
||||
data.getpathinfo = getpathinfo;
|
||||
data.fsuserdata = userdata;
|
||||
data.basedirlen = SDL_strlen(path) + 1; // +1 for the '/' we'll be adding.
|
||||
|
||||
char **retval = NULL;
|
||||
if (data.enumerator(path, GlobDirectoryCallback, &data, data.fsuserdata) == 0) {
|
||||
const size_t streamlen = (size_t) SDL_GetIOSize(data.string_stream);
|
||||
const size_t buflen = streamlen + ((data.num_entries + 1) * sizeof (char *)); // +1 for NULL terminator at end of array.
|
||||
retval = (char **) SDL_malloc(buflen);
|
||||
if (retval) {
|
||||
if (data.num_entries > 0) {
|
||||
Sint64 iorc = SDL_SeekIO(data.string_stream, 0, SDL_IO_SEEK_SET);
|
||||
SDL_assert(iorc == 0); // this should never fail for a memory stream!
|
||||
char *ptr = (char *) (retval + (data.num_entries + 1));
|
||||
iorc = SDL_ReadIO(data.string_stream, ptr, streamlen);
|
||||
SDL_assert(iorc == (Sint64) streamlen); // this should never fail for a memory stream!
|
||||
for (int i = 0; i < data.num_entries; i++) {
|
||||
retval[i] = ptr;
|
||||
ptr += SDL_strlen(ptr) + 1;
|
||||
}
|
||||
}
|
||||
retval[data.num_entries] = NULL; // NULL terminate the list.
|
||||
*count = data.num_entries;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CloseIO(data.string_stream);
|
||||
SDL_free(folded);
|
||||
SDL_free(pathcpy);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int GlobDirectoryGetPathInfo(const char *path, SDL_PathInfo *info, void *userdata)
|
||||
{
|
||||
return SDL_GetPathInfo(path, info);
|
||||
}
|
||||
|
||||
static int GlobDirectoryEnumerator(const char *path, SDL_EnumerateDirectoryCallback cb, void *cbuserdata, void *userdata)
|
||||
{
|
||||
return SDL_EnumerateDirectory(path, cb, cbuserdata);
|
||||
}
|
||||
|
||||
char **SDL_GlobDirectory(const char *path, const char *pattern, Uint32 flags, int *count)
|
||||
{
|
||||
//SDL_Log("SDL_GlobDirectory('%s', '%s') ...", path, pattern);
|
||||
return SDL_InternalGlobDirectory(path, pattern, flags, count, GlobDirectoryEnumerator, GlobDirectoryGetPathInfo, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,9 @@ int SDL_SYS_RenamePath(const char *oldpath, const char *newpath);
|
|||
int SDL_SYS_CreateDirectory(const char *path);
|
||||
int SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info);
|
||||
|
||||
typedef int (*SDL_GlobEnumeratorFunc)(const char *path, SDL_EnumerateDirectoryCallback cb, void *cbuserdata, void *userdata);
|
||||
typedef int (*SDL_GlobGetPathInfoFunc)(const char *path, SDL_PathInfo *info, void *userdata);
|
||||
char **SDL_InternalGlobDirectory(const char *path, const char *pattern, Uint32 flags, int *count, SDL_GlobEnumeratorFunc enumerator, SDL_GlobGetPathInfoFunc getpathinfo, void *userdata);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "SDL_internal.h"
|
||||
|
||||
#include "SDL_sysstorage.h"
|
||||
#include "../filesystem/SDL_sysfilesystem.h"
|
||||
|
||||
/* Available title storage drivers */
|
||||
static TitleStorageBootStrap *titlebootstrap[] = {
|
||||
|
@ -321,3 +322,20 @@ Uint64 SDL_GetStorageSpaceRemaining(SDL_Storage *storage)
|
|||
|
||||
return storage->iface.space_remaining(storage->userdata);
|
||||
}
|
||||
|
||||
static int GlobStorageDirectoryGetPathInfo(const char *path, SDL_PathInfo *info, void *userdata)
|
||||
{
|
||||
return SDL_GetStoragePathInfo((SDL_Storage *) userdata, path, info);
|
||||
}
|
||||
|
||||
static int GlobStorageDirectoryEnumerator(const char *path, SDL_EnumerateDirectoryCallback cb, void *cbuserdata, void *userdata)
|
||||
{
|
||||
return SDL_EnumerateStorageDirectory((SDL_Storage *) userdata, path, cb, cbuserdata);
|
||||
}
|
||||
|
||||
char **SDL_GlobStorageDirectory(SDL_Storage *storage, const char *path, const char *pattern, Uint32 flags, int *count)
|
||||
{
|
||||
CHECK_STORAGE_MAGIC_RET(NULL)
|
||||
return SDL_InternalGlobDirectory(path, pattern, flags, count, GlobStorageDirectoryEnumerator, GlobStorageDirectoryGetPathInfo, storage);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,10 +110,23 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (base_path) {
|
||||
char **globlist;
|
||||
|
||||
if (SDL_EnumerateDirectory(base_path, enum_callback, NULL) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path enumeration failed!");
|
||||
}
|
||||
|
||||
globlist = SDL_GlobDirectory(base_path, "*/test*/Test*", SDL_GLOBDIR_CASEINSENSITIVE, NULL);
|
||||
if (!globlist) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Base path globbing failed!");
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; globlist[i]; i++) {
|
||||
SDL_Log("GLOB[%d]: '%s'", i, globlist[i]);
|
||||
}
|
||||
SDL_free(globlist);
|
||||
}
|
||||
|
||||
/* !!! FIXME: put this in a subroutine and make it test more thoroughly (and put it in testautomation). */
|
||||
if (SDL_CreateDirectory("testfilesystem-test") == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateDirectory('testfilesystem-test') failed: %s", SDL_GetError());
|
||||
|
|
Loading…
Reference in New Issue