summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKWSys Upstream <kwrobot@kitware.com>2018-02-01 12:44:45 (GMT)
committerBrad King <brad.king@kitware.com>2018-02-01 13:15:44 (GMT)
commit854feacc60c5d1dcf53652a764841e1d9d602ac3 (patch)
tree5679894f4e8dd9feed0a17296aa5c91f8db634d9
parent7a75657084c518a39b192c7ee1568588944677af (diff)
downloadCMake-854feacc60c5d1dcf53652a764841e1d9d602ac3.zip
CMake-854feacc60c5d1dcf53652a764841e1d9d602ac3.tar.gz
CMake-854feacc60c5d1dcf53652a764841e1d9d602ac3.tar.bz2
KWSys 2018-02-01 (04fcc449)
Code extracted from: https://gitlab.kitware.com/utils/kwsys.git at commit 04fcc449646eb2ff3d701986946a1db60b2161b7 (master). Upstream Shortlog ----------------- Ben Boeckel (11): ba270398 SystemToolsAppendComponents: move strings when building components cfd0f1e6 JoinPath: push back as a character 6770cb3e GetFilenameName: optionally don't search for \ on non-Windows 22b189b0 ConvertToUnixSlashes: remove escaped space logic 342d69a4 ConvertToUnixSlashes: short-circuit on hasDoubleSlash 5dd87350 ConvertToUnixSlashes: remove pos1 3b46b7c0 ConvertToUnixSlashes: bail early on empty paths 55d1d6ab CollapseFullPath: reserve space for components 68807138 CollapseFullPath: prefer .empty() to .length() == 0 71a6de42 CollapseFullPath: refactor the overloads to share implementations 318550c7 CheckCollapsePath: add more test cases
-rw-r--r--CMakeLists.txt10
-rw-r--r--SystemTools.cxx141
-rw-r--r--testSystemTools.cxx36
3 files changed, 89 insertions, 98 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2570e5b..c0154c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -496,6 +496,16 @@ IF(KWSYS_USE_SystemTools)
KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
)
+ IF(NOT WIN32)
+ IF(KWSYS_STANDALONE)
+ OPTION(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
+ ENDIF()
+ IF(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+ SET_PROPERTY(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES
+ )
+ ENDIF()
+ ENDIF()
# Disable getpwnam for static linux builds since it depends on shared glibc
GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
diff --git a/SystemTools.cxx b/SystemTools.cxx
index 999beb3..38910c8 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -1884,21 +1884,23 @@ static void ConvertVMSToUnix(std::string& path)
// convert windows slashes to unix slashes
void SystemTools::ConvertToUnixSlashes(std::string& path)
{
+ if (path.empty()) {
+ return;
+ }
+
const char* pathCString = path.c_str();
bool hasDoubleSlash = false;
#ifdef __VMS
ConvertVMSToUnix(path);
#else
const char* pos0 = pathCString;
- const char* pos1 = pathCString + 1;
for (std::string::size_type pos = 0; *pos0; ++pos) {
- // make sure we don't convert an escaped space to a unix slash
- if (*pos0 == '\\' && *pos1 != ' ') {
+ if (*pos0 == '\\') {
path[pos] = '/';
}
// Also, reuse the loop to check for slash followed by another slash
- if (*pos1 == '/' && *(pos1 + 1) == '/' && !hasDoubleSlash) {
+ if (!hasDoubleSlash && *(pos0 + 1) == '/' && *(pos0 + 2) == '/') {
#ifdef _WIN32
// However, on windows if the first characters are both slashes,
// then keep them that way, so that network paths can be handled.
@@ -1911,43 +1913,41 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
}
pos0++;
- pos1++;
}
if (hasDoubleSlash) {
SystemTools::ReplaceString(path, "//", "/");
}
#endif
+
// remove any trailing slash
- if (!path.empty()) {
- // if there is a tilda ~ then replace it with HOME
- pathCString = path.c_str();
- if (pathCString[0] == '~' &&
- (pathCString[1] == '/' || pathCString[1] == '\0')) {
- std::string homeEnv;
- if (SystemTools::GetEnv("HOME", homeEnv)) {
- path.replace(0, 1, homeEnv);
- }
+ // if there is a tilda ~ then replace it with HOME
+ pathCString = path.c_str();
+ if (pathCString[0] == '~' &&
+ (pathCString[1] == '/' || pathCString[1] == '\0')) {
+ std::string homeEnv;
+ if (SystemTools::GetEnv("HOME", homeEnv)) {
+ path.replace(0, 1, homeEnv);
}
+ }
#ifdef HAVE_GETPWNAM
- else if (pathCString[0] == '~') {
- std::string::size_type idx = path.find_first_of("/\0");
- std::string user = path.substr(1, idx - 1);
- passwd* pw = getpwnam(user.c_str());
- if (pw) {
- path.replace(0, idx, pw->pw_dir);
- }
+ else if (pathCString[0] == '~') {
+ std::string::size_type idx = path.find_first_of("/\0");
+ std::string user = path.substr(1, idx - 1);
+ passwd* pw = getpwnam(user.c_str());
+ if (pw) {
+ path.replace(0, idx, pw->pw_dir);
}
+ }
#endif
- // remove trailing slash if the path is more than
- // a single /
- pathCString = path.c_str();
- size_t size = path.size();
- if (size > 1 && *path.rbegin() == '/') {
- // if it is c:/ then do not remove the trailing slash
- if (!((size == 3 && pathCString[1] == ':'))) {
- path.resize(size - 1);
- }
+ // remove trailing slash if the path is more than
+ // a single /
+ pathCString = path.c_str();
+ size_t size = path.size();
+ if (size > 1 && *path.rbegin() == '/') {
+ // if it is c:/ then do not remove the trailing slash
+ if (!((size == 3 && pathCString[1] == ':'))) {
+ path.resize(size - 1);
}
}
}
@@ -3171,8 +3171,8 @@ void SystemTools::CheckTranslationPath(std::string& path)
static void SystemToolsAppendComponents(
std::vector<std::string>& out_components,
- std::vector<std::string>::const_iterator first,
- std::vector<std::string>::const_iterator last)
+ std::vector<std::string>::iterator first,
+ std::vector<std::string>::iterator last)
{
static const std::string up = "..";
static const std::string cur = ".";
@@ -3182,7 +3182,11 @@ static void SystemToolsAppendComponents(
out_components.resize(out_components.size() - 1);
}
} else if (!i->empty() && *i != cur) {
+#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
+ out_components.push_back(std::move(*i));
+#else
out_components.push_back(*i);
+#endif
}
}
}
@@ -3190,63 +3194,18 @@ static void SystemToolsAppendComponents(
std::string SystemTools::CollapseFullPath(const std::string& in_path,
const char* in_base)
{
- // Collect the output path components.
- std::vector<std::string> out_components;
-
- // Split the input path components.
- std::vector<std::string> path_components;
- SystemTools::SplitPath(in_path, path_components);
-
- // If the input path is relative, start with a base path.
- if (path_components[0].empty()) {
- std::vector<std::string> base_components;
- if (in_base) {
- // Use the given base path.
- SystemTools::SplitPath(in_base, base_components);
+ // Use the current working directory as a base path.
+ char buf[2048];
+ const char* res_in_base = in_base;
+ if (!res_in_base) {
+ if (const char* cwd = Getcwd(buf, 2048)) {
+ res_in_base = cwd;
} else {
- // Use the current working directory as a base path.
- char buf[2048];
- if (const char* cwd = Getcwd(buf, 2048)) {
- SystemTools::SplitPath(cwd, base_components);
- } else {
- base_components.push_back("");
- }
+ res_in_base = "";
}
-
- // Append base path components to the output path.
- out_components.push_back(base_components[0]);
- SystemToolsAppendComponents(out_components, base_components.begin() + 1,
- base_components.end());
}
- // Append input path components to the output path.
- SystemToolsAppendComponents(out_components, path_components.begin(),
- path_components.end());
-
- // Transform the path back to a string.
- std::string newPath = SystemTools::JoinPath(out_components);
-
- // Update the translation table with this potentially new path. I am not
- // sure why this line is here, it seems really questionable, but yet I
- // would put good money that if I remove it something will break, basically
- // from what I can see it created a mapping from the collapsed path, to be
- // replaced by the input path, which almost completely does the opposite of
- // this function, the only thing preventing this from happening a lot is
- // that if the in_path has a .. in it, then it is not added to the
- // translation table. So for most calls this either does nothing due to the
- // .. or it adds a translation between identical paths as nothing was
- // collapsed, so I am going to try to comment it out, and see what hits the
- // fan, hopefully quickly.
- // Commented out line below:
- // SystemTools::AddTranslationPath(newPath, in_path);
-
- SystemTools::CheckTranslationPath(newPath);
-#ifdef _WIN32
- newPath = SystemTools::GetActualCaseForPath(newPath);
- SystemTools::ConvertToUnixSlashes(newPath);
-#endif
- // Return the reconstructed path.
- return newPath;
+ return SystemTools::CollapseFullPath(in_path, std::string(res_in_base));
}
std::string SystemTools::CollapseFullPath(const std::string& in_path,
@@ -3258,9 +3217,10 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
// Split the input path components.
std::vector<std::string> path_components;
SystemTools::SplitPath(in_path, path_components);
+ out_components.reserve(path_components.size());
// If the input path is relative, start with a base path.
- if (path_components[0].length() == 0) {
+ if (path_components[0].empty()) {
std::vector<std::string> base_components;
// Use the given base path.
SystemTools::SplitPath(in_base, base_components);
@@ -3619,7 +3579,7 @@ std::string SystemTools::JoinPath(
// All remaining components are always separated with a slash.
while (first != last) {
- result.append("/");
+ result.push_back('/');
result.append((*first++));
}
@@ -3715,7 +3675,12 @@ std::string SystemTools::GetFilenamePath(const std::string& filename)
*/
std::string SystemTools::GetFilenameName(const std::string& filename)
{
- std::string::size_type slash_pos = filename.find_last_of("/\\");
+#if defined(_WIN32) || defined(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+ const char* separators = "/\\";
+#else
+ char separators = '/';
+#endif
+ std::string::size_type slash_pos = filename.find_last_of(separators);
if (slash_pos != std::string::npos) {
return filename.substr(slash_pos + 1);
} else {
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index f1321e5..e436a2b 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -39,19 +39,19 @@ typedef unsigned short mode_t;
static const char* toUnixPaths[][2] = {
{ "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
{ "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
- { "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo/ cal/bin/pa/ sswd" },
{ "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" },
{ "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" },
- { "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo/ cal/bin/pa/ sswd" },
{ "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" },
{ "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" },
- { "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo/ cal/bin/pa/ sswd" },
{ "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" },
{ "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" },
- { "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo/ cal/bin/pa/ sswd" },
{ "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
{ "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
- { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo\\ cal/bin/pa\\ sswd" },
+ { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo/ cal/bin/pa/ sswd" },
{ KWSYS_NULLPTR, KWSYS_NULLPTR }
};
@@ -700,6 +700,16 @@ static bool CheckCollapsePath()
bool res = true;
res &= CheckCollapsePath("/usr/share/*", "/usr/share/*");
res &= CheckCollapsePath("C:/Windows/*", "C:/Windows/*");
+ res &= CheckCollapsePath("/usr/share/../lib", "/usr/lib");
+ res &= CheckCollapsePath("/usr/share/./lib", "/usr/share/lib");
+ res &= CheckCollapsePath("/usr/share/../../lib", "/lib");
+ res &= CheckCollapsePath("/usr/share/.././../lib", "/lib");
+ res &= CheckCollapsePath("/../lib", "/lib");
+ res &= CheckCollapsePath("/../lib/", "/lib");
+ res &= CheckCollapsePath("/", "/");
+ res &= CheckCollapsePath("C:/", "C:/");
+ res &= CheckCollapsePath("C:/../", "C:/");
+ res &= CheckCollapsePath("C:/../../", "C:/");
return res;
}
@@ -764,20 +774,26 @@ static bool CheckGetFilenameName()
const char* windowsFilepath = "C:\\somewhere\\something";
const char* unixFilepath = "/somewhere/something";
- std::string expectedFilename = "something";
+#if defined(_WIN32) || defined(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+ std::string expectedWindowsFilename = "something";
+#else
+ std::string expectedWindowsFilename = "C:\\somewhere\\something";
+#endif
+ std::string expectedUnixFilename = "something";
bool res = true;
std::string filename = kwsys::SystemTools::GetFilenameName(windowsFilepath);
- if (filename != expectedFilename) {
+ if (filename != expectedWindowsFilename) {
std::cerr << "GetFilenameName(" << windowsFilepath << ") yielded "
- << filename << " instead of " << expectedFilename << std::endl;
+ << filename << " instead of " << expectedWindowsFilename
+ << std::endl;
res = false;
}
filename = kwsys::SystemTools::GetFilenameName(unixFilepath);
- if (filename != expectedFilename) {
+ if (filename != expectedUnixFilename) {
std::cerr << "GetFilenameName(" << unixFilepath << ") yielded " << filename
- << " instead of " << expectedFilename << std::endl;
+ << " instead of " << expectedUnixFilename << std::endl;
res = false;
}
return res;