blob: bc1334aca46c07ded17ed05784a70a9d436747d3 [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"
Zachary Turnerf343968f2016-08-09 23:06:08 +000020#include "lldb/Host/PosixApi.h"
Eli Friedman48862d42010-06-09 09:32:42 +000021#include "lldb/Target/PathMappingList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// PathMappingList constructor
28//----------------------------------------------------------------------
Greg Claytond804d282012-03-15 21:01:31 +000029PathMappingList::PathMappingList () :
Eugene Zelenko9394d7722016-02-18 00:10:17 +000030 m_pairs(),
31 m_callback(nullptr),
32 m_callback_baton(nullptr),
33 m_mod_id(0)
Greg Claytond804d282012-03-15 21:01:31 +000034{
35}
36
Greg Clayton4a895012013-03-14 22:52:17 +000037PathMappingList::PathMappingList (ChangedCallback callback,
38 void *callback_baton) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039 m_pairs (),
40 m_callback (callback),
Greg Clayton4a895012013-03-14 22:52:17 +000041 m_callback_baton (callback_baton),
42 m_mod_id (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
44}
45
Greg Clayton7e14f912011-04-23 02:04:55 +000046PathMappingList::PathMappingList (const PathMappingList &rhs) :
Eugene Zelenko9394d7722016-02-18 00:10:17 +000047 m_pairs(rhs.m_pairs),
48 m_callback(nullptr),
49 m_callback_baton(nullptr),
50 m_mod_id(0)
Greg Clayton7e14f912011-04-23 02:04:55 +000051{
Greg Clayton7e14f912011-04-23 02:04:55 +000052}
53
54const PathMappingList &
55PathMappingList::operator =(const PathMappingList &rhs)
56{
57 if (this != &rhs)
58 {
59 m_pairs = rhs.m_pairs;
Eugene Zelenko9394d7722016-02-18 00:10:17 +000060 m_callback = nullptr;
61 m_callback_baton = nullptr;
Greg Clayton4a895012013-03-14 22:52:17 +000062 m_mod_id = rhs.m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +000063 }
64 return *this;
65}
66
Eugene Zelenko9394d7722016-02-18 00:10:17 +000067PathMappingList::~PathMappingList() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
69void
70PathMappingList::Append (const ConstString &path,
71 const ConstString &replacement,
72 bool notify)
73{
Greg Clayton4a895012013-03-14 22:52:17 +000074 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075 m_pairs.push_back(pair(path, replacement));
76 if (notify && m_callback)
77 m_callback (*this, m_callback_baton);
78}
79
80void
Greg Claytond804d282012-03-15 21:01:31 +000081PathMappingList::Append (const PathMappingList &rhs, bool notify)
82{
Greg Clayton4a895012013-03-14 22:52:17 +000083 ++m_mod_id;
Greg Claytond804d282012-03-15 21:01:31 +000084 if (!rhs.m_pairs.empty())
85 {
86 const_iterator pos, end = rhs.m_pairs.end();
87 for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
88 m_pairs.push_back(*pos);
89 if (notify && m_callback)
90 m_callback (*this, m_callback_baton);
91 }
92}
93
94void
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095PathMappingList::Insert (const ConstString &path,
96 const ConstString &replacement,
97 uint32_t index,
98 bool notify)
99{
Greg Clayton4a895012013-03-14 22:52:17 +0000100 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 iterator insert_iter;
102 if (index >= m_pairs.size())
103 insert_iter = m_pairs.end();
104 else
105 insert_iter = m_pairs.begin() + index;
106 m_pairs.insert(insert_iter, pair(path, replacement));
107 if (notify && m_callback)
108 m_callback (*this, m_callback_baton);
109}
110
111bool
Greg Clayton67cc0632012-08-22 17:17:09 +0000112PathMappingList::Replace (const ConstString &path,
113 const ConstString &replacement,
114 uint32_t index,
115 bool notify)
116{
117 iterator insert_iter;
118 if (index >= m_pairs.size())
119 return false;
Greg Clayton4a895012013-03-14 22:52:17 +0000120 ++m_mod_id;
Greg Clayton67cc0632012-08-22 17:17:09 +0000121 m_pairs[index] = pair(path, replacement);
122 if (notify && m_callback)
123 m_callback (*this, m_callback_baton);
124 return true;
125}
126
127bool
Zachary Turnera746e8e2014-07-02 17:24:07 +0000128PathMappingList::Remove (size_t index, bool notify)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129{
Zachary Turnera746e8e2014-07-02 17:24:07 +0000130 if (index >= m_pairs.size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131 return false;
132
Greg Clayton4a895012013-03-14 22:52:17 +0000133 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134 iterator iter = m_pairs.begin() + index;
135 m_pairs.erase(iter);
136 if (notify && m_callback)
137 m_callback (*this, m_callback_baton);
138 return true;
139}
140
Johnny Chen64bab482011-12-12 21:59:28 +0000141// For clients which do not need the pair index dumped, pass a pair_index >= 0
142// to only dump the indicated pair.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143void
Johnny Chen64bab482011-12-12 21:59:28 +0000144PathMappingList::Dump (Stream *s, int pair_index)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145{
146 unsigned int numPairs = m_pairs.size();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147
Johnny Chen64bab482011-12-12 21:59:28 +0000148 if (pair_index < 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149 {
Johnny Chen64bab482011-12-12 21:59:28 +0000150 unsigned int index;
151 for (index = 0; index < numPairs; ++index)
152 s->Printf("[%d] \"%s\" -> \"%s\"\n",
153 index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
154 }
155 else
156 {
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +0000157 if (static_cast<unsigned int>(pair_index) < numPairs)
Johnny Chen64bab482011-12-12 21:59:28 +0000158 s->Printf("%s -> %s",
159 m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 }
161}
162
163void
164PathMappingList::Clear (bool notify)
165{
Greg Clayton4a895012013-03-14 22:52:17 +0000166 if (!m_pairs.empty())
167 ++m_mod_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 m_pairs.clear();
169 if (notify && m_callback)
170 m_callback (*this, m_callback_baton);
171}
172
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173bool
Greg Claytond804d282012-03-15 21:01:31 +0000174PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175{
Sean Callananf6015032012-09-26 01:28:11 +0000176 const char *path_cstr = path.GetCString();
177
178 if (!path_cstr)
179 return false;
180
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 const_iterator pos, end = m_pairs.end();
182 for (pos = m_pairs.begin(); pos != end; ++pos)
183 {
184 const size_t prefixLen = pos->first.GetLength();
185
Sean Callananf6015032012-09-26 01:28:11 +0000186 if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187 {
188 std::string new_path_str (pos->second.GetCString());
189 new_path_str.append(path.GetCString() + prefixLen);
190 new_path.SetCString(new_path_str.c_str());
191 return true;
192 }
193 }
194 return false;
195}
Greg Clayton7e14f912011-04-23 02:04:55 +0000196
197bool
Greg Claytonf9be6932012-03-19 22:22:41 +0000198PathMappingList::RemapPath (const char *path, std::string &new_path) const
199{
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000200 if (m_pairs.empty() || path == nullptr || path[0] == '\0')
Greg Claytonf9be6932012-03-19 22:22:41 +0000201 return false;
202
203 const_iterator pos, end = m_pairs.end();
204 for (pos = m_pairs.begin(); pos != end; ++pos)
205 {
206 const size_t prefix_len = pos->first.GetLength();
207
208 if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0)
209 {
210 new_path = pos->second.GetCString();
211 new_path.append(path + prefix_len);
212 return true;
213 }
214 }
215 return false;
216}
217
218bool
Tamas Berghammerb0b1ea32016-03-04 11:26:44 +0000219PathMappingList::ReverseRemapPath (const ConstString &path, ConstString &new_path) const
220{
221 const char *path_cstr = path.GetCString();
222 if (!path_cstr)
223 return false;
224
225 for (const auto& it : m_pairs)
226 {
Jim Ingham291fd352016-08-23 17:13:33 +0000227 // FIXME: This should be using FileSpec API's to do the path appending.
Tamas Berghammerb0b1ea32016-03-04 11:26:44 +0000228 const size_t prefixLen = it.second.GetLength();
229 if (::strncmp (it.second.GetCString(), path_cstr, prefixLen) == 0)
230 {
231 std::string new_path_str (it.first.GetCString());
232 new_path_str.append(path.GetCString() + prefixLen);
233 new_path.SetCString(new_path_str.c_str());
234 return true;
235 }
236 }
237 return false;
238}
239
240bool
Greg Claytond804d282012-03-15 21:01:31 +0000241PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
242{
243 if (!m_pairs.empty())
244 {
245 char orig_path[PATH_MAX];
Greg Claytond804d282012-03-15 21:01:31 +0000246 const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
247 if (orig_path_len > 0)
248 {
249 const_iterator pos, end = m_pairs.end();
250 for (pos = m_pairs.begin(); pos != end; ++pos)
251 {
252 const size_t prefix_len = pos->first.GetLength();
253
254 if (orig_path_len >= prefix_len)
255 {
256 if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
257 {
Jim Ingham291fd352016-08-23 17:13:33 +0000258 new_spec.SetFile(pos->second.GetCString(), false);
259 new_spec.AppendPathComponent(orig_path+prefix_len);
260 if (new_spec.Exists())
261 return true;
Greg Claytond804d282012-03-15 21:01:31 +0000262 }
263 }
264 }
265 }
266 }
267 new_spec.Clear();
268 return false;
269}
270
271bool
Greg Clayton7e14f912011-04-23 02:04:55 +0000272PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
273{
274 uint32_t idx = FindIndexForPath (path);
275 if (idx < m_pairs.size())
276 {
Greg Clayton4a895012013-03-14 22:52:17 +0000277 ++m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +0000278 m_pairs[idx].second = new_path;
279 if (notify && m_callback)
280 m_callback (*this, m_callback_baton);
281 return true;
282 }
283 return false;
284}
285
286bool
287PathMappingList::Remove (const ConstString &path, bool notify)
288{
289 iterator pos = FindIteratorForPath (path);
290 if (pos != m_pairs.end())
291 {
Greg Clayton4a895012013-03-14 22:52:17 +0000292 ++m_mod_id;
Greg Clayton7e14f912011-04-23 02:04:55 +0000293 m_pairs.erase (pos);
294 if (notify && m_callback)
295 m_callback (*this, m_callback_baton);
296 return true;
297 }
298 return false;
299}
300
301PathMappingList::const_iterator
302PathMappingList::FindIteratorForPath (const ConstString &path) const
303{
304 const_iterator pos;
305 const_iterator begin = m_pairs.begin();
306 const_iterator end = m_pairs.end();
307
308 for (pos = begin; pos != end; ++pos)
309 {
310 if (pos->first == path)
311 break;
312 }
313 return pos;
314}
315
316PathMappingList::iterator
317PathMappingList::FindIteratorForPath (const ConstString &path)
318{
319 iterator pos;
320 iterator begin = m_pairs.begin();
321 iterator end = m_pairs.end();
322
323 for (pos = begin; pos != end; ++pos)
324 {
325 if (pos->first == path)
326 break;
327 }
328 return pos;
329}
330
331bool
332PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
333{
334 if (idx < m_pairs.size())
335 {
336 path = m_pairs[idx].first;
337 new_path = m_pairs[idx].second;
338 return true;
339 }
340 return false;
341}
342
Greg Clayton7e14f912011-04-23 02:04:55 +0000343uint32_t
344PathMappingList::FindIndexForPath (const ConstString &path) const
345{
346 const_iterator pos;
347 const_iterator begin = m_pairs.begin();
348 const_iterator end = m_pairs.end();
349
350 for (pos = begin; pos != end; ++pos)
351 {
352 if (pos->first == path)
353 return std::distance (begin, pos);
354 }
355 return UINT32_MAX;
356}