40#ifdef GTEST_OS_WINDOWS_MOBILE
42#elif defined(GTEST_OS_WINDOWS)
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
63#if GTEST_HAS_FILE_SYSTEM
68#ifdef GTEST_OS_WINDOWS
73const char kPathSeparator =
'\\';
74const char kAlternatePathSeparator =
'/';
75const char kAlternatePathSeparatorString[] =
"/";
76#ifdef GTEST_OS_WINDOWS_MOBILE
80const char kCurrentDirectoryString[] =
"\\";
82const DWORD kInvalidFileAttributes = 0xffffffff;
84const char kCurrentDirectoryString[] =
".\\";
87const char kPathSeparator =
'/';
88const char kCurrentDirectoryString[] =
"./";
92static bool IsPathSeparator(
char c) {
93#if GTEST_HAS_ALT_PATH_SEP_
94 return (c == kPathSeparator) || (c == kAlternatePathSeparator);
96 return c == kPathSeparator;
101FilePath 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);
122 return FilePath(result ==
nullptr ?
"" : cwd);
130FilePath FilePath::RemoveExtension(
const char* extension)
const {
131 const std::string dot_extension = std::string(
".") + extension;
134 pathname_.substr(0, pathname_.length() - dot_extension.length()));
142const 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)) {
155size_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());
199FilePath FilePath::RemoveDirectoryName()
const {
200 const char*
const last_sep = FindLastPathSeparator();
201 return last_sep ? FilePath(last_sep + 1) : *
this;
210FilePath 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);
227FilePath 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));
242FilePath 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());
251bool 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;
265bool 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)) {
295bool FilePath::IsRootDirectory()
const {
296 size_t root_length = CalculateRootLength();
297 return root_length > 0 && root_length == pathname_.size() &&
298 IsPathSeparator(pathname_[root_length - 1]);
302bool FilePath::IsAbsolutePath()
const {
return CalculateRootLength() > 0; }
312FilePath 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;
326bool FilePath::IsDirectory()
const {
327 return !pathname_.empty() &&
328 IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
334bool FilePath::CreateDirectoriesRecursively()
const {
335 if (!this->IsDirectory()) {
339 if (pathname_.length() == 0 || this->DirectoryExists()) {
343 const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
344 return parent.CreateDirectoriesRecursively() && this->CreateFolder();
351bool 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);
369 return this->DirectoryExists();
377FilePath FilePath::RemoveTrailingPathSeparator()
const {
378 return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))
386void 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());
static bool EndsWithCaseInsensitive(const std::string &str, const std::string &suffix)
Definition gtest.cc:2173
int i
Definition gmock-matchers-comparisons_test.cc:603
#define GTEST_PATH_MAX_
Definition gtest-filepath.cc:60
int Stat(const char *path, StatStruct *buf)
Definition gtest-port.h:2022
struct stat StatStruct
Definition gtest-port.h:2019
bool IsDir(const StatStruct &st)
Definition gtest-port.h:2029
std::string StreamableToString(const T &streamable)
Definition gtest-message.h:243
Definition gmock-actions.h:151