180814287SRaphael Isemann //===-- StringList.cpp ----------------------------------------------------===//
2573ab909SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6573ab909SZachary Turner //
7573ab909SZachary Turner //===----------------------------------------------------------------------===//
8573ab909SZachary Turner
9573ab909SZachary Turner #include "lldb/Utility/StringList.h"
10573ab909SZachary Turner
11573ab909SZachary Turner #include "lldb/Utility/Log.h"
12672d2c12SJonas Devlieghere #include "lldb/Utility/Stream.h"
13573ab909SZachary Turner #include "lldb/Utility/StreamString.h"
14672d2c12SJonas Devlieghere #include "llvm/ADT/ArrayRef.h"
15573ab909SZachary Turner
16672d2c12SJonas Devlieghere #include <algorithm>
1776e47d48SRaphael Isemann #include <cstdint>
1876e47d48SRaphael Isemann #include <cstring>
19573ab909SZachary Turner
20573ab909SZachary Turner using namespace lldb_private;
21573ab909SZachary Turner
StringList()22573ab909SZachary Turner StringList::StringList() : m_strings() {}
23573ab909SZachary Turner
StringList(const char * str)24573ab909SZachary Turner StringList::StringList(const char *str) : m_strings() {
25573ab909SZachary Turner if (str)
26573ab909SZachary Turner m_strings.push_back(str);
27573ab909SZachary Turner }
28573ab909SZachary Turner
StringList(const char ** strv,int strc)29573ab909SZachary Turner StringList::StringList(const char **strv, int strc) : m_strings() {
30573ab909SZachary Turner for (int i = 0; i < strc; ++i) {
31573ab909SZachary Turner if (strv[i])
32573ab909SZachary Turner m_strings.push_back(strv[i]);
33573ab909SZachary Turner }
34573ab909SZachary Turner }
35573ab909SZachary Turner
36fd2433e1SJonas Devlieghere StringList::~StringList() = default;
37573ab909SZachary Turner
AppendString(const char * str)38573ab909SZachary Turner void StringList::AppendString(const char *str) {
39573ab909SZachary Turner if (str)
40573ab909SZachary Turner m_strings.push_back(str);
41573ab909SZachary Turner }
42573ab909SZachary Turner
AppendString(const std::string & s)43573ab909SZachary Turner void StringList::AppendString(const std::string &s) { m_strings.push_back(s); }
44573ab909SZachary Turner
AppendString(std::string && s)4567c937f8SDave Lee void StringList::AppendString(std::string &&s) {
4667c937f8SDave Lee m_strings.push_back(std::move(s));
4767c937f8SDave Lee }
48573ab909SZachary Turner
AppendString(const char * str,size_t str_len)49573ab909SZachary Turner void StringList::AppendString(const char *str, size_t str_len) {
50573ab909SZachary Turner if (str)
51573ab909SZachary Turner m_strings.push_back(std::string(str, str_len));
52573ab909SZachary Turner }
53573ab909SZachary Turner
AppendString(llvm::StringRef str)54573ab909SZachary Turner void StringList::AppendString(llvm::StringRef str) {
55573ab909SZachary Turner m_strings.push_back(str.str());
56573ab909SZachary Turner }
57573ab909SZachary Turner
AppendString(const llvm::Twine & str)583a1a0d49SDave Lee void StringList::AppendString(const llvm::Twine &str) {
593a1a0d49SDave Lee m_strings.push_back(str.str());
603a1a0d49SDave Lee }
613a1a0d49SDave Lee
AppendList(const char ** strv,int strc)62573ab909SZachary Turner void StringList::AppendList(const char **strv, int strc) {
63573ab909SZachary Turner for (int i = 0; i < strc; ++i) {
64573ab909SZachary Turner if (strv[i])
65573ab909SZachary Turner m_strings.push_back(strv[i]);
66573ab909SZachary Turner }
67573ab909SZachary Turner }
68573ab909SZachary Turner
AppendList(StringList strings)69573ab909SZachary Turner void StringList::AppendList(StringList strings) {
7021599876SRaphael Isemann m_strings.reserve(m_strings.size() + strings.GetSize());
714c78b788SRaphael Isemann m_strings.insert(m_strings.end(), strings.begin(), strings.end());
72573ab909SZachary Turner }
73573ab909SZachary Turner
GetSize() const74573ab909SZachary Turner size_t StringList::GetSize() const { return m_strings.size(); }
75573ab909SZachary Turner
GetMaxStringLength() const76573ab909SZachary Turner size_t StringList::GetMaxStringLength() const {
77573ab909SZachary Turner size_t max_length = 0;
78573ab909SZachary Turner for (const auto &s : m_strings) {
79573ab909SZachary Turner const size_t len = s.size();
80573ab909SZachary Turner if (max_length < len)
81573ab909SZachary Turner max_length = len;
82573ab909SZachary Turner }
83573ab909SZachary Turner return max_length;
84573ab909SZachary Turner }
85573ab909SZachary Turner
GetStringAtIndex(size_t idx) const86573ab909SZachary Turner const char *StringList::GetStringAtIndex(size_t idx) const {
87573ab909SZachary Turner if (idx < m_strings.size())
88573ab909SZachary Turner return m_strings[idx].c_str();
8965e5e278SJonas Devlieghere return nullptr;
90573ab909SZachary Turner }
91573ab909SZachary Turner
Join(const char * separator,Stream & strm)92573ab909SZachary Turner void StringList::Join(const char *separator, Stream &strm) {
93573ab909SZachary Turner size_t size = GetSize();
94573ab909SZachary Turner
95573ab909SZachary Turner if (size == 0)
96573ab909SZachary Turner return;
97573ab909SZachary Turner
98573ab909SZachary Turner for (uint32_t i = 0; i < size; ++i) {
99573ab909SZachary Turner if (i > 0)
100573ab909SZachary Turner strm.PutCString(separator);
101573ab909SZachary Turner strm.PutCString(GetStringAtIndex(i));
102573ab909SZachary Turner }
103573ab909SZachary Turner }
104573ab909SZachary Turner
Clear()105573ab909SZachary Turner void StringList::Clear() { m_strings.clear(); }
106573ab909SZachary Turner
LongestCommonPrefix()107175f0930SJonas Devlieghere std::string StringList::LongestCommonPrefix() {
108573ab909SZachary Turner if (m_strings.empty())
109175f0930SJonas Devlieghere return {};
110573ab909SZachary Turner
111*984b800aSserge-sans-paille auto args = llvm::ArrayRef(m_strings);
112573ab909SZachary Turner llvm::StringRef prefix = args.front();
113573ab909SZachary Turner for (auto arg : args.drop_front()) {
114573ab909SZachary Turner size_t count = 0;
115573ab909SZachary Turner for (count = 0; count < std::min(prefix.size(), arg.size()); ++count) {
116573ab909SZachary Turner if (prefix[count] != arg[count])
117573ab909SZachary Turner break;
118573ab909SZachary Turner }
119573ab909SZachary Turner prefix = prefix.take_front(count);
120573ab909SZachary Turner }
121175f0930SJonas Devlieghere return prefix.str();
122573ab909SZachary Turner }
123573ab909SZachary Turner
InsertStringAtIndex(size_t idx,const char * str)124573ab909SZachary Turner void StringList::InsertStringAtIndex(size_t idx, const char *str) {
125573ab909SZachary Turner if (str) {
126573ab909SZachary Turner if (idx < m_strings.size())
127573ab909SZachary Turner m_strings.insert(m_strings.begin() + idx, str);
128573ab909SZachary Turner else
129573ab909SZachary Turner m_strings.push_back(str);
130573ab909SZachary Turner }
131573ab909SZachary Turner }
132573ab909SZachary Turner
InsertStringAtIndex(size_t idx,const std::string & str)133573ab909SZachary Turner void StringList::InsertStringAtIndex(size_t idx, const std::string &str) {
134573ab909SZachary Turner if (idx < m_strings.size())
135573ab909SZachary Turner m_strings.insert(m_strings.begin() + idx, str);
136573ab909SZachary Turner else
137573ab909SZachary Turner m_strings.push_back(str);
138573ab909SZachary Turner }
139573ab909SZachary Turner
InsertStringAtIndex(size_t idx,std::string && str)140573ab909SZachary Turner void StringList::InsertStringAtIndex(size_t idx, std::string &&str) {
141573ab909SZachary Turner if (idx < m_strings.size())
14267c937f8SDave Lee m_strings.insert(m_strings.begin() + idx, std::move(str));
143573ab909SZachary Turner else
14467c937f8SDave Lee m_strings.push_back(std::move(str));
145573ab909SZachary Turner }
146573ab909SZachary Turner
DeleteStringAtIndex(size_t idx)147573ab909SZachary Turner void StringList::DeleteStringAtIndex(size_t idx) {
148573ab909SZachary Turner if (idx < m_strings.size())
149573ab909SZachary Turner m_strings.erase(m_strings.begin() + idx);
150573ab909SZachary Turner }
151573ab909SZachary Turner
SplitIntoLines(const std::string & lines)152573ab909SZachary Turner size_t StringList::SplitIntoLines(const std::string &lines) {
153573ab909SZachary Turner return SplitIntoLines(lines.c_str(), lines.size());
154573ab909SZachary Turner }
155573ab909SZachary Turner
SplitIntoLines(const char * lines,size_t len)156573ab909SZachary Turner size_t StringList::SplitIntoLines(const char *lines, size_t len) {
157573ab909SZachary Turner const size_t orig_size = m_strings.size();
158573ab909SZachary Turner
159573ab909SZachary Turner if (len == 0)
160573ab909SZachary Turner return 0;
161573ab909SZachary Turner
162573ab909SZachary Turner const char *k_newline_chars = "\r\n";
163573ab909SZachary Turner const char *p = lines;
164573ab909SZachary Turner const char *end = lines + len;
165573ab909SZachary Turner while (p < end) {
166573ab909SZachary Turner size_t count = strcspn(p, k_newline_chars);
167573ab909SZachary Turner if (count == 0) {
168573ab909SZachary Turner if (p[count] == '\r' || p[count] == '\n')
169573ab909SZachary Turner m_strings.push_back(std::string());
170573ab909SZachary Turner else
171573ab909SZachary Turner break;
172573ab909SZachary Turner } else {
173573ab909SZachary Turner if (p + count > end)
174573ab909SZachary Turner count = end - p;
175573ab909SZachary Turner m_strings.push_back(std::string(p, count));
176573ab909SZachary Turner }
177573ab909SZachary Turner if (p[count] == '\r' && p[count + 1] == '\n')
178573ab909SZachary Turner count++; // Skip an extra newline char for the DOS newline
179573ab909SZachary Turner count++; // Skip the newline character
180573ab909SZachary Turner p += count;
181573ab909SZachary Turner }
182573ab909SZachary Turner return m_strings.size() - orig_size;
183573ab909SZachary Turner }
184573ab909SZachary Turner
RemoveBlankLines()185573ab909SZachary Turner void StringList::RemoveBlankLines() {
186573ab909SZachary Turner if (GetSize() == 0)
187573ab909SZachary Turner return;
188573ab909SZachary Turner
189573ab909SZachary Turner size_t idx = 0;
190573ab909SZachary Turner while (idx < m_strings.size()) {
191573ab909SZachary Turner if (m_strings[idx].empty())
192573ab909SZachary Turner DeleteStringAtIndex(idx);
193573ab909SZachary Turner else
194573ab909SZachary Turner idx++;
195573ab909SZachary Turner }
196573ab909SZachary Turner }
197573ab909SZachary Turner
CopyList(const char * item_preamble,const char * items_sep) const198573ab909SZachary Turner std::string StringList::CopyList(const char *item_preamble,
199573ab909SZachary Turner const char *items_sep) const {
200573ab909SZachary Turner StreamString strm;
201573ab909SZachary Turner for (size_t i = 0; i < GetSize(); i++) {
202573ab909SZachary Turner if (i && items_sep && items_sep[0])
203573ab909SZachary Turner strm << items_sep;
204573ab909SZachary Turner if (item_preamble)
205573ab909SZachary Turner strm << item_preamble;
206573ab909SZachary Turner strm << GetStringAtIndex(i);
207573ab909SZachary Turner }
208adcd0268SBenjamin Kramer return std::string(strm.GetString());
209573ab909SZachary Turner }
210573ab909SZachary Turner
operator <<(const char * str)211573ab909SZachary Turner StringList &StringList::operator<<(const char *str) {
212573ab909SZachary Turner AppendString(str);
213573ab909SZachary Turner return *this;
214573ab909SZachary Turner }
215573ab909SZachary Turner
operator <<(const std::string & str)216573ab909SZachary Turner StringList &StringList::operator<<(const std::string &str) {
217573ab909SZachary Turner AppendString(str);
218573ab909SZachary Turner return *this;
219573ab909SZachary Turner }
220573ab909SZachary Turner
operator <<(const StringList & strings)2210d5fc822SJonas Devlieghere StringList &StringList::operator<<(const StringList &strings) {
222573ab909SZachary Turner AppendList(strings);
223573ab909SZachary Turner return *this;
224573ab909SZachary Turner }
225573ab909SZachary Turner
operator =(const std::vector<std::string> & rhs)226573ab909SZachary Turner StringList &StringList::operator=(const std::vector<std::string> &rhs) {
227573ab909SZachary Turner m_strings.assign(rhs.begin(), rhs.end());
228573ab909SZachary Turner
229573ab909SZachary Turner return *this;
230573ab909SZachary Turner }
231573ab909SZachary Turner
LogDump(Log * log,const char * name)232573ab909SZachary Turner void StringList::LogDump(Log *log, const char *name) {
233573ab909SZachary Turner if (!log)
234573ab909SZachary Turner return;
235573ab909SZachary Turner
236573ab909SZachary Turner StreamString strm;
237573ab909SZachary Turner if (name)
238573ab909SZachary Turner strm.Printf("Begin %s:\n", name);
239573ab909SZachary Turner for (const auto &s : m_strings) {
240573ab909SZachary Turner strm.Indent();
241573ab909SZachary Turner strm.Printf("%s\n", s.c_str());
242573ab909SZachary Turner }
243573ab909SZachary Turner if (name)
244573ab909SZachary Turner strm.Printf("End %s.\n", name);
245573ab909SZachary Turner
246573ab909SZachary Turner LLDB_LOGV(log, "{0}", strm.GetData());
247573ab909SZachary Turner }
248