diff options
author | 2017-03-21 14:52:38 +0100 | |
---|---|---|
committer | 2017-03-21 14:52:38 +0100 | |
commit | ea90356b818bb1b64e7ea0e185b8a2270c52ae6f (patch) | |
tree | dd1bbe77e047b48943b69ac406db45b18e2d9ab0 /third_party | |
parent | 44c322b4e654930dfe8a7260843695289b9ecf39 (diff) |
Windows, protoc: support long paths
Fixes https://github.com/bazelbuild/bazel/issues/2634
Fixes https://github.com/google/protobuf/issues/2891
Change-Id: I5b82954cbced4e0d3fcd7ac6f168cca34e57f731
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/protobuf/3.0.0/src/google/protobuf/compiler/command_line_interface.cc | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/third_party/protobuf/3.0.0/src/google/protobuf/compiler/command_line_interface.cc b/third_party/protobuf/3.0.0/src/google/protobuf/compiler/command_line_interface.cc index bb781b0a63..be47bbabe4 100644 --- a/third_party/protobuf/3.0.0/src/google/protobuf/compiler/command_line_interface.cc +++ b/third_party/protobuf/3.0.0/src/google/protobuf/compiler/command_line_interface.cc @@ -35,6 +35,10 @@ #include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/stubs/platform_macros.h> +#ifdef _MSC_VER +#include <Windows.h> +#endif + #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -52,6 +56,7 @@ #include <limits.h> //For PATH_MAX +#include <string> #include <memory> #ifndef _SHARED_PTR_H #include <google/protobuf/stubs/shared_ptr.h> @@ -86,7 +91,73 @@ namespace protobuf { namespace compiler { #if defined(_WIN32) -#define mkdir(name, mode) mkdir(name) + +static bool is_path_absolute(const std::string& path) { + return ((path.size() > 2 && path[1] == ':') || + (path.size() > 4 && path[0] == '\\' && path[1] == '\\' && + path[2] == '?' && path[3] == '\\')); +} + +static std::wstring as_windows_path(const std::string& path) { + // Convert `path` to WCHAR string. + int len = + ::MultiByteToWideChar(CP_UTF8, 0, path.c_str(), path.size(), NULL, 0); + std::unique_ptr<WCHAR[]> wbuf(new WCHAR[len + 1]); + ::MultiByteToWideChar(CP_UTF8, 0, path.c_str(), path.size(), wbuf.get(), + len + 1); + wbuf.get()[len] = 0; + + // Replace all '/' with '\'. + for (WCHAR* p = wbuf.get(); *p != L'\0'; ++p) { + if (*p == L'/') { + *p = L'\\'; + } + } + + // Create a wstring of the WCHAR buffer. + std::wstring wpath(wbuf.get()); + + // Make the path absolute. + if (!is_path_absolute(path)) { + // Get the current working directory. + DWORD result = ::GetCurrentDirectoryW(0, NULL); + std::unique_ptr<WCHAR[]> cwd(new WCHAR[result]); + ::GetCurrentDirectoryW(result, cwd.get()); + cwd.get()[result - 1] = 0; + std::wstring wcwd(cwd.get()); + // Make the path absolute by appending it to the cwd. + wpath = wcwd.back() == L'\\' ? (wcwd + wpath) : (wcwd + L'\\' + wpath); + } + + // Prepend UNC prefix if necessary. + if (wpath.size() >= MAX_PATH) { + wpath = std::wstring(L"\\\\?\\") + wpath; + } + + return wpath; +} + +#ifdef open +#undef open +#endif +static int open(const char* path, int flags, int mode) { + return _wopen(as_windows_path(path).c_str(), flags, mode); +} + +#ifdef mkdir +#undef mkdir +#endif +static int mkdir(const char* name, int _mode) { + return _wmkdir(as_windows_path(name).c_str()); +} + +#ifdef access +#undef access +#endif +static int access(const char* pathname, int mode) { + return _waccess(as_windows_path(pathname).c_str(), mode); +} + #ifndef W_OK #define W_OK 02 // not defined by MSVC for whatever reason #endif @@ -99,7 +170,7 @@ namespace compiler { #ifndef STDOUT_FILENO #define STDOUT_FILENO 1 #endif -#endif +#endif // defined(_WIN32) #ifndef O_BINARY #ifdef _O_BINARY |