diff --git a/libretro-common/file/dir_list.c b/libretro-common/file/dir_list.c index 66cef873a2..4eb9baf5e5 100644 --- a/libretro-common/file/dir_list.c +++ b/libretro-common/file/dir_list.c @@ -192,20 +192,20 @@ static int parse_dir_entry(const char *name, char *file_path, /** * dir_list_new: - * @dir : directory path. + * @dir : directories path. * @ext : allowed extensions of file directory entries to include. * @include_dirs : include directories as part of the finished directory listing? * * Create a directory listing. * - * Returns: pointer to a directory listing of type 'struct string_list *' on success, + * Returns: pointer to a file listing of type 'struct string_list *' on success, * NULL in case of error. Has to be freed manually. **/ struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs) { char path_buf[PATH_MAX_LENGTH]; - struct string_list *ext_list, *list; + struct string_list *ext_list, *list, *dir_list; #ifdef _WIN32 WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; @@ -215,6 +215,7 @@ struct string_list *dir_list_new(const char *dir, #endif ext_list = NULL; + dir_list = NULL; (void)path_buf; if (!(list = string_list_new())) @@ -223,6 +224,9 @@ struct string_list *dir_list_new(const char *dir, if (ext) ext_list = string_split(ext, "|"); + if (dir) + dir_list = string_split(dir, ";"); + #ifdef _WIN32 snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); @@ -230,72 +234,79 @@ struct string_list *dir_list_new(const char *dir, if (hFind == INVALID_HANDLE_VALUE) goto error; - do + // Process the directory list from the end to the start to have an override + // of file from the first directory by the file from the last directory. + for (int i = dir_list->size -1; i >= 0; i--) { - int ret = 0; - char file_path[PATH_MAX_LENGTH]; - const char *name = ffd.cFileName; - const char *file_ext = path_get_extension(name); - bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + const char * dir_name = dir_list->elems[i].data; + do + { + int ret = 0; + char file_path[PATH_MAX_LENGTH]; + const char *name = ffd.cFileName; + const char *file_ext = path_get_extension(name); + bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - fill_pathname_join(file_path, dir, name, sizeof(file_path)); + fill_pathname_join(file_path, dir_name, name, sizeof(file_path)); - ret = parse_dir_entry(name, file_path, is_dir, - include_dirs, list, ext_list, file_ext); + ret = parse_dir_entry(name, file_path, is_dir, + include_dirs, list, ext_list, file_ext); - if (ret == -1) - goto error; + if (ret == -1) + break; //invalid folder continue with next - if (ret == 1) - continue; - }while (FindNextFile(hFind, &ffd) != 0); + if (ret == 1) + continue; + }while (FindNextFile(hFind, &ffd) != 0); - FindClose(hFind); - string_list_free(ext_list); - return list; - -error: - if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); + } #else - directory = opendir(dir); - if (!directory) - goto error; - - while ((entry = readdir(directory))) + // Process the directory list from the end to the start to have an override + // of file from the first directory by the file from the last directory. + for (int i = dir_list->size-1; i >= 0; i--) { - int ret = 0; - char file_path[PATH_MAX_LENGTH]; - const char *name = entry->d_name; - const char *file_ext = path_get_extension(name); - bool is_dir = false; + const char * dir_name = dir_list->elems[i].data; - fill_pathname_join(file_path, dir, name, sizeof(file_path)); + directory = opendir(dir_name); - is_dir = dirent_is_directory(file_path, entry); - - ret = parse_dir_entry(name, file_path, is_dir, - include_dirs, list, ext_list, file_ext); - - if (ret == -1) - goto error; - - if (ret == 1) + if (!directory) continue; + + while ((entry = readdir(directory))) + { + int ret = 0; + char file_path[PATH_MAX_LENGTH]; + const char *name = entry->d_name; + const char *file_ext = path_get_extension(name); + bool is_dir = false; + + fill_pathname_join(file_path, dir_name, name, sizeof(file_path)); + + is_dir = dirent_is_directory(file_path, entry); + + ret = parse_dir_entry(name, file_path, is_dir, + include_dirs, list, ext_list, file_ext); + + if (ret == -1) + break; //invalid folder continue with next + + if (ret == 1) + continue; + } + + closedir(directory); } - closedir(directory); - - string_list_free(ext_list); - return list; - -error: - - if (directory) - closedir(directory); - #endif - string_list_free(list); + string_list_free(dir_list); string_list_free(ext_list); - return NULL; + + if (list->size == 0) + { + string_list_free(list); + return NULL; + } + + return list; }