diff --git a/Makefile.common b/Makefile.common index 00a5e7c0ce..ffa0299863 100644 --- a/Makefile.common +++ b/Makefile.common @@ -130,6 +130,7 @@ OBJ += frontend/frontend.o \ content.o \ libretro-common/file/file_list.o \ libretro-common/file/dir_list.o \ + libretro-common/file/retro_dirent.o \ libretro-common/string/string_list.o \ libretro-common/string/stdstring.o \ libretro-common/memmap/memalign.o \ diff --git a/griffin/griffin.c b/griffin/griffin.c index f7cef3f818..30cdf96a80 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -584,6 +584,7 @@ FILE #ifndef IOS #include "../libretro-common/file/dir_list.c" #endif +#include "../libretro-common/file/retro_dirent.c" #include "../dir_list_special.c" #include "../libretro-common/string/string_list.c" #include "../libretro-common/string/stdstring.c" diff --git a/libretro-common/file/dir_list.c b/libretro-common/file/dir_list.c index 744a36d0fa..e9d8a81aaa 100644 --- a/libretro-common/file/dir_list.c +++ b/libretro-common/file/dir_list.c @@ -20,36 +20,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include #include #include #include - -#if defined(_WIN32) -#ifdef _MSC_VER -#define setmode _setmode -#endif -#ifdef _XBOX -#include -#define INVALID_FILE_ATTRIBUTES -1 -#else -#include -#include -#include -#include -#endif -#elif defined(VITA) -#include -#include -#else -#if defined(PSP) -#include -#endif -#include -#include -#include -#include -#endif +#include #include @@ -102,46 +79,6 @@ void dir_list_free(struct string_list *list) string_list_free(list); } -/** - * - * dirent_is_directory: - * @path : path to the directory entry. - * @entry : pointer to the directory entry. - * - * Is the directory listing entry a directory? - * - * Returns: true if directory listing entry is - * a directory, false if not. - */ - -static bool dirent_is_directory(const char *path, const void *data) -{ -#if defined(_WIN32) - const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)data; - return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; -#elif defined(PSP) || defined(VITA) - - const SceIoDirent *entry = (const SceIoDirent*)data; -#if defined(PSP) - return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; -#elif defined(VITA) - return PSP2_S_ISDIR(entry->d_stat.st_mode); -#endif - -#elif defined(DT_DIR) - const struct dirent *entry = (const struct dirent*)data; - if (entry->d_type == DT_DIR) - return true; - else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */ - || entry->d_type == DT_LNK) - return path_is_directory(path); - return false; -#else /* dirent struct doesn't have d_type, do it the slow way ... */ - const struct dirent *entry = (const struct dirent*)data; - return path_is_directory(path); -#endif -} - /** * parse_dir_entry: * @name : name of the directory listing entry. @@ -208,44 +145,6 @@ static int parse_dir_entry(const char *name, char *file_path, return 0; } -#if defined(_WIN32) -#define dirent_opendir(directory, dir) \ -{ \ - char path_buf[PATH_MAX_LENGTH]; \ - snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); \ - directory = FindFirstFile(path_buf, &entry); \ -} -#elif defined(VITA) || defined(PSP) -#define dirent_opendir(directory, dir) directory = sceIoDopen(dir) -#else -#define dirent_opendir(directory, dir) directory = opendir(dir) -#endif - -#if defined(_WIN32) -#define dirent_error(directory) ((directory) == INVALID_HANDLE_VALUE) -#elif defined(VITA) || defined(PSP) -#define dirent_error(directory) ((directory) < 0) -#else -#define dirent_error(directory) (!(directory)) -#endif - -#if defined(_WIN32) -#define dirent_readdir(directory, entry) (FindNextFile((directory), &(entry)) != 0) -#elif defined(VITA) || defined(PSP) -#define dirent_readdir(directory, entry) (sceIoDread((directory), &(entry)) > 0) -#else -#define dirent_readdir(directory, entry) (entry = readdir(directory)) -#endif - -#if defined(_WIN32) -#define dirent_closedir(directory) if (directory != INVALID_HANDLE_VALUE) FindClose(directory) -#elif defined(VITA) || defined(PSP) -#define dirent_closedir(directory) sceIoDclose(directory) -#else -#define dirent_closedir(directory) if (directory) closedir(directory) -#endif - - /** * dir_list_new: * @dir : directory path. @@ -261,16 +160,7 @@ static int parse_dir_entry(const char *name, char *file_path, struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs, bool include_compressed) { -#if defined(_WIN32) - WIN32_FIND_DATA entry; - HANDLE directory = INVALID_HANDLE_VALUE; -#elif defined(VITA) || defined(PSP) - SceUID directory; - SceIoDirent entry; -#else - DIR *directory = NULL; - const struct dirent *entry = NULL; -#endif + struct RDIR *entry = NULL; struct string_list *ext_list = NULL; struct string_list *list = NULL; @@ -280,25 +170,20 @@ struct string_list *dir_list_new(const char *dir, if (ext) ext_list = string_split(ext, "|"); - dirent_opendir(directory, dir); + entry = retro_opendir(dir); - if (dirent_error(directory)) + if (!entry) goto error; - while (dirent_readdir(directory, entry)) + if (retro_dirent_error(entry)) + goto error; + + while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; int ret = 0; -#ifdef _WIN32 - const char *name = entry.cFileName; - bool is_dir = dirent_is_directory(file_path, &entry); -#elif defined(VITA) || defined(PSP) - const char *name = entry.d_name; - bool is_dir = dirent_is_directory(file_path, &entry); -#else - const char *name = entry->d_name; - bool is_dir = dirent_is_directory(file_path, entry); -#endif + const char *name = retro_dirent_get_name(entry); + bool is_dir = retro_dirent_is_dir(entry, file_path); const char *file_ext = path_get_extension(name); fill_pathname_join(file_path, dir, name, sizeof(file_path)); @@ -313,13 +198,13 @@ struct string_list *dir_list_new(const char *dir, continue; } - dirent_closedir(directory); + retro_closedir(entry); string_list_free(ext_list); return list; error: - dirent_closedir(directory); + retro_closedir(entry); string_list_free(list); string_list_free(ext_list); diff --git a/libretro-common/file/retro_dirent.c b/libretro-common/file/retro_dirent.c new file mode 100644 index 0000000000..f2194442b4 --- /dev/null +++ b/libretro-common/file/retro_dirent.c @@ -0,0 +1,155 @@ +#include + +#if defined(_WIN32) +#ifdef _MSC_VER +#define setmode _setmode +#endif +#ifdef _XBOX +#include +#define INVALID_FILE_ATTRIBUTES -1 +#else +#include +#include +#include +#include +#endif +#elif defined(VITA) +#include +#include +#else +#if defined(PSP) +#include +#endif +#include +#include +#include +#include +#endif + +#include + +#include + +struct RDIR +{ +#if defined(_WIN32) + WIN32_FIND_DATA entry; + HANDLE directory; +#elif defined(VITA) || defined(PSP) + SceUID directory; + SceIoDirent entry; +#else + DIR *directory; + const struct dirent *entry; +#endif +}; + +struct RDIR *retro_opendir(const char *name) +{ + char path_buf[1024]; + struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir)); + if (!rdir) + return NULL; +#if defined(_WIN32) + snprintf(path_buf, sizeof(path_buf), "%s\\*", name); + rdir->directory = FindFirstFile(path_buf, &rdir->entry); +#elif defined(VITA) || defined(PSP) + rdir->directory = sceIoDopen(name); + rdir->entry = NULL; +#else + rdir->directory = opendir(name); + rdir->entry = NULL; +#endif + + return rdir; +} + +bool retro_dirent_error(struct RDIR *rdir) +{ +#if defined(_WIN32) + return (rdir->directory == INVALID_HANDLE_VALUE); +#elif defined(VITA) || defined(PSP) + return (rdir->directory < 0); +#else + return !(rdir->directory); +#endif +} + +int retro_readdir(struct RDIR *rdir) +{ +#if defined(_WIN32) + return (FindNextFile(rdir->directory, &rdir->entry) != 0); +#elif defined(VITA) || defined(PSP) + return (sceIoDread(rdir->directory, &rdir->entry) > 0); +#else + return ((rdir->entry = readdir(rdir->directory)) != NULL); +#endif +} + +const char *retro_dirent_get_name(struct RDIR *rdir) +{ +#if defined(_WIN32) + return rdir->entry.cFileName; +#elif defined(VITA) || defined(PSP) + return rdir->entry.d_name; +#else + return rdir->entry->d_name; +#endif +} + +/** + * + * retro_dirent_is_dir: + * @rdir : pointer to the directory entry. + * @path : path to the directory entry. + * + * Is the directory listing entry a directory? + * + * Returns: true if directory listing entry is + * a directory, false if not. + */ +bool retro_dirent_is_dir(struct RDIR *rdir, const char *path) +{ +#if defined(_WIN32) + const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)rdir->entry; + return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; +#elif defined(PSP) || defined(VITA) + + const SceIoDirent *entry = (const SceIoDirent*)rdir->entry; +#if defined(PSP) + return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; +#elif defined(VITA) + return PSP2_S_ISDIR(entry->d_stat.st_mode); +#endif + +#elif defined(DT_DIR) + const struct dirent *entry = (const struct dirent*)rdir->entry; + if (entry->d_type == DT_DIR) + return true; + else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */ + || entry->d_type == DT_LNK) + return path_is_directory(path); + return false; +#else /* dirent struct doesn't have d_type, do it the slow way ... */ + const struct dirent *entry = (const struct dirent*)data; + return path_is_directory(path); +#endif +} + +void retro_closedir(struct RDIR *rdir) +{ + if (!rdir) + return; + +#if defined(_WIN32) + if (rdir->directory != INVALID_HANDLE_VALUE) + FindClose(rdir->directory); +#elif defined(VITA) || defined(PSP) + sceIoDclose(rdir->directory); +#else + if (rdir->directory) + closedir(rdir->directory); +#endif + + free(rdir); +} diff --git a/libretro-common/include/retro_dirent.h b/libretro-common/include/retro_dirent.h new file mode 100644 index 0000000000..6ef801ed82 --- /dev/null +++ b/libretro-common/include/retro_dirent.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (retro_dirent.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __RETRO_DIRENT_H +#define __RETRO_DIRENT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct RDIR; + +struct RDIR *retro_opendir(const char *name); + +int retro_readdir(struct RDIR *rdir); + +bool retro_dirent_error(struct RDIR *rdir); + +const char *retro_dirent_get_name(struct RDIR *rdir); + +/** + * + * retro_dirent_is_dir: + * @rdir : pointer to the directory entry. + * @path : path to the directory entry. + * + * Is the directory listing entry a directory? + * + * Returns: true if directory listing entry is + * a directory, false if not. + */ +bool retro_dirent_is_dir(struct RDIR *rdir, const char *path); + +void retro_closedir(struct RDIR *rdir); + +#ifdef __cplusplus +} +#endif + +#endif