Bazel client: platform-specific JoinPath This allows joining paths on "\" instead of "/" when building for Windows. See https://github.com/bazelbuild/bazel/issues/2107 -- Change-Id: I417ba40af6530650be2394db4bd445f0883d40e5 Reviewed-on: https://cr.bazel.build/8495 PiperOrigin-RevId: 145961689 MOS_MIGRATED_REVID=145961689
diff --git a/src/main/cpp/util/file.cc b/src/main/cpp/util/file.cc index 392af37..cae8719 100644 --- a/src/main/cpp/util/file.cc +++ b/src/main/cpp/util/file.cc
@@ -77,31 +77,6 @@ return SplitPath(path).second; } -string JoinPath(const string &path1, const string &path2) { - if (path1.empty()) { - // "" + "/bar" - return path2; - } - - if (path1[path1.size() - 1] == '/') { - if (path2.find('/') == 0) { - // foo/ + /bar - return path1 + path2.substr(1); - } else { - // foo/ + bar - return path1 + path2; - } - } else { - if (path2.find('/') == 0) { - // foo + /bar - return path1 + path2; - } else { - // foo + bar - return path1 + "/" + path2; - } - } -} - class DirectoryTreeWalker : public DirectoryEntryConsumer { public: DirectoryTreeWalker(vector<string> *files,
diff --git a/src/main/cpp/util/file.h b/src/main/cpp/util/file.h index efe963c..e3a744f 100644 --- a/src/main/cpp/util/file.h +++ b/src/main/cpp/util/file.h
@@ -17,6 +17,7 @@ #include <functional> #include <string> #include <vector> +#include "src/main/cpp/util/file_platform.h" namespace blaze_util { @@ -59,8 +60,6 @@ // "/" in the path, the result is the same as the input. std::string Basename(const std::string &path); -std::string JoinPath(const std::string &path1, const std::string &path2); - // Lists all files in `path` and all of its subdirectories. // // Does not follow symlinks / junctions.
diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h index 600820b..99cf990 100644 --- a/src/main/cpp/util/file_platform.h +++ b/src/main/cpp/util/file_platform.h
@@ -50,6 +50,8 @@ // Creates a platform-specific implementation of `IFileMtime`. IFileMtime *CreateFileMtime(); +std::string JoinPath(const std::string &path1, const std::string &path2); + // Split a path to dirname and basename parts. std::pair<std::string, std::string> SplitPath(const std::string &path);
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index a1d806a..57c994a 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc
@@ -168,6 +168,35 @@ return new PosixPipe(fd[0], fd[1]); } +string JoinPath(const string &path1, const string &path2) { + if (path1.empty()) { + // "" + "/bar" + return path2; + } + if (path2.empty()) { + // "foo/" + "" + return path1; + } + + if (path1.back() == '/') { + if (path2.front() == '/') { + // foo/ + /bar + return path1 + path2.substr(1); + } else { + // foo/ + bar + return path1 + path2; + } + } else { + if (path2.front() == '/') { + // foo + /bar + return path1 + path2; + } else { + // foo + bar + return path1 + "/" + path2; + } + } +} + pair<string, string> SplitPath(const string &path) { size_t pos = path.rfind('/');
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc index b1faddd..2deee0b 100644 --- a/src/main/cpp/util/file_windows.cc +++ b/src/main/cpp/util/file_windows.cc
@@ -323,6 +323,44 @@ HasDriveSpecifierPrefix(path.c_str() + 4) && IsPathSeparator(path[6])); } +string JoinPath(const string& path1, const string& path2) { + if (path1.empty()) { + // "" + "/bar" + return path2; + } + if (path2.empty()) { + // "foo/" + "" + return path1; + } + + string p1 = path1; + if (path1.back() == '/') { + p1.pop_back(); + } + string p2 = path2; + if (path2.front() == '/') { + p2[0] = '\\'; + } + + if (IsPathSeparator(p1.back())) { + if (!p2.empty() && IsPathSeparator(p2.front())) { + // foo/ + /bar + return p1 + p2.substr(1); + } else { + // foo/ + bar + return p1 + p2; + } + } else { + if (!p2.empty() && IsPathSeparator(p2.front())) { + // foo + /bar + return p1 + p2; + } else { + // foo + bar + return p1 + "\\" + p2; + } + } +} + pair<string, string> SplitPath(const string& path) { if (path.empty()) { return std::make_pair("", "");