40 #ifdef GTEST_OS_WINDOWS_MOBILE
42 #elif defined(GTEST_OS_WINDOWS)
49 #endif // GTEST_OS_WINDOWS_MOBILE
53 #ifdef GTEST_OS_WINDOWS
54 #define GTEST_PATH_MAX_ _MAX_PATH
55 #elif defined(PATH_MAX)
56 #define GTEST_PATH_MAX_ PATH_MAX
57 #elif defined(_XOPEN_PATH_MAX)
58 #define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
60 #define GTEST_PATH_MAX_ _POSIX_PATH_MAX
61 #endif // GTEST_OS_WINDOWS
63 #if GTEST_HAS_FILE_SYSTEM
68 #ifdef GTEST_OS_WINDOWS
73 const char kPathSeparator =
'\\';
74 const char kAlternatePathSeparator =
'/';
75 const char kAlternatePathSeparatorString[] =
"/";
76 #ifdef GTEST_OS_WINDOWS_MOBILE
80 const char kCurrentDirectoryString[] =
"\\";
82 const DWORD kInvalidFileAttributes = 0xffffffff;
84 const char kCurrentDirectoryString[] =
".\\";
85 #endif // GTEST_OS_WINDOWS_MOBILE
87 const char kPathSeparator =
'/';
88 const char kCurrentDirectoryString[] =
"./";
89 #endif // GTEST_OS_WINDOWS
92 static bool IsPathSeparator(
char c) {
93 #if GTEST_HAS_ALT_PATH_SEP_
94 return (c == kPathSeparator) || (c == kAlternatePathSeparator);
96 return c == kPathSeparator;
101 FilePath FilePath::GetCurrentDir() {
102 #if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
103 defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
104 defined(GTEST_OS_ESP32) || defined(GTEST_OS_XTENSA) || \
105 defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
106 defined(GTEST_OS_NRF52)
109 return FilePath(kCurrentDirectoryString);
110 #elif defined(GTEST_OS_WINDOWS)
112 return FilePath(_getcwd(cwd,
sizeof(cwd)) ==
nullptr ?
"" : cwd);
115 char* result = getcwd(cwd,
sizeof(cwd));
120 return FilePath(result ==
nullptr ? kCurrentDirectoryString : cwd);
121 #endif // GTEST_OS_NACL
122 return FilePath(result ==
nullptr ?
"" : cwd);
123 #endif // GTEST_OS_WINDOWS_MOBILE
130 FilePath FilePath::RemoveExtension(
const char* extension)
const {
131 const std::string dot_extension = std::string(
".") + extension;
134 pathname_.substr(0, pathname_.length() - dot_extension.length()));
142 const char* FilePath::FindLastPathSeparator()
const {
143 const char*
const last_sep = strrchr(c_str(), kPathSeparator);
144 #if GTEST_HAS_ALT_PATH_SEP_
145 const char*
const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
147 if (last_alt_sep !=
nullptr &&
148 (last_sep ==
nullptr || last_alt_sep > last_sep)) {
155 size_t FilePath::CalculateRootLength()
const {
156 const auto& path = pathname_;
157 auto s = path.begin();
158 auto end = path.end();
159 #ifdef GTEST_OS_WINDOWS
160 if (end - s >= 2 && s[1] ==
':' && (end - s == 2 || IsPathSeparator(s[2])) &&
161 ((
'A' <= s[0] && s[0] <=
'Z') || (
'a' <= s[0] && s[0] <=
'z'))) {
167 }
else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1)) &&
168 !IsPathSeparator(*(s + 2))) {
172 for (
int i = 0;
i < 2; ++
i) {
174 bool stop = IsPathSeparator(*s);
181 }
else if (s != end && IsPathSeparator(*s)) {
186 if (s != end && IsPathSeparator(*s)) {
190 return static_cast<size_t>(s - path.begin());
199 FilePath FilePath::RemoveDirectoryName()
const {
200 const char*
const last_sep = FindLastPathSeparator();
201 return last_sep ? FilePath(last_sep + 1) : *
this;
210 FilePath FilePath::RemoveFileName()
const {
211 const char*
const last_sep = FindLastPathSeparator();
214 dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));
216 dir = kCurrentDirectoryString;
218 return FilePath(dir);
227 FilePath FilePath::MakeFileName(
const FilePath& directory,
228 const FilePath& base_name,
int number,
229 const char* extension) {
232 file = base_name.string() +
"." + extension;
237 return ConcatPaths(directory, FilePath(file));
242 FilePath FilePath::ConcatPaths(
const FilePath& directory,
243 const FilePath& relative_path) {
244 if (directory.IsEmpty())
return relative_path;
245 const FilePath dir(directory.RemoveTrailingPathSeparator());
246 return FilePath(dir.string() + kPathSeparator + relative_path.string());
251 bool FilePath::FileOrDirectoryExists()
const {
252 #ifdef GTEST_OS_WINDOWS_MOBILE
253 LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
254 const DWORD attributes = GetFileAttributes(unicode);
256 return attributes != kInvalidFileAttributes;
259 return posix::Stat(pathname_.c_str(), &file_stat) == 0;
260 #endif // GTEST_OS_WINDOWS_MOBILE
265 bool FilePath::DirectoryExists()
const {
267 #ifdef GTEST_OS_WINDOWS
270 const FilePath& path(IsRootDirectory() ? *
this
271 : RemoveTrailingPathSeparator());
273 const FilePath& path(*
this);
276 #ifdef GTEST_OS_WINDOWS_MOBILE
277 LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
278 const DWORD attributes = GetFileAttributes(unicode);
280 if ((attributes != kInvalidFileAttributes) &&
281 (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
288 #endif // GTEST_OS_WINDOWS_MOBILE
295 bool FilePath::IsRootDirectory()
const {
296 size_t root_length = CalculateRootLength();
297 return root_length > 0 && root_length == pathname_.size() &&
298 IsPathSeparator(pathname_[root_length - 1]);
302 bool FilePath::IsAbsolutePath()
const {
return CalculateRootLength() > 0; }
312 FilePath FilePath::GenerateUniqueFileName(
const FilePath& directory,
313 const FilePath& base_name,
314 const char* extension) {
315 FilePath full_pathname;
318 full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
319 }
while (full_pathname.FileOrDirectoryExists());
320 return full_pathname;
326 bool FilePath::IsDirectory()
const {
327 return !pathname_.empty() &&
328 IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
334 bool FilePath::CreateDirectoriesRecursively()
const {
335 if (!this->IsDirectory()) {
339 if (pathname_.empty() || this->DirectoryExists()) {
343 const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
344 return parent.CreateDirectoriesRecursively() && this->CreateFolder();
351 bool FilePath::CreateFolder()
const {
352 #ifdef GTEST_OS_WINDOWS_MOBILE
353 FilePath removed_sep(this->RemoveTrailingPathSeparator());
354 LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
355 int result = CreateDirectory(unicode,
nullptr) ? 0 : -1;
357 #elif defined(GTEST_OS_WINDOWS)
358 int result = _mkdir(pathname_.c_str());
359 #elif defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
360 defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
361 defined(GTEST_OS_NRF52)
365 int result = mkdir(pathname_.c_str(), 0777);
366 #endif // GTEST_OS_WINDOWS_MOBILE
369 return this->DirectoryExists();
377 FilePath FilePath::RemoveTrailingPathSeparator()
const {
378 return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))
386 void FilePath::Normalize() {
387 auto out = pathname_.begin();
389 auto i = pathname_.cbegin();
390 #ifdef GTEST_OS_WINDOWS
392 if (pathname_.end() -
i >= 3 && IsPathSeparator(*
i) &&
393 IsPathSeparator(*(
i + 1)) && !IsPathSeparator(*(
i + 2))) {
394 *(out++) = kPathSeparator;
395 *(out++) = kPathSeparator;
398 while (
i != pathname_.end()) {
399 const char character = *
i;
400 if (!IsPathSeparator(character)) {
401 *(out++) = character;
402 }
else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
403 *(out++) = kPathSeparator;
408 pathname_.erase(out, pathname_.end());
414 #endif // GTEST_HAS_FILE_SYSTEM
static bool EndsWithCaseInsensitive(const std::string &str, const std::string &suffix)
int Stat(const char *path, StatStruct *buf)
std::string StreamableToString(const T &streamable)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
bool IsDir(const StatStruct &st)