Index: lldb/trunk/source/Host/common/FileSpec.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp +++ lldb/trunk/source/Host/common/FileSpec.cpp @@ -1248,6 +1248,22 @@ return ConstString(); } +static std::string +join_path_components(FileSpec::PathSyntax syntax, + const std::vector components) { + std::string result; + for (size_t i = 0; i < components.size(); ++i) { + if (components[i].empty()) + continue; + result += components[i]; + if (i != components.size() - 1 && + !IsPathSeparator(components[i].back(), syntax)) + result += GetPreferredPathSeparator(syntax); + } + + return result; +} + void FileSpec::PrependPathComponent(llvm::StringRef component) { if (component.empty()) return; @@ -1258,16 +1274,9 @@ return; } - char sep = GetPreferredPathSeparator(m_syntax); - std::string result; - if (m_filename.IsEmpty()) - result = llvm::join_items(sep, component, m_directory.GetStringRef()); - else if (m_directory.IsEmpty()) - result = llvm::join_items(sep, component, m_filename.GetStringRef()); - else - result = llvm::join_items(sep, component, m_directory.GetStringRef(), - m_filename.GetStringRef()); - + std::string result = + join_path_components(m_syntax, {component, m_directory.GetStringRef(), + m_filename.GetStringRef()}); SetFile(result, resolve); } @@ -1279,23 +1288,12 @@ if (component.empty()) return; - std::string result; - if (!m_directory.IsEmpty()) { - result += m_directory.GetStringRef(); - if (!IsPathSeparator(m_directory.GetStringRef().back(), m_syntax)) - result += GetPreferredPathSeparator(m_syntax); - } - - if (!m_filename.IsEmpty()) { - result += m_filename.GetStringRef(); - if (!IsPathSeparator(m_filename.GetStringRef().back(), m_syntax)) - result += GetPreferredPathSeparator(m_syntax); - } - component = component.drop_while( [this](char c) { return IsPathSeparator(c, m_syntax); }); - result += component; + std::string result = + join_path_components(m_syntax, {m_directory.GetStringRef(), + m_filename.GetStringRef(), component}); SetFile(result, false, m_syntax); } Index: lldb/trunk/unittests/Host/FileSpecTest.cpp =================================================================== --- lldb/trunk/unittests/Host/FileSpecTest.cpp +++ lldb/trunk/unittests/Host/FileSpecTest.cpp @@ -109,6 +109,28 @@ EXPECT_STREQ("bar", fs.GetFilename().GetCString()); } +TEST(FileSpecTest, PrependPathComponent) { + FileSpec fs_posix("foo", false, FileSpec::ePathSyntaxPosix); + fs_posix.PrependPathComponent("/bar"); + EXPECT_STREQ("/bar/foo", fs_posix.GetCString()); + + FileSpec fs_posix_2("foo/bar", false, FileSpec::ePathSyntaxPosix); + fs_posix_2.PrependPathComponent("/baz"); + EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetCString()); + + FileSpec fs_windows("baz", false, FileSpec::ePathSyntaxWindows); + fs_windows.PrependPathComponent("F:\\bar"); + EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString()); + + FileSpec fs_posix_root("bar", false, FileSpec::ePathSyntaxPosix); + fs_posix_root.PrependPathComponent("/"); + EXPECT_STREQ("/bar", fs_posix_root.GetCString()); + + FileSpec fs_windows_root("bar", false, FileSpec::ePathSyntaxWindows); + fs_windows_root.PrependPathComponent("F:\\"); + EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString()); +} + static void Compare(const FileSpec &one, const FileSpec &two, bool full_match, bool remove_backup_dots, bool result) { EXPECT_EQ(result, FileSpec::Equal(one, two, full_match, remove_backup_dots)) @@ -283,4 +305,4 @@ EXPECT_EQ("foo", llvm::formatv("{0}", F).str()); EXPECT_EQ("foo", llvm::formatv("{0:F}", F).str()); EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str()); -} \ No newline at end of file +}