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 17 using namespace lldb_private; 18 19 StringList::StringList () : 20 m_strings () 21 { 22 } 23 24 StringList::StringList (const char *str) : 25 m_strings () 26 { 27 if (str) 28 m_strings.push_back (str); 29 } 30 31 StringList::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 41 StringList::~StringList () 42 { 43 } 44 45 void 46 StringList::AppendString (const char *str) 47 { 48 if (str) 49 m_strings.push_back (str); 50 } 51 52 void 53 StringList::AppendString (const std::string &s) 54 { 55 m_strings.push_back (s); 56 } 57 58 void 59 StringList::AppendString (const char *str, size_t str_len) 60 { 61 if (str) 62 m_strings.push_back (std::string (str, str_len)); 63 } 64 65 void 66 StringList::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 75 void 76 StringList::AppendList (StringList strings) 77 { 78 size_t len = strings.GetSize(); 79 80 for (size_t i = 0; i < len; ++i) 81 m_strings.push_back (strings.GetStringAtIndex(i)); 82 } 83 84 bool 85 StringList::ReadFileLines (FileSpec &input_file) 86 { 87 return input_file.ReadFileLines (m_strings); 88 } 89 90 size_t 91 StringList::GetSize () const 92 { 93 return m_strings.size(); 94 } 95 96 const char * 97 StringList::GetStringAtIndex (size_t idx) const 98 { 99 if (idx < m_strings.size()) 100 return m_strings[idx].c_str(); 101 return NULL; 102 } 103 104 void 105 StringList::Join (const char *separator, Stream &strm) 106 { 107 size_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 120 void 121 StringList::Clear () 122 { 123 m_strings.clear(); 124 } 125 126 void 127 StringList::LongestCommonPrefix (std::string &common_prefix) 128 { 129 //arg_sstr_collection::iterator pos, end = m_args.end(); 130 size_t pos = 0; 131 size_t 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 163 void 164 StringList::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 175 void 176 StringList::DeleteStringAtIndex (size_t idx) 177 { 178 if (idx < m_strings.size()) 179 m_strings.erase (m_strings.begin() + idx); 180 } 181 182 size_t 183 StringList::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 217 void 218 StringList::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 233 std::string 234 StringList::CopyList(const char* item_preamble, 235 const char* items_sep) 236 { 237 StreamString strm; 238 for (size_t 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 249 StringList& 250 StringList::operator << (const char* str) 251 { 252 AppendString(str); 253 return *this; 254 } 255 256 StringList& 257 StringList::operator << (StringList strings) 258 { 259 AppendList(strings); 260 return *this; 261 } 262 263 size_t 264 StringList::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