Changed a number of FileSystemUtil functions to use std::filesystem facilities

This commit is contained in:
Leon Styhre 2023-12-13 22:04:14 +01:00
parent 6bcbd70237
commit b72e2a20a8
4 changed files with 119 additions and 42 deletions

View file

@ -697,8 +697,8 @@ void ThemeData::populateThemes()
} }
#if defined(__ANDROID__) #if defined(__ANDROID__)
const std::vector<std::string> themePaths {Utils::FileSystem::getProgramDataPath() + "/themes", const std::vector<std::string> themePaths {
userThemeDirectory}; Utils::FileSystem::getProgramDataPath().string() + "/themes", userThemeDirectory};
#elif defined(__APPLE__) #elif defined(__APPLE__)
const std::vector<std::string> themePaths { const std::vector<std::string> themePaths {
Utils::FileSystem::getExePath() + "/themes", Utils::FileSystem::getExePath() + "/themes",
@ -707,9 +707,9 @@ void ThemeData::populateThemes()
const std::vector<std::string> themePaths {Utils::FileSystem::getExePath() + "/themes", const std::vector<std::string> themePaths {Utils::FileSystem::getExePath() + "/themes",
userThemeDirectory}; userThemeDirectory};
#else #else
const std::vector<std::string> themePaths {Utils::FileSystem::getExePath() + "/themes", const std::vector<std::string> themePaths {
Utils::FileSystem::getProgramDataPath() + "/themes", Utils::FileSystem::getExePath() + "/themes",
userThemeDirectory}; Utils::FileSystem::getProgramDataPath().string() + "/themes", userThemeDirectory};
#endif #endif
for (auto path : themePaths) { for (auto path : themePaths) {

View file

@ -43,7 +43,7 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi
} }
#elif (defined(__unix__) && !defined(APPIMAGE_BUILD)) || defined(__ANDROID__) #elif (defined(__unix__) && !defined(APPIMAGE_BUILD)) || defined(__ANDROID__)
// Check in the program data directory. // Check in the program data directory.
std::string testDataPath {Utils::FileSystem::getProgramDataPath() + "/resources/" + std::string testDataPath {Utils::FileSystem::getProgramDataPath().string() + "/resources/" +
&path[2]}; &path[2]};
if (Utils::FileSystem::exists(testDataPath)) if (Utils::FileSystem::exists(testDataPath))
return testDataPath; return testDataPath;

View file

@ -42,14 +42,14 @@
// build environment is broken. // build environment is broken.
#if defined(__unix__) #if defined(__unix__)
#if defined(ES_INSTALL_PREFIX) #if defined(ES_INSTALL_PREFIX)
const std::string installPrefix {ES_INSTALL_PREFIX}; const std::filesystem::path installPrefix {ES_INSTALL_PREFIX};
#else #else
#if defined(__linux__) #if defined(__linux__)
const std::string installPrefix {"/usr"}; const std::filesystem::path installPrefix {"/usr"};
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
const std::string installPrefix {"/usr/pkg"}; const std::filesystem::path installPrefix {"/usr/pkg"};
#else #else
const std::string installPrefix {"/usr/local"}; const std::filesystem::path installPrefix {"/usr/local"};
#endif #endif
#endif #endif
#endif #endif
@ -59,8 +59,9 @@ namespace Utils
namespace FileSystem namespace FileSystem
{ {
static std::string homePath; static std::string homePath;
static std::string exePath; static std::filesystem::path homePathSTD;
static std::string esBinary; static std::filesystem::path exePath;
static std::filesystem::path esBinary;
StringList getDirContent(const std::string& path, const bool recursive) StringList getDirContent(const std::string& path, const bool recursive)
{ {
@ -168,6 +169,7 @@ namespace Utils
{ {
// Set home path. // Set home path.
homePath = getGenericPath(path); homePath = getGenericPath(path);
homePathSTD = std::filesystem::path {homePath};
} }
std::string getHomePath() std::string getHomePath()
@ -208,11 +210,52 @@ namespace Utils
// No homepath found, fall back to current working directory. // No homepath found, fall back to current working directory.
if (!homePath.length()) if (!homePath.length())
homePath = getCWDPath(); homePath = std::filesystem::current_path().string();
return homePath; return homePath;
} }
std::filesystem::path getHomePathSTD()
{
// Only construct the homepath once.
if (!homePathSTD.empty())
return homePathSTD;
#if defined(_WIN64)
// On Windows we need to check HOMEDRIVE and HOMEPATH.
std::wstring envHomeDrive;
std::wstring envHomePath;
#if defined(_MSC_VER) // MSVC compiler.
wchar_t* buffer;
if (!_wdupenv_s(&buffer, nullptr, L"HOMEDRIVE"))
envHomeDrive = buffer;
if (!_wdupenv_s(&buffer, nullptr, L"HOMEPATH"))
envHomePath = buffer;
#else
envHomeDrive = _wgetenv(L"HOMEDRIVE");
envHomePath = _wgetenv(L"HOMEPATH");
#endif
if (envHomeDrive.length() && envHomePath.length())
homePathSTD = std::filesystem::path {
getGenericPath(Utils::String::wideStringToString(envHomeDrive) + "/" +
Utils::String::wideStringToString(envHomePath))};
#else
std::string envHome;
if (getenv("HOME") != nullptr)
envHome = getenv("HOME");
if (envHome.length())
homePathSTD = std::filesystem::path {getGenericPath(envHome)};
#endif
// No homepath found, fall back to current working directory.
if (homePathSTD.empty())
homePathSTD = std::filesystem::current_path();
return homePathSTD;
}
std::string getSystemHomeDirectory() std::string getSystemHomeDirectory()
{ {
#if defined(_WIN64) #if defined(_WIN64)
@ -241,18 +284,12 @@ namespace Utils
return ""; return "";
} }
std::string getCWDPath() std::filesystem::path getESDataDirectory()
{ {
// Return current working directory. #if defined(__ANDROID__)
return getHomePathSTD().append(".emulationstation");
#if defined(_WIN64)
wchar_t tempWide[512];
return (_wgetcwd(tempWide, 512) ?
getGenericPath(Utils::String::wideStringToString(tempWide)) :
"");
#else #else
char temp[512]; return getHomePathSTD().append(".emulationstation");
return (getcwd(temp, 512) ? getGenericPath(temp) : "");
#endif #endif
} }
@ -321,56 +358,75 @@ namespace Utils
void setExePath(const std::string& path) void setExePath(const std::string& path)
{ {
std::string exePathTemp;
std::string esBinaryTemp;
constexpr int pathMax {32767}; constexpr int pathMax {32767};
#if defined(_WIN64) #if defined(_WIN64)
std::wstring result(pathMax, 0); std::wstring result(pathMax, 0);
if (GetModuleFileNameW(nullptr, &result[0], pathMax) != 0) if (GetModuleFileNameW(nullptr, &result[0], pathMax) != 0)
exePath = Utils::String::wideStringToString(result); exePathTemp = Utils::String::wideStringToString(result);
#else #else
std::string result(pathMax, 0); std::string result(pathMax, 0);
if (readlink("/proc/self/exe", &result[0], pathMax) != -1) if (readlink("/proc/self/exe", &result[0], pathMax) != -1)
exePath = result; exePathTemp = result;
#endif #endif
exePath.erase(std::find(exePath.begin(), exePath.end(), '\0'), exePath.end()); exePathTemp.erase(std::find(exePathTemp.begin(), exePathTemp.end(), '\0'),
esBinary = exePath; exePathTemp.end());
exePath = getCanonicalPath(exePath); esBinaryTemp = exePathTemp;
exePathTemp = getCanonicalPath(exePathTemp);
// Fallback to argv[0] if everything else fails. // Fallback to argv[0] if everything else fails.
if (exePath.empty()) { if (exePathTemp.empty()) {
esBinary = path; esBinaryTemp = path;
exePath = getCanonicalPath(path); exePathTemp = getCanonicalPath(path);
} }
if (isRegularFile(exePath)) if (isRegularFile(exePathTemp))
exePath = getParent(exePath); exePathTemp = getParent(exePathTemp);
exePath = std::filesystem::path {exePathTemp};
esBinary = std::filesystem::path {esBinaryTemp};
#if defined(APPIMAGE_BUILD) #if defined(APPIMAGE_BUILD)
// We need to check that the APPIMAGE variable is available as the APPIMAGE_BUILD // We need to check that the APPIMAGE variable is available as the APPIMAGE_BUILD
// build flag could have been passed without running as an actual AppImage. // build flag could have been passed without running as an actual AppImage.
if (getenv("APPIMAGE") != nullptr) if (getenv("APPIMAGE") != nullptr)
esBinary = getenv("APPIMAGE"); esBinary = std::filesystem::path {getenv("APPIMAGE")};
#endif #endif
} }
std::string getExePath() std::string getExePath()
{
// Return executable path.
return exePath.string();
}
std::filesystem::path getExePathSTD()
{ {
// Return executable path. // Return executable path.
return exePath; return exePath;
} }
std::string getEsBinary() std::string getEsBinary()
{
// Return the absolute path to the ES-DE binary.
return esBinary.string();
}
std::filesystem::path getEsBinarySTD()
{ {
// Return the absolute path to the ES-DE binary. // Return the absolute path to the ES-DE binary.
return esBinary; return esBinary;
} }
std::string getProgramDataPath() std::filesystem::path getProgramDataPath()
{ {
#if defined(__ANDROID__) #if defined(__ANDROID__)
return AndroidVariables::sPrivateDataDirectory; return AndroidVariables::sPrivateDataDirectory;
#elif defined(__unix__) #elif defined(__unix__)
return installPrefix + "/share/emulationstation"; return std::filesystem::path {installPrefix}.append("share").append("emulationstation");
#else #else
return ""; return std::filesystem::path {};
#endif #endif
} }
@ -789,7 +845,7 @@ namespace Utils
bool createEmptyFile(const std::filesystem::path& path) bool createEmptyFile(const std::filesystem::path& path)
{ {
const std::filesystem::path cleanPath {path.lexically_normal().make_preferred()}; const std::filesystem::path cleanPath {path.lexically_normal().make_preferred()};
if (exists(path)) { if (existsSTD(path)) {
LOG(LogError) << "Couldn't create target file \"" << cleanPath.string() LOG(LogError) << "Couldn't create target file \"" << cleanPath.string()
<< "\" as it already exists"; << "\" as it already exists";
return false; return false;
@ -897,6 +953,22 @@ namespace Utils
} }
} }
bool existsSTD(const std::filesystem::path& path)
{
const std::string& genericPath {getGenericPath(path.string())};
try {
#if defined(_WIN64)
return std::filesystem::exists(Utils::String::stringToWideString(genericPath));
#else
return std::filesystem::exists(genericPath);
#endif
}
catch (std::filesystem::filesystem_error& error) {
LOG(LogError) << "FileSystemUtil::exists(): " << error.what();
return false;
}
}
bool driveExists(const std::string& path) bool driveExists(const std::string& path)
{ {
#if defined(_WIN64) #if defined(_WIN64)

View file

@ -26,19 +26,23 @@ namespace Utils
StringList getPathList(const std::string& path); StringList getPathList(const std::string& path);
void setHomePath(const std::string& path); void setHomePath(const std::string& path);
std::string getHomePath(); std::string getHomePath();
std::filesystem::path getHomePathSTD();
std::string getSystemHomeDirectory(); std::string getSystemHomeDirectory();
std::string getCWDPath(); std::filesystem::path getESDataDirectory();
std::string getPathToBinary(const std::string& executable); std::string getPathToBinary(const std::string& executable);
void setExePath(const std::string& path); void setExePath(const std::string& path);
std::string getExePath(); std::string getExePath();
std::filesystem::path getExePathSTD();
std::string getEsBinary(); std::string getEsBinary();
std::string getProgramDataPath(); std::filesystem::path getEsBinarySTD();
std::filesystem::path getProgramDataPath();
std::string getPreferredPath(const std::string& path); std::string getPreferredPath(const std::string& path);
std::string getGenericPath(const std::string& path); std::string getGenericPath(const std::string& path);
std::string getEscapedPath(const std::string& path); std::string getEscapedPath(const std::string& path);
std::string getCanonicalPath(const std::string& path); std::string getCanonicalPath(const std::string& path);
std::string getAbsolutePath(const std::string& path, std::string getAbsolutePath(
const std::string& base = getCWDPath()); const std::string& path,
const std::string& base = std::filesystem::current_path().string());
std::string getParent(const std::string& path); std::string getParent(const std::string& path);
std::string getFileName(const std::string& path); std::string getFileName(const std::string& path);
std::string getStem(const std::string& path); std::string getStem(const std::string& path);
@ -66,6 +70,7 @@ namespace Utils
bool removeDirectory(const std::string& path, bool recursive); bool removeDirectory(const std::string& path, bool recursive);
bool createDirectory(const std::string& path); bool createDirectory(const std::string& path);
bool exists(const std::string& path); bool exists(const std::string& path);
bool existsSTD(const std::filesystem::path& path);
bool driveExists(const std::string& path); bool driveExists(const std::string& path);
bool isAbsolute(const std::string& path); bool isAbsolute(const std::string& path);
bool isRegularFile(const std::string& path); bool isRegularFile(const std::string& path);