blob: 345bbed3b14220fe055db9282ec2d0325848b2ea [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
Benjamin Kramer44057c32012-03-18 13:06:54 +000011#include <limits.h>
Greg Claytond804d282012-03-15 21:01:31 +000012#include <string.h>
13
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014// C++ Includes
15// 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 () :
29 m_pairs (),
30 m_callback (NULL),
31 m_callback_baton (NULL)
32{
33}
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035PathMappingList::PathMappingList
36(
37 ChangedCallback callback,
38 void *callback_baton
39) :
40 m_pairs (),
41 m_callback (callback),
42 m_callback_baton (callback_baton)
43{
44}
45
Greg Clayton7e14f912011-04-23 02:04:55 +000046
47PathMappingList::PathMappingList (const PathMappingList &rhs) :
48 m_pairs (rhs.m_pairs),
49 m_callback (NULL),
50 m_callback_baton (NULL)
51{
52
53}
54
55const PathMappingList &
56PathMappingList::operator =(const PathMappingList &rhs)
57{
58 if (this != &rhs)
59 {
60 m_pairs = rhs.m_pairs;
61 m_callback = NULL;
62 m_callback_baton = NULL;
63 }
64 return *this;
65}
66
67
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068//----------------------------------------------------------------------
69// Destructor
70//----------------------------------------------------------------------
71PathMappingList::~PathMappingList ()
72{
73}
74
75void
76PathMappingList::Append (const ConstString &path,
77 const ConstString &replacement,
78 bool notify)
79{
80 m_pairs.push_back(pair(path, replacement));
81 if (notify && m_callback)
82 m_callback (*this, m_callback_baton);
83}
84
85void
Greg Claytond804d282012-03-15 21:01:31 +000086PathMappingList::Append (const PathMappingList &rhs, bool notify)
87{
88 if (!rhs.m_pairs.empty())
89 {
90 const_iterator pos, end = rhs.m_pairs.end();
91 for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
92 m_pairs.push_back(*pos);
93 if (notify && m_callback)
94 m_callback (*this, m_callback_baton);
95 }
96}
97
98void
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099PathMappingList::Insert (const ConstString &path,
100 const ConstString &replacement,
101 uint32_t index,
102 bool notify)
103{
104 iterator insert_iter;
105 if (index >= m_pairs.size())
106 insert_iter = m_pairs.end();
107 else
108 insert_iter = m_pairs.begin() + index;
109 m_pairs.insert(insert_iter, pair(path, replacement));
110 if (notify && m_callback)
111 m_callback (*this, m_callback_baton);
112}
113
114bool
115PathMappingList::Remove (off_t index, bool notify)
116{
117 if (index >= m_pairs.size())
118 return false;
119
120 iterator iter = m_pairs.begin() + index;
121 m_pairs.erase(iter);
122 if (notify && m_callback)
123 m_callback (*this, m_callback_baton);
124 return true;
125}
126
Johnny Chen64bab482011-12-12 21:59:28 +0000127// For clients which do not need the pair index dumped, pass a pair_index >= 0
128// to only dump the indicated pair.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129void
Johnny Chen64bab482011-12-12 21:59:28 +0000130PathMappingList::Dump (Stream *s, int pair_index)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131{
132 unsigned int numPairs = m_pairs.size();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133
Johnny Chen64bab482011-12-12 21:59:28 +0000134 if (pair_index < 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 {
Johnny Chen64bab482011-12-12 21:59:28 +0000136 unsigned int index;
137 for (index = 0; index < numPairs; ++index)
138 s->Printf("[%d] \"%s\" -> \"%s\"\n",
139 index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
140 }
141 else
142 {
143 if (pair_index < numPairs)
144 s->Printf("%s -> %s",
145 m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 }
147}
148
149void
150PathMappingList::Clear (bool notify)
151{
152 m_pairs.clear();
153 if (notify && m_callback)
154 m_callback (*this, m_callback_baton);
155}
156
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157bool
Greg Claytond804d282012-03-15 21:01:31 +0000158PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159{
160 const_iterator pos, end = m_pairs.end();
161 for (pos = m_pairs.begin(); pos != end; ++pos)
162 {
163 const size_t prefixLen = pos->first.GetLength();
164
165 if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0)
166 {
167 std::string new_path_str (pos->second.GetCString());
168 new_path_str.append(path.GetCString() + prefixLen);
169 new_path.SetCString(new_path_str.c_str());
170 return true;
171 }
172 }
173 return false;
174}
Greg Clayton7e14f912011-04-23 02:04:55 +0000175
176bool
Greg Claytonf9be6932012-03-19 22:22:41 +0000177PathMappingList::RemapPath (const char *path, std::string &new_path) const
178{
179 if (!m_pairs.empty() || path == NULL || path[0] == '\0')
180 return false;
181
182 const_iterator pos, end = m_pairs.end();
183 for (pos = m_pairs.begin(); pos != end; ++pos)
184 {
185 const size_t prefix_len = pos->first.GetLength();
186
187 if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0)
188 {
189 new_path = pos->second.GetCString();
190 new_path.append(path + prefix_len);
191 return true;
192 }
193 }
194 return false;
195}
196
197bool
Greg Claytond804d282012-03-15 21:01:31 +0000198PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const
199{
200 if (!m_pairs.empty())
201 {
202 char orig_path[PATH_MAX];
203 char new_path[PATH_MAX];
204 const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path));
205 if (orig_path_len > 0)
206 {
207 const_iterator pos, end = m_pairs.end();
208 for (pos = m_pairs.begin(); pos != end; ++pos)
209 {
210 const size_t prefix_len = pos->first.GetLength();
211
212 if (orig_path_len >= prefix_len)
213 {
214 if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0)
215 {
216 const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len);
217 if (new_path_len < sizeof(new_path))
218 {
219 new_spec.SetFile (new_path, true);
220 if (new_spec.Exists())
221 return true;
222 }
223 }
224 }
225 }
226 }
227 }
228 new_spec.Clear();
229 return false;
230}
231
232bool
Greg Clayton7e14f912011-04-23 02:04:55 +0000233PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
234{
235 uint32_t idx = FindIndexForPath (path);
236 if (idx < m_pairs.size())
237 {
238 m_pairs[idx].second = new_path;
239 if (notify && m_callback)
240 m_callback (*this, m_callback_baton);
241 return true;
242 }
243 return false;
244}
245
246bool
247PathMappingList::Remove (const ConstString &path, bool notify)
248{
249 iterator pos = FindIteratorForPath (path);
250 if (pos != m_pairs.end())
251 {
252 m_pairs.erase (pos);
253 if (notify && m_callback)
254 m_callback (*this, m_callback_baton);
255 return true;
256 }
257 return false;
258}
259
260PathMappingList::const_iterator
261PathMappingList::FindIteratorForPath (const ConstString &path) const
262{
263 const_iterator pos;
264 const_iterator begin = m_pairs.begin();
265 const_iterator end = m_pairs.end();
266
267 for (pos = begin; pos != end; ++pos)
268 {
269 if (pos->first == path)
270 break;
271 }
272 return pos;
273}
274
275PathMappingList::iterator
276PathMappingList::FindIteratorForPath (const ConstString &path)
277{
278 iterator pos;
279 iterator begin = m_pairs.begin();
280 iterator end = m_pairs.end();
281
282 for (pos = begin; pos != end; ++pos)
283 {
284 if (pos->first == path)
285 break;
286 }
287 return pos;
288}
289
290bool
291PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
292{
293 if (idx < m_pairs.size())
294 {
295 path = m_pairs[idx].first;
296 new_path = m_pairs[idx].second;
297 return true;
298 }
299 return false;
300}
301
302
303
304uint32_t
305PathMappingList::FindIndexForPath (const ConstString &path) const
306{
307 const_iterator pos;
308 const_iterator begin = m_pairs.begin();
309 const_iterator end = m_pairs.end();
310
311 for (pos = begin; pos != end; ++pos)
312 {
313 if (pos->first == path)
314 return std::distance (begin, pos);
315 }
316 return UINT32_MAX;
317}
318