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