blob: bc14be1785d3c09e867b45a61f29a6624dd6b355 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- PathMappingList.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// C Includes
11// C++ Includes
Eugene Zelenko9394d7722016-02-18 00:10:17 +000012#include <climits>
13#include <cstring>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// Other libraries and framework includes
Greg Claytond804d282012-03-15 21:01:31 +000016// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/Error.h"
18#include "lldb/Core/Stream.h"
Greg Claytond804d282012-03-15 21:01:31 +000019#include "lldb/Host/FileSpec.h"
Eli Friedman48862d42010-06-09 09:32:42 +000020#include "lldb/Target/PathMappingList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021
22using namespace lldb;
23using namespace lldb_private;
24
25//----------------------------------------------------------------------
26// PathMappingList constructor
27//----------------------------------------------------------------------
Greg Claytond804d282012-03-15 21:01:31 +000028PathMappingList::PathMappingList () :
Eugene Zelenko9394d7722016-02-18 00:10:17 +000029 m_pairs(),
30 m_callback(nullptr),
31 m_callback_baton(nullptr),
32 m_mod_id(0)
Greg Claytond804d282012-03-15 21:01:31 +000033{
34}
35
Greg Clayton4a895012013-03-14 22:52:17 +000036PathMappingList::PathMappingList (ChangedCallback callback,
37 void *callback_baton) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038 m_pairs (),
39 m_callback (callback),
Greg Clayton4a895012013-03-14 22:52:17 +000040 m_callback_baton (callback_baton),
41 m_mod_id (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
43}
44
Greg Clayton7e14f912011-04-23 02:04:55 +000045PathMappingList::PathMappingList (const PathMappingList &rhs) :
Eugene Zelenko9394d7722016-02-18 00:10:17 +000046 m_pairs(rhs.m_pairs),
47 m_callback(nullptr),
48 m_callback_baton(nullptr),
49 m_mod_id(0)
Greg Clayton7e14f912011-04-23 02:04:55 +000050{
Greg Clayton7e14f912011-04-23 02:04:55 +000051}
52
53const PathMappingList &
54PathMappingList::operator =(const PathMappingList &rhs)
55{
56 if (this != &rhs)
57 {
58 m_pairs = rhs.m_pairs;
Eugene Zelenko9394d7722016-02-18 00:10:17 +000059 m_callback = nullptr;
60 m_callback_baton = nullptr;
Greg Clayton4a895012013-03-14 22:52:17 +000061 m_mod_id = rhs.m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +000062 }
63 return *this;
64}
65
Eugene Zelenko9394d7722016-02-18 00:10:17 +000066PathMappingList::~PathMappingList() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067
68void
69PathMappingList::Append (const ConstString &path,
70 const ConstString &replacement,
71 bool notify)
72{
Greg Clayton4a895012013-03-14 22:52:17 +000073 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074 m_pairs.push_back(pair(path, replacement));
75 if (notify && m_callback)
76 m_callback (*this, m_callback_baton);
77}
78
79void
Greg Claytond804d282012-03-15 21:01:31 +000080PathMappingList::Append (const PathMappingList &rhs, bool notify)
81{
Greg Clayton4a895012013-03-14 22:52:17 +000082 ++m_mod_id;
Greg Claytond804d282012-03-15 21:01:31 +000083 if (!rhs.m_pairs.empty())
84 {
85 const_iterator pos, end = rhs.m_pairs.end();
86 for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
87 m_pairs.push_back(*pos);
88 if (notify && m_callback)
89 m_callback (*this, m_callback_baton);
90 }
91}
92
93void
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094PathMappingList::Insert (const ConstString &path,
95 const ConstString &replacement,
96 uint32_t index,
97 bool notify)
98{
Greg Clayton4a895012013-03-14 22:52:17 +000099 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100 iterator insert_iter;
101 if (index >= m_pairs.size())
102 insert_iter = m_pairs.end();
103 else
104 insert_iter = m_pairs.begin() + index;
105 m_pairs.insert(insert_iter, pair(path, replacement));
106 if (notify && m_callback)
107 m_callback (*this, m_callback_baton);
108}
109
110bool
Greg Clayton67cc0632012-08-22 17:17:09 +0000111PathMappingList::Replace (const ConstString &path,
112 const ConstString &replacement,
113 uint32_t index,
114 bool notify)
115{
116 iterator insert_iter;
117 if (index >= m_pairs.size())
118 return false;
Greg Clayton4a895012013-03-14 22:52:17 +0000119 ++m_mod_id;
Greg Clayton67cc0632012-08-22 17:17:09 +0000120 m_pairs[index] = pair(path, replacement);
121 if (notify && m_callback)
122 m_callback (*this, m_callback_baton);
123 return true;
124}
125
126bool
Zachary Turnera746e8e2014-07-02 17:24:07 +0000127PathMappingList::Remove (size_t index, bool notify)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128{
Zachary Turnera746e8e2014-07-02 17:24:07 +0000129 if (index >= m_pairs.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 return false;
131
Greg Clayton4a895012013-03-14 22:52:17 +0000132 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133 iterator iter = m_pairs.begin() + index;
134 m_pairs.erase(iter);
135 if (notify && m_callback)
136 m_callback (*this, m_callback_baton);
137 return true;
138}
139
Johnny Chen64bab482011-12-12 21:59:28 +0000140// For clients which do not need the pair index dumped, pass a pair_index >= 0
141// to only dump the indicated pair.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142void
Johnny Chen64bab482011-12-12 21:59:28 +0000143PathMappingList::Dump (Stream *s, int pair_index)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144{
145 unsigned int numPairs = m_pairs.size();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Johnny Chen64bab482011-12-12 21:59:28 +0000147 if (pair_index < 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 {
Johnny Chen64bab482011-12-12 21:59:28 +0000149 unsigned int index;
150 for (index = 0; index < numPairs; ++index)
151 s->Printf("[%d] \"%s\" -> \"%s\"\n",
152 index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
153 }
154 else
155 {
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +0000156 if (static_cast<unsigned int>(pair_index) < numPairs)
Johnny Chen64bab482011-12-12 21:59:28 +0000157 s->Printf("%s -> %s",
158 m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 }
160}
161
162void
163PathMappingList::Clear (bool notify)
164{
Greg Clayton4a895012013-03-14 22:52:17 +0000165 if (!m_pairs.empty())
166 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 m_pairs.clear();
168 if (notify && m_callback)
169 m_callback (*this, m_callback_baton);
170}
171
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172bool
Greg Claytond804d282012-03-15 21:01:31 +0000173PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174{
Sean Callananf6015032012-09-26 01:28:11 +0000175 const char *path_cstr = path.GetCString();
176
177 if (!path_cstr)
178 return false;
179
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 const_iterator pos, end = m_pairs.end();
181 for (pos = m_pairs.begin(); pos != end; ++pos)
182 {
183 const size_t prefixLen = pos->first.GetLength();
184
Sean Callananf6015032012-09-26 01:28:11 +0000185 if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 {
187 std::string new_path_str (pos->second.GetCString());
188 new_path_str.append(path.GetCString() + prefixLen);
189 new_path.SetCString(new_path_str.c_str());
190 return true;
191 }
192 }
193 return false;
194}
Greg Clayton7e14f912011-04-23 02:04:55 +0000195
196bool
Greg Claytonf9be6932012-03-19 22:22:41 +0000197PathMappingList::RemapPath (const char *path, std::string &new_path) const
198{
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000199 if (m_pairs.empty() || path == nullptr || path[0] == '\0')
Greg Claytonf9be6932012-03-19 22:22:41 +0000200 return false;
201
202 const_iterator pos, end = m_pairs.end();
203 for (pos = m_pairs.begin(); pos != end; ++pos)
204 {
205 const size_t prefix_len = pos->first.GetLength();
206
207 if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0)
208 {
209 new_path = pos->second.GetCString();
210 new_path.append(path + prefix_len);
211 return true;
212 }
213 }
214 return false;
215}
216
217bool
Greg Claytond804d282012-03-15 21:01:31 +0000218PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
219{
220 if (!m_pairs.empty())
221 {
222 char orig_path[PATH_MAX];
223 char new_path[PATH_MAX];
224 const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
225 if (orig_path_len > 0)
226 {
227 const_iterator pos, end = m_pairs.end();
228 for (pos = m_pairs.begin(); pos != end; ++pos)
229 {
230 const size_t prefix_len = pos->first.GetLength();
231
232 if (orig_path_len >= prefix_len)
233 {
234 if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
235 {
236 const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len);
237 if (new_path_len < sizeof(new_path))
238 {
239 new_spec.SetFile (new_path, true);
240 if (new_spec.Exists())
241 return true;
242 }
243 }
244 }
245 }
246 }
247 }
248 new_spec.Clear();
249 return false;
250}
251
252bool
Greg Clayton7e14f912011-04-23 02:04:55 +0000253PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
254{
255 uint32_t idx = FindIndexForPath (path);
256 if (idx < m_pairs.size())
257 {
Greg Clayton4a895012013-03-14 22:52:17 +0000258 ++m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +0000259 m_pairs[idx].second = new_path;
260 if (notify && m_callback)
261 m_callback (*this, m_callback_baton);
262 return true;
263 }
264 return false;
265}
266
267bool
268PathMappingList::Remove (const ConstString &path, bool notify)
269{
270 iterator pos = FindIteratorForPath (path);
271 if (pos != m_pairs.end())
272 {
Greg Clayton4a895012013-03-14 22:52:17 +0000273 ++m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +0000274 m_pairs.erase (pos);
275 if (notify && m_callback)
276 m_callback (*this, m_callback_baton);
277 return true;
278 }
279 return false;
280}
281
282PathMappingList::const_iterator
283PathMappingList::FindIteratorForPath (const ConstString &path) const
284{
285 const_iterator pos;
286 const_iterator begin = m_pairs.begin();
287 const_iterator end = m_pairs.end();
288
289 for (pos = begin; pos != end; ++pos)
290 {
291 if (pos->first == path)
292 break;
293 }
294 return pos;
295}
296
297PathMappingList::iterator
298PathMappingList::FindIteratorForPath (const ConstString &path)
299{
300 iterator pos;
301 iterator begin = m_pairs.begin();
302 iterator end = m_pairs.end();
303
304 for (pos = begin; pos != end; ++pos)
305 {
306 if (pos->first == path)
307 break;
308 }
309 return pos;
310}
311
312bool
313PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
314{
315 if (idx < m_pairs.size())
316 {
317 path = m_pairs[idx].first;
318 new_path = m_pairs[idx].second;
319 return true;
320 }
321 return false;
322}
323
Greg Clayton7e14f912011-04-23 02:04:55 +0000324uint32_t
325PathMappingList::FindIndexForPath (const ConstString &path) const
326{
327 const_iterator pos;
328 const_iterator begin = m_pairs.begin();
329 const_iterator end = m_pairs.end();
330
331 for (pos = begin; pos != end; ++pos)
332 {
333 if (pos->first == path)
334 return std::distance (begin, pos);
335 }
336 return UINT32_MAX;
337}