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