test/fmw/gtest/src/gtest-filepath.cc
author hseigel
Tue, 15 Nov 2016 08:34:56 -0500
changeset 42569 fccb65782775
parent 37967 8dd54c3bf02a
child 54913 9cfbe22bcdf8
permissions -rw-r--r--
8169551: Segfaults in error traces when module version is null Summary: Make sure module->version() is not null before dereferencing it. Reviewed-by: coleenp, gtriantafill, lfoltan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37967
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     1
// Copyright 2008, Google Inc.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     2
// All rights reserved.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     3
//
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     4
// Redistribution and use in source and binary forms, with or without
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     5
// modification, are permitted provided that the following conditions are
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     6
// met:
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     7
//
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     8
//     * Redistributions of source code must retain the above copyright
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
     9
// notice, this list of conditions and the following disclaimer.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    10
//     * Redistributions in binary form must reproduce the above
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    11
// copyright notice, this list of conditions and the following disclaimer
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    12
// in the documentation and/or other materials provided with the
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    13
// distribution.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    14
//     * Neither the name of Google Inc. nor the names of its
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    15
// contributors may be used to endorse or promote products derived from
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    16
// this software without specific prior written permission.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    17
//
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    22
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    24
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    25
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    26
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    29
//
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    30
// Authors: keith.ray@gmail.com (Keith Ray)
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    31
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    32
#include "gtest/gtest-message.h"
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    33
#include "gtest/internal/gtest-filepath.h"
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    34
#include "gtest/internal/gtest-port.h"
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    35
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    36
#include <stdlib.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    37
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    38
#if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    39
# include <windows.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    40
#elif GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    41
# include <direct.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    42
# include <io.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    43
#elif GTEST_OS_SYMBIAN
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    44
// Symbian OpenC has PATH_MAX in sys/syslimits.h
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    45
# include <sys/syslimits.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    46
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    47
# include <limits.h>
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    48
# include <climits>  // Some Linux distributions define PATH_MAX here.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    49
#endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    50
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    51
#if GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    52
# define GTEST_PATH_MAX_ _MAX_PATH
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    53
#elif defined(PATH_MAX)
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    54
# define GTEST_PATH_MAX_ PATH_MAX
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    55
#elif defined(_XOPEN_PATH_MAX)
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    56
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    57
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    58
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    59
#endif  // GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    60
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    61
#include "gtest/internal/gtest-string.h"
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    62
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    63
namespace testing {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    64
namespace internal {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    65
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    66
#if GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    67
// On Windows, '\\' is the standard path separator, but many tools and the
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    68
// Windows API also accept '/' as an alternate path separator. Unless otherwise
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    69
// noted, a file path can contain either kind of path separators, or a mixture
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    70
// of them.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    71
const char kPathSeparator = '\\';
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    72
const char kAlternatePathSeparator = '/';
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    73
const char kPathSeparatorString[] = "\\";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    74
const char kAlternatePathSeparatorString[] = "/";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    75
# if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    76
// Windows CE doesn't have a current directory. You should not use
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    77
// the current directory in tests on Windows CE, but this at least
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    78
// provides a reasonable fallback.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    79
const char kCurrentDirectoryString[] = "\\";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    80
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    81
const DWORD kInvalidFileAttributes = 0xffffffff;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    82
# else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    83
const char kCurrentDirectoryString[] = ".\\";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    84
# endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    85
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    86
const char kPathSeparator = '/';
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    87
const char kPathSeparatorString[] = "/";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    88
const char kCurrentDirectoryString[] = "./";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    89
#endif  // GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    90
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    91
// Returns whether the given character is a valid path separator.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    92
static bool IsPathSeparator(char c) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    93
#if GTEST_HAS_ALT_PATH_SEP_
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    94
  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    95
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    96
  return c == kPathSeparator;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    97
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    98
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
    99
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   100
// Returns the current working directory, or "" if unsuccessful.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   101
FilePath FilePath::GetCurrentDir() {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   102
#if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   103
  // Windows CE doesn't have a current directory, so we just return
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   104
  // something reasonable.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   105
  return FilePath(kCurrentDirectoryString);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   106
#elif GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   107
  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   108
  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   109
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   110
  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   111
  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   112
#endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   113
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   114
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   115
// Returns a copy of the FilePath with the case-insensitive extension removed.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   116
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   117
// FilePath("dir/file"). If a case-insensitive extension is not
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   118
// found, returns a copy of the original FilePath.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   119
FilePath FilePath::RemoveExtension(const char* extension) const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   120
  const std::string dot_extension = std::string(".") + extension;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   121
  if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   122
    return FilePath(pathname_.substr(
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   123
        0, pathname_.length() - dot_extension.length()));
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   124
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   125
  return *this;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   126
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   127
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   128
// Returns a pointer to the last occurence of a valid path separator in
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   129
// the FilePath. On Windows, for example, both '/' and '\' are valid path
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   130
// separators. Returns NULL if no path separator was found.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   131
const char* FilePath::FindLastPathSeparator() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   132
  const char* const last_sep = strrchr(c_str(), kPathSeparator);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   133
#if GTEST_HAS_ALT_PATH_SEP_
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   134
  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   135
  // Comparing two pointers of which only one is NULL is undefined.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   136
  if (last_alt_sep != NULL &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   137
      (last_sep == NULL || last_alt_sep > last_sep)) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   138
    return last_alt_sep;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   139
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   140
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   141
  return last_sep;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   142
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   143
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   144
// Returns a copy of the FilePath with the directory part removed.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   145
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   146
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   147
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   148
// returns an empty FilePath ("").
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   149
// On Windows platform, '\' is the path separator, otherwise it is '/'.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   150
FilePath FilePath::RemoveDirectoryName() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   151
  const char* const last_sep = FindLastPathSeparator();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   152
  return last_sep ? FilePath(last_sep + 1) : *this;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   153
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   154
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   155
// RemoveFileName returns the directory path with the filename removed.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   156
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   157
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   158
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   159
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   160
// On Windows platform, '\' is the path separator, otherwise it is '/'.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   161
FilePath FilePath::RemoveFileName() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   162
  const char* const last_sep = FindLastPathSeparator();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   163
  std::string dir;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   164
  if (last_sep) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   165
    dir = std::string(c_str(), last_sep + 1 - c_str());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   166
  } else {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   167
    dir = kCurrentDirectoryString;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   168
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   169
  return FilePath(dir);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   170
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   171
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   172
// Helper functions for naming files in a directory for xml output.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   173
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   174
// Given directory = "dir", base_name = "test", number = 0,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   175
// extension = "xml", returns "dir/test.xml". If number is greater
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   176
// than zero (e.g., 12), returns "dir/test_12.xml".
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   177
// On Windows platform, uses \ as the separator rather than /.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   178
FilePath FilePath::MakeFileName(const FilePath& directory,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   179
                                const FilePath& base_name,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   180
                                int number,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   181
                                const char* extension) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   182
  std::string file;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   183
  if (number == 0) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   184
    file = base_name.string() + "." + extension;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   185
  } else {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   186
    file = base_name.string() + "_" + StreamableToString(number)
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   187
        + "." + extension;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   188
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   189
  return ConcatPaths(directory, FilePath(file));
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   190
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   191
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   192
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   193
// On Windows, uses \ as the separator rather than /.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   194
FilePath FilePath::ConcatPaths(const FilePath& directory,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   195
                               const FilePath& relative_path) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   196
  if (directory.IsEmpty())
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   197
    return relative_path;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   198
  const FilePath dir(directory.RemoveTrailingPathSeparator());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   199
  return FilePath(dir.string() + kPathSeparator + relative_path.string());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   200
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   201
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   202
// Returns true if pathname describes something findable in the file-system,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   203
// either a file, directory, or whatever.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   204
bool FilePath::FileOrDirectoryExists() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   205
#if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   206
  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   207
  const DWORD attributes = GetFileAttributes(unicode);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   208
  delete [] unicode;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   209
  return attributes != kInvalidFileAttributes;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   210
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   211
  posix::StatStruct file_stat;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   212
  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   213
#endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   214
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   215
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   216
// Returns true if pathname describes a directory in the file-system
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   217
// that exists.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   218
bool FilePath::DirectoryExists() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   219
  bool result = false;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   220
#if GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   221
  // Don't strip off trailing separator if path is a root directory on
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   222
  // Windows (like "C:\\").
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   223
  const FilePath& path(IsRootDirectory() ? *this :
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   224
                                           RemoveTrailingPathSeparator());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   225
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   226
  const FilePath& path(*this);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   227
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   228
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   229
#if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   230
  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   231
  const DWORD attributes = GetFileAttributes(unicode);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   232
  delete [] unicode;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   233
  if ((attributes != kInvalidFileAttributes) &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   234
      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   235
    result = true;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   236
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   237
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   238
  posix::StatStruct file_stat;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   239
  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   240
      posix::IsDir(file_stat);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   241
#endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   242
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   243
  return result;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   244
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   245
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   246
// Returns true if pathname describes a root directory. (Windows has one
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   247
// root directory per disk drive.)
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   248
bool FilePath::IsRootDirectory() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   249
#if GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   250
  // TODO(wan@google.com): on Windows a network share like
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   251
  // \\server\share can be a root directory, although it cannot be the
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   252
  // current directory.  Handle this properly.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   253
  return pathname_.length() == 3 && IsAbsolutePath();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   254
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   255
  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   256
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   257
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   258
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   259
// Returns true if pathname describes an absolute path.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   260
bool FilePath::IsAbsolutePath() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   261
  const char* const name = pathname_.c_str();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   262
#if GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   263
  return pathname_.length() >= 3 &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   264
     ((name[0] >= 'a' && name[0] <= 'z') ||
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   265
      (name[0] >= 'A' && name[0] <= 'Z')) &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   266
     name[1] == ':' &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   267
     IsPathSeparator(name[2]);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   268
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   269
  return IsPathSeparator(name[0]);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   270
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   271
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   272
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   273
// Returns a pathname for a file that does not currently exist. The pathname
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   274
// will be directory/base_name.extension or
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   275
// directory/base_name_<number>.extension if directory/base_name.extension
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   276
// already exists. The number will be incremented until a pathname is found
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   277
// that does not already exist.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   278
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   279
// There could be a race condition if two or more processes are calling this
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   280
// function at the same time -- they could both pick the same filename.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   281
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   282
                                          const FilePath& base_name,
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   283
                                          const char* extension) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   284
  FilePath full_pathname;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   285
  int number = 0;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   286
  do {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   287
    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   288
  } while (full_pathname.FileOrDirectoryExists());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   289
  return full_pathname;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   290
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   291
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   292
// Returns true if FilePath ends with a path separator, which indicates that
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   293
// it is intended to represent a directory. Returns false otherwise.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   294
// This does NOT check that a directory (or file) actually exists.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   295
bool FilePath::IsDirectory() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   296
  return !pathname_.empty() &&
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   297
         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   298
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   299
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   300
// Create directories so that path exists. Returns true if successful or if
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   301
// the directories already exist; returns false if unable to create directories
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   302
// for any reason.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   303
bool FilePath::CreateDirectoriesRecursively() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   304
  if (!this->IsDirectory()) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   305
    return false;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   306
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   307
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   308
  if (pathname_.length() == 0 || this->DirectoryExists()) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   309
    return true;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   310
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   311
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   312
  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   313
  return parent.CreateDirectoriesRecursively() && this->CreateFolder();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   314
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   315
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   316
// Create the directory so that path exists. Returns true if successful or
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   317
// if the directory already exists; returns false if unable to create the
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   318
// directory for any reason, including if the parent directory does not
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   319
// exist. Not named "CreateDirectory" because that's a macro on Windows.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   320
bool FilePath::CreateFolder() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   321
#if GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   322
  FilePath removed_sep(this->RemoveTrailingPathSeparator());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   323
  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   324
  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   325
  delete [] unicode;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   326
#elif GTEST_OS_WINDOWS
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   327
  int result = _mkdir(pathname_.c_str());
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   328
#else
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   329
  int result = mkdir(pathname_.c_str(), 0777);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   330
#endif  // GTEST_OS_WINDOWS_MOBILE
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   331
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   332
  if (result == -1) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   333
    return this->DirectoryExists();  // An error is OK if the directory exists.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   334
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   335
  return true;  // No error.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   336
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   337
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   338
// If input name has a trailing separator character, remove it and return the
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   339
// name, otherwise return the name string unmodified.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   340
// On Windows platform, uses \ as the separator, other platforms use /.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   341
FilePath FilePath::RemoveTrailingPathSeparator() const {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   342
  return IsDirectory()
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   343
      ? FilePath(pathname_.substr(0, pathname_.length() - 1))
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   344
      : *this;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   345
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   346
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   347
// Removes any redundant separators that might be in the pathname.
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   348
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   349
// redundancies that might be in a pathname involving "." or "..".
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   350
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   351
void FilePath::Normalize() {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   352
  if (pathname_.c_str() == NULL) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   353
    pathname_ = "";
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   354
    return;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   355
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   356
  const char* src = pathname_.c_str();
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   357
  char* const dest = new char[pathname_.length() + 1];
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   358
  char* dest_ptr = dest;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   359
  memset(dest_ptr, 0, pathname_.length() + 1);
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   360
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   361
  while (*src != '\0') {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   362
    *dest_ptr = *src;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   363
    if (!IsPathSeparator(*src)) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   364
      src++;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   365
    } else {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   366
#if GTEST_HAS_ALT_PATH_SEP_
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   367
      if (*dest_ptr == kAlternatePathSeparator) {
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   368
        *dest_ptr = kPathSeparator;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   369
      }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   370
#endif
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   371
      while (IsPathSeparator(*src))
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   372
        src++;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   373
    }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   374
    dest_ptr++;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   375
  }
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   376
  *dest_ptr = '\0';
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   377
  pathname_ = dest;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   378
  delete[] dest;
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   379
}
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   380
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   381
}  // namespace internal
8dd54c3bf02a 8148244: Finalize and integrate GTest implementation
iignatyev
parents:
diff changeset
   382
}  // namespace testing