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
StringList()19 StringList::StringList () :
20 m_strings ()
21 {
22 }
23
StringList(const char * str)24 StringList::StringList (const char *str) :
25 m_strings ()
26 {
27 if (str)
28 m_strings.push_back (str);
29 }
30
StringList(const char ** strv,int strc)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
~StringList()41 StringList::~StringList ()
42 {
43 }
44
45 void
AppendString(const char * str)46 StringList::AppendString (const char *str)
47 {
48 if (str)
49 m_strings.push_back (str);
50 }
51
52 void
AppendString(const std::string & s)53 StringList::AppendString (const std::string &s)
54 {
55 m_strings.push_back (s);
56 }
57
58 void
AppendString(const char * str,size_t str_len)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
AppendList(const char ** strv,int strc)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
AppendList(StringList strings)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
ReadFileLines(FileSpec & input_file)85 StringList::ReadFileLines (FileSpec &input_file)
86 {
87 return input_file.ReadFileLines (m_strings);
88 }
89
90 size_t
GetSize() const91 StringList::GetSize () const
92 {
93 return m_strings.size();
94 }
95
96 const char *
GetStringAtIndex(size_t idx) const97 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
Join(const char * separator,Stream & strm)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
Clear()121 StringList::Clear ()
122 {
123 m_strings.clear();
124 }
125
126 void
LongestCommonPrefix(std::string & common_prefix)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
InsertStringAtIndex(size_t idx,const char * str)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
DeleteStringAtIndex(size_t idx)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
SplitIntoLines(const char * lines,size_t len)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
RemoveBlankLines()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
CopyList(const char * item_preamble,const char * items_sep)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&
operator <<(const char * str)250 StringList::operator << (const char* str)
251 {
252 AppendString(str);
253 return *this;
254 }
255
256 StringList&
operator <<(StringList strings)257 StringList::operator << (StringList strings)
258 {
259 AppendList(strings);
260 return *this;
261 }
262
263 size_t
AutoComplete(const char * s,StringList & matches,size_t & exact_idx) const264 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