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 11*d804d285SGreg Clayton #include <string.h> 12*d804d285SGreg Clayton 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 15*d804d285SGreg Clayton // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Error.h" 1730fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 18*d804d285SGreg Clayton #include "lldb/Host/FileSpec.h" 1948862d45SEli Friedman #include "lldb/Target/PathMappingList.h" 2030fdc8d8SChris Lattner 2130fdc8d8SChris Lattner using namespace lldb; 2230fdc8d8SChris Lattner using namespace lldb_private; 2330fdc8d8SChris Lattner 2430fdc8d8SChris Lattner //---------------------------------------------------------------------- 2530fdc8d8SChris Lattner // PathMappingList constructor 2630fdc8d8SChris Lattner //---------------------------------------------------------------------- 27*d804d285SGreg Clayton PathMappingList::PathMappingList () : 28*d804d285SGreg Clayton m_pairs (), 29*d804d285SGreg Clayton m_callback (NULL), 30*d804d285SGreg Clayton m_callback_baton (NULL) 31*d804d285SGreg Clayton { 32*d804d285SGreg Clayton } 33*d804d285SGreg Clayton 3430fdc8d8SChris Lattner PathMappingList::PathMappingList 3530fdc8d8SChris Lattner ( 3630fdc8d8SChris Lattner ChangedCallback callback, 3730fdc8d8SChris Lattner void *callback_baton 3830fdc8d8SChris Lattner ) : 3930fdc8d8SChris Lattner m_pairs (), 4030fdc8d8SChris Lattner m_callback (callback), 4130fdc8d8SChris Lattner m_callback_baton (callback_baton) 4230fdc8d8SChris Lattner { 4330fdc8d8SChris Lattner } 4430fdc8d8SChris Lattner 457e14f91dSGreg Clayton 467e14f91dSGreg Clayton PathMappingList::PathMappingList (const PathMappingList &rhs) : 477e14f91dSGreg Clayton m_pairs (rhs.m_pairs), 487e14f91dSGreg Clayton m_callback (NULL), 497e14f91dSGreg Clayton m_callback_baton (NULL) 507e14f91dSGreg Clayton { 517e14f91dSGreg Clayton 527e14f91dSGreg Clayton } 537e14f91dSGreg Clayton 547e14f91dSGreg Clayton const PathMappingList & 557e14f91dSGreg Clayton PathMappingList::operator =(const PathMappingList &rhs) 567e14f91dSGreg Clayton { 577e14f91dSGreg Clayton if (this != &rhs) 587e14f91dSGreg Clayton { 597e14f91dSGreg Clayton m_pairs = rhs.m_pairs; 607e14f91dSGreg Clayton m_callback = NULL; 617e14f91dSGreg Clayton m_callback_baton = NULL; 627e14f91dSGreg Clayton } 637e14f91dSGreg Clayton return *this; 647e14f91dSGreg Clayton } 657e14f91dSGreg Clayton 667e14f91dSGreg Clayton 6730fdc8d8SChris Lattner //---------------------------------------------------------------------- 6830fdc8d8SChris Lattner // Destructor 6930fdc8d8SChris Lattner //---------------------------------------------------------------------- 7030fdc8d8SChris Lattner PathMappingList::~PathMappingList () 7130fdc8d8SChris Lattner { 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 7430fdc8d8SChris Lattner void 7530fdc8d8SChris Lattner PathMappingList::Append (const ConstString &path, 7630fdc8d8SChris Lattner const ConstString &replacement, 7730fdc8d8SChris Lattner bool notify) 7830fdc8d8SChris Lattner { 7930fdc8d8SChris Lattner m_pairs.push_back(pair(path, replacement)); 8030fdc8d8SChris Lattner if (notify && m_callback) 8130fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 8230fdc8d8SChris Lattner } 8330fdc8d8SChris Lattner 8430fdc8d8SChris Lattner void 85*d804d285SGreg Clayton PathMappingList::Append (const PathMappingList &rhs, bool notify) 86*d804d285SGreg Clayton { 87*d804d285SGreg Clayton if (!rhs.m_pairs.empty()) 88*d804d285SGreg Clayton { 89*d804d285SGreg Clayton const_iterator pos, end = rhs.m_pairs.end(); 90*d804d285SGreg Clayton for (pos = rhs.m_pairs.begin(); pos != end; ++pos) 91*d804d285SGreg Clayton m_pairs.push_back(*pos); 92*d804d285SGreg Clayton if (notify && m_callback) 93*d804d285SGreg Clayton m_callback (*this, m_callback_baton); 94*d804d285SGreg Clayton } 95*d804d285SGreg Clayton } 96*d804d285SGreg Clayton 97*d804d285SGreg Clayton void 9830fdc8d8SChris Lattner PathMappingList::Insert (const ConstString &path, 9930fdc8d8SChris Lattner const ConstString &replacement, 10030fdc8d8SChris Lattner uint32_t index, 10130fdc8d8SChris Lattner bool notify) 10230fdc8d8SChris Lattner { 10330fdc8d8SChris Lattner iterator insert_iter; 10430fdc8d8SChris Lattner if (index >= m_pairs.size()) 10530fdc8d8SChris Lattner insert_iter = m_pairs.end(); 10630fdc8d8SChris Lattner else 10730fdc8d8SChris Lattner insert_iter = m_pairs.begin() + index; 10830fdc8d8SChris Lattner m_pairs.insert(insert_iter, pair(path, replacement)); 10930fdc8d8SChris Lattner if (notify && m_callback) 11030fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 11130fdc8d8SChris Lattner } 11230fdc8d8SChris Lattner 11330fdc8d8SChris Lattner bool 11430fdc8d8SChris Lattner PathMappingList::Remove (off_t index, bool notify) 11530fdc8d8SChris Lattner { 11630fdc8d8SChris Lattner if (index >= m_pairs.size()) 11730fdc8d8SChris Lattner return false; 11830fdc8d8SChris Lattner 11930fdc8d8SChris Lattner iterator iter = m_pairs.begin() + index; 12030fdc8d8SChris Lattner m_pairs.erase(iter); 12130fdc8d8SChris Lattner if (notify && m_callback) 12230fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 12330fdc8d8SChris Lattner return true; 12430fdc8d8SChris Lattner } 12530fdc8d8SChris Lattner 12664bab489SJohnny Chen // For clients which do not need the pair index dumped, pass a pair_index >= 0 12764bab489SJohnny Chen // to only dump the indicated pair. 12830fdc8d8SChris Lattner void 12964bab489SJohnny Chen PathMappingList::Dump (Stream *s, int pair_index) 13030fdc8d8SChris Lattner { 13130fdc8d8SChris Lattner unsigned int numPairs = m_pairs.size(); 13230fdc8d8SChris Lattner 13364bab489SJohnny Chen if (pair_index < 0) 13430fdc8d8SChris Lattner { 13564bab489SJohnny Chen unsigned int index; 13664bab489SJohnny Chen for (index = 0; index < numPairs; ++index) 13730fdc8d8SChris Lattner s->Printf("[%d] \"%s\" -> \"%s\"\n", 13830fdc8d8SChris Lattner index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString()); 13930fdc8d8SChris Lattner } 14064bab489SJohnny Chen else 14164bab489SJohnny Chen { 14264bab489SJohnny Chen if (pair_index < numPairs) 14364bab489SJohnny Chen s->Printf("%s -> %s", 14464bab489SJohnny Chen m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString()); 14564bab489SJohnny Chen } 14630fdc8d8SChris Lattner } 14730fdc8d8SChris Lattner 14830fdc8d8SChris Lattner void 14930fdc8d8SChris Lattner PathMappingList::Clear (bool notify) 15030fdc8d8SChris Lattner { 15130fdc8d8SChris Lattner m_pairs.clear(); 15230fdc8d8SChris Lattner if (notify && m_callback) 15330fdc8d8SChris Lattner m_callback (*this, m_callback_baton); 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner 15630fdc8d8SChris Lattner bool 157*d804d285SGreg Clayton PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const 15830fdc8d8SChris Lattner { 15930fdc8d8SChris Lattner const_iterator pos, end = m_pairs.end(); 16030fdc8d8SChris Lattner for (pos = m_pairs.begin(); pos != end; ++pos) 16130fdc8d8SChris Lattner { 16230fdc8d8SChris Lattner const size_t prefixLen = pos->first.GetLength(); 16330fdc8d8SChris Lattner 16430fdc8d8SChris Lattner if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0) 16530fdc8d8SChris Lattner { 16630fdc8d8SChris Lattner std::string new_path_str (pos->second.GetCString()); 16730fdc8d8SChris Lattner new_path_str.append(path.GetCString() + prefixLen); 16830fdc8d8SChris Lattner new_path.SetCString(new_path_str.c_str()); 16930fdc8d8SChris Lattner return true; 17030fdc8d8SChris Lattner } 17130fdc8d8SChris Lattner } 17230fdc8d8SChris Lattner return false; 17330fdc8d8SChris Lattner } 1747e14f91dSGreg Clayton 1757e14f91dSGreg Clayton bool 176*d804d285SGreg Clayton PathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const 177*d804d285SGreg Clayton { 178*d804d285SGreg Clayton if (!m_pairs.empty()) 179*d804d285SGreg Clayton { 180*d804d285SGreg Clayton char orig_path[PATH_MAX]; 181*d804d285SGreg Clayton char new_path[PATH_MAX]; 182*d804d285SGreg Clayton const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path)); 183*d804d285SGreg Clayton if (orig_path_len > 0) 184*d804d285SGreg Clayton { 185*d804d285SGreg Clayton const_iterator pos, end = m_pairs.end(); 186*d804d285SGreg Clayton for (pos = m_pairs.begin(); pos != end; ++pos) 187*d804d285SGreg Clayton { 188*d804d285SGreg Clayton const size_t prefix_len = pos->first.GetLength(); 189*d804d285SGreg Clayton 190*d804d285SGreg Clayton if (orig_path_len >= prefix_len) 191*d804d285SGreg Clayton { 192*d804d285SGreg Clayton if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0) 193*d804d285SGreg Clayton { 194*d804d285SGreg Clayton const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len); 195*d804d285SGreg Clayton if (new_path_len < sizeof(new_path)) 196*d804d285SGreg Clayton { 197*d804d285SGreg Clayton new_spec.SetFile (new_path, true); 198*d804d285SGreg Clayton if (new_spec.Exists()) 199*d804d285SGreg Clayton return true; 200*d804d285SGreg Clayton } 201*d804d285SGreg Clayton } 202*d804d285SGreg Clayton } 203*d804d285SGreg Clayton } 204*d804d285SGreg Clayton } 205*d804d285SGreg Clayton } 206*d804d285SGreg Clayton new_spec.Clear(); 207*d804d285SGreg Clayton return false; 208*d804d285SGreg Clayton } 209*d804d285SGreg Clayton 210*d804d285SGreg Clayton bool 2117e14f91dSGreg Clayton PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify) 2127e14f91dSGreg Clayton { 2137e14f91dSGreg Clayton uint32_t idx = FindIndexForPath (path); 2147e14f91dSGreg Clayton if (idx < m_pairs.size()) 2157e14f91dSGreg Clayton { 2167e14f91dSGreg Clayton m_pairs[idx].second = new_path; 2177e14f91dSGreg Clayton if (notify && m_callback) 2187e14f91dSGreg Clayton m_callback (*this, m_callback_baton); 2197e14f91dSGreg Clayton return true; 2207e14f91dSGreg Clayton } 2217e14f91dSGreg Clayton return false; 2227e14f91dSGreg Clayton } 2237e14f91dSGreg Clayton 2247e14f91dSGreg Clayton bool 2257e14f91dSGreg Clayton PathMappingList::Remove (const ConstString &path, bool notify) 2267e14f91dSGreg Clayton { 2277e14f91dSGreg Clayton iterator pos = FindIteratorForPath (path); 2287e14f91dSGreg Clayton if (pos != m_pairs.end()) 2297e14f91dSGreg Clayton { 2307e14f91dSGreg Clayton m_pairs.erase (pos); 2317e14f91dSGreg Clayton if (notify && m_callback) 2327e14f91dSGreg Clayton m_callback (*this, m_callback_baton); 2337e14f91dSGreg Clayton return true; 2347e14f91dSGreg Clayton } 2357e14f91dSGreg Clayton return false; 2367e14f91dSGreg Clayton } 2377e14f91dSGreg Clayton 2387e14f91dSGreg Clayton PathMappingList::const_iterator 2397e14f91dSGreg Clayton PathMappingList::FindIteratorForPath (const ConstString &path) const 2407e14f91dSGreg Clayton { 2417e14f91dSGreg Clayton const_iterator pos; 2427e14f91dSGreg Clayton const_iterator begin = m_pairs.begin(); 2437e14f91dSGreg Clayton const_iterator end = m_pairs.end(); 2447e14f91dSGreg Clayton 2457e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 2467e14f91dSGreg Clayton { 2477e14f91dSGreg Clayton if (pos->first == path) 2487e14f91dSGreg Clayton break; 2497e14f91dSGreg Clayton } 2507e14f91dSGreg Clayton return pos; 2517e14f91dSGreg Clayton } 2527e14f91dSGreg Clayton 2537e14f91dSGreg Clayton PathMappingList::iterator 2547e14f91dSGreg Clayton PathMappingList::FindIteratorForPath (const ConstString &path) 2557e14f91dSGreg Clayton { 2567e14f91dSGreg Clayton iterator pos; 2577e14f91dSGreg Clayton iterator begin = m_pairs.begin(); 2587e14f91dSGreg Clayton iterator end = m_pairs.end(); 2597e14f91dSGreg Clayton 2607e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 2617e14f91dSGreg Clayton { 2627e14f91dSGreg Clayton if (pos->first == path) 2637e14f91dSGreg Clayton break; 2647e14f91dSGreg Clayton } 2657e14f91dSGreg Clayton return pos; 2667e14f91dSGreg Clayton } 2677e14f91dSGreg Clayton 2687e14f91dSGreg Clayton bool 2697e14f91dSGreg Clayton PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const 2707e14f91dSGreg Clayton { 2717e14f91dSGreg Clayton if (idx < m_pairs.size()) 2727e14f91dSGreg Clayton { 2737e14f91dSGreg Clayton path = m_pairs[idx].first; 2747e14f91dSGreg Clayton new_path = m_pairs[idx].second; 2757e14f91dSGreg Clayton return true; 2767e14f91dSGreg Clayton } 2777e14f91dSGreg Clayton return false; 2787e14f91dSGreg Clayton } 2797e14f91dSGreg Clayton 2807e14f91dSGreg Clayton 2817e14f91dSGreg Clayton 2827e14f91dSGreg Clayton uint32_t 2837e14f91dSGreg Clayton PathMappingList::FindIndexForPath (const ConstString &path) const 2847e14f91dSGreg Clayton { 2857e14f91dSGreg Clayton const_iterator pos; 2867e14f91dSGreg Clayton const_iterator begin = m_pairs.begin(); 2877e14f91dSGreg Clayton const_iterator end = m_pairs.end(); 2887e14f91dSGreg Clayton 2897e14f91dSGreg Clayton for (pos = begin; pos != end; ++pos) 2907e14f91dSGreg Clayton { 2917e14f91dSGreg Clayton if (pos->first == path) 2927e14f91dSGreg Clayton return std::distance (begin, pos); 2937e14f91dSGreg Clayton } 2947e14f91dSGreg Clayton return UINT32_MAX; 2957e14f91dSGreg Clayton } 2967e14f91dSGreg Clayton 297