KWSys 2016-09-14 (c4049689)

Code extracted from:

    http://public.kitware.com/KWSys.git

at commit c4049689d1ff6e3b9f59358023aebb1a7e0fd149 (master).

Upstream Shortlog
-----------------

Brad King (2):
      0504dcaf SystemTools: Fix path comparison in test case
      c4049689 SystemTools: Teach GetActualCaseForPath to convert as much as possible
This commit is contained in:
KWSys Upstream 2016-09-14 09:38:50 -04:00 committed by Brad King
parent b80d613632
commit d28e4467aa
3 changed files with 44 additions and 37 deletions

View File

@ -3982,16 +3982,16 @@ std::string SystemTools::RelativePath(const std::string& local, const std::strin
} }
#ifdef _WIN32 #ifdef _WIN32
static int GetCasePathName(const std::string & pathIn, static std::string GetCasePathName(std::string const& pathIn)
std::string & casePath)
{ {
std::string casePath;
std::vector<std::string> path_components; std::vector<std::string> path_components;
SystemTools::SplitPath(pathIn, path_components); SystemTools::SplitPath(pathIn, path_components);
if(path_components[0].empty()) // First component always exists. if(path_components[0].empty()) // First component always exists.
{ {
// Relative paths cannot be converted. // Relative paths cannot be converted.
casePath = ""; casePath = pathIn;
return 0; return casePath;
} }
// Start with root component. // Start with root component.
@ -4015,38 +4015,45 @@ static int GetCasePathName(const std::string & pathIn,
sep = "/"; sep = "/";
} }
// Convert case of all components that exist.
bool converting = true;
for(; idx < path_components.size(); idx++) for(; idx < path_components.size(); idx++)
{ {
casePath += sep; casePath += sep;
sep = "/"; sep = "/";
std::string test_str = casePath;
test_str += path_components[idx];
// If path component contains wildcards, we skip matching if (converting)
// 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)
{ {
casePath = ""; // If path component contains wildcards, we skip matching
return 0; // 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(Encoding::ToWide(test_str).c_str(),
&findData);
if (INVALID_HANDLE_VALUE != hFind)
{
path_components[idx] = Encoding::ToNarrow(findData.cFileName);
::FindClose(hFind);
}
else
{
converting = false;
}
}
} }
WIN32_FIND_DATAW findData; casePath += path_components[idx];
HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
&findData);
if (INVALID_HANDLE_VALUE != hFind)
{
casePath += Encoding::ToNarrow(findData.cFileName);
::FindClose(hFind);
}
else
{
casePath = "";
return 0;
}
} }
return (int)casePath.size(); return casePath;
} }
#endif #endif
@ -4065,11 +4072,10 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p)
{ {
return i->second; return i->second;
} }
std::string casePath; std::string casePath = GetCasePathName(p);
int len = GetCasePathName(p, casePath); if (casePath.size() > MAX_PATH)
if(len == 0 || len > MAX_PATH+1)
{ {
return p; return casePath;
} }
(*SystemTools::PathCaseMap)[p] = casePath; (*SystemTools::PathCaseMap)[p] = casePath;
return casePath; return casePath;

View File

@ -374,10 +374,11 @@ public:
static const char* GetExecutableExtension(); static const char* GetExecutableExtension();
/** /**
* Given a path that exists on a windows machine, return the * Given a path on a Windows machine, return the actual case of
* actuall case of the path as it was created. If the file * the path as it exists on disk. Path components that do not
* does not exist path is returned unchanged. This does nothing * exist on disk are returned unchanged. Relative paths are always
* on unix but return path. * returned unchanged. Drive letters are always made upper case.
* This does nothing on non-Windows systems but return the path.
*/ */
static std::string GetActualCaseForPath(const std::string& path); static std::string GetActualCaseForPath(const std::string& path);

View File

@ -940,7 +940,7 @@ static bool CheckRelativePath(
const std::string& expected) const std::string& expected)
{ {
std::string result = kwsys::SystemTools::RelativePath(local, remote); std::string result = kwsys::SystemTools::RelativePath(local, remote);
if(expected != result) if (!kwsys::SystemTools::ComparePath(expected, result))
{ {
std::cerr << "RelativePath(" << local << ", " << remote std::cerr << "RelativePath(" << local << ", " << remote
<< ") yielded " << result << " instead of " << expected << std::endl; << ") yielded " << result << " instead of " << expected << std::endl;
@ -965,7 +965,7 @@ static bool CheckCollapsePath(
const std::string& expected) const std::string& expected)
{ {
std::string result = kwsys::SystemTools::CollapseFullPath(path); std::string result = kwsys::SystemTools::CollapseFullPath(path);
if(expected != result) if (!kwsys::SystemTools::ComparePath(expected, result))
{ {
std::cerr << "CollapseFullPath(" << path std::cerr << "CollapseFullPath(" << path
<< ") yielded " << result << " instead of " << expected << std::endl; << ") yielded " << result << " instead of " << expected << std::endl;