mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
cmSystemTools: adopt the GetActualCaseForPath method from KWSys
No other project uses it and it simplifies KWSys.
This commit is contained in:
@@ -2024,6 +2024,81 @@ std::string cmSystemTools::RelativeIfUnder(std::string const& top,
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string cmSystemTools::GetActualCaseForPath(std::string const& p)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::string casePath;
|
||||
|
||||
// First check if the file is relative. We don't fix relative paths since the
|
||||
// real case depends on the root directory and the given path fragment may
|
||||
// have meaning elsewhere in the project.
|
||||
if (!cmsys::SystemTools::FileIsFullPath(p)) {
|
||||
// This looks unnecessary, but it allows for the return value optimization
|
||||
// since all return paths return the same local variable.
|
||||
casePath = p;
|
||||
return casePath;
|
||||
}
|
||||
|
||||
std::vector<std::string> path_components;
|
||||
cmsys::SystemTools::SplitPath(p, path_components);
|
||||
|
||||
// Start with root component.
|
||||
std::vector<std::string>::size_type idx = 0;
|
||||
casePath = path_components[idx++];
|
||||
// make sure drive letter is always upper case
|
||||
if (casePath.size() > 1 && casePath[1] == ':') {
|
||||
casePath[0] = cmsysString_toupper(casePath[0]);
|
||||
}
|
||||
char const* sep = "";
|
||||
|
||||
// If network path, fill casePath with server/share so FindFirstFile
|
||||
// will work after that. Maybe someday call other APIs to get
|
||||
// actual case of servers and shares.
|
||||
if (path_components.size() > 2 && path_components[0] == "//") {
|
||||
casePath += path_components[idx++];
|
||||
casePath += '/';
|
||||
casePath += path_components[idx++];
|
||||
sep = "/";
|
||||
}
|
||||
|
||||
// Convert case of all components that exist.
|
||||
bool converting = true;
|
||||
for (; idx < path_components.size(); idx++) {
|
||||
casePath += sep;
|
||||
sep = "/";
|
||||
|
||||
if (converting) {
|
||||
// If path component contains wildcards, we skip matching
|
||||
// because these filenames are not allowed on windows,
|
||||
// and we do not want to match a different file.
|
||||
if (path_components[idx].find('*') != std::string::npos ||
|
||||
path_components[idx].find('?') != std::string::npos) {
|
||||
converting = false;
|
||||
} else {
|
||||
std::string test_str = casePath;
|
||||
test_str += path_components[idx];
|
||||
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE hFind = ::FindFirstFileW(
|
||||
cmsys::Encoding::ToWide(test_str).c_str(), &findData);
|
||||
if (INVALID_HANDLE_VALUE != hFind) {
|
||||
auto case_file_name = cmsys::Encoding::ToNarrow(findData.cFileName);
|
||||
path_components[idx] = std::move(case_file_name);
|
||||
::FindClose(hFind);
|
||||
} else {
|
||||
converting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
casePath += path_components[idx];
|
||||
}
|
||||
return casePath;
|
||||
#else
|
||||
return p;
|
||||
#endif
|
||||
}
|
||||
|
||||
cm::optional<std::string> cmSystemTools::GetEnvVar(std::string const& var)
|
||||
{
|
||||
cm::optional<std::string> result;
|
||||
|
||||
@@ -426,6 +426,8 @@ public:
|
||||
static std::string RelativeIfUnder(std::string const& top,
|
||||
std::string const& in);
|
||||
|
||||
static std::string GetActualCaseForPath(std::string const& p);
|
||||
|
||||
static cm::optional<std::string> GetEnvVar(std::string const& var);
|
||||
static std::vector<std::string> GetEnvPathNormalized(std::string const& var);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user