From fe00919d5f4286b889e00ddbe6b161689069f9f1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 6 Jun 2021 11:20:43 +0200 Subject: [PATCH] [util] Handle upper-case file extensions correctly --- src/dxvk/dxvk_state_cache.cpp | 7 +------ src/util/log/log.cpp | 7 +------ src/util/util_env.cpp | 34 ++++++++++++++++++++++++++++++++-- src/util/util_env.h | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 280824127..1ae453b48 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -985,12 +985,7 @@ namespace dxvk { if (!path.empty() && *path.rbegin() != '/') path += '/'; - std::string exeName = env::getExeName(); - auto extp = exeName.find_last_of('.'); - - if (extp != std::string::npos && exeName.substr(extp + 1) == "exe") - exeName.erase(extp); - + std::string exeName = env::getExeBaseName(); path += exeName + ".dxvk-cache"; return str::tows(path.c_str()); } diff --git a/src/util/log/log.cpp b/src/util/log/log.cpp index a64a0c315..eae1e1a2a 100644 --- a/src/util/log/log.cpp +++ b/src/util/log/log.cpp @@ -100,12 +100,7 @@ namespace dxvk { if (!path.empty() && *path.rbegin() != '/') path += '/'; - std::string exeName = env::getExeName(); - auto extp = exeName.find_last_of('.'); - - if (extp != std::string::npos && exeName.substr(extp + 1) == "exe") - exeName.erase(extp); - + std::string exeName = env::getExeBaseName(); path += exeName + "_" + base; return path; } diff --git a/src/util/util_env.cpp b/src/util/util_env.cpp index 0df61a174..41b859bc3 100644 --- a/src/util/util_env.cpp +++ b/src/util/util_env.cpp @@ -1,3 +1,5 @@ +#include + #include "util_env.h" #include "./com/com_include.h" @@ -13,8 +15,25 @@ namespace dxvk::env { return str::fromws(result.data()); } - - + + + size_t matchFileExtension(const std::string& name, const char* ext) { + auto pos = name.find_last_of('.'); + + if (pos == std::string::npos) + return pos; + + bool matches = std::accumulate(name.begin() + pos + 1, name.end(), true, + [&ext] (bool current, char a) { + if (a >= 'A' && a <= 'Z') + a += 'a' - 'A'; + return current && *ext && a == *(ext++); + }); + + return matches ? pos : std::string::npos; + } + + std::string getExeName() { std::string fullPath = getExePath(); auto n = fullPath.find_last_of('\\'); @@ -25,6 +44,17 @@ namespace dxvk::env { } + std::string getExeBaseName() { + auto exeName = getExeName(); + auto extp = matchFileExtension(exeName, "exe"); + + if (extp != std::string::npos) + exeName.erase(extp); + + return exeName; + } + + std::string getExePath() { std::vector exePath; exePath.resize(MAX_PATH + 1); diff --git a/src/util/util_env.h b/src/util/util_env.h index 2f0008052..e4a1020da 100644 --- a/src/util/util_env.h +++ b/src/util/util_env.h @@ -15,6 +15,16 @@ namespace dxvk::env { */ std::string getEnvVar(const char* name); + /** + * \brief Checks whether a file name has a given extension + * + * \param [in] name File name + * \param [in] ext Extension to match, in lowercase letters + * \returns Position of the extension within the file name, or + * \c std::string::npos if the file has a different extension + */ + size_t matchFileExtension(const std::string& name, const char* ext); + /** * \brief Gets the executable name * @@ -25,6 +35,14 @@ namespace dxvk::env { */ std::string getExeName(); + /** + * \brief Gets the executable name without extension + * + * Same as \ref getExeName but without the file extension. + * \returns Executable name + */ + std::string getExeBaseName(); + /** * \brief Gets full path to executable * \returns Path to executable