From a225426510fc25316b3868e8764893dff284e77e Mon Sep 17 00:00:00 2001 From: comex Date: Sat, 15 Nov 2014 15:46:40 -0500 Subject: Rewrite FileSearch and improve ScanDirectoryTree. - FileSearch is now just one function, and it converts the original glob into a regex on all platforms rather than relying on native Windows pattern matching on there and a complete hack elsewhere. It now supports recursion out of the box rather than manually expanding into a full list of directories in multiple call sites. - This adds a GCC >= 4.9 dependency due to older versions having outright broken . MSVC is fine with it. - ScanDirectoryTree returns the parent entry rather than filling parts of it in via reference. The count is now stored in the entry like it was for subdirectories. - .glsl file search is now done with DoFileSearch. - IOCTLV_READ_DIR now uses ScanDirectoryTree directly and sorts the results after replacements for better determinism. --- Source/Core/Common/FileUtil.cpp | 75 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 38 deletions(-) (limited to 'Source/Core/Common/FileUtil.cpp') diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 6e721b9766..980821e010 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -453,11 +453,14 @@ bool CreateEmptyFile(const std::string &filename) // Scans the directory tree gets, starting from _Directory and adds the // results into parentEntry. Returns the number of files+directories found -u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) +FSTEntry ScanDirectoryTree(const std::string &directory, bool recursive) { INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); // How many files + directories we found - u32 foundEntries = 0; + FSTEntry parent_entry; + parent_entry.physicalName = directory; + parent_entry.isDirectory = true; + parent_entry.size = 0; #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; @@ -466,59 +469,55 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); - return foundEntries; + return parent_entry; } // Windows loop do { - FSTEntry entry; - const std::string virtualName(TStrToUTF8(ffd.cFileName)); + const std::string virtual_name(TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = nullptr; DIR *dirp = opendir(directory.c_str()); if (!dirp) - return 0; - - // non Windows loop - while (!readdir_r(dirp, &dirent, &result) && result) - { - FSTEntry entry; - const std::string virtualName(result->d_name); -#endif - // check for "." and ".." - if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || - ((virtualName[0] == '.') && (virtualName[1] == '.') && - (virtualName[2] == '\0'))) - continue; - entry.virtualName = virtualName; - entry.physicalName = directory; - entry.physicalName += DIR_SEP + entry.virtualName; + return parent_entry; - if (IsDirectory(entry.physicalName)) + // non Windows loop + while (!readdir_r(dirp, &dirent, &result) && result) { - entry.isDirectory = true; - // is a directory, lets go inside - entry.size = ScanDirectoryTree(entry.physicalName, entry); - foundEntries += (u32)entry.size; - } - else - { // is a file - entry.isDirectory = false; - entry.size = GetSize(entry.physicalName.c_str()); - } - ++foundEntries; - // Push into the tree - parentEntry.children.push_back(entry); -#ifdef _WIN32 - } while (FindNextFile(hFind, &ffd) != 0); + const std::string virtual_name(result->d_name); + #endif + if (virtual_name == "." || virtual_name == "..") + continue; + auto physical_name = directory + DIR_SEP + virtual_name; + FSTEntry entry; + entry.isDirectory = IsDirectory(physical_name); + if (entry.isDirectory) + { + if (recursive) + entry = ScanDirectoryTree(physical_name, true); + else + entry.size = 0; + } + else + { + entry.size = GetSize(physical_name); + } + entry.virtualName = virtual_name; + entry.physicalName = physical_name; + + ++parent_entry.size; + // Push into the tree + parent_entry.children.push_back(entry); + #ifdef _WIN32 + } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else } closedir(dirp); #endif // Return number of entries found. - return foundEntries; + return parent_entry; } -- cgit v1.2.3 From a0a80c9a9cc247024c012be474fb92d1c290d9b1 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 16 Nov 2014 13:54:41 -0500 Subject: Fix CopyDir to not require source and dest paths to end with "/". --- Source/Core/Common/FileUtil.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'Source/Core/Common/FileUtil.cpp') diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 980821e010..19269e88d3 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -627,14 +627,11 @@ void CopyDir(const std::string &source_path, const std::string &dest_path) if (virtualName == "." || virtualName == "..") continue; - std::string source, dest; - source = source_path + virtualName; - dest = dest_path + virtualName; + std::string source = source_path + DIR_SEP + virtualName; + std::string dest = dest_path + DIR_SEP + virtualName; if (IsDirectory(source)) { - source += '/'; - dest += '/'; - if (!File::Exists(dest)) File::CreateFullPath(dest); + if (!File::Exists(dest)) File::CreateFullPath(dest + DIR_SEP); CopyDir(source, dest); } else if (!File::Exists(dest)) File::Copy(source, dest); -- cgit v1.2.3 From dc91e8b60793276e83cc3c141dcdc551aa36d8ed Mon Sep 17 00:00:00 2001 From: comex Date: Mon, 17 Nov 2014 20:59:14 -0500 Subject: Add a mode to use a dummy Wii NAND. Eventually, netplay will be able to use the host's NAND, but this could still be useful in some cases; for TAS it definitely makes sense to have a way to avoid using any preexisting NAND. In terms of implementation: remove D_WIIUSER_IDX, which was just WIIROOT + "/", as well as some other indices which are pointless to have as separate variables rather than just using the actual path (fixed, since they're actual Wii NAND paths) at the call site. Then split off D_SESSION_WIIROOT_IDX, which can point to the dummy NAND directory, from D_WIIROOT_IDX, which always points to the "real" one the user configured. --- Source/Core/Common/FileUtil.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'Source/Core/Common/FileUtil.cpp') diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 19269e88d3..925e3f1ed3 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -20,6 +20,7 @@ #include // for GetSaveFileName #include // getcwd #include +#include // guid stuff #include #include #else @@ -666,6 +667,32 @@ bool SetCurrentDir(const std::string &directory) return __chdir(directory.c_str()) == 0; } +std::string CreateTempDir() +{ +#ifdef _WIN32 + TCHAR temp[MAX_PATH]; + if (!GetTempPath(MAX_PATH, temp)) + return ""; + + GUID guid; + CoCreateGuid(&guid); + TCHAR tguid[40]; + StringFromGUID2(guid, tguid, 39); + tguid[39] = 0; + std::string dir = TStrToUTF8(temp) + "/" + TStrToUTF8(tguid); + if (!CreateDir(dir)) + return ""; + dir = ReplaceAll(dir, "\\", DIR_SEP); + return dir; +#else + const char* base = getenv("TMPDIR") ?: "/tmp"; + std::string path = std::string(base) + "/DolphinWii.XXXXXX"; + if (!mkdtemp(&path[0])) + return ""; + return path; +#endif +} + std::string GetTempFilenameForAtomicWrite(const std::string &path) { std::string abs = path; @@ -734,17 +761,9 @@ static void RebuildUserDirectories(unsigned int dir_index) { switch (dir_index) { - case D_WIIROOT_IDX: - s_user_paths[D_WIIUSER_IDX] = s_user_paths[D_WIIROOT_IDX] + DIR_SEP; - s_user_paths[D_WIISYSCONF_IDX] = s_user_paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR + DIR_SEP; - s_user_paths[D_WIIWC24_IDX] = s_user_paths[D_WIIUSER_IDX] + WII_WC24CONF_DIR DIR_SEP; - s_user_paths[F_WIISYSCONF_IDX] = s_user_paths[D_WIISYSCONF_IDX] + WII_SYSCONF; - break; - case D_USER_IDX: s_user_paths[D_GCUSER_IDX] = s_user_paths[D_USER_IDX] + GC_USER_DIR DIR_SEP; s_user_paths[D_WIIROOT_IDX] = s_user_paths[D_USER_IDX] + WII_USER_DIR; - s_user_paths[D_WIIUSER_IDX] = s_user_paths[D_WIIROOT_IDX] + DIR_SEP; s_user_paths[D_CONFIG_IDX] = s_user_paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; s_user_paths[D_GAMESETTINGS_IDX] = s_user_paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP; s_user_paths[D_MAPS_IDX] = s_user_paths[D_USER_IDX] + MAPS_DIR DIR_SEP; @@ -762,14 +781,11 @@ static void RebuildUserDirectories(unsigned int dir_index) s_user_paths[D_DUMPDSP_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP; s_user_paths[D_LOGS_IDX] = s_user_paths[D_USER_IDX] + LOGS_DIR DIR_SEP; s_user_paths[D_MAILLOGS_IDX] = s_user_paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP; - s_user_paths[D_WIISYSCONF_IDX] = s_user_paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP; - s_user_paths[D_WIIWC24_IDX] = s_user_paths[D_WIIUSER_IDX] + WII_WC24CONF_DIR DIR_SEP; s_user_paths[D_THEMES_IDX] = s_user_paths[D_USER_IDX] + THEMES_DIR DIR_SEP; s_user_paths[F_DOLPHINCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DOLPHIN_CONFIG; s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG; s_user_paths[F_MAINLOG_IDX] = s_user_paths[D_LOGS_IDX] + MAIN_LOG; - s_user_paths[F_WIISYSCONF_IDX] = s_user_paths[D_WIISYSCONF_IDX] + WII_SYSCONF; s_user_paths[F_RAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + RAM_DUMP; s_user_paths[F_ARAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + ARAM_DUMP; s_user_paths[F_FAKEVMEMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + FAKEVMEM_DUMP; -- cgit v1.2.3