1254721Semaste//===-- StringList.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/StringList.h" 11254721Semaste 12254721Semaste#include "lldb/Core/StreamString.h" 13254721Semaste#include "lldb/Host/FileSpec.h" 14254721Semaste 15254721Semaste#include <string> 16254721Semaste 17254721Semasteusing namespace lldb_private; 18254721Semaste 19254721SemasteStringList::StringList () : 20254721Semaste m_strings () 21254721Semaste{ 22254721Semaste} 23254721Semaste 24254721SemasteStringList::StringList (const char *str) : 25254721Semaste m_strings () 26254721Semaste{ 27254721Semaste if (str) 28254721Semaste m_strings.push_back (str); 29254721Semaste} 30254721Semaste 31254721SemasteStringList::StringList (const char **strv, int strc) : 32254721Semaste m_strings () 33254721Semaste{ 34254721Semaste for (int i = 0; i < strc; ++i) 35254721Semaste { 36254721Semaste if (strv[i]) 37254721Semaste m_strings.push_back (strv[i]); 38254721Semaste } 39254721Semaste} 40254721Semaste 41254721SemasteStringList::~StringList () 42254721Semaste{ 43254721Semaste} 44254721Semaste 45254721Semastevoid 46254721SemasteStringList::AppendString (const char *str) 47254721Semaste{ 48254721Semaste if (str) 49254721Semaste m_strings.push_back (str); 50254721Semaste} 51254721Semaste 52254721Semastevoid 53254721SemasteStringList::AppendString (const std::string &s) 54254721Semaste{ 55254721Semaste m_strings.push_back (s); 56254721Semaste} 57254721Semaste 58254721Semastevoid 59269024SemasteStringList::AppendString (std::string &&s) 60269024Semaste{ 61269024Semaste m_strings.push_back (s); 62269024Semaste} 63269024Semaste 64269024Semastevoid 65254721SemasteStringList::AppendString (const char *str, size_t str_len) 66254721Semaste{ 67254721Semaste if (str) 68254721Semaste m_strings.push_back (std::string (str, str_len)); 69254721Semaste} 70254721Semaste 71254721Semastevoid 72254721SemasteStringList::AppendList (const char **strv, int strc) 73254721Semaste{ 74254721Semaste for (int i = 0; i < strc; ++i) 75254721Semaste { 76254721Semaste if (strv[i]) 77254721Semaste m_strings.push_back (strv[i]); 78254721Semaste } 79254721Semaste} 80254721Semaste 81254721Semastevoid 82254721SemasteStringList::AppendList (StringList strings) 83254721Semaste{ 84254721Semaste size_t len = strings.GetSize(); 85254721Semaste 86254721Semaste for (size_t i = 0; i < len; ++i) 87254721Semaste m_strings.push_back (strings.GetStringAtIndex(i)); 88254721Semaste} 89254721Semaste 90254721Semastebool 91254721SemasteStringList::ReadFileLines (FileSpec &input_file) 92254721Semaste{ 93254721Semaste return input_file.ReadFileLines (m_strings); 94254721Semaste} 95254721Semaste 96254721Semastesize_t 97254721SemasteStringList::GetSize () const 98254721Semaste{ 99254721Semaste return m_strings.size(); 100254721Semaste} 101254721Semaste 102269024Semastesize_t 103269024SemasteStringList::GetMaxStringLength () const 104269024Semaste{ 105269024Semaste size_t max_length = 0; 106269024Semaste for (const auto &s : m_strings) 107269024Semaste { 108269024Semaste const size_t len = s.size(); 109269024Semaste if (max_length < len) 110269024Semaste max_length = len; 111269024Semaste } 112269024Semaste return max_length; 113269024Semaste} 114269024Semaste 115269024Semaste 116254721Semasteconst char * 117254721SemasteStringList::GetStringAtIndex (size_t idx) const 118254721Semaste{ 119254721Semaste if (idx < m_strings.size()) 120254721Semaste return m_strings[idx].c_str(); 121254721Semaste return NULL; 122254721Semaste} 123254721Semaste 124254721Semastevoid 125254721SemasteStringList::Join (const char *separator, Stream &strm) 126254721Semaste{ 127254721Semaste size_t size = GetSize(); 128254721Semaste 129254721Semaste if (size == 0) 130254721Semaste return; 131254721Semaste 132254721Semaste for (uint32_t i = 0; i < size; ++i) 133254721Semaste { 134254721Semaste if (i > 0) 135254721Semaste strm.PutCString(separator); 136254721Semaste strm.PutCString(GetStringAtIndex(i)); 137254721Semaste } 138254721Semaste} 139254721Semaste 140254721Semastevoid 141254721SemasteStringList::Clear () 142254721Semaste{ 143254721Semaste m_strings.clear(); 144254721Semaste} 145254721Semaste 146254721Semastevoid 147254721SemasteStringList::LongestCommonPrefix (std::string &common_prefix) 148254721Semaste{ 149269024Semaste const size_t num_strings = m_strings.size(); 150254721Semaste 151269024Semaste if (num_strings == 0) 152269024Semaste { 153254721Semaste common_prefix.clear(); 154269024Semaste } 155254721Semaste else 156254721Semaste { 157269024Semaste common_prefix = m_strings.front(); 158254721Semaste 159269024Semaste for (size_t idx = 1; idx < num_strings; ++idx) 160269024Semaste { 161269024Semaste std::string &curr_string = m_strings[idx]; 162269024Semaste size_t new_size = curr_string.size(); 163254721Semaste 164269024Semaste // First trim common_prefix if it is longer than the current element: 165269024Semaste if (common_prefix.size() > new_size) 166269024Semaste common_prefix.erase (new_size); 167254721Semaste 168269024Semaste // Then trim it at the first disparity: 169269024Semaste for (size_t i = 0; i < common_prefix.size(); i++) 170254721Semaste { 171269024Semaste if (curr_string[i] != common_prefix[i]) 172269024Semaste { 173269024Semaste common_prefix.erase(i); 174269024Semaste break; 175269024Semaste } 176269024Semaste } 177269024Semaste 178269024Semaste // If we've emptied the common prefix, we're done. 179269024Semaste if (common_prefix.empty()) 180254721Semaste break; 181254721Semaste } 182254721Semaste } 183254721Semaste} 184254721Semaste 185254721Semastevoid 186254721SemasteStringList::InsertStringAtIndex (size_t idx, const char *str) 187254721Semaste{ 188254721Semaste if (str) 189254721Semaste { 190254721Semaste if (idx < m_strings.size()) 191254721Semaste m_strings.insert (m_strings.begin() + idx, str); 192254721Semaste else 193254721Semaste m_strings.push_back (str); 194254721Semaste } 195254721Semaste} 196254721Semaste 197254721Semastevoid 198269024SemasteStringList::InsertStringAtIndex (size_t idx, const std::string &str) 199269024Semaste{ 200269024Semaste if (idx < m_strings.size()) 201269024Semaste m_strings.insert (m_strings.begin() + idx, str); 202269024Semaste else 203269024Semaste m_strings.push_back (str); 204269024Semaste} 205269024Semaste 206269024Semastevoid 207269024SemasteStringList::InsertStringAtIndex (size_t idx, std::string &&str) 208269024Semaste{ 209269024Semaste if (idx < m_strings.size()) 210269024Semaste m_strings.insert (m_strings.begin() + idx, str); 211269024Semaste else 212269024Semaste m_strings.push_back (str); 213269024Semaste} 214269024Semaste 215269024Semastevoid 216254721SemasteStringList::DeleteStringAtIndex (size_t idx) 217254721Semaste{ 218254721Semaste if (idx < m_strings.size()) 219254721Semaste m_strings.erase (m_strings.begin() + idx); 220254721Semaste} 221254721Semaste 222254721Semastesize_t 223269024SemasteStringList::SplitIntoLines (const std::string &lines) 224269024Semaste{ 225269024Semaste return SplitIntoLines (lines.c_str(), lines.size()); 226269024Semaste} 227269024Semaste 228269024Semastesize_t 229254721SemasteStringList::SplitIntoLines (const char *lines, size_t len) 230254721Semaste{ 231254721Semaste const size_t orig_size = m_strings.size(); 232254721Semaste 233254721Semaste if (len == 0) 234254721Semaste return 0; 235254721Semaste 236254721Semaste const char *k_newline_chars = "\r\n"; 237254721Semaste const char *p = lines; 238254721Semaste const char *end = lines + len; 239254721Semaste while (p < end) 240254721Semaste { 241254721Semaste size_t count = strcspn (p, k_newline_chars); 242254721Semaste if (count == 0) 243254721Semaste { 244254721Semaste if (p[count] == '\r' || p[count] == '\n') 245254721Semaste m_strings.push_back(std::string()); 246254721Semaste else 247254721Semaste break; 248254721Semaste } 249254721Semaste else 250254721Semaste { 251254721Semaste if (p + count > end) 252254721Semaste count = end - p; 253254721Semaste m_strings.push_back(std::string(p, count)); 254254721Semaste } 255254721Semaste if (p[count] == '\r' && p[count+1] == '\n') 256254721Semaste count++; // Skip an extra newline char for the DOS newline 257254721Semaste count++; // Skip the newline character 258254721Semaste p += count; 259254721Semaste } 260254721Semaste return m_strings.size() - orig_size; 261254721Semaste} 262254721Semaste 263254721Semastevoid 264254721SemasteStringList::RemoveBlankLines () 265254721Semaste{ 266254721Semaste if (GetSize() == 0) 267254721Semaste return; 268254721Semaste 269254721Semaste size_t idx = 0; 270254721Semaste while (idx < m_strings.size()) 271254721Semaste { 272254721Semaste if (m_strings[idx].empty()) 273254721Semaste DeleteStringAtIndex(idx); 274254721Semaste else 275254721Semaste idx++; 276254721Semaste } 277254721Semaste} 278254721Semaste 279254721Semastestd::string 280269024SemasteStringList::CopyList(const char* item_preamble, const char* items_sep) const 281254721Semaste{ 282254721Semaste StreamString strm; 283254721Semaste for (size_t i = 0; i < GetSize(); i++) 284254721Semaste { 285254721Semaste if (i && items_sep && items_sep[0]) 286254721Semaste strm << items_sep; 287254721Semaste if (item_preamble) 288254721Semaste strm << item_preamble; 289254721Semaste strm << GetStringAtIndex(i); 290254721Semaste } 291254721Semaste return std::string(strm.GetData()); 292254721Semaste} 293254721Semaste 294254721SemasteStringList& 295254721SemasteStringList::operator << (const char* str) 296254721Semaste{ 297254721Semaste AppendString(str); 298254721Semaste return *this; 299254721Semaste} 300254721Semaste 301254721SemasteStringList& 302254721SemasteStringList::operator << (StringList strings) 303254721Semaste{ 304254721Semaste AppendList(strings); 305254721Semaste return *this; 306254721Semaste} 307254721Semaste 308254721Semastesize_t 309254721SemasteStringList::AutoComplete (const char *s, StringList &matches, size_t &exact_idx) const 310254721Semaste{ 311254721Semaste matches.Clear(); 312254721Semaste exact_idx = SIZE_MAX; 313254721Semaste if (s && s[0]) 314254721Semaste { 315254721Semaste const size_t s_len = strlen (s); 316254721Semaste const size_t num_strings = m_strings.size(); 317254721Semaste 318254721Semaste for (size_t i=0; i<num_strings; ++i) 319254721Semaste { 320254721Semaste if (m_strings[i].find(s) == 0) 321254721Semaste { 322254721Semaste if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len) 323254721Semaste exact_idx = matches.GetSize(); 324254721Semaste matches.AppendString (m_strings[i]); 325254721Semaste } 326254721Semaste } 327254721Semaste } 328254721Semaste else 329254721Semaste { 330254721Semaste // No string, so it matches everything 331254721Semaste matches = *this; 332254721Semaste } 333254721Semaste return matches.GetSize(); 334254721Semaste} 335254721Semaste 336