/** * dir_list_new: * @dir : directory path. * @ext : allowed extensions of file directory entries to include. * @include_dirs : include directories as part of the finished directory listing? * @include_compressed : Only include files which match ext. Do not try to match compressed files, etc. * * Create a directory listing. * * Returns: pointer to a directory 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, bool include_compressed) { struct RDIR *entry = NULL; struct string_list *ext_list = NULL; struct string_list *list = NULL; if (!(list = string_list_new())) return NULL; if (ext) ext_list = string_split(ext, "|"); entry = retro_opendir(dir); if (!entry) goto error; if (retro_dirent_error(entry)) goto error; while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; bool is_dir; int ret = 0; const char *name = retro_dirent_get_name(entry); const char *file_ext = path_get_extension(name); fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); if (ret == -1) goto error; if (ret == 1) continue; } retro_closedir(entry); string_list_free(ext_list); return list; error: retro_closedir(entry); string_list_free(list); string_list_free(ext_list); return NULL; }
/** * dir_list_read: * @dir : directory path. * @list : the string list to add files to * @ext_list : the string list of extensions to include * @include_dirs : include directories as part of the finished directory listing? * @include_hidden : include hidden files and directories as part of the finished directory listing? * @include_compressed : Only include files which match ext. Do not try to match compressed files, etc. * @recursive : list directory contents recursively * * Add files within a directory to an existing string list * * Returns: -1 on error, 0 on success. **/ int dir_list_read(const char *dir, struct string_list *list, struct string_list *ext_list, bool include_dirs, bool include_hidden, bool include_compressed, bool recursive) { struct RDIR *entry = retro_opendir(dir); if (!entry) return -1; if (retro_dirent_error(entry)) { retro_closedir(entry); return -1; } #ifdef _WIN32 if (include_hidden) entry->entry.dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; else entry->entry.dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN; #endif while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; bool is_dir = false; int ret = 0; const char *name = retro_dirent_get_name(entry); const char *file_ext = path_get_extension(name); file_path[0] = '\0'; fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); if (!include_hidden) { if (*name == '.') continue; } if(is_dir && recursive) { if(strstr(name, ".") || strstr(name, "..")) continue; dir_list_read(file_path, list, ext_list, include_dirs, include_hidden, include_compressed, recursive); } ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); if (ret == -1) { retro_closedir(entry); return -1; } if (ret == 1) continue; } retro_closedir(entry); return 0; }
/** * dir_list_new: * @dir : directory 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, * 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) { #ifdef _WIN32 WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; #else DIR *directory = NULL; const struct dirent *entry = NULL; #endif char path_buf[PATH_MAX_LENGTH] = {0}; struct string_list *ext_list = NULL; struct string_list *list = NULL; (void)path_buf; if (!(list = string_list_new())) return NULL; if (ext) ext_list = string_split(ext, "|"); #ifdef _WIN32 snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); hFind = FindFirstFile(path_buf, &ffd); if (hFind == INVALID_HANDLE_VALUE) goto error; do { char file_path[PATH_MAX_LENGTH]; int ret = 0; 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)); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, list, ext_list, file_ext); if (ret == -1) goto error; 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))) { char file_path[PATH_MAX_LENGTH]; int ret = 0; 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, 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) goto error; if (ret == 1) continue; } closedir(directory); string_list_free(ext_list); return list; error: if (directory) closedir(directory); #endif string_list_free(list); string_list_free(ext_list); return NULL; }