diff options
-rw-r--r-- | lldb/include/lldb/Utility/FileSpec.h | 9 | ||||
-rw-r--r-- | lldb/source/Utility/FileSpec.cpp | 37 | ||||
-rw-r--r-- | lldb/unittests/Utility/FileSpecTest.cpp | 41 |
3 files changed, 57 insertions, 30 deletions
diff --git a/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h index a7e634e32fe..a32dab96b40 100644 --- a/lldb/include/lldb/Utility/FileSpec.h +++ b/lldb/include/lldb/Utility/FileSpec.h @@ -532,7 +532,14 @@ public: void AppendPathComponent(llvm::StringRef component); void AppendPathComponent(const FileSpec &new_path); - void RemoveLastPathComponent(); + //------------------------------------------------------------------ + /// Removes the last path component by replacing the current path with its + /// parent. When the current path has no parent, this is a no-op. + /// + /// @return + /// A boolean value indicating whether the path was updated. + //------------------------------------------------------------------ + bool RemoveLastPathComponent(); ConstString GetLastPathComponent() const; diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp index ac404cea435..cc36f47e48d 100644 --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -785,36 +785,15 @@ void FileSpec::AppendPathComponent(const FileSpec &new_path) { return AppendPathComponent(new_path.GetPath(false)); } -void FileSpec::RemoveLastPathComponent() { - // CLEANUP: Use StringRef for string handling. - - const bool resolve = false; - if (m_filename.IsEmpty() && m_directory.IsEmpty()) { - SetFile("", resolve); - return; - } - if (m_directory.IsEmpty()) { - SetFile("", resolve); - return; +bool FileSpec::RemoveLastPathComponent() { + llvm::SmallString<64> current_path; + GetPath(current_path, false); + if (llvm::sys::path::has_parent_path(current_path, m_style)) { + SetFile(llvm::sys::path::parent_path(current_path, m_style), false, + m_style); + return true; } - if (m_filename.IsEmpty()) { - const char *dir_cstr = m_directory.GetCString(); - const char *last_slash_ptr = ::strrchr(dir_cstr, '/'); - - // check for obvious cases before doing the full thing - if (!last_slash_ptr) { - SetFile("", resolve); - return; - } - if (last_slash_ptr == dir_cstr) { - SetFile("/", resolve); - return; - } - size_t last_slash_pos = last_slash_ptr - dir_cstr + 1; - ConstString new_path(dir_cstr, last_slash_pos); - SetFile(new_path.GetCString(), resolve); - } else - SetFile(m_directory.GetCString(), resolve); + return false; } //------------------------------------------------------------------ /// Returns true if the filespec represents an implementation source diff --git a/lldb/unittests/Utility/FileSpecTest.cpp b/lldb/unittests/Utility/FileSpecTest.cpp index 03c9793fc15..2e02579797a 100644 --- a/lldb/unittests/Utility/FileSpecTest.cpp +++ b/lldb/unittests/Utility/FileSpecTest.cpp @@ -320,3 +320,44 @@ TEST(FileSpecTest, IsRelative) { } } +TEST(FileSpecTest, RemoveLastPathComponent) { + FileSpec fs_posix("/foo/bar/baz", false, FileSpec::Style::posix); + EXPECT_STREQ("/foo/bar/baz", fs_posix.GetCString()); + EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); + EXPECT_STREQ("/foo/bar", fs_posix.GetCString()); + EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); + EXPECT_STREQ("/foo", fs_posix.GetCString()); + EXPECT_TRUE(fs_posix.RemoveLastPathComponent()); + EXPECT_STREQ("/", fs_posix.GetCString()); + EXPECT_FALSE(fs_posix.RemoveLastPathComponent()); + EXPECT_STREQ("/", fs_posix.GetCString()); + + FileSpec fs_posix_relative("./foo/bar/baz", false, FileSpec::Style::posix); + EXPECT_STREQ("foo/bar/baz", fs_posix_relative.GetCString()); + EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); + EXPECT_STREQ("foo/bar", fs_posix_relative.GetCString()); + EXPECT_TRUE(fs_posix_relative.RemoveLastPathComponent()); + EXPECT_STREQ("foo", fs_posix_relative.GetCString()); + EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); + EXPECT_STREQ("foo", fs_posix_relative.GetCString()); + + FileSpec fs_posix_relative2("./", false, FileSpec::Style::posix); + EXPECT_STREQ(".", fs_posix_relative2.GetCString()); + EXPECT_FALSE(fs_posix_relative2.RemoveLastPathComponent()); + EXPECT_STREQ(".", fs_posix_relative2.GetCString()); + EXPECT_FALSE(fs_posix_relative.RemoveLastPathComponent()); + EXPECT_STREQ(".", fs_posix_relative2.GetCString()); + + FileSpec fs_windows("C:\\foo\\bar\\baz", false, FileSpec::Style::windows); + EXPECT_STREQ("C:\\foo\\bar\\baz", fs_windows.GetCString()); + EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); + EXPECT_STREQ("C:\\foo\\bar", fs_windows.GetCString()); + EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); + EXPECT_STREQ("C:\\foo", fs_windows.GetCString()); + EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); + EXPECT_STREQ("C:\\", fs_windows.GetCString()); + EXPECT_TRUE(fs_windows.RemoveLastPathComponent()); + EXPECT_STREQ("C:", fs_windows.GetCString()); + EXPECT_FALSE(fs_windows.RemoveLastPathComponent()); + EXPECT_STREQ("C:", fs_windows.GetCString()); +} |