|
|
@@ -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 {
|