[Lldb-commits] [lldb] f4b71e3 - [llvm] [ADT] Add a range/iterator-based Split()
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 27 01:43:19 PDT 2021
Author: Michał Górny
Date: 2021-09-27T10:43:09+02:00
New Revision: f4b71e3479bfaec71ba5f4bb56c6a34357a7f938
URL: https://github.com/llvm/llvm-project/commit/f4b71e3479bfaec71ba5f4bb56c6a34357a7f938
DIFF: https://github.com/llvm/llvm-project/commit/f4b71e3479bfaec71ba5f4bb56c6a34357a7f938.diff
LOG: [llvm] [ADT] Add a range/iterator-based Split()
Add a llvm::Split() implementation that can be used via range-for loop,
e.g.:
for (StringRef x : llvm::Split("foo,bar,baz", ','))
...
The implementation uses an additional SplittingIterator class that
uses StringRef::split() internally.
Differential Revision: https://reviews.llvm.org/D110496
Added:
Modified:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
llvm/include/llvm/ADT/StringExtras.h
llvm/unittests/ADT/StringExtrasTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 6d2a267f294c..805a836942d6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -355,10 +355,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
// configuration of the transport before attaching/launching the process.
m_qSupported_response = response.GetStringRef().str();
- llvm::SmallVector<llvm::StringRef, 16> server_features;
- response.GetStringRef().split(server_features, ';');
-
- for (llvm::StringRef x : server_features) {
+ for (llvm::StringRef x : llvm::Split(response.GetStringRef(), ';')) {
if (x == "qXfer:auxv:read+")
m_supports_qXfer_auxv_read = eLazyBoolYes;
else if (x == "qXfer:libraries-svr4:read+")
@@ -1659,10 +1656,8 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
error_extractor.GetHexByteString(error_string);
error.SetErrorString(error_string.c_str());
} else if (name.equals("dirty-pages")) {
- llvm::SmallVector<llvm::StringRef, 16> split_value;
std::vector<addr_t> dirty_page_list;
- value.split(split_value, ',');
- for (llvm::StringRef x : split_value) {
+ for (llvm::StringRef x : llvm::Split(value, ',')) {
addr_t page;
x.consume_front("0x");
if (llvm::to_integer(x, page, 16))
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 1ad838b51c26..cd8537812eff 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -3656,10 +3656,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
StringRef packet_str{packet.GetStringRef()};
assert(packet_str.startswith("qSaveCore"));
if (packet_str.consume_front("qSaveCore;")) {
- llvm::SmallVector<llvm::StringRef, 2> fields;
- packet_str.split(fields, ';');
-
- for (auto x : fields) {
+ for (auto x : llvm::Split(packet_str, ';')) {
if (x.consume_front("path-hint:"))
StringExtractor(x).GetHexByteString(path_hint);
else
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2c1b4fa319ff..fdedb9b83416 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -383,9 +383,7 @@ static size_t SplitCommaSeparatedRegisterNumberString(
const llvm::StringRef &comma_separated_register_numbers,
std::vector<uint32_t> ®nums, int base) {
regnums.clear();
- llvm::SmallVector<llvm::StringRef, 4> split_string;
- comma_separated_register_numbers.split(split_string, ',');
- for (llvm::StringRef x : split_string) {
+ for (llvm::StringRef x : llvm::Split(comma_separated_register_numbers, ',')) {
uint32_t reg;
if (llvm::to_integer(x, reg, base))
regnums.push_back(reg);
@@ -1457,9 +1455,7 @@ size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
size_t ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(
llvm::StringRef value) {
m_thread_pcs.clear();
- llvm::SmallVector<llvm::StringRef, 16> split_value;
- value.split(split_value, ',');
- for (llvm::StringRef x : split_value) {
+ for (llvm::StringRef x : llvm::Split(value, ',')) {
lldb::addr_t pc;
if (llvm::to_integer(x, pc, 16))
m_thread_pcs.push_back(pc);
@@ -5111,9 +5107,7 @@ llvm::Expected<bool> ProcessGDBRemote::SaveCore(llvm::StringRef outfile) {
std::string path;
// process the response
- llvm::SmallVector<llvm::StringRef, 1> reply_data;
- response.GetStringRef().split(reply_data, ';');
- for (auto x : reply_data) {
+ for (auto x : llvm::Split(response.GetStringRef(), ';')) {
if (x.consume_front("core-path:"))
StringExtractor(x).GetHexByteString(path);
}
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 6bda25b85313..41dc7e291916 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -501,6 +501,62 @@ class ListSeparator {
}
};
+/// A forward iterator over partitions of string over a separator.
+class SplittingIterator
+ : public iterator_facade_base<SplittingIterator, std::forward_iterator_tag,
+ StringRef> {
+ StringRef Current;
+ StringRef Next;
+ StringRef Separator;
+
+public:
+ SplittingIterator(StringRef Str, StringRef Separator)
+ : Next(Str), Separator(Separator) {
+ ++*this;
+ }
+
+ bool operator==(const SplittingIterator &R) const {
+ return Current == R.Current && Next == R.Next && Separator == R.Separator;
+ }
+
+ const StringRef &operator*() const { return Current; }
+
+ StringRef &operator*() { return Current; }
+
+ SplittingIterator &operator++() {
+ std::pair<StringRef, StringRef> Res = Next.split(Separator);
+ Current = Res.first;
+ Next = Res.second;
+ return *this;
+ }
+};
+
+/// Split the specified string over a separator and return a range-compatible
+/// iterable over its partitions. Used to permit conveniently iterating
+/// over separated strings like so:
+///
+/// \code
+/// for (StringRef x : llvm::Split("foo,bar,baz", ','))
+/// ...;
+/// \end
+///
+/// Note that the passed string must remain valid throuhgout lifetime
+/// of the iterators.
+class Split {
+ StringRef Str;
+ std::string SeparatorStr;
+
+public:
+ Split(StringRef NewStr, StringRef Separator)
+ : Str(NewStr), SeparatorStr(Separator) {}
+ Split(StringRef NewStr, char Separator)
+ : Str(NewStr), SeparatorStr(1, Separator) {}
+
+ SplittingIterator begin() { return SplittingIterator(Str, SeparatorStr); }
+
+ SplittingIterator end() { return SplittingIterator("", SeparatorStr); }
+};
+
} // end namespace llvm
#endif // LLVM_ADT_STRINGEXTRAS_H
diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp
index 3918a35fcef3..35d3535ec268 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -274,3 +274,35 @@ TEST(StringExtrasTest, toStringAPSInt) {
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "-1");
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "-1");
}
+
+TEST(StringExtrasTest, splitStringRef) {
+ auto Spl = Split("foo<=>bar<=><=>baz", "<=>");
+ auto It = Spl.begin();
+ auto End = Spl.end();
+
+ ASSERT_NE(It, End);
+ EXPECT_EQ(*It, StringRef("foo"));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef("bar"));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef(""));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef("baz"));
+ ASSERT_EQ(++It, End);
+}
+
+TEST(StringExtrasTest, splItChar) {
+ auto Spl = Split("foo,bar,,baz", ',');
+ auto It = Spl.begin();
+ auto End = Spl.end();
+
+ ASSERT_NE(It, End);
+ EXPECT_EQ(*It, StringRef("foo"));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef("bar"));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef(""));
+ ASSERT_NE(++It, End);
+ EXPECT_EQ(*It, StringRef("baz"));
+ ASSERT_EQ(++It, End);
+}
More information about the lldb-commits
mailing list