aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2018-06-20 07:56:11 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-20 07:57:33 -0700
commit4e578e6f7205a352630720ed482967b6edb4afca (patch)
tree72183211005d58534693656832922c63a5f55f15 /src/main/cpp
parent3e1e177502133f906d1614e32f2c4af02167e990 (diff)
Make blaze_util::AsAbsoluteWindowsPath support wstring as input
Now we have: bool AsAbsoluteWindowsPath(const std::wstring& path, std::wstring* result, std::string* error); This change helps making the C++ native launcher work with UTF-16. See https://github.com/bazelbuild/bazel/issues/4473 Closes #5406. Change-Id: I7eaf55f9fe5a4d41e3dd09edc2a21e9b3cc9277c PiperOrigin-RevId: 201352866
Diffstat (limited to 'src/main/cpp')
-rw-r--r--src/main/cpp/util/BUILD5
-rw-r--r--src/main/cpp/util/logging.cc7
-rw-r--r--src/main/cpp/util/logging.h1
-rw-r--r--src/main/cpp/util/path_platform.h40
-rw-r--r--src/main/cpp/util/path_windows.cc51
5 files changed, 81 insertions, 23 deletions
diff --git a/src/main/cpp/util/BUILD b/src/main/cpp/util/BUILD
index 6f53b4d590..eed2a60a12 100644
--- a/src/main/cpp/util/BUILD
+++ b/src/main/cpp/util/BUILD
@@ -107,7 +107,10 @@ cc_library(
srcs = ["logging.cc"],
hdrs = ["logging.h"],
visibility = ["//visibility:public"],
- deps = [":blaze_exit_code"],
+ deps = [
+ ":blaze_exit_code",
+ ":strings",
+ ],
)
cc_library(
diff --git a/src/main/cpp/util/logging.cc b/src/main/cpp/util/logging.cc
index 40a54aed17..c2e7565bd8 100644
--- a/src/main/cpp/util/logging.cc
+++ b/src/main/cpp/util/logging.cc
@@ -21,6 +21,7 @@
#include <memory>
#include "src/main/cpp/util/exit_code.h"
+#include "src/main/cpp/util/strings.h"
namespace blaze_util {
@@ -68,6 +69,12 @@ DECLARE_STREAM_OPERATOR(float)
DECLARE_STREAM_OPERATOR(double)
DECLARE_STREAM_OPERATOR(long double)
DECLARE_STREAM_OPERATOR(void*)
+
+LogMessage& LogMessage::operator<<(const std::wstring& wstr) {
+ message_ << WstringToString(wstr);
+ return *this;
+}
+
#undef DECLARE_STREAM_OPERATOR
void LogMessage::Finish() {
diff --git a/src/main/cpp/util/logging.h b/src/main/cpp/util/logging.h
index b2cd459d06..7346c18176 100644
--- a/src/main/cpp/util/logging.h
+++ b/src/main/cpp/util/logging.h
@@ -53,6 +53,7 @@ class LogMessage {
int exit_code);
LogMessage& operator<<(const std::string& value);
+ LogMessage& operator<<(const std::wstring& wstr);
LogMessage& operator<<(const char* value);
LogMessage& operator<<(char value);
LogMessage& operator<<(bool value);
diff --git a/src/main/cpp/util/path_platform.h b/src/main/cpp/util/path_platform.h
index 3c4671f004..e2efe097fe 100644
--- a/src/main/cpp/util/path_platform.h
+++ b/src/main/cpp/util/path_platform.h
@@ -77,9 +77,6 @@ std::pair<std::wstring, std::wstring> SplitPathW(const std::wstring &path);
bool IsRootDirectoryW(const std::wstring &path);
-bool AsWindowsPath(const std::string &path, std::string *result,
- std::string *error);
-
// Returns a normalized form of the input `path`.
//
// `path` must be a relative or absolute Windows path, it may use "/" instead of
@@ -95,7 +92,14 @@ bool AsWindowsPath(const std::string &path, std::string *result,
// "foo".
//
// Visible for testing, would be static otherwise.
-std::string NormalizeWindowsPath(std::string path);
+template <typename char_type>
+std::basic_string<char_type> NormalizeWindowsPath(
+ std::basic_string<char_type> path);
+
+template <typename char_type>
+std::basic_string<char_type> NormalizeWindowsPath(const char_type *path) {
+ return NormalizeWindowsPath(std::basic_string<char_type>(path));
+}
// Converts a UTF8-encoded `path` to a normalized, widechar Windows path.
//
@@ -116,8 +120,32 @@ std::string NormalizeWindowsPath(std::string path);
bool AsWindowsPath(const std::string &path, std::wstring *result,
std::string *error);
-bool AsAbsoluteWindowsPath(const std::string &path, std::wstring *wpath,
- std::string *error);
+template <typename char_type>
+bool AsWindowsPath(const std::basic_string<char_type> &path,
+ std::basic_string<char_type> *result, std::string *error);
+
+template <typename char_type>
+bool AsWindowsPath(const char_type *path, std::basic_string<char_type> *result,
+ std::string *error) {
+ return AsWindowsPath(std::basic_string<char_type>(path), result, error);
+}
+
+template <typename char_type>
+bool AsAbsoluteWindowsPath(const std::basic_string<char_type> &path,
+ std::wstring *result, std::string *error);
+
+template <typename char_type>
+bool AsAbsoluteWindowsPath(const char_type *path, std::wstring *result,
+ std::string *error) {
+ return AsAbsoluteWindowsPath(std::basic_string<char_type>(path), result,
+ error);
+}
+
+// Explicit instantiate AsAbsoluteWindowsPath for char and wchar_t.
+template bool AsAbsoluteWindowsPath<char>(const char *, std::wstring *,
+ std::string *);
+template bool AsAbsoluteWindowsPath<wchar_t>(const wchar_t *, std::wstring *,
+ std::string *);
// Same as `AsWindowsPath`, but returns a lowercase 8dot3 style shortened path.
// Result will never have a UNC prefix, nor a trailing "/" or "\".
diff --git a/src/main/cpp/util/path_windows.cc b/src/main/cpp/util/path_windows.cc
index 15dd0ddce6..d115b6e6d9 100644
--- a/src/main/cpp/util/path_windows.cc
+++ b/src/main/cpp/util/path_windows.cc
@@ -215,14 +215,19 @@ std::pair<std::wstring, std::wstring> SplitPathW(const std::wstring& path) {
return SplitPathImpl(path);
}
-bool AsWindowsPath(const std::string& path, std::string* result,
- std::string* error) {
+void assignNUL(std::string* s) { s->assign("NUL"); }
+
+void assignNUL(std::wstring* s) { s->assign(L"NUL"); }
+
+template <typename char_type>
+bool AsWindowsPath(const std::basic_string<char_type>& path,
+ std::basic_string<char_type>* result, std::string* error) {
if (path.empty()) {
result->clear();
return true;
}
if (IsDevNull(path.c_str())) {
- result->assign("NUL");
+ assignNUL(result);
return true;
}
if (HasUncPrefix(path.c_str())) {
@@ -247,7 +252,7 @@ bool AsWindowsPath(const std::string& path, std::string* result,
return false;
}
- std::string mutable_path = path;
+ std::basic_string<char_type> mutable_path = path;
if (path[0] == '/') {
if (error) {
*error = "Unix-style paths are unsupported";
@@ -257,9 +262,10 @@ bool AsWindowsPath(const std::string& path, std::string* result,
if (path[0] == '\\') {
// This is an absolute Windows path on the current drive, e.g. "\foo\bar".
- mutable_path = std::string(1, GetCurrentDrive()) + ":" + path;
+ std::basic_string<char_type> drive(1, GetCurrentDrive());
+ drive.push_back(':');
+ mutable_path = drive + path;
} // otherwise this is a relative path, or absolute Windows path.
-
result->assign(NormalizeWindowsPath(mutable_path));
return true;
}
@@ -275,8 +281,9 @@ bool AsWindowsPath(const std::string& path, std::wstring* result,
return true;
}
-bool AsAbsoluteWindowsPath(const std::string& path, std::wstring* result,
- std::string* error) {
+template <typename char_type>
+bool AsAbsoluteWindowsPath(const std::basic_string<char_type>& path,
+ std::wstring* result, std::string* error) {
if (path.empty()) {
result->clear();
return true;
@@ -373,6 +380,14 @@ bool IsDevNull(const char* path) {
(path[2] == 'L' || path[2] == 'l') && path[3] == 0));
}
+bool IsDevNull(const wchar_t* path) {
+ return path != NULL && *path != 0 &&
+ (wcsncmp(L"/dev/null\0", path, 10) == 0 ||
+ ((path[0] == L'N' || path[0] == L'n') &&
+ (path[1] == L'U' || path[1] == L'u') &&
+ (path[2] == L'L' || path[2] == L'l') && path[3] == 0));
+}
+
bool IsRootDirectory(const std::string& path) {
return IsRootOrAbsolute(path, true);
}
@@ -392,9 +407,11 @@ static char GetCurrentDrive() {
return 'a' + wdrive - offset;
}
-std::string NormalizeWindowsPath(std::string path) {
+template <typename char_type>
+std::basic_string<char_type> NormalizeWindowsPath(
+ std::basic_string<char_type> path) {
if (path.empty()) {
- return "";
+ return std::basic_string<char_type>();
}
if (path[0] == '/') {
// This is an absolute MSYS path, error out.
@@ -405,10 +422,10 @@ std::string NormalizeWindowsPath(std::string path) {
path = path.substr(4);
}
- static const std::string dot(".");
- static const std::string dotdot("..");
+ static const std::basic_string<char_type> dot(1, '.');
+ static const std::basic_string<char_type> dotdot(2, '.');
- std::vector<std::string> segments;
+ std::vector<std::basic_string<char_type>> segments;
int segment_start = -1;
// Find the path segments in `path` (separated by "/").
for (int i = 0;; ++i) {
@@ -421,7 +438,8 @@ std::string NormalizeWindowsPath(std::string path) {
} else if (segment_start >= 0 && i > segment_start) {
// The current character is "/" or "\0", so this ends a segment.
// Add that to `segments` if there's anything to add; handle "." and "..".
- std::string segment(path, segment_start, i - segment_start);
+ std::basic_string<char_type> segment(path, segment_start,
+ i - segment_start);
segment_start = -1;
if (segment == dotdot) {
if (!segments.empty() &&
@@ -441,12 +459,13 @@ std::string NormalizeWindowsPath(std::string path) {
// form of it, e.g. "c:\..").
if (segments.size() == 1 && segments[0].size() == 2 &&
HasDriveSpecifierPrefix(segments[0].c_str())) {
- return segments[0] + '\\';
+ segments[0].push_back('\\');
+ return segments[0];
}
// Join all segments.
bool first = true;
- std::ostringstream result;
+ std::basic_ostringstream<char_type> result;
for (const auto& s : segments) {
if (!first) {
result << '\\';