1 //===-- StringList.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Utility/StringList.h"
11 #include "lldb/Utility/Log.h"
12 #include "lldb/Utility/Stream.h"
13 #include "lldb/Utility/StreamString.h"
14 #include "llvm/ADT/ArrayRef.h"
20 using namespace lldb_private
;
22 StringList::StringList() : m_strings() {}
24 StringList::StringList(const char *str
) : m_strings() {
26 m_strings
.push_back(str
);
29 StringList::StringList(const char **strv
, int strc
) : m_strings() {
30 for (int i
= 0; i
< strc
; ++i
) {
32 m_strings
.push_back(strv
[i
]);
36 StringList::~StringList() = default;
38 void StringList::AppendString(const char *str
) {
40 m_strings
.push_back(str
);
43 void StringList::AppendString(const std::string
&s
) { m_strings
.push_back(s
); }
45 void StringList::AppendString(std::string
&&s
) {
46 m_strings
.push_back(std::move(s
));
49 void StringList::AppendString(const char *str
, size_t str_len
) {
51 m_strings
.push_back(std::string(str
, str_len
));
54 void StringList::AppendString(llvm::StringRef str
) {
55 m_strings
.push_back(str
.str());
58 void StringList::AppendString(const llvm::Twine
&str
) {
59 m_strings
.push_back(str
.str());
62 void StringList::AppendList(const char **strv
, int strc
) {
63 for (int i
= 0; i
< strc
; ++i
) {
65 m_strings
.push_back(strv
[i
]);
69 void StringList::AppendList(StringList strings
) {
70 m_strings
.reserve(m_strings
.size() + strings
.GetSize());
71 m_strings
.insert(m_strings
.end(), strings
.begin(), strings
.end());
74 size_t StringList::GetSize() const { return m_strings
.size(); }
76 size_t StringList::GetMaxStringLength() const {
77 size_t max_length
= 0;
78 for (const auto &s
: m_strings
) {
79 const size_t len
= s
.size();
86 const char *StringList::GetStringAtIndex(size_t idx
) const {
87 if (idx
< m_strings
.size())
88 return m_strings
[idx
].c_str();
92 void StringList::Join(const char *separator
, Stream
&strm
) {
93 size_t size
= GetSize();
98 for (uint32_t i
= 0; i
< size
; ++i
) {
100 strm
.PutCString(separator
);
101 strm
.PutCString(GetStringAtIndex(i
));
105 void StringList::Clear() { m_strings
.clear(); }
107 std::string
StringList::LongestCommonPrefix() {
108 if (m_strings
.empty())
111 auto args
= llvm::ArrayRef(m_strings
);
112 llvm::StringRef prefix
= args
.front();
113 for (auto arg
: args
.drop_front()) {
115 for (count
= 0; count
< std::min(prefix
.size(), arg
.size()); ++count
) {
116 if (prefix
[count
] != arg
[count
])
119 prefix
= prefix
.take_front(count
);
124 void StringList::InsertStringAtIndex(size_t idx
, const char *str
) {
126 if (idx
< m_strings
.size())
127 m_strings
.insert(m_strings
.begin() + idx
, str
);
129 m_strings
.push_back(str
);
133 void StringList::InsertStringAtIndex(size_t idx
, const std::string
&str
) {
134 if (idx
< m_strings
.size())
135 m_strings
.insert(m_strings
.begin() + idx
, str
);
137 m_strings
.push_back(str
);
140 void StringList::InsertStringAtIndex(size_t idx
, std::string
&&str
) {
141 if (idx
< m_strings
.size())
142 m_strings
.insert(m_strings
.begin() + idx
, std::move(str
));
144 m_strings
.push_back(std::move(str
));
147 void StringList::DeleteStringAtIndex(size_t idx
) {
148 if (idx
< m_strings
.size())
149 m_strings
.erase(m_strings
.begin() + idx
);
152 size_t StringList::SplitIntoLines(const std::string
&lines
) {
153 return SplitIntoLines(lines
.c_str(), lines
.size());
156 size_t StringList::SplitIntoLines(const char *lines
, size_t len
) {
157 const size_t orig_size
= m_strings
.size();
162 const char *k_newline_chars
= "\r\n";
163 const char *p
= lines
;
164 const char *end
= lines
+ len
;
166 size_t count
= strcspn(p
, k_newline_chars
);
168 if (p
[count
] == '\r' || p
[count
] == '\n')
169 m_strings
.push_back(std::string());
175 m_strings
.push_back(std::string(p
, count
));
177 if (p
[count
] == '\r' && p
[count
+ 1] == '\n')
178 count
++; // Skip an extra newline char for the DOS newline
179 count
++; // Skip the newline character
182 return m_strings
.size() - orig_size
;
185 void StringList::RemoveBlankLines() {
190 while (idx
< m_strings
.size()) {
191 if (m_strings
[idx
].empty())
192 DeleteStringAtIndex(idx
);
198 std::string
StringList::CopyList(const char *item_preamble
,
199 const char *items_sep
) const {
201 for (size_t i
= 0; i
< GetSize(); i
++) {
202 if (i
&& items_sep
&& items_sep
[0])
205 strm
<< item_preamble
;
206 strm
<< GetStringAtIndex(i
);
208 return std::string(strm
.GetString());
211 StringList
&StringList::operator<<(const char *str
) {
216 StringList
&StringList::operator<<(const std::string
&str
) {
221 StringList
&StringList::operator<<(const StringList
&strings
) {
226 StringList
&StringList::operator=(const std::vector
<std::string
> &rhs
) {
227 m_strings
.assign(rhs
.begin(), rhs
.end());
232 void StringList::LogDump(Log
*log
, const char *name
) {
238 strm
.Printf("Begin %s:\n", name
);
239 for (const auto &s
: m_strings
) {
241 strm
.Printf("%s\n", s
.c_str());
244 strm
.Printf("End %s.\n", name
);
246 LLDB_LOGV(log
, "{0}", strm
.GetData());