StringList.cpp revision 360660
174432Sjedgar//===-- StringList.cpp ------------------------------------------*- C++ -*-===// 290781Sjedgar// 374432Sjedgar// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 474432Sjedgar// See https://llvm.org/LICENSE.txt for license information. 574432Sjedgar// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 674432Sjedgar// 774432Sjedgar//===----------------------------------------------------------------------===// 874432Sjedgar 974432Sjedgar#include "lldb/Utility/StringList.h" 1074432Sjedgar 1174432Sjedgar#include "lldb/Utility/Log.h" 1274432Sjedgar#include "lldb/Utility/Stream.h" 1374432Sjedgar#include "lldb/Utility/StreamString.h" 1474432Sjedgar#include "llvm/ADT/ArrayRef.h" 1574432Sjedgar 1674432Sjedgar#include <algorithm> 1774432Sjedgar#include <stdint.h> 1874432Sjedgar#include <string.h> 1974432Sjedgar 2074432Sjedgarusing namespace lldb_private; 2174432Sjedgar 2274432SjedgarStringList::StringList() : m_strings() {} 2374432Sjedgar 2474432SjedgarStringList::StringList(const char *str) : m_strings() { 2574432Sjedgar if (str) 2674432Sjedgar m_strings.push_back(str); 2792986Sobrien} 2892986Sobrien 2992986SobrienStringList::StringList(const char **strv, int strc) : m_strings() { 3074432Sjedgar for (int i = 0; i < strc; ++i) { 3175185Stmm if (strv[i]) 3274432Sjedgar m_strings.push_back(strv[i]); 3375185Stmm } 3474432Sjedgar} 3574432Sjedgar 36194955StraszStringList::~StringList() {} 3774432Sjedgar 38194955Straszvoid StringList::AppendString(const char *str) { 39194955Strasz if (str) 40194955Strasz m_strings.push_back(str); 41194955Strasz} 42194955Strasz 43194955Straszvoid StringList::AppendString(const std::string &s) { m_strings.push_back(s); } 44194955Strasz 45194955Straszvoid StringList::AppendString(std::string &&s) { m_strings.push_back(s); } 46194955Strasz 47194955Straszvoid StringList::AppendString(const char *str, size_t str_len) { 48194955Strasz if (str) 49194955Strasz m_strings.push_back(std::string(str, str_len)); 50194955Strasz} 51194955Strasz 52194955Straszvoid StringList::AppendString(llvm::StringRef str) { 53194955Strasz m_strings.push_back(str.str()); 54194955Strasz} 55194955Strasz 56194955Straszvoid StringList::AppendList(const char **strv, int strc) { 57194955Strasz for (int i = 0; i < strc; ++i) { 58194955Strasz if (strv[i]) 59194955Strasz m_strings.push_back(strv[i]); 60194955Strasz } 61194955Strasz} 62194955Strasz 63194955Straszvoid StringList::AppendList(StringList strings) { 64194955Strasz size_t len = strings.GetSize(); 65194955Strasz 66194955Strasz for (size_t i = 0; i < len; ++i) 67194955Strasz m_strings.push_back(strings.GetStringAtIndex(i)); 68194955Strasz} 69194955Strasz 7075928Sjedgarsize_t StringList::GetSize() const { return m_strings.size(); } 7175928Sjedgar 7275928Sjedgarsize_t StringList::GetMaxStringLength() const { 7375928Sjedgar size_t max_length = 0; 7474432Sjedgar for (const auto &s : m_strings) { 7574432Sjedgar const size_t len = s.size(); 7674432Sjedgar if (max_length < len) 7775928Sjedgar max_length = len; 78200992Smarkus } 79194955Strasz return max_length; 8074432Sjedgar} 8190781Sjedgar 8274432Sjedgarconst char *StringList::GetStringAtIndex(size_t idx) const { 8390781Sjedgar if (idx < m_strings.size()) 8474432Sjedgar return m_strings[idx].c_str(); 8575928Sjedgar return nullptr; 8675928Sjedgar} 8775928Sjedgar 88194955Straszvoid StringList::Join(const char *separator, Stream &strm) { 89194955Strasz size_t size = GetSize(); 90194955Strasz 91194955Strasz if (size == 0) 92194955Strasz return; 9375928Sjedgar 9475928Sjedgar for (uint32_t i = 0; i < size; ++i) { 9575928Sjedgar if (i > 0) 9690781Sjedgar strm.PutCString(separator); 9775928Sjedgar strm.PutCString(GetStringAtIndex(i)); 98200992Smarkus } 99200992Smarkus} 100200992Smarkus 101200992Smarkusvoid StringList::Clear() { m_strings.clear(); } 102194955Strasz 103200992Smarkusvoid StringList::LongestCommonPrefix(std::string &common_prefix) { 10474432Sjedgar common_prefix.clear(); 105194955Strasz if (m_strings.empty()) 106194955Strasz return; 107194955Strasz 10874432Sjedgar auto args = llvm::makeArrayRef(m_strings); 10975928Sjedgar llvm::StringRef prefix = args.front(); 110194955Strasz for (auto arg : args.drop_front()) { 11175928Sjedgar size_t count = 0; 11275928Sjedgar for (count = 0; count < std::min(prefix.size(), arg.size()); ++count) { 113194955Strasz if (prefix[count] != arg[count]) 114194955Strasz break; 115194955Strasz } 116194955Strasz prefix = prefix.take_front(count); 117194955Strasz } 11874432Sjedgar common_prefix = prefix; 11974432Sjedgar} 120194955Strasz 121194955Straszvoid StringList::InsertStringAtIndex(size_t idx, const char *str) { 12274432Sjedgar if (str) { 12374432Sjedgar if (idx < m_strings.size()) 12490781Sjedgar m_strings.insert(m_strings.begin() + idx, str); 12574432Sjedgar else 126194955Strasz m_strings.push_back(str); 127194955Strasz } 128194955Strasz} 129194955Strasz 130194955Straszvoid StringList::InsertStringAtIndex(size_t idx, const std::string &str) { 131194955Strasz if (idx < m_strings.size()) 132194955Strasz m_strings.insert(m_strings.begin() + idx, str); 133194955Strasz else 134194955Strasz m_strings.push_back(str); 135194955Strasz} 136194955Strasz 137194955Straszvoid StringList::InsertStringAtIndex(size_t idx, std::string &&str) { 138194955Strasz if (idx < m_strings.size()) 139194955Strasz m_strings.insert(m_strings.begin() + idx, str); 140194955Strasz else 141194955Strasz m_strings.push_back(str); 142194955Strasz} 143194955Strasz 144194955Straszvoid StringList::DeleteStringAtIndex(size_t idx) { 145194955Strasz if (idx < m_strings.size()) 146194955Strasz m_strings.erase(m_strings.begin() + idx); 147194955Strasz} 148194955Strasz 149194955Straszsize_t StringList::SplitIntoLines(const std::string &lines) { 150194955Strasz return SplitIntoLines(lines.c_str(), lines.size()); 151194955Strasz} 152194955Strasz 153194955Straszsize_t StringList::SplitIntoLines(const char *lines, size_t len) { 154194955Strasz const size_t orig_size = m_strings.size(); 155194955Strasz 156194955Strasz if (len == 0) 157194955Strasz return 0; 158194955Strasz 159194955Strasz const char *k_newline_chars = "\r\n"; 160194955Strasz const char *p = lines; 161194955Strasz const char *end = lines + len; 162194955Strasz while (p < end) { 163 size_t count = strcspn(p, k_newline_chars); 164 if (count == 0) { 165 if (p[count] == '\r' || p[count] == '\n') 166 m_strings.push_back(std::string()); 167 else 168 break; 169 } else { 170 if (p + count > end) 171 count = end - p; 172 m_strings.push_back(std::string(p, count)); 173 } 174 if (p[count] == '\r' && p[count + 1] == '\n') 175 count++; // Skip an extra newline char for the DOS newline 176 count++; // Skip the newline character 177 p += count; 178 } 179 return m_strings.size() - orig_size; 180} 181 182void StringList::RemoveBlankLines() { 183 if (GetSize() == 0) 184 return; 185 186 size_t idx = 0; 187 while (idx < m_strings.size()) { 188 if (m_strings[idx].empty()) 189 DeleteStringAtIndex(idx); 190 else 191 idx++; 192 } 193} 194 195std::string StringList::CopyList(const char *item_preamble, 196 const char *items_sep) const { 197 StreamString strm; 198 for (size_t i = 0; i < GetSize(); i++) { 199 if (i && items_sep && items_sep[0]) 200 strm << items_sep; 201 if (item_preamble) 202 strm << item_preamble; 203 strm << GetStringAtIndex(i); 204 } 205 return strm.GetString(); 206} 207 208StringList &StringList::operator<<(const char *str) { 209 AppendString(str); 210 return *this; 211} 212 213StringList &StringList::operator<<(const std::string &str) { 214 AppendString(str); 215 return *this; 216} 217 218StringList &StringList::operator<<(StringList strings) { 219 AppendList(strings); 220 return *this; 221} 222 223StringList &StringList::operator=(const std::vector<std::string> &rhs) { 224 m_strings.assign(rhs.begin(), rhs.end()); 225 226 return *this; 227} 228 229size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches, 230 size_t &exact_idx) const { 231 matches.Clear(); 232 exact_idx = SIZE_MAX; 233 if (s.empty()) { 234 // No string, so it matches everything 235 matches = *this; 236 return matches.GetSize(); 237 } 238 239 const size_t s_len = s.size(); 240 const size_t num_strings = m_strings.size(); 241 242 for (size_t i = 0; i < num_strings; ++i) { 243 if (m_strings[i].find(s) == 0) { 244 if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len) 245 exact_idx = matches.GetSize(); 246 matches.AppendString(m_strings[i]); 247 } 248 } 249 return matches.GetSize(); 250} 251 252void StringList::LogDump(Log *log, const char *name) { 253 if (!log) 254 return; 255 256 StreamString strm; 257 if (name) 258 strm.Printf("Begin %s:\n", name); 259 for (const auto &s : m_strings) { 260 strm.Indent(); 261 strm.Printf("%s\n", s.c_str()); 262 } 263 if (name) 264 strm.Printf("End %s.\n", name); 265 266 LLDB_LOGV(log, "{0}", strm.GetData()); 267} 268