blob: c3f098cd695beb01dfe83fd6e80bea2556c9ae7d [file] [log] [blame]
ccalvarinac69da02018-06-05 15:27:26 -07001// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#ifndef BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_
15#define BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_
16
17#include <string>
18
19namespace blaze_util {
20
21// Convert a path from Bazel internal form to underlying OS form.
22// On Unixes this is an identity operation.
23// On Windows, Bazel internal form is cygwin path, and underlying OS form
24// is Windows path.
25std::string ConvertPath(const std::string &path);
26
27// Converts `path` to a string that's safe to pass as path in a JVM flag.
28// See https://github.com/bazelbuild/bazel/issues/2576
29std::string PathAsJvmFlag(const std::string &path);
30
31// Compares two absolute paths. Necessary because the same path can have
32// multiple different names under msys2: "C:\foo\bar" or "C:/foo/bar"
33// (Windows-style) and "/c/foo/bar" (msys2 style). Returns if the paths are
34// equal.
35bool CompareAbsolutePaths(const std::string &a, const std::string &b);
36
37// Split a path to dirname and basename parts.
38std::pair<std::string, std::string> SplitPath(const std::string &path);
39
40bool IsDevNull(const char *path);
41
42// Returns true if `path` is the root directory or a Windows drive root.
43bool IsRootDirectory(const std::string &path);
44
45// Returns true if `path` is absolute.
46bool IsAbsolute(const std::string &path);
47
ccalvarin755278d2018-06-07 11:05:54 -070048// Returns the given path in absolute form. Does not change paths that are
49// already absolute.
50//
51// If called from working directory "/bar":
52// MakeAbsolute("foo") --> "/bar/foo"
53// MakeAbsolute("/foo") ---> "/foo"
54// MakeAbsolute("C:/foo") ---> "C:/foo"
55std::string MakeAbsolute(const std::string &path);
56
ccalvarind39de3a2018-06-19 08:52:08 -070057// Returns the given path in absolute form, taking into account a possible
58// starting environment variable on the windows platform, so that we can
59// accept standard path variables like %USERPROFILE%. We do not support
60// unix-style envvars here: recreating that logic is error-prone and not
61// worthwhile, since they are less critical to standard paths as in Windows.
62//
63// MakeAbsolute("foo") in wd "/bar" --> "/bar/foo"
64// MakeAbsolute("%USERPROFILE%/foo") --> "C:\Users\bazel-user\foo"
65std::string MakeAbsoluteAndResolveWindowsEnvvars(const std::string &path);
66
ccalvarinac69da02018-06-05 15:27:26 -070067// TODO(bazel-team) consider changing the path(_platform) header split to be a
68// path.h and path_windows.h split, which would make it clearer what functions
69// are included by an import statement. The downside to this gain in clarity
70// is that this would add more complexity to the implementation file(s)? of
71// path.h, which would have to have the platform-specific implementations.
Loo Rong Jie4022bac2018-06-11 02:04:52 -070072#if defined(_WIN32) || defined(__CYGWIN__)
Yun Peng40f5a772018-06-25 05:35:50 -070073bool IsDevNull(const wchar_t *path);
74
75bool IsAbsolute(const std::wstring &path);
76
ccalvarinac69da02018-06-05 15:27:26 -070077const wchar_t *RemoveUncPrefixMaybe(const wchar_t *ptr);
Yun Peng40f5a772018-06-25 05:35:50 -070078
ccalvarinac69da02018-06-05 15:27:26 -070079void AddUncPrefixMaybe(std::wstring *path);
80
81std::pair<std::wstring, std::wstring> SplitPathW(const std::wstring &path);
82
83bool IsRootDirectoryW(const std::wstring &path);
84
Laszlo Csomorac545372018-09-14 05:32:42 -070085namespace testing {
Yun Peng4e578e62018-06-20 07:56:11 -070086
Laszlo Csomorac545372018-09-14 05:32:42 -070087bool TestOnly_NormalizeWindowsPath(const std::string &path,
88 std::string *result);
89
Yun Peng4e578e62018-06-20 07:56:11 -070090}
ccalvarinac69da02018-06-05 15:27:26 -070091
92// Converts a UTF8-encoded `path` to a normalized, widechar Windows path.
93//
94// Returns true if conversion succeeded and sets the contents of `result` to it.
95//
96// The input `path` may be an absolute or relative Windows path.
97//
98// The returned path is normalized (see NormalizeWindowsPath).
99//
100// If `path` had a "\\?\" prefix then the function assumes it's already Windows
101// style and converts it to wstring without any alterations.
102// Otherwise `path` is normalized and converted to a Windows path and the result
103// won't have a "\\?\" prefix even if it's longer than MAX_PATH (adding the
104// prefix is the caller's responsibility).
105//
106// The method recognizes current-drive-relative Windows paths ("\foo") turning
107// them into absolute paths ("c:\foo").
108bool AsWindowsPath(const std::string &path, std::wstring *result,
109 std::string *error);
110
Yun Peng4e578e62018-06-20 07:56:11 -0700111template <typename char_type>
112bool AsWindowsPath(const std::basic_string<char_type> &path,
113 std::basic_string<char_type> *result, std::string *error);
114
115template <typename char_type>
116bool AsWindowsPath(const char_type *path, std::basic_string<char_type> *result,
117 std::string *error) {
118 return AsWindowsPath(std::basic_string<char_type>(path), result, error);
119}
120
121template <typename char_type>
122bool AsAbsoluteWindowsPath(const std::basic_string<char_type> &path,
123 std::wstring *result, std::string *error);
124
125template <typename char_type>
126bool AsAbsoluteWindowsPath(const char_type *path, std::wstring *result,
127 std::string *error) {
128 return AsAbsoluteWindowsPath(std::basic_string<char_type>(path), result,
129 error);
130}
131
132// Explicit instantiate AsAbsoluteWindowsPath for char and wchar_t.
133template bool AsAbsoluteWindowsPath<char>(const char *, std::wstring *,
134 std::string *);
135template bool AsAbsoluteWindowsPath<wchar_t>(const wchar_t *, std::wstring *,
136 std::string *);
ccalvarinac69da02018-06-05 15:27:26 -0700137
138// Same as `AsWindowsPath`, but returns a lowercase 8dot3 style shortened path.
139// Result will never have a UNC prefix, nor a trailing "/" or "\".
140// Works also for non-existent paths; shortens as much of them as it can.
141// Also works for non-existent drives.
142bool AsShortWindowsPath(const std::string &path, std::string *result,
143 std::string *error);
144
145template <typename char_type>
146bool IsPathSeparator(char_type ch);
147
148template <typename char_type>
149bool HasDriveSpecifierPrefix(const char_type *ch);
150
Loo Rong Jie4022bac2018-06-11 02:04:52 -0700151#endif // defined(_WIN32) || defined(__CYGWIN__)
ccalvarinac69da02018-06-05 15:27:26 -0700152} // namespace blaze_util
153
154#endif // BAZEL_SRC_MAIN_CPP_UTIL_PATH_PLATFORM_H_