]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp
Merge llvm trunk r338150, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / PathMappingList.cpp
1 //===-- 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
12 #include <climits>
13 #include <cstring>
14
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Host/PosixApi.h"
18 #include "lldb/Target/PathMappingList.h"
19 #include "lldb/Utility/FileSpec.h"
20 #include "lldb/Utility/Status.h"
21 #include "lldb/Utility/Stream.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 //----------------------------------------------------------------------
27 // PathMappingList constructor
28 //----------------------------------------------------------------------
29 PathMappingList::PathMappingList()
30     : m_pairs(), m_callback(nullptr), m_callback_baton(nullptr), m_mod_id(0) {}
31
32 PathMappingList::PathMappingList(ChangedCallback callback, void *callback_baton)
33     : m_pairs(), m_callback(callback), m_callback_baton(callback_baton),
34       m_mod_id(0) {}
35
36 PathMappingList::PathMappingList(const PathMappingList &rhs)
37     : m_pairs(rhs.m_pairs), m_callback(nullptr), m_callback_baton(nullptr),
38       m_mod_id(0) {}
39
40 const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) {
41   if (this != &rhs) {
42     m_pairs = rhs.m_pairs;
43     m_callback = nullptr;
44     m_callback_baton = nullptr;
45     m_mod_id = rhs.m_mod_id;
46   }
47   return *this;
48 }
49
50 PathMappingList::~PathMappingList() = default;
51
52 void PathMappingList::Append(const ConstString &path,
53                              const ConstString &replacement, bool notify) {
54   ++m_mod_id;
55   m_pairs.push_back(pair(path, replacement));
56   if (notify && m_callback)
57     m_callback(*this, m_callback_baton);
58 }
59
60 void PathMappingList::Append(const PathMappingList &rhs, bool notify) {
61   ++m_mod_id;
62   if (!rhs.m_pairs.empty()) {
63     const_iterator pos, end = rhs.m_pairs.end();
64     for (pos = rhs.m_pairs.begin(); pos != end; ++pos)
65       m_pairs.push_back(*pos);
66     if (notify && m_callback)
67       m_callback(*this, m_callback_baton);
68   }
69 }
70
71 void PathMappingList::Insert(const ConstString &path,
72                              const ConstString &replacement, uint32_t index,
73                              bool notify) {
74   ++m_mod_id;
75   iterator insert_iter;
76   if (index >= m_pairs.size())
77     insert_iter = m_pairs.end();
78   else
79     insert_iter = m_pairs.begin() + index;
80   m_pairs.insert(insert_iter, pair(path, replacement));
81   if (notify && m_callback)
82     m_callback(*this, m_callback_baton);
83 }
84
85 bool PathMappingList::Replace(const ConstString &path,
86                               const ConstString &replacement, uint32_t index,
87                               bool notify) {
88   if (index >= m_pairs.size())
89     return false;
90   ++m_mod_id;
91   m_pairs[index] = pair(path, replacement);
92   if (notify && m_callback)
93     m_callback(*this, m_callback_baton);
94   return true;
95 }
96
97 bool PathMappingList::Remove(size_t index, bool notify) {
98   if (index >= m_pairs.size())
99     return false;
100
101   ++m_mod_id;
102   iterator iter = m_pairs.begin() + index;
103   m_pairs.erase(iter);
104   if (notify && m_callback)
105     m_callback(*this, m_callback_baton);
106   return true;
107 }
108
109 // For clients which do not need the pair index dumped, pass a pair_index >= 0
110 // to only dump the indicated pair.
111 void PathMappingList::Dump(Stream *s, int pair_index) {
112   unsigned int numPairs = m_pairs.size();
113
114   if (pair_index < 0) {
115     unsigned int index;
116     for (index = 0; index < numPairs; ++index)
117       s->Printf("[%d] \"%s\" -> \"%s\"\n", index,
118                 m_pairs[index].first.GetCString(),
119                 m_pairs[index].second.GetCString());
120   } else {
121     if (static_cast<unsigned int>(pair_index) < numPairs)
122       s->Printf("%s -> %s", m_pairs[pair_index].first.GetCString(),
123                 m_pairs[pair_index].second.GetCString());
124   }
125 }
126
127 void PathMappingList::Clear(bool notify) {
128   if (!m_pairs.empty())
129     ++m_mod_id;
130   m_pairs.clear();
131   if (notify && m_callback)
132     m_callback(*this, m_callback_baton);
133 }
134
135 bool PathMappingList::RemapPath(const ConstString &path,
136                                 ConstString &new_path) const {
137   const char *path_cstr = path.GetCString();
138   // CLEANUP: Convert this function to use StringRefs internally instead
139   // of raw c-strings.
140   if (!path_cstr)
141     return false;
142
143   const_iterator pos, end = m_pairs.end();
144   for (pos = m_pairs.begin(); pos != end; ++pos) {
145     const size_t prefixLen = pos->first.GetLength();
146
147     if (::strncmp(pos->first.GetCString(), path_cstr, prefixLen) == 0) {
148       std::string new_path_str(pos->second.GetCString());
149       new_path_str.append(path.GetCString() + prefixLen);
150       new_path.SetCString(new_path_str.c_str());
151       return true;
152     }
153   }
154   return false;
155 }
156
157 bool PathMappingList::RemapPath(llvm::StringRef path,
158                                 std::string &new_path) const {
159   if (m_pairs.empty() || path.empty())
160     return false;
161
162   const_iterator pos, end = m_pairs.end();
163   for (pos = m_pairs.begin(); pos != end; ++pos) {
164     if (!path.consume_front(pos->first.GetStringRef()))
165       continue;
166
167     new_path = pos->second.GetStringRef();
168     new_path.append(path);
169     return true;
170   }
171   return false;
172 }
173
174 bool PathMappingList::ReverseRemapPath(const ConstString &path,
175                                        ConstString &new_path) const {
176   const char *path_cstr = path.GetCString();
177   if (!path_cstr)
178     return false;
179
180   for (const auto &it : m_pairs) {
181     // FIXME: This should be using FileSpec API's to do the path appending.
182     const size_t prefixLen = it.second.GetLength();
183     if (::strncmp(it.second.GetCString(), path_cstr, prefixLen) == 0) {
184       std::string new_path_str(it.first.GetCString());
185       new_path_str.append(path.GetCString() + prefixLen);
186       new_path.SetCString(new_path_str.c_str());
187       return true;
188     }
189   }
190   return false;
191 }
192
193 bool PathMappingList::FindFile(const FileSpec &orig_spec,
194                                FileSpec &new_spec) const {
195   if (!m_pairs.empty()) {
196     char orig_path[PATH_MAX];
197     const size_t orig_path_len =
198         orig_spec.GetPath(orig_path, sizeof(orig_path));
199     if (orig_path_len > 0) {
200       const_iterator pos, end = m_pairs.end();
201       for (pos = m_pairs.begin(); pos != end; ++pos) {
202         const size_t prefix_len = pos->first.GetLength();
203
204         if (orig_path_len >= prefix_len) {
205           if (::strncmp(pos->first.GetCString(), orig_path, prefix_len) == 0) {
206             new_spec.SetFile(pos->second.GetCString(), false);
207             new_spec.AppendPathComponent(orig_path + prefix_len);
208             if (new_spec.Exists())
209               return true;
210           }
211         }
212       }
213     }
214   }
215   new_spec.Clear();
216   return false;
217 }
218
219 bool PathMappingList::Replace(const ConstString &path,
220                               const ConstString &new_path, bool notify) {
221   uint32_t idx = FindIndexForPath(path);
222   if (idx < m_pairs.size()) {
223     ++m_mod_id;
224     m_pairs[idx].second = new_path;
225     if (notify && m_callback)
226       m_callback(*this, m_callback_baton);
227     return true;
228   }
229   return false;
230 }
231
232 bool PathMappingList::Remove(const ConstString &path, bool notify) {
233   iterator pos = FindIteratorForPath(path);
234   if (pos != m_pairs.end()) {
235     ++m_mod_id;
236     m_pairs.erase(pos);
237     if (notify && m_callback)
238       m_callback(*this, m_callback_baton);
239     return true;
240   }
241   return false;
242 }
243
244 PathMappingList::const_iterator
245 PathMappingList::FindIteratorForPath(const ConstString &path) const {
246   const_iterator pos;
247   const_iterator begin = m_pairs.begin();
248   const_iterator end = m_pairs.end();
249
250   for (pos = begin; pos != end; ++pos) {
251     if (pos->first == path)
252       break;
253   }
254   return pos;
255 }
256
257 PathMappingList::iterator
258 PathMappingList::FindIteratorForPath(const ConstString &path) {
259   iterator pos;
260   iterator begin = m_pairs.begin();
261   iterator end = m_pairs.end();
262
263   for (pos = begin; pos != end; ++pos) {
264     if (pos->first == path)
265       break;
266   }
267   return pos;
268 }
269
270 bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path,
271                                       ConstString &new_path) const {
272   if (idx < m_pairs.size()) {
273     path = m_pairs[idx].first;
274     new_path = m_pairs[idx].second;
275     return true;
276   }
277   return false;
278 }
279
280 uint32_t PathMappingList::FindIndexForPath(const ConstString &path) const {
281   const_iterator pos;
282   const_iterator begin = m_pairs.begin();
283   const_iterator end = m_pairs.end();
284
285   for (pos = begin; pos != end; ++pos) {
286     if (pos->first == path)
287       return std::distance(begin, pos);
288   }
289   return UINT32_MAX;
290 }