Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "gtest/gtest-message.h"
00033 #include "gtest/internal/gtest-filepath.h"
00034 #include "gtest/internal/gtest-port.h"
00035
00036 #include <stdlib.h>
00037
00038 #if GTEST_OS_WINDOWS_MOBILE
00039 # include <windows.h>
00040 #elif GTEST_OS_WINDOWS
00041 # include <direct.h>
00042 # include <io.h>
00043 #elif GTEST_OS_SYMBIAN
00044
00045 # include <sys/syslimits.h>
00046 #else
00047 # include <limits.h>
00048 # include <climits>
00049 #endif // GTEST_OS_WINDOWS_MOBILE
00050
00051 #if GTEST_OS_WINDOWS
00052 # define GTEST_PATH_MAX_ _MAX_PATH
00053 #elif defined(PATH_MAX)
00054 # define GTEST_PATH_MAX_ PATH_MAX
00055 #elif defined(_XOPEN_PATH_MAX)
00056 # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
00057 #else
00058 # define GTEST_PATH_MAX_ _POSIX_PATH_MAX
00059 #endif // GTEST_OS_WINDOWS
00060
00061 #include "gtest/internal/gtest-string.h"
00062
00063 namespace testing {
00064 namespace internal {
00065
00066 #if GTEST_OS_WINDOWS
00067
00068
00069
00070
00071 const char kPathSeparator = '\\';
00072 const char kAlternatePathSeparator = '/';
00073 const char kAlternatePathSeparatorString[] = "/";
00074 # if GTEST_OS_WINDOWS_MOBILE
00075
00076
00077
00078 const char kCurrentDirectoryString[] = "\\";
00079
00080 const DWORD kInvalidFileAttributes = 0xffffffff;
00081 # else
00082 const char kCurrentDirectoryString[] = ".\\";
00083 # endif // GTEST_OS_WINDOWS_MOBILE
00084 #else
00085 const char kPathSeparator = '/';
00086 const char kCurrentDirectoryString[] = "./";
00087 #endif // GTEST_OS_WINDOWS
00088
00089
00090 static bool IsPathSeparator(char c) {
00091 #if GTEST_HAS_ALT_PATH_SEP_
00092 return (c == kPathSeparator) || (c == kAlternatePathSeparator);
00093 #else
00094 return c == kPathSeparator;
00095 #endif
00096 }
00097
00098
00099 FilePath FilePath::GetCurrentDir() {
00100 #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
00101
00102
00103 return FilePath(kCurrentDirectoryString);
00104 #elif GTEST_OS_WINDOWS
00105 char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
00106 return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
00107 #else
00108 char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
00109 char* result = getcwd(cwd, sizeof(cwd));
00110 # if GTEST_OS_NACL
00111
00112
00113
00114 return FilePath(result == NULL ? kCurrentDirectoryString : cwd);
00115 # endif // GTEST_OS_NACL
00116 return FilePath(result == NULL ? "" : cwd);
00117 #endif // GTEST_OS_WINDOWS_MOBILE
00118 }
00119
00120
00121
00122
00123
00124 FilePath FilePath::RemoveExtension(const char* extension) const {
00125 const std::string dot_extension = std::string(".") + extension;
00126 if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
00127 return FilePath(pathname_.substr(
00128 0, pathname_.length() - dot_extension.length()));
00129 }
00130 return *this;
00131 }
00132
00133
00134
00135
00136 const char* FilePath::FindLastPathSeparator() const {
00137 const char* const last_sep = strrchr(c_str(), kPathSeparator);
00138 #if GTEST_HAS_ALT_PATH_SEP_
00139 const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
00140
00141 if (last_alt_sep != NULL &&
00142 (last_sep == NULL || last_alt_sep > last_sep)) {
00143 return last_alt_sep;
00144 }
00145 #endif
00146 return last_sep;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 FilePath FilePath::RemoveDirectoryName() const {
00156 const char* const last_sep = FindLastPathSeparator();
00157 return last_sep ? FilePath(last_sep + 1) : *this;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 FilePath FilePath::RemoveFileName() const {
00167 const char* const last_sep = FindLastPathSeparator();
00168 std::string dir;
00169 if (last_sep) {
00170 dir = std::string(c_str(), last_sep + 1 - c_str());
00171 } else {
00172 dir = kCurrentDirectoryString;
00173 }
00174 return FilePath(dir);
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 FilePath FilePath::MakeFileName(const FilePath& directory,
00184 const FilePath& base_name,
00185 int number,
00186 const char* extension) {
00187 std::string file;
00188 if (number == 0) {
00189 file = base_name.string() + "." + extension;
00190 } else {
00191 file = base_name.string() + "_" + StreamableToString(number)
00192 + "." + extension;
00193 }
00194 return ConcatPaths(directory, FilePath(file));
00195 }
00196
00197
00198
00199 FilePath FilePath::ConcatPaths(const FilePath& directory,
00200 const FilePath& relative_path) {
00201 if (directory.IsEmpty())
00202 return relative_path;
00203 const FilePath dir(directory.RemoveTrailingPathSeparator());
00204 return FilePath(dir.string() + kPathSeparator + relative_path.string());
00205 }
00206
00207
00208
00209 bool FilePath::FileOrDirectoryExists() const {
00210 #if GTEST_OS_WINDOWS_MOBILE
00211 LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
00212 const DWORD attributes = GetFileAttributes(unicode);
00213 delete [] unicode;
00214 return attributes != kInvalidFileAttributes;
00215 #else
00216 posix::StatStruct file_stat;
00217 return posix::Stat(pathname_.c_str(), &file_stat) == 0;
00218 #endif // GTEST_OS_WINDOWS_MOBILE
00219 }
00220
00221
00222
00223 bool FilePath::DirectoryExists() const {
00224 bool result = false;
00225 #if GTEST_OS_WINDOWS
00226
00227
00228 const FilePath& path(IsRootDirectory() ? *this :
00229 RemoveTrailingPathSeparator());
00230 #else
00231 const FilePath& path(*this);
00232 #endif
00233
00234 #if GTEST_OS_WINDOWS_MOBILE
00235 LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
00236 const DWORD attributes = GetFileAttributes(unicode);
00237 delete [] unicode;
00238 if ((attributes != kInvalidFileAttributes) &&
00239 (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
00240 result = true;
00241 }
00242 #else
00243 posix::StatStruct file_stat;
00244 result = posix::Stat(path.c_str(), &file_stat) == 0 &&
00245 posix::IsDir(file_stat);
00246 #endif // GTEST_OS_WINDOWS_MOBILE
00247
00248 return result;
00249 }
00250
00251
00252
00253 bool FilePath::IsRootDirectory() const {
00254 #if GTEST_OS_WINDOWS
00255
00256
00257
00258 return pathname_.length() == 3 && IsAbsolutePath();
00259 #else
00260 return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
00261 #endif
00262 }
00263
00264
00265 bool FilePath::IsAbsolutePath() const {
00266 const char* const name = pathname_.c_str();
00267 #if GTEST_OS_WINDOWS
00268 return pathname_.length() >= 3 &&
00269 ((name[0] >= 'a' && name[0] <= 'z') ||
00270 (name[0] >= 'A' && name[0] <= 'Z')) &&
00271 name[1] == ':' &&
00272 IsPathSeparator(name[2]);
00273 #else
00274 return IsPathSeparator(name[0]);
00275 #endif
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
00287 const FilePath& base_name,
00288 const char* extension) {
00289 FilePath full_pathname;
00290 int number = 0;
00291 do {
00292 full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
00293 } while (full_pathname.FileOrDirectoryExists());
00294 return full_pathname;
00295 }
00296
00297
00298
00299
00300 bool FilePath::IsDirectory() const {
00301 return !pathname_.empty() &&
00302 IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
00303 }
00304
00305
00306
00307
00308 bool FilePath::CreateDirectoriesRecursively() const {
00309 if (!this->IsDirectory()) {
00310 return false;
00311 }
00312
00313 if (pathname_.length() == 0 || this->DirectoryExists()) {
00314 return true;
00315 }
00316
00317 const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
00318 return parent.CreateDirectoriesRecursively() && this->CreateFolder();
00319 }
00320
00321
00322
00323
00324
00325 bool FilePath::CreateFolder() const {
00326 #if GTEST_OS_WINDOWS_MOBILE
00327 FilePath removed_sep(this->RemoveTrailingPathSeparator());
00328 LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
00329 int result = CreateDirectory(unicode, NULL) ? 0 : -1;
00330 delete [] unicode;
00331 #elif GTEST_OS_WINDOWS
00332 int result = _mkdir(pathname_.c_str());
00333 #else
00334 int result = mkdir(pathname_.c_str(), 0777);
00335 #endif // GTEST_OS_WINDOWS_MOBILE
00336
00337 if (result == -1) {
00338 return this->DirectoryExists();
00339 }
00340 return true;
00341 }
00342
00343
00344
00345
00346 FilePath FilePath::RemoveTrailingPathSeparator() const {
00347 return IsDirectory()
00348 ? FilePath(pathname_.substr(0, pathname_.length() - 1))
00349 : *this;
00350 }
00351
00352
00353
00354
00355
00356 void FilePath::Normalize() {
00357 if (pathname_.c_str() == NULL) {
00358 pathname_ = "";
00359 return;
00360 }
00361 const char* src = pathname_.c_str();
00362 char* const dest = new char[pathname_.length() + 1];
00363 char* dest_ptr = dest;
00364 memset(dest_ptr, 0, pathname_.length() + 1);
00365
00366 while (*src != '\0') {
00367 *dest_ptr = *src;
00368 if (!IsPathSeparator(*src)) {
00369 src++;
00370 } else {
00371 #if GTEST_HAS_ALT_PATH_SEP_
00372 if (*dest_ptr == kAlternatePathSeparator) {
00373 *dest_ptr = kPathSeparator;
00374 }
00375 #endif
00376 while (IsPathSeparator(*src))
00377 src++;
00378 }
00379 dest_ptr++;
00380 }
00381 *dest_ptr = '\0';
00382 pathname_ = dest;
00383 delete[] dest;
00384 }
00385
00386 }
00387 }