StringList.cpp revision 9f282851b07ff6daee37cd3b1a3fbc43ef11da29
1//===-- StringList.cpp ------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/Core/StringList.h" 11 12#include "lldb/Core/StreamString.h" 13#include "lldb/Host/FileSpec.h" 14 15#include <string> 16 17using namespace lldb_private; 18 19StringList::StringList () : 20 m_strings () 21{ 22} 23 24StringList::StringList (const char *str) : 25 m_strings () 26{ 27 if (str) 28 m_strings.push_back (str); 29} 30 31StringList::StringList (const char **strv, int strc) : 32 m_strings () 33{ 34 for (int i = 0; i < strc; ++i) 35 { 36 if (strv[i]) 37 m_strings.push_back (strv[i]); 38 } 39} 40 41StringList::~StringList () 42{ 43} 44 45void 46StringList::AppendString (const char *str) 47{ 48 if (str) 49 m_strings.push_back (str); 50} 51 52void 53StringList::AppendString (const std::string &s) 54{ 55 m_strings.push_back (s); 56} 57 58void 59StringList::AppendString (const char *str, size_t str_len) 60{ 61 if (str) 62 m_strings.push_back (std::string (str, str_len)); 63} 64 65void 66StringList::AppendList (const char **strv, int strc) 67{ 68 for (int i = 0; i < strc; ++i) 69 { 70 if (strv[i]) 71 m_strings.push_back (strv[i]); 72 } 73} 74 75void 76StringList::AppendList (StringList strings) 77{ 78 uint32_t len = strings.GetSize(); 79 80 for (uint32_t i = 0; i < len; ++i) 81 m_strings.push_back (strings.GetStringAtIndex(i)); 82} 83 84bool 85StringList::ReadFileLines (FileSpec &input_file) 86{ 87 return input_file.ReadFileLines (m_strings); 88} 89 90uint32_t 91StringList::GetSize () const 92{ 93 return m_strings.size(); 94} 95 96const char * 97StringList::GetStringAtIndex (size_t idx) const 98{ 99 if (idx < m_strings.size()) 100 return m_strings[idx].c_str(); 101 return NULL; 102} 103 104void 105StringList::Join (const char *separator, Stream &strm) 106{ 107 uint32_t size = GetSize(); 108 109 if (size == 0) 110 return; 111 112 for (uint32_t i = 0; i < size; ++i) 113 { 114 if (i > 0) 115 strm.PutCString(separator); 116 strm.PutCString(GetStringAtIndex(i)); 117 } 118} 119 120void 121StringList::Clear () 122{ 123 m_strings.clear(); 124} 125 126void 127StringList::LongestCommonPrefix (std::string &common_prefix) 128{ 129 //arg_sstr_collection::iterator pos, end = m_args.end(); 130 int pos = 0; 131 int end = m_strings.size(); 132 133 if (pos == end) 134 common_prefix.clear(); 135 else 136 common_prefix = m_strings[pos]; 137 138 for (++pos; pos != end; ++pos) 139 { 140 size_t new_size = strlen (m_strings[pos].c_str()); 141 142 // First trim common_prefix if it is longer than the current element: 143 if (common_prefix.size() > new_size) 144 common_prefix.erase (new_size); 145 146 // Then trim it at the first disparity: 147 148 for (size_t i = 0; i < common_prefix.size(); i++) 149 { 150 if (m_strings[pos][i] != common_prefix[i]) 151 { 152 common_prefix.erase(i); 153 break; 154 } 155 } 156 157 // If we've emptied the common prefix, we're done. 158 if (common_prefix.empty()) 159 break; 160 } 161} 162 163void 164StringList::InsertStringAtIndex (size_t idx, const char *str) 165{ 166 if (str) 167 { 168 if (idx < m_strings.size()) 169 m_strings.insert (m_strings.begin() + idx, str); 170 else 171 m_strings.push_back (str); 172 } 173} 174 175void 176StringList::DeleteStringAtIndex (size_t idx) 177{ 178 if (idx < m_strings.size()) 179 m_strings.erase (m_strings.begin() + idx); 180} 181 182size_t 183StringList::SplitIntoLines (const char *lines, size_t len) 184{ 185 const size_t orig_size = m_strings.size(); 186 187 if (len == 0) 188 return 0; 189 190 const char *k_newline_chars = "\r\n"; 191 const char *p = lines; 192 const char *end = lines + len; 193 while (p < end) 194 { 195 size_t count = strcspn (p, k_newline_chars); 196 if (count == 0) 197 { 198 if (p[count] == '\r' || p[count] == '\n') 199 m_strings.push_back(std::string()); 200 else 201 break; 202 } 203 else 204 { 205 if (p + count > end) 206 count = end - p; 207 m_strings.push_back(std::string(p, count)); 208 } 209 if (p[count] == '\r' && p[count+1] == '\n') 210 count++; // Skip an extra newline char for the DOS newline 211 count++; // Skip the newline character 212 p += count; 213 } 214 return m_strings.size() - orig_size; 215} 216 217void 218StringList::RemoveBlankLines () 219{ 220 if (GetSize() == 0) 221 return; 222 223 size_t idx = 0; 224 while (idx < m_strings.size()) 225 { 226 if (m_strings[idx].empty()) 227 DeleteStringAtIndex(idx); 228 else 229 idx++; 230 } 231} 232 233std::string 234StringList::CopyList(const char* item_preamble, 235 const char* items_sep) 236{ 237 StreamString strm; 238 for (int i = 0; i < GetSize(); i++) 239 { 240 if (i && items_sep && items_sep[0]) 241 strm << items_sep; 242 if (item_preamble) 243 strm << item_preamble; 244 strm << GetStringAtIndex(i); 245 } 246 return std::string(strm.GetData()); 247} 248 249StringList& 250StringList::operator << (const char* str) 251{ 252 AppendString(str); 253 return *this; 254} 255 256StringList& 257StringList::operator << (StringList strings) 258{ 259 AppendList(strings); 260 return *this; 261} 262 263size_t 264StringList::AutoComplete (const char *s, StringList &matches, size_t &exact_idx) const 265{ 266 matches.Clear(); 267 exact_idx = SIZE_MAX; 268 if (s && s[0]) 269 { 270 const size_t s_len = strlen (s); 271 const size_t num_strings = m_strings.size(); 272 273 for (size_t i=0; i<num_strings; ++i) 274 { 275 if (m_strings[i].find(s) == 0) 276 { 277 if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len) 278 exact_idx = matches.GetSize(); 279 matches.AppendString (m_strings[i]); 280 } 281 } 282 } 283 else 284 { 285 // No string, so it matches everything 286 matches = *this; 287 } 288 return matches.GetSize(); 289} 290 291