| // Copyright 2018 The Bazel Authors. All rights reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #ifndef BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_ | |
| #define BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_ | |
| #include <string> | |
| namespace blaze_util { | |
| // Platform-native, absolute, normalized path. | |
| // It can be converted to a printable path (for error messages) or to a native | |
| // path (for API calls). | |
| class Path { | |
| public: | |
| Path() {} | |
| explicit Path(const std::string &path); | |
| bool operator==(const Path &o) const { return path_ == o.path_; } | |
| bool operator!=(const Path &o) const { return path_ != o.path_; } | |
| bool operator<(const Path &o) const { return path_ < o.path_; } | |
| bool IsEmpty() const { return path_.empty(); } | |
| bool IsNull() const; | |
| bool Contains(const char c) const; | |
| bool Contains(const std::string &s) const; | |
| Path GetRelative(const std::string &r) const; | |
| // Returns the canonical form (like realpath(1)) of this path. | |
| // All symlinks in the path are resolved. | |
| // If canonicalization fails, returns an empty Path. | |
| Path Canonicalize() const; | |
| Path GetParent() const; | |
| // Returns a printable string representing this path. | |
| // Only use when printing user messages, do not pass to filesystem API | |
| // functions. | |
| std::string AsPrintablePath() const; | |
| // Returns a string representation of this path that's safe to pass on the | |
| // command line as a JVM argument. | |
| std::string AsJvmArgument() const; | |
| // Returns a string representation of this path, safe to pass to the Bazel | |
| // server. | |
| std::string AsCommandLineArgument() const; | |
| #if defined(_WIN32) || defined(__CYGWIN__) | |
| // Returns a platform-native, absolute, normalized path. | |
| // Use this to pass paths to filesystem API functions. | |
| const std::wstring AsNativePath() const { return path_; } | |
| #else | |
| // Returns a platform-native, absolute, normalized path. | |
| // Use this to pass paths to filesystem API functions. | |
| const std::string AsNativePath() const { return path_; } | |
| #endif | |
| private: | |
| #if defined(_WIN32) || defined(__CYGWIN__) | |
| explicit Path(const std::wstring &wpath) : path_(wpath) {} | |
| std::wstring path_; | |
| #else | |
| std::string path_; | |
| #endif | |
| }; | |
| // Convert a path from Bazel internal form to underlying OS form. | |
| // On Unixes this is an identity operation. | |
| // On Windows, Bazel internal form is cygwin path, and underlying OS form | |
| // is Windows path. | |
| std::string ConvertPath(const std::string &path); | |
| // Converts `path` to a string that's safe to pass as path in a JVM flag. | |
| // See https://github.com/bazelbuild/bazel/issues/2576 | |
| std::string PathAsJvmFlag(const std::string &path); | |
| // Compares two absolute paths. Necessary because the same path can have | |
| // multiple different names under msys2: "C:\foo\bar" or "C:/foo/bar" | |
| // (Windows-style) and "/c/foo/bar" (msys2 style). Returns if the paths are | |
| // equal. | |
| bool CompareAbsolutePaths(const std::string &a, const std::string &b); | |
| // Split a path to dirname and basename parts. | |
| std::pair<std::string, std::string> SplitPath(const std::string &path); | |
| bool IsDevNull(const char *path); | |
| // Returns true if `path` is the root directory or a Windows drive root. | |
| bool IsRootDirectory(const std::string &path); | |
| bool IsRootDirectory(const Path &path); | |
| // Returns true if `path` is absolute. | |
| bool IsAbsolute(const std::string &path); | |
| // Returns the given path in absolute form. Does not change paths that are | |
| // already absolute. | |
| // | |
| // If called from working directory "/bar": | |
| // MakeAbsolute("foo") --> "/bar/foo" | |
| // MakeAbsolute("/foo") ---> "/foo" | |
| // MakeAbsolute("C:/foo") ---> "C:/foo" | |
| std::string MakeAbsolute(const std::string &path); | |
| // Returns the given path in absolute form, taking into account a | |
| // possible starting environment variable, so that we can accept | |
| // standard path variables like %USERPROFILE% or ${BAZEL}. For | |
| // simplicity, we implement only those two forms, not $BAZEL. | |
| // | |
| // MakeAbsolute("foo") in wd "/bar" --> "/bar/foo" | |
| // MakeAbsoluteAndResolveEnvvars("%USERPROFILE%/foo") --> | |
| // "C:\Users\bazel-user\foo" | |
| // MakeAbsoluteAndResolveEnvvars("${BAZEL}/foo") --> "/opt/bazel/foo" | |
| std::string MakeAbsoluteAndResolveEnvvars(const std::string &path); | |
| // TODO(bazel-team) consider changing the path(_platform) header split to be a | |
| // path.h and path_windows.h split, which would make it clearer what functions | |
| // are included by an import statement. The downside to this gain in clarity | |
| // is that this would add more complexity to the implementation file(s)? of | |
| // path.h, which would have to have the platform-specific implementations. | |
| #if defined(_WIN32) || defined(__CYGWIN__) | |
| bool IsDevNull(const wchar_t *path); | |
| bool IsAbsolute(const std::wstring &path); | |
| const wchar_t *RemoveUncPrefixMaybe(const wchar_t *ptr); | |
| void AddUncPrefixMaybe(std::wstring *path); | |
| std::pair<std::wstring, std::wstring> SplitPathW(const std::wstring &path); | |
| bool IsRootDirectoryW(const std::wstring &path); | |
| // Converts 'path' to Windows style. | |
| // | |
| // 'path' is absolute or relative or current-drive-relative (e.g. | |
| // "\foo"), possibly non-normalized, possibly using slash as separator. If it | |
| // starts with the UNC prefix, the function won't process it further, just | |
| // copies it to 'result'. | |
| // | |
| // 'result' equals 'path' if 'path' started with the UNC prefix, otherwise | |
| // 'result' is normalized, using backslash as separator. | |
| // | |
| // Encoding: there is no assumption about encoding, 'path' is read as ASCII | |
| // (Latin-1) and 'result' uses the same encoding. | |
| bool AsWindowsPath(const std::string &path, std::string *result, | |
| std::string *error); | |
| // Converts 'path' to Windows style. | |
| // | |
| // Same as the other AsWindowsPath methods, but 'path' is encoded as multibyte | |
| // and 'result' is widechar. (MSDN does not clarify what multibyte means. The | |
| // function uses blaze_util::WstringToCstring.) | |
| bool AsWindowsPath(const std::string &path, std::wstring *result, | |
| std::string *error); | |
| // Converts 'path' to Windows style. | |
| // | |
| // Same as the other AsWindowsPath methods, but 'path' and 'result' are | |
| // widechar. | |
| bool AsWindowsPath(const std::wstring &path, std::wstring *result, | |
| std::string *error); | |
| // Converts 'path' to absolute, Windows-style path. | |
| // | |
| // Same as AsWindowsPath, but 'result' is always absolute and always has a UNC | |
| // prefix. | |
| bool AsAbsoluteWindowsPath(const std::string &path, std::wstring *result, | |
| std::string *error); | |
| // Converts 'path' to absolute, Windows-style path. | |
| // | |
| // Same as AsWindowsPath, but 'result' is always absolute and always has a UNC | |
| // prefix. | |
| bool AsAbsoluteWindowsPath(const std::wstring &path, std::wstring *result, | |
| std::string *error); | |
| // Converts 'path' to absolute, shortened, Windows-style path. | |
| // | |
| // Same as `AsWindowsPath`, but 'result' is always absolute, lowercase, | |
| // 8dot3-style shortened path, without trailing backslash and without UNC | |
| // prefix. | |
| // | |
| // Works even for non-existent paths (and non-existent drives), shortening the | |
| // existing segments and leaving the rest unshortened. | |
| bool AsShortWindowsPath(const std::string &path, std::string *result, | |
| std::string *error); | |
| bool AsShortWindowsPath(const std::wstring &path, std::wstring *result, | |
| std::string *error); | |
| #else | |
| std::string TestOnly_NormalizeAbsPath(const std::string &s); | |
| #endif // defined(_WIN32) || defined(__CYGWIN__) | |
| } // namespace blaze_util | |
| #endif // BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_ |