17ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Copyright 2008, Google Inc. 27ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// All rights reserved. 37ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 47ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Redistribution and use in source and binary forms, with or without 57ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// modification, are permitted provided that the following conditions are 67ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// met: 77ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 87ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// * Redistributions of source code must retain the above copyright 97ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// notice, this list of conditions and the following disclaimer. 107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// * Redistributions in binary form must reproduce the above 117ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// copyright notice, this list of conditions and the following disclaimer 127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// in the documentation and/or other materials provided with the 137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// distribution. 147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// * Neither the name of Google Inc. nor the names of its 157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// contributors may be used to endorse or promote products derived from 167ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// this software without specific prior written permission. 177ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 187ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 197ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 207ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 217ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 227ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 237ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Author: keith.ray@gmail.com (Keith Ray) 317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 327ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Google Test filepath utilities 337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This header file declares classes and functions used internally by 357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Google Test. They are subject to change without notice. 367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 37e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer// This file is #included in <gtest/internal/gtest-internal.h>. 387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Do not include this header file separately! 397ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 407ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 417ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 427ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 43b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad#include "gtest/internal/gtest-string.h" 447ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 457ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace testing { 467ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace internal { 477ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 487ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// FilePath - a class for file and directory pathname manipulation which 497ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// handles platform-specific conventions (like the pathname separator). 507ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Used for helper functions for naming files in a directory for xml output. 517ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Except for Set methods, all methods are const or static, which provides an 527ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// "immutable value object" -- useful for peace of mind. 537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// A FilePath with a value ending in a path separator ("like/this/") represents 547ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// a directory, otherwise it is assumed to represent a file. In either case, 557ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// it may or may not represent an actual file or directory in the file system. 567ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Names are NOT checked for syntax correctness -- no checking for illegal 577ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// characters, malformed paths, etc. 587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 5957240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramerclass GTEST_API_ FilePath { 607ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman public: 617ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath() : pathname_("") { } 627ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } 637ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 647ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman explicit FilePath(const char* pathname) : pathname_(pathname) { 657ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman Normalize(); 667ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman explicit FilePath(const String& pathname) : pathname_(pathname) { 697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman Normalize(); 707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 717ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 727ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath& operator=(const FilePath& rhs) { 737ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman Set(rhs); 747ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman return *this; 757ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 767ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 777ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman void Set(const FilePath& rhs) { 787ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman pathname_ = rhs.pathname_; 797ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 807ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 817ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman String ToString() const { return pathname_; } 827ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const char* c_str() const { return pathname_.c_str(); } 837ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 847ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns the current working directory, or "" if unsuccessful. 857ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman static FilePath GetCurrentDir(); 867ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 877ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Given directory = "dir", base_name = "test", number = 0, 887ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // extension = "xml", returns "dir/test.xml". If number is greater 897ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // than zero (e.g., 12), returns "dir/test_12.xml". 907ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // On Windows platform, uses \ as the separator rather than /. 917ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman static FilePath MakeFileName(const FilePath& directory, 927ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const FilePath& base_name, 937ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman int number, 947ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const char* extension); 957ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 96e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Given directory = "dir", relative_path = "test.xml", 97e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // returns "dir/test.xml". 98e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // On Windows, uses \ as the separator rather than /. 99e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer static FilePath ConcatPaths(const FilePath& directory, 100e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const FilePath& relative_path); 101e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 1027ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns a pathname for a file that does not currently exist. The pathname 1037ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // will be directory/base_name.extension or 1047ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // directory/base_name_<number>.extension if directory/base_name.extension 1057ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // already exists. The number will be incremented until a pathname is found 1067ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // that does not already exist. 1077ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. 1087ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // There could be a race condition if two or more processes are calling this 1097ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // function at the same time -- they could both pick the same filename. 1107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman static FilePath GenerateUniqueFileName(const FilePath& directory, 1117ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const FilePath& base_name, 1127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const char* extension); 1137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns true iff the path is NULL or "". 1157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } 1167ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1177ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // If input name has a trailing separator character, removes it and returns 1187ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // the name, otherwise return the name string unmodified. 1197ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // On Windows platform, uses \ as the separator, other platforms use /. 1207ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath RemoveTrailingPathSeparator() const; 1217ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1227ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns a copy of the FilePath with the directory part removed. 1237ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Example: FilePath("path/to/file").RemoveDirectoryName() returns 1247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // FilePath("file"). If there is no directory part ("just_a_file"), it returns 1257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // the FilePath unmodified. If there is no file part ("just_a_dir/") it 1267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // returns an empty FilePath (""). 1277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // On Windows platform, '\' is the path separator, otherwise it is '/'. 1287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath RemoveDirectoryName() const; 1297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // RemoveFileName returns the directory path with the filename removed. 1317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". 1327ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // If the FilePath is "a_file" or "/a_file", RemoveFileName returns 1337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does 1347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // not have a file, like "just/a/dir/", it returns the FilePath unmodified. 1357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // On Windows platform, '\' is the path separator, otherwise it is '/'. 1367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath RemoveFileName() const; 1377ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns a copy of the FilePath with the case-insensitive extension removed. 1397ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns 1407ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // FilePath("dir/file"). If a case-insensitive extension is not 1417ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // found, returns a copy of the original FilePath. 1427ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FilePath RemoveExtension(const char* extension) const; 1437ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1447ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Creates directories so that path exists. Returns true if successful or if 1457ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // the directories already exist; returns false if unable to create 1467ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // directories for any reason. Will also return false if the FilePath does 1477ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // not represent a directory (that is, it doesn't end with a path separator). 1487ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool CreateDirectoriesRecursively() const; 1497ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1507ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Create the directory so that path exists. Returns true if successful or 1517ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // if the directory already exists; returns false if unable to create the 1527ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // directory for any reason, including if the parent directory does not 1537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // exist. Not named "CreateDirectory" because that's a macro on Windows. 1547ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool CreateFolder() const; 1557ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1567ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns true if FilePath describes something in the file-system, 1577ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // either a file, directory, or whatever, and that something exists. 1587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool FileOrDirectoryExists() const; 1597ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1607ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns true if pathname describes a directory in the file-system 1617ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // that exists. 1627ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool DirectoryExists() const; 1637ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1647ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns true if FilePath ends with a path separator, which indicates that 1657ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // it is intended to represent a directory. Returns false otherwise. 1667ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // This does NOT check that a directory (or file) actually exists. 1677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool IsDirectory() const; 1687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns true if pathname describes a root directory. (Windows has one 1707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // root directory per disk drive.) 1717ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman bool IsRootDirectory() const; 1727ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 173e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Returns true if pathname describes an absolute path. 174e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer bool IsAbsolutePath() const; 175e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 1767ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman private: 1777ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Replaces multiple consecutive separators with a single separator. 1787ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // For example, "bar///foo" becomes "bar/foo". Does not eliminate other 1797ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // redundancies that might be in a pathname involving "." or "..". 1807ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // 1817ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // A pathname with multiple consecutive separators may occur either through 1827ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // user error or as a result of some scripts or APIs that generate a pathname 1837ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // with a trailing separator. On other platforms the same API or script 1847ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // may NOT generate a pathname with a trailing "/". Then elsewhere that 1857ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // pathname may have another "/" and pathname components added to it, 1867ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // without checking for the separator already being there. 1877ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // The script language and operating system may allow paths like "foo//bar" 1887ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // but some of the functions in FilePath will not handle that correctly. In 1897ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // particular, RemoveTrailingPathSeparator() only removes one separator, and 1907ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // it is called in CreateDirectoriesRecursively() assuming that it will change 1917ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // a pathname from directory syntax (trailing separator) to filename syntax. 19257240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // 19357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // On Windows this method also replaces the alternate path separator '/' with 19457240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // the primary path separator '\\', so that for example "bar\\/\\foo" becomes 19557240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // "bar\\foo". 1967ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1977ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman void Normalize(); 1987ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1997a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Returns a pointer to the last occurrence of a valid path separator in 20057240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // the FilePath. On Windows, for example, both '/' and '\' are valid path 20157240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // separators. Returns NULL if no path separator was found. 20257240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer const char* FindLastPathSeparator() const; 20357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer 2047ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman String pathname_; 2057ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman}; // class FilePath 2067ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 2077ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman} // namespace internal 2087ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman} // namespace testing 2097ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 2107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 211