130fdc8d8SChris Lattner //===-- PathMappingList.cpp -------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner // C Includes 1130fdc8d8SChris Lattner // C++ Includes 129394d772SEugene Zelenko #include <climits> 139394d772SEugene Zelenko #include <cstring> 149394d772SEugene Zelenko 1530fdc8d8SChris Lattner // Other libraries and framework includes 16d804d285SGreg Clayton // Project includes 1730fdc8d8SChris Lattner #include "lldb/Core/Error.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 19d804d285SGreg Clayton #include "lldb/Host/FileSpec.h" 2048862d45SEli Friedman #include "lldb/Target/PathMappingList.h" 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner using namespace lldb; 2330fdc8d8SChris Lattner using namespace lldb_private; 2430fdc8d8SChris Lattner 2530fdc8d8SChris Lattner //---------------------------------------------------------------------- 2630fdc8d8SChris Lattner // PathMappingList constructor 2730fdc8d8SChris Lattner //---------------------------------------------------------------------- 28d804d285SGreg Clayton PathMappingList::PathMappingList () : 29d804d285SGreg Clayton m_pairs(), 309394d772SEugene Zelenko m_callback(nullptr), 319394d772SEugene Zelenko m_callback_baton(nullptr), 324a89501fSGreg Clayton m_mod_id(0) 33d804d285SGreg Clayton { 34d804d285SGreg Clayton } 35d804d285SGreg Clayton 364a89501fSGreg Clayton PathMappingList::PathMappingList (ChangedCallback callback, 374a89501fSGreg Clayton void *callback_baton) : 3830fdc8d8SChris Lattner m_pairs (), 3930fdc8d8SChris Lattner m_callback (callback), 404a89501fSGreg Clayton m_callback_baton (callback_baton), 414a89501fSGreg Clayton m_mod_id (0) 4230fdc8d8SChris Lattner { 4330fdc8d8SChris Lattner } 4430fdc8d8SChris Lattner 457e14f91dSGreg Clayton PathMappingList::PathMappingList (const PathMappingList &rhs) : 467e14f91dSGreg Clayton m_pairs(rhs.m_pairs), 479394d772SEugene Zelenko m_callback(nullptr), 489394d772SEugene Zelenko m_callback_baton(nullptr), 494a89501fSGreg Clayton m_mod_id(0) 507e14f91dSGreg Clayton { 517e14f91dSGreg Clayton } 527e14f91dSGreg Clayton 537e14f91dSGreg Clayton const PathMappingList & 547e14f91dSGreg Clayton PathMappingList::operator =(const PathMappingList &rhs) 557e14f91dSGreg Clayton { 567e14f91dSGreg Clayton if (this != &rhs) 577e14f91dSGreg Clayton { 587e14f91dSGreg Clayton m_pairs = rhs.m_pairs; 599394d772SEugene Zelenko m_callback = nullptr; 609394d772SEugene Zelenko m_callback_baton = nullptr; 614a89501fSGreg Clayton m_mod_id = rhs.m_mod_id; 627e14f91dSGreg Clayton } 637e14f91dSGreg Clayton return *this; 647e14f91dSGreg Clayton } 657e14f91dSGreg Clayton 669394d772SEugene Zelenko PathMappingList::~PathMappingList() = default; 6730fdc8d8SChris Lattner 6830fdc8d8SChris Lattner void 6930fdc8d8SChris Lattner PathMappingList::Append (const ConstString &path, 7030fdc8d8SChris Lattner const ConstString &replacement, 7130fdc8d8SChris Lattner bool notify) 7230fdc8d8SChris Lattner { 734a89501fSGreg Clayton ++m_mod_id; 7430fdc8d8SChris Lattner m_pairs.push_back(pair(path, replacement)); 7530fdc8d8SChris Lattner if (notify && m_callback) 7630fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner void 80d804d285SGreg Clayton PathMappingList::Append (const PathMappingList &rhs, bool notify) 81d804d285SGreg Clayton { 824a89501fSGreg Clayton ++m_mod_id; 83d804d285SGreg Clayton if (!rhs.m_pairs.empty()) 84d804d285SGreg Clayton { 85d804d285SGreg Clayton const_iterator pos, end = rhs.m_pairs.end(); 86d804d285SGreg Clayton for (pos = rhs.m_pairs.begin(); pos != end; ++pos) 87d804d285SGreg Clayton m_pairs.push_back(*pos); 88d804d285SGreg Clayton if (notify && m_callback) 89d804d285SGreg Clayton m_callback (*this, m_callback_baton); 90d804d285SGreg Clayton } 91d804d285SGreg Clayton } 92d804d285SGreg Clayton 93d804d285SGreg Clayton void 9430fdc8d8SChris Lattner PathMappingList::Insert (const ConstString &path, 9530fdc8d8SChris Lattner const ConstString &replacement, 9630fdc8d8SChris Lattner uint32_t index, 9730fdc8d8SChris Lattner bool notify) 9830fdc8d8SChris Lattner { 994a89501fSGreg Clayton ++m_mod_id; 10030fdc8d8SChris Lattner iterator insert_iter; 10130fdc8d8SChris Lattner if (index >= m_pairs.size()) 10230fdc8d8SChris Lattner insert_iter = m_pairs.end(); 10330fdc8d8SChris Lattner else 10430fdc8d8SChris Lattner insert_iter = m_pairs.begin() + index; 10530fdc8d8SChris Lattner m_pairs.insert(insert_iter, pair(path, replacement)); 10630fdc8d8SChris Lattner if (notify && m_callback) 10730fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 10830fdc8d8SChris Lattner } 10930fdc8d8SChris Lattner 11030fdc8d8SChris Lattner bool 11167cc0636SGreg Clayton PathMappingList::Replace (const ConstString &path, 11267cc0636SGreg Clayton const ConstString &replacement, 11367cc0636SGreg Clayton uint32_t index, 11467cc0636SGreg Clayton bool notify) 11567cc0636SGreg Clayton { 11667cc0636SGreg Clayton iterator insert_iter; 11767cc0636SGreg Clayton if (index >= m_pairs.size()) 11867cc0636SGreg Clayton return false; 1194a89501fSGreg Clayton ++m_mod_id; 12067cc0636SGreg Clayton m_pairs[index] = pair(path, replacement); 12167cc0636SGreg Clayton if (notify && m_callback) 12267cc0636SGreg Clayton m_callback (*this, m_callback_baton); 12367cc0636SGreg Clayton return true; 12467cc0636SGreg Clayton } 12567cc0636SGreg Clayton 12667cc0636SGreg Clayton bool 127a746e8e5SZachary Turner PathMappingList::Remove (size_t index, bool notify) 12830fdc8d8SChris Lattner { 129a746e8e5SZachary Turner if (index >= m_pairs.size()) 13030fdc8d8SChris Lattner return false; 13130fdc8d8SChris Lattner 1324a89501fSGreg Clayton ++m_mod_id; 13330fdc8d8SChris Lattner iterator iter = m_pairs.begin() + index; 13430fdc8d8SChris Lattner m_pairs.erase(iter); 13530fdc8d8SChris Lattner if (notify && m_callback) 13630fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 13730fdc8d8SChris Lattner return true; 13830fdc8d8SChris Lattner } 13930fdc8d8SChris Lattner 14064bab489SJohnny Chen // For clients which do not need the pair index dumped, pass a pair_index >= 0 14164bab489SJohnny Chen // to only dump the indicated pair. 14230fdc8d8SChris Lattner void 14364bab489SJohnny Chen PathMappingList::Dump (Stream *s, int pair_index) 14430fdc8d8SChris Lattner { 14530fdc8d8SChris Lattner unsigned int numPairs = m_pairs.size(); 14630fdc8d8SChris Lattner 14764bab489SJohnny Chen if (pair_index < 0) 14830fdc8d8SChris Lattner { 14964bab489SJohnny Chen unsigned int index; 15064bab489SJohnny Chen for (index = 0; index < numPairs; ++index) 15130fdc8d8SChris Lattner s->Printf("[%d] \"%s\" -> \"%s\"\n", 15230fdc8d8SChris Lattner index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString()); 15330fdc8d8SChris Lattner } 15464bab489SJohnny Chen else 15564bab489SJohnny Chen { 1563985c8c6SSaleem Abdulrasool if (static_cast<unsigned int>(pair_index) < numPairs) 15764bab489SJohnny Chen s->Printf("%s -> %s", 15864bab489SJohnny Chen m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString()); 15964bab489SJohnny Chen } 16030fdc8d8SChris Lattner } 16130fdc8d8SChris Lattner 16230fdc8d8SChris Lattner void 16330fdc8d8SChris Lattner PathMappingList::Clear (bool notify) 16430fdc8d8SChris Lattner { 1654a89501fSGreg Clayton if (!m_pairs.empty()) 1664a89501fSGreg Clayton ++m_mod_id; 16730fdc8d8SChris Lattner m_pairs.clear(); 16830fdc8d8SChris Lattner if (notify && m_callback) 16930fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 17030fdc8d8SChris Lattner } 17130fdc8d8SChris Lattner 17230fdc8d8SChris Lattner bool 173d804d285SGreg Clayton PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const 17430fdc8d8SChris Lattner { 175f601503aSSean Callanan const char *path_cstr = path.GetCString(); 176f601503aSSean Callanan 177f601503aSSean Callanan if (!path_cstr) 178f601503aSSean Callanan return false; 179f601503aSSean Callanan 18030fdc8d8SChris Lattner const_iterator pos, end = m_pairs.end(); 18130fdc8d8SChris Lattner for (pos = m_pairs.begin(); pos != end; ++pos) 18230fdc8d8SChris Lattner { 18330fdc8d8SChris Lattner const size_t prefixLen = pos->first.GetLength(); 18430fdc8d8SChris Lattner 185f601503aSSean Callanan if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0) 18630fdc8d8SChris Lattner { 18730fdc8d8SChris Lattner std::string new_path_str (pos->second.GetCString()); 18830fdc8d8SChris Lattner new_path_str.append(path.GetCString() + prefixLen); 18930fdc8d8SChris Lattner new_path.SetCString(new_path_str.c_str()); 19030fdc8d8SChris Lattner return true; 19130fdc8d8SChris Lattner } 19230fdc8d8SChris Lattner } 19330fdc8d8SChris Lattner return false; 19430fdc8d8SChris Lattner } 1957e14f91dSGreg Clayton 1967e14f91dSGreg Clayton bool 197f9be6933SGreg Clayton PathMappingList::RemapPath (const char *path, std::string &new_path) const 198f9be6933SGreg Clayton { 1999394d772SEugene Zelenko if (m_pairs.empty() || path == nullptr || path[0] == '\0') 200f9be6933SGreg Clayton return false; 201f9be6933SGreg Clayton 202f9be6933SGreg Clayton const_iterator pos, end = m_pairs.end(); 203f9be6933SGreg Clayton for (pos = m_pairs.begin(); pos != end; ++pos) 204f9be6933SGreg Clayton { 205f9be6933SGreg Clayton const size_t prefix_len = pos->first.GetLength(); 206f9be6933SGreg Clayton 207f9be6933SGreg Clayton if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0) 208f9be6933SGreg Clayton { 209f9be6933SGreg Clayton new_path = pos->second.GetCString(); 210f9be6933SGreg Clayton new_path.append(path + prefix_len); 211f9be6933SGreg Clayton return true; 212f9be6933SGreg Clayton } 213f9be6933SGreg Clayton } 214f9be6933SGreg Clayton return false; 215f9be6933SGreg Clayton } 216f9be6933SGreg Clayton 217f9be6933SGreg Clayton bool 218*b0b1ea36STamas Berghammer PathMappingList::ReverseRemapPath (const ConstString &path, ConstString &new_path) const 219*b0b1ea36STamas Berghammer { 220*b0b1ea36STamas Berghammer const char *path_cstr = path.GetCString(); 221*b0b1ea36STamas Berghammer if (!path_cstr) 222*b0b1ea36STamas Berghammer return false; 223*b0b1ea36STamas Berghammer 224*b0b1ea36STamas Berghammer for (const auto& it : m_pairs) 225*b0b1ea36STamas Berghammer { 226*b0b1ea36STamas Berghammer const size_t prefixLen = it.second.GetLength(); 227*b0b1ea36STamas Berghammer if (::strncmp (it.second.GetCString(), path_cstr, prefixLen) == 0) 228*b0b1ea36STamas Berghammer { 229*b0b1ea36STamas Berghammer std::string new_path_str (it.first.GetCString()); 230*b0b1ea36STamas Berghammer new_path_str.append(path.GetCString() + prefixLen); 231*b0b1ea36STamas Berghammer new_path.SetCString(new_path_str.c_str()); 232*b0b1ea36STamas Berghammer return true; 233*b0b1ea36STamas Berghammer } 234*b0b1ea36STamas Berghammer } 235*b0b1ea36STamas Berghammer return false; 236*b0b1ea36STamas Berghammer } 237*b0b1ea36STamas Berghammer 238*b0b1ea36STamas Berghammer bool 239d804d285SGreg Clayton PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const 240d804d285SGreg Clayton { 241d804d285SGreg Clayton if (!m_pairs.empty()) 242d804d285SGreg Clayton { 243d804d285SGreg Clayton char orig_path[PATH_MAX]; 244d804d285SGreg Clayton char new_path[PATH_MAX]; 245d804d285SGreg Clayton const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path)); 246d804d285SGreg Clayton if (orig_path_len > 0) 247d804d285SGreg Clayton { 248d804d285SGreg Clayton const_iterator pos, end = m_pairs.end(); 249d804d285SGreg Clayton for (pos = m_pairs.begin(); pos != end; ++pos) 250d804d285SGreg Clayton { 251d804d285SGreg Clayton const size_t prefix_len = pos->first.GetLength(); 252d804d285SGreg Clayton 253d804d285SGreg Clayton if (orig_path_len >= prefix_len) 254d804d285SGreg Clayton { 255d804d285SGreg Clayton if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0) 256d804d285SGreg Clayton { 257d804d285SGreg Clayton const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len); 258d804d285SGreg Clayton if (new_path_len < sizeof(new_path)) 259d804d285SGreg Clayton { 260d804d285SGreg Clayton new_spec.SetFile (new_path, true); 261d804d285SGreg Clayton if (new_spec.Exists()) 262d804d285SGreg Clayton return true; 263d804d285SGreg Clayton } 264d804d285SGreg Clayton } 265d804d285SGreg Clayton } 266d804d285SGreg Clayton } 267d804d285SGreg Clayton } 268d804d285SGreg Clayton } 269d804d285SGreg Clayton new_spec.Clear(); 270d804d285SGreg Clayton return false; 271d804d285SGreg Clayton } 272d804d285SGreg Clayton 273d804d285SGreg Clayton bool 2747e14f91dSGreg Clayton PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify) 2757e14f91dSGreg Clayton { 2767e14f91dSGreg Clayton uint32_t idx = FindIndexForPath (path); 2777e14f91dSGreg Clayton if (idx < m_pairs.size()) 2787e14f91dSGreg Clayton { 2794a89501fSGreg Clayton ++m_mod_id; 2807e14f91dSGreg Clayton m_pairs[idx].second = new_path; 2817e14f91dSGreg Clayton if (notify && m_callback) 2827e14f91dSGreg Clayton m_callback (*this, m_callback_baton); 2837e14f91dSGreg Clayton return true; 2847e14f91dSGreg Clayton } 2857e14f91dSGreg Clayton return false; 2867e14f91dSGreg Clayton } 2877e14f91dSGreg Clayton 2887e14f91dSGreg Clayton bool 2897e14f91dSGreg Clayton PathMappingList::Remove (const ConstString &path, bool notify) 2907e14f91dSGreg Clayton { 2917e14f91dSGreg Clayton iterator pos = FindIteratorForPath (path); 2927e14f91dSGreg Clayton if (pos != m_pairs.end()) 2937e14f91dSGreg Clayton { 2944a89501fSGreg Clayton ++m_mod_id; 2957e14f91dSGreg Clayton m_pairs.erase (pos); 2967e14f91dSGreg Clayton if (notify && m_callback) 2977e14f91dSGreg Clayton m_callback (*this, m_callback_baton); 2987e14f91dSGreg Clayton return true; 2997e14f91dSGreg Clayton } 3007e14f91dSGreg Clayton return false; 3017e14f91dSGreg Clayton } 3027e14f91dSGreg Clayton 3037e14f91dSGreg Clayton PathMappingList::const_iterator 3047e14f91dSGreg Clayton PathMappingList::FindIteratorForPath (const ConstString &path) const 3057e14f91dSGreg Clayton { 3067e14f91dSGreg Clayton const_iterator pos; 3077e14f91dSGreg Clayton const_iterator begin = m_pairs.begin(); 3087e14f91dSGreg Clayton const_iterator end = m_pairs.end(); 3097e14f91dSGreg Clayton 3107e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 3117e14f91dSGreg Clayton { 3127e14f91dSGreg Clayton if (pos->first == path) 3137e14f91dSGreg Clayton break; 3147e14f91dSGreg Clayton } 3157e14f91dSGreg Clayton return pos; 3167e14f91dSGreg Clayton } 3177e14f91dSGreg Clayton 3187e14f91dSGreg Clayton PathMappingList::iterator 3197e14f91dSGreg Clayton PathMappingList::FindIteratorForPath (const ConstString &path) 3207e14f91dSGreg Clayton { 3217e14f91dSGreg Clayton iterator pos; 3227e14f91dSGreg Clayton iterator begin = m_pairs.begin(); 3237e14f91dSGreg Clayton iterator end = m_pairs.end(); 3247e14f91dSGreg Clayton 3257e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 3267e14f91dSGreg Clayton { 3277e14f91dSGreg Clayton if (pos->first == path) 3287e14f91dSGreg Clayton break; 3297e14f91dSGreg Clayton } 3307e14f91dSGreg Clayton return pos; 3317e14f91dSGreg Clayton } 3327e14f91dSGreg Clayton 3337e14f91dSGreg Clayton bool 3347e14f91dSGreg Clayton PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const 3357e14f91dSGreg Clayton { 3367e14f91dSGreg Clayton if (idx < m_pairs.size()) 3377e14f91dSGreg Clayton { 3387e14f91dSGreg Clayton path = m_pairs[idx].first; 3397e14f91dSGreg Clayton new_path = m_pairs[idx].second; 3407e14f91dSGreg Clayton return true; 3417e14f91dSGreg Clayton } 3427e14f91dSGreg Clayton return false; 3437e14f91dSGreg Clayton } 3447e14f91dSGreg Clayton 3457e14f91dSGreg Clayton uint32_t 3467e14f91dSGreg Clayton PathMappingList::FindIndexForPath (const ConstString &path) const 3477e14f91dSGreg Clayton { 3487e14f91dSGreg Clayton const_iterator pos; 3497e14f91dSGreg Clayton const_iterator begin = m_pairs.begin(); 3507e14f91dSGreg Clayton const_iterator end = m_pairs.end(); 3517e14f91dSGreg Clayton 3527e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 3537e14f91dSGreg Clayton { 3547e14f91dSGreg Clayton if (pos->first == path) 3557e14f91dSGreg Clayton return std::distance (begin, pos); 3567e14f91dSGreg Clayton } 3577e14f91dSGreg Clayton return UINT32_MAX; 3587e14f91dSGreg Clayton } 359