Index: include/lldb/Host/FileSpec.h =================================================================== --- include/lldb/Host/FileSpec.h +++ include/lldb/Host/FileSpec.h @@ -259,13 +259,9 @@ /// /// @param[in] s /// The stream to which to dump the object description. - /// - /// @param[in] trailing_slash - /// If true and the file is a non root directory, then a trailing slash - /// will be added. //------------------------------------------------------------------ void - Dump(Stream *s, bool trailing_slash = true) const; + Dump(Stream *s) const; //------------------------------------------------------------------ /// Existence test. @@ -635,10 +631,6 @@ lldb::DataBufferSP ReadFileContentsAsCString(Error *error_ptr = NULL); - static void Normalize(llvm::SmallVectorImpl &path, PathSyntax syntax = ePathSyntaxHostNative); - static void DeNormalize(llvm::SmallVectorImpl &path, PathSyntax syntax = ePathSyntaxHostNative); - - //------------------------------------------------------------------ /// Run through the input string, replaying the effect of any ".." and produce /// the resultant path. The input path is not required to be in the host file system Index: source/Host/common/FileSpec.cpp =================================================================== --- source/Host/common/FileSpec.cpp +++ source/Host/common/FileSpec.cpp @@ -47,7 +47,45 @@ using namespace lldb; using namespace lldb_private; -static bool +namespace { + +bool +PathSyntaxIsPosix(FileSpec::PathSyntax syntax) +{ + return (syntax == FileSpec::ePathSyntaxPosix || + (syntax == FileSpec::ePathSyntaxHostNative && + FileSystem::GetNativePathSyntax() == FileSpec::ePathSyntaxPosix)); +} + +char +GetPathSeparator(FileSpec::PathSyntax syntax) +{ + return PathSyntaxIsPosix(syntax) ? '/' : '\\'; +} + +void +Normalize(llvm::SmallVectorImpl &path, FileSpec::PathSyntax syntax) +{ + if (PathSyntaxIsPosix(syntax)) return; + + std::replace(path.begin(), path.end(), '\\', '/'); + // Windows path can have \\ slashes which can be changed by replace + // call above to //. Here we remove the duplicate. + auto iter = std::unique ( path.begin(), path.end(), + []( char &c1, char &c2 ){ + return (c1 == '/' && c2 == '/');}); + path.erase(iter, path.end()); +} + +void +Denormalize(llvm::SmallVectorImpl &path, FileSpec::PathSyntax syntax) +{ + if (PathSyntaxIsPosix(syntax)) return; + + std::replace(path.begin(), path.end(), '/', '\\'); +} + +bool GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr) { char resolved_path[PATH_MAX]; @@ -56,6 +94,8 @@ return false; } +} + // Resolves the username part of a path of the form ~user/other/directories, and // writes the result into dst_path. This will also resolve "~" to the current user. // If you want to complete "~" to the list of users, pass it to ResolvePartialUsername. @@ -252,30 +292,6 @@ return *this; } -void FileSpec::Normalize(llvm::SmallVectorImpl &path, PathSyntax syntax) -{ - if (syntax == ePathSyntaxPosix || - (syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix)) - return; - - std::replace(path.begin(), path.end(), '\\', '/'); - // Windows path can have \\ slashes which can be changed by replace - // call above to //. Here we remove the duplicate. - auto iter = std::unique ( path.begin(), path.end(), - []( char &c1, char &c2 ){ - return (c1 == '/' && c2 == '/');}); - path.erase(iter, path.end()); -} - -void FileSpec::DeNormalize(llvm::SmallVectorImpl &path, PathSyntax syntax) -{ - if (syntax == ePathSyntaxPosix || - (syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix)) - return; - - std::replace(path.begin(), path.end(), '/', '\\'); -} - //------------------------------------------------------------------ // Update the contents of this object with a new path. The path will // be split up into a directory and filename and stored as uniqued @@ -609,15 +625,15 @@ // directory delimiter, and the filename. //------------------------------------------------------------------ void -FileSpec::Dump(Stream *s, bool trailing_slash) const +FileSpec::Dump(Stream *s) const { if (s) { - m_directory.Dump(s); - if ((m_filename || trailing_slash) && m_directory && - !m_directory.GetStringRef().endswith("/")) - s->PutChar('/'); - m_filename.Dump(s); + std::string path{GetPath(true)}; + s->PutCString(path.c_str()); + char path_separator = GetPathSeparator(m_syntax); + if (!m_filename && !path.empty() && path.back() != path_separator) + s->PutChar(path_separator); } } @@ -816,12 +832,14 @@ void FileSpec::GetPath(llvm::SmallVectorImpl &path, bool denormalize) const { - StreamString stream; - Dump(&stream, false); - path.append(stream.GetString().begin(), stream.GetString().end()); + path.append(m_directory.GetStringRef().begin(), m_directory.GetStringRef().end()); + if (m_directory) + path.insert(path.end(), '/'); + path.append(m_filename.GetStringRef().begin(), m_filename.GetStringRef().end()); Normalize(path, m_syntax); + if (path.size() > 1 && path.back() == '/') path.pop_back(); if (denormalize && !path.empty()) - DeNormalize(path, m_syntax); + Denormalize(path, m_syntax); } ConstString @@ -1383,15 +1401,7 @@ if (directory.size() > 0) { - if (m_syntax == ePathSyntaxWindows) - { - if (directory.size() >= 2 && directory[1] == ':') - return false; - if (directory[0] == '/') - return false; - return true; - } - else + if (PathSyntaxIsPosix(m_syntax)) { // If the path doesn't start with '/' or '~', return true switch (directory[0]) @@ -1403,6 +1413,14 @@ return true; } } + else + { + if (directory.size() >= 2 && directory[1] == ':') + return false; + if (directory[0] == '/') + return false; + return true; + } } else if (m_filename) {