blob: 18b6224a5201b823662eff7ec4c5ef35041251dc [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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"
Enrico Granataf7a9b142011-07-15 02:26:42 +000011
12#include "lldb/Core/StreamString.h"
Jim Ingham949d5ac2011-02-18 00:54:25 +000013#include "lldb/Host/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014
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
Greg Clayton73844aa2012-08-22 17:17:09 +000053StringList::AppendString (const std::string &s)
54{
55 m_strings.push_back (s);
56}
57
58void
Chris Lattner24943d22010-06-08 16:52:24 +000059StringList::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
Greg Clayton54e7afa2010-07-09 20:39:50 +000080 for (uint32_t i = 0; i < len; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +000081 m_strings.push_back (strings.GetStringAtIndex(i));
82}
83
Jim Ingham949d5ac2011-02-18 00:54:25 +000084bool
85StringList::ReadFileLines (FileSpec &input_file)
86{
87 return input_file.ReadFileLines (m_strings);
88}
89
Chris Lattner24943d22010-06-08 16:52:24 +000090uint32_t
Jim Ingham80539042011-03-11 01:48:52 +000091StringList::GetSize () const
Chris Lattner24943d22010-06-08 16:52:24 +000092{
93 return m_strings.size();
94}
95
96const char *
Jim Ingham80539042011-03-11 01:48:52 +000097StringList::GetStringAtIndex (size_t idx) const
Chris Lattner24943d22010-06-08 16:52:24 +000098{
99 if (idx < m_strings.size())
100 return m_strings[idx].c_str();
101 return NULL;
102}
103
Greg Claytondc43bbf2012-05-26 17:21:14 +0000104void
105StringList::Join (const char *separator, Stream &strm)
Johnny Chen746323a2012-05-26 00:32:39 +0000106{
107 uint32_t size = GetSize();
Greg Claytondc43bbf2012-05-26 17:21:14 +0000108
Johnny Chen746323a2012-05-26 00:32:39 +0000109 if (size == 0)
Greg Claytondc43bbf2012-05-26 17:21:14 +0000110 return;
111
Johnny Chen746323a2012-05-26 00:32:39 +0000112 for (uint32_t i = 0; i < size; ++i)
113 {
114 if (i > 0)
Greg Claytondc43bbf2012-05-26 17:21:14 +0000115 strm.PutCString(separator);
116 strm.PutCString(GetStringAtIndex(i));
Johnny Chen746323a2012-05-26 00:32:39 +0000117 }
Johnny Chen746323a2012-05-26 00:32:39 +0000118}
119
Chris Lattner24943d22010-06-08 16:52:24 +0000120void
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 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000140 size_t new_size = strlen (m_strings[pos].c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000141
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
Greg Clayton54e7afa2010-07-09 20:39:50 +0000148 for (size_t i = 0; i < common_prefix.size(); i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000149 {
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
Greg Clayton54e7afa2010-07-09 20:39:50 +0000223 size_t idx = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000224 while (idx < m_strings.size())
225 {
226 if (m_strings[idx].empty())
227 DeleteStringAtIndex(idx);
228 else
229 idx++;
230 }
231}
Enrico Granataf7a9b142011-07-15 02:26:42 +0000232
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;
Greg Clayton153ccd72011-08-10 02:10:13 +0000261}
Greg Clayton73844aa2012-08-22 17:17:09 +0000262
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 }
Greg Clayton9f282852012-08-23 00:22:02 +0000283 else
284 {
285 // No string, so it matches everything
286 matches = *this;
287 }
Greg Clayton73844aa2012-08-22 17:17:09 +0000288 return matches.GetSize();
289}
290