summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Utility/FileSpec.h9
-rw-r--r--lldb/source/Utility/FileSpec.cpp37
-rw-r--r--lldb/unittests/Utility/FileSpecTest.cpp41
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());
+}
OpenPOWER on IntegriCloud