diff options
author | Zachary Turner <zturner@google.com> | 2016-10-03 22:51:09 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-10-03 22:51:09 +0000 |
commit | 691405be388fd7ad8d0cc792cc9b56f94c7e401d (patch) | |
tree | 4a8ab166d0f5323f112307c62976d62917234be6 /lldb/source/Core/StringList.cpp | |
parent | 44761a6e47f8ebe314bfd4c7278e630538c286b8 (diff) | |
download | bcm5719-llvm-691405be388fd7ad8d0cc792cc9b56f94c7e401d.tar.gz bcm5719-llvm-691405be388fd7ad8d0cc792cc9b56f94c7e401d.zip |
Refactor the Args class.
There were a number of issues with the Args class preventing
efficient use of strings and incoporating LLVM's StringRef class.
The two biggest were:
1. Backing memory stored in a std::string, so we would frequently
have to use const_cast to get a mutable buffer for passing to
various low level APIs.
2. backing std::strings stored in a std::list, which doesn't
provide random access.
I wanted to solve these two issues so that we could provide
StringRef access to the underlying arguments, and also a way
to provide range-based access to the underlying argument array
while still providing convenient c-style access via an argv style
const char**.
The solution here is to store arguments in a single "entry" class
which contains the backing memory, a StringRef with precomputed
length, and the quote char. The backing memory is a manually
allocated const char* so that it is not invalidated when the
container is resized, and there is a separate argv array provided
for c-style access.
Differential revision: https://reviews.llvm.org/D25099
llvm-svn: 283157
Diffstat (limited to 'lldb/source/Core/StringList.cpp')
-rw-r--r-- | lldb/source/Core/StringList.cpp | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/lldb/source/Core/StringList.cpp b/lldb/source/Core/StringList.cpp index 5085c439d0e..cde02e19732 100644 --- a/lldb/source/Core/StringList.cpp +++ b/lldb/source/Core/StringList.cpp @@ -103,34 +103,21 @@ void StringList::Join(const char *separator, Stream &strm) { void StringList::Clear() { m_strings.clear(); } void StringList::LongestCommonPrefix(std::string &common_prefix) { - const size_t num_strings = m_strings.size(); - - if (num_strings == 0) { - common_prefix.clear(); - } else { - common_prefix = m_strings.front(); - - for (size_t idx = 1; idx < num_strings; ++idx) { - std::string &curr_string = m_strings[idx]; - size_t new_size = curr_string.size(); - - // First trim common_prefix if it is longer than the current element: - if (common_prefix.size() > new_size) - common_prefix.erase(new_size); - - // Then trim it at the first disparity: - for (size_t i = 0; i < common_prefix.size(); i++) { - if (curr_string[i] != common_prefix[i]) { - common_prefix.erase(i); - break; - } - } + common_prefix.clear(); + if (m_strings.empty()) + return; - // If we've emptied the common prefix, we're done. - if (common_prefix.empty()) + auto args = llvm::makeArrayRef(m_strings); + llvm::StringRef prefix = args.front(); + for (auto arg : args.drop_front()) { + size_t count = 0; + for (count = 0; count < std::min(prefix.size(), arg.size()); ++count) { + if (prefix[count] != arg[count]) break; } + prefix = prefix.take_front(count); } + common_prefix = prefix; } void StringList::InsertStringAtIndex(size_t idx, const char *str) { |