1254721Semaste//===-- PathMappingList.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste#include <limits.h> 12254721Semaste#include <string.h> 13254721Semaste 14254721Semaste// C++ Includes 15254721Semaste// Other libraries and framework includes 16254721Semaste// Project includes 17254721Semaste#include "lldb/Core/Error.h" 18254721Semaste#include "lldb/Core/Stream.h" 19254721Semaste#include "lldb/Host/FileSpec.h" 20254721Semaste#include "lldb/Target/PathMappingList.h" 21254721Semaste 22254721Semasteusing namespace lldb; 23254721Semasteusing namespace lldb_private; 24254721Semaste 25254721Semaste//---------------------------------------------------------------------- 26254721Semaste// PathMappingList constructor 27254721Semaste//---------------------------------------------------------------------- 28254721SemastePathMappingList::PathMappingList () : 29254721Semaste m_pairs (), 30254721Semaste m_callback (NULL), 31254721Semaste m_callback_baton (NULL), 32254721Semaste m_mod_id (0) 33254721Semaste{ 34254721Semaste} 35254721Semaste 36254721SemastePathMappingList::PathMappingList (ChangedCallback callback, 37254721Semaste void *callback_baton) : 38254721Semaste m_pairs (), 39254721Semaste m_callback (callback), 40254721Semaste m_callback_baton (callback_baton), 41254721Semaste m_mod_id (0) 42254721Semaste{ 43254721Semaste} 44254721Semaste 45254721Semaste 46254721SemastePathMappingList::PathMappingList (const PathMappingList &rhs) : 47254721Semaste m_pairs (rhs.m_pairs), 48254721Semaste m_callback (NULL), 49254721Semaste m_callback_baton (NULL), 50254721Semaste m_mod_id (0) 51254721Semaste{ 52254721Semaste 53254721Semaste} 54254721Semaste 55254721Semasteconst PathMappingList & 56254721SemastePathMappingList::operator =(const PathMappingList &rhs) 57254721Semaste{ 58254721Semaste if (this != &rhs) 59254721Semaste { 60254721Semaste m_pairs = rhs.m_pairs; 61254721Semaste m_callback = NULL; 62254721Semaste m_callback_baton = NULL; 63254721Semaste m_mod_id = rhs.m_mod_id; 64254721Semaste } 65254721Semaste return *this; 66254721Semaste} 67254721Semaste 68254721Semaste 69254721Semaste//---------------------------------------------------------------------- 70254721Semaste// Destructor 71254721Semaste//---------------------------------------------------------------------- 72254721SemastePathMappingList::~PathMappingList () 73254721Semaste{ 74254721Semaste} 75254721Semaste 76254721Semastevoid 77254721SemastePathMappingList::Append (const ConstString &path, 78254721Semaste const ConstString &replacement, 79254721Semaste bool notify) 80254721Semaste{ 81254721Semaste ++m_mod_id; 82254721Semaste m_pairs.push_back(pair(path, replacement)); 83254721Semaste if (notify && m_callback) 84254721Semaste m_callback (*this, m_callback_baton); 85254721Semaste} 86254721Semaste 87254721Semastevoid 88254721SemastePathMappingList::Append (const PathMappingList &rhs, bool notify) 89254721Semaste{ 90254721Semaste ++m_mod_id; 91254721Semaste if (!rhs.m_pairs.empty()) 92254721Semaste { 93254721Semaste const_iterator pos, end = rhs.m_pairs.end(); 94254721Semaste for (pos = rhs.m_pairs.begin(); pos != end; ++pos) 95254721Semaste m_pairs.push_back(*pos); 96254721Semaste if (notify && m_callback) 97254721Semaste m_callback (*this, m_callback_baton); 98254721Semaste } 99254721Semaste} 100254721Semaste 101254721Semastevoid 102254721SemastePathMappingList::Insert (const ConstString &path, 103254721Semaste const ConstString &replacement, 104254721Semaste uint32_t index, 105254721Semaste bool notify) 106254721Semaste{ 107254721Semaste ++m_mod_id; 108254721Semaste iterator insert_iter; 109254721Semaste if (index >= m_pairs.size()) 110254721Semaste insert_iter = m_pairs.end(); 111254721Semaste else 112254721Semaste insert_iter = m_pairs.begin() + index; 113254721Semaste m_pairs.insert(insert_iter, pair(path, replacement)); 114254721Semaste if (notify && m_callback) 115254721Semaste m_callback (*this, m_callback_baton); 116254721Semaste} 117254721Semaste 118254721Semastebool 119254721SemastePathMappingList::Replace (const ConstString &path, 120254721Semaste const ConstString &replacement, 121254721Semaste uint32_t index, 122254721Semaste bool notify) 123254721Semaste{ 124254721Semaste iterator insert_iter; 125254721Semaste if (index >= m_pairs.size()) 126254721Semaste return false; 127254721Semaste ++m_mod_id; 128254721Semaste m_pairs[index] = pair(path, replacement); 129254721Semaste if (notify && m_callback) 130254721Semaste m_callback (*this, m_callback_baton); 131254721Semaste return true; 132254721Semaste} 133254721Semaste 134254721Semastebool 135254721SemastePathMappingList::Remove (off_t index, bool notify) 136254721Semaste{ 137254721Semaste if (index >= m_pairs.size()) 138254721Semaste return false; 139254721Semaste 140254721Semaste ++m_mod_id; 141254721Semaste iterator iter = m_pairs.begin() + index; 142254721Semaste m_pairs.erase(iter); 143254721Semaste if (notify && m_callback) 144254721Semaste m_callback (*this, m_callback_baton); 145254721Semaste return true; 146254721Semaste} 147254721Semaste 148254721Semaste// For clients which do not need the pair index dumped, pass a pair_index >= 0 149254721Semaste// to only dump the indicated pair. 150254721Semastevoid 151254721SemastePathMappingList::Dump (Stream *s, int pair_index) 152254721Semaste{ 153254721Semaste unsigned int numPairs = m_pairs.size(); 154254721Semaste 155254721Semaste if (pair_index < 0) 156254721Semaste { 157254721Semaste unsigned int index; 158254721Semaste for (index = 0; index < numPairs; ++index) 159254721Semaste s->Printf("[%d] \"%s\" -> \"%s\"\n", 160254721Semaste index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString()); 161254721Semaste } 162254721Semaste else 163254721Semaste { 164254721Semaste if (pair_index < numPairs) 165254721Semaste s->Printf("%s -> %s", 166254721Semaste m_pairs[pair_index].first.GetCString(), m_pairs[pair_index].second.GetCString()); 167254721Semaste } 168254721Semaste} 169254721Semaste 170254721Semastevoid 171254721SemastePathMappingList::Clear (bool notify) 172254721Semaste{ 173254721Semaste if (!m_pairs.empty()) 174254721Semaste ++m_mod_id; 175254721Semaste m_pairs.clear(); 176254721Semaste if (notify && m_callback) 177254721Semaste m_callback (*this, m_callback_baton); 178254721Semaste} 179254721Semaste 180254721Semastebool 181254721SemastePathMappingList::RemapPath (const ConstString &path, ConstString &new_path) const 182254721Semaste{ 183254721Semaste const char *path_cstr = path.GetCString(); 184254721Semaste 185254721Semaste if (!path_cstr) 186254721Semaste return false; 187254721Semaste 188254721Semaste const_iterator pos, end = m_pairs.end(); 189254721Semaste for (pos = m_pairs.begin(); pos != end; ++pos) 190254721Semaste { 191254721Semaste const size_t prefixLen = pos->first.GetLength(); 192254721Semaste 193254721Semaste if (::strncmp (pos->first.GetCString(), path_cstr, prefixLen) == 0) 194254721Semaste { 195254721Semaste std::string new_path_str (pos->second.GetCString()); 196254721Semaste new_path_str.append(path.GetCString() + prefixLen); 197254721Semaste new_path.SetCString(new_path_str.c_str()); 198254721Semaste return true; 199254721Semaste } 200254721Semaste } 201254721Semaste return false; 202254721Semaste} 203254721Semaste 204254721Semastebool 205254721SemastePathMappingList::RemapPath (const char *path, std::string &new_path) const 206254721Semaste{ 207254721Semaste if (m_pairs.empty() || path == NULL || path[0] == '\0') 208254721Semaste return false; 209254721Semaste 210254721Semaste const_iterator pos, end = m_pairs.end(); 211254721Semaste for (pos = m_pairs.begin(); pos != end; ++pos) 212254721Semaste { 213254721Semaste const size_t prefix_len = pos->first.GetLength(); 214254721Semaste 215254721Semaste if (::strncmp (pos->first.GetCString(), path, prefix_len) == 0) 216254721Semaste { 217254721Semaste new_path = pos->second.GetCString(); 218254721Semaste new_path.append(path + prefix_len); 219254721Semaste return true; 220254721Semaste } 221254721Semaste } 222254721Semaste return false; 223254721Semaste} 224254721Semaste 225254721Semastebool 226254721SemastePathMappingList::FindFile (const FileSpec &orig_spec, FileSpec &new_spec) const 227254721Semaste{ 228254721Semaste if (!m_pairs.empty()) 229254721Semaste { 230254721Semaste char orig_path[PATH_MAX]; 231254721Semaste char new_path[PATH_MAX]; 232254721Semaste const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path)); 233254721Semaste if (orig_path_len > 0) 234254721Semaste { 235254721Semaste const_iterator pos, end = m_pairs.end(); 236254721Semaste for (pos = m_pairs.begin(); pos != end; ++pos) 237254721Semaste { 238254721Semaste const size_t prefix_len = pos->first.GetLength(); 239254721Semaste 240254721Semaste if (orig_path_len >= prefix_len) 241254721Semaste { 242254721Semaste if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0) 243254721Semaste { 244254721Semaste const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len); 245254721Semaste if (new_path_len < sizeof(new_path)) 246254721Semaste { 247254721Semaste new_spec.SetFile (new_path, true); 248254721Semaste if (new_spec.Exists()) 249254721Semaste return true; 250254721Semaste } 251254721Semaste } 252254721Semaste } 253254721Semaste } 254254721Semaste } 255254721Semaste } 256254721Semaste new_spec.Clear(); 257254721Semaste return false; 258254721Semaste} 259254721Semaste 260254721Semastebool 261254721SemastePathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify) 262254721Semaste{ 263254721Semaste uint32_t idx = FindIndexForPath (path); 264254721Semaste if (idx < m_pairs.size()) 265254721Semaste { 266254721Semaste ++m_mod_id; 267254721Semaste m_pairs[idx].second = new_path; 268254721Semaste if (notify && m_callback) 269254721Semaste m_callback (*this, m_callback_baton); 270254721Semaste return true; 271254721Semaste } 272254721Semaste return false; 273254721Semaste} 274254721Semaste 275254721Semastebool 276254721SemastePathMappingList::Remove (const ConstString &path, bool notify) 277254721Semaste{ 278254721Semaste iterator pos = FindIteratorForPath (path); 279254721Semaste if (pos != m_pairs.end()) 280254721Semaste { 281254721Semaste ++m_mod_id; 282254721Semaste m_pairs.erase (pos); 283254721Semaste if (notify && m_callback) 284254721Semaste m_callback (*this, m_callback_baton); 285254721Semaste return true; 286254721Semaste } 287254721Semaste return false; 288254721Semaste} 289254721Semaste 290254721SemastePathMappingList::const_iterator 291254721SemastePathMappingList::FindIteratorForPath (const ConstString &path) const 292254721Semaste{ 293254721Semaste const_iterator pos; 294254721Semaste const_iterator begin = m_pairs.begin(); 295254721Semaste const_iterator end = m_pairs.end(); 296254721Semaste 297254721Semaste for (pos = begin; pos != end; ++pos) 298254721Semaste { 299254721Semaste if (pos->first == path) 300254721Semaste break; 301254721Semaste } 302254721Semaste return pos; 303254721Semaste} 304254721Semaste 305254721SemastePathMappingList::iterator 306254721SemastePathMappingList::FindIteratorForPath (const ConstString &path) 307254721Semaste{ 308254721Semaste iterator pos; 309254721Semaste iterator begin = m_pairs.begin(); 310254721Semaste iterator end = m_pairs.end(); 311254721Semaste 312254721Semaste for (pos = begin; pos != end; ++pos) 313254721Semaste { 314254721Semaste if (pos->first == path) 315254721Semaste break; 316254721Semaste } 317254721Semaste return pos; 318254721Semaste} 319254721Semaste 320254721Semastebool 321254721SemastePathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const 322254721Semaste{ 323254721Semaste if (idx < m_pairs.size()) 324254721Semaste { 325254721Semaste path = m_pairs[idx].first; 326254721Semaste new_path = m_pairs[idx].second; 327254721Semaste return true; 328254721Semaste } 329254721Semaste return false; 330254721Semaste} 331254721Semaste 332254721Semaste 333254721Semaste 334254721Semasteuint32_t 335254721SemastePathMappingList::FindIndexForPath (const ConstString &path) const 336254721Semaste{ 337254721Semaste const_iterator pos; 338254721Semaste const_iterator begin = m_pairs.begin(); 339254721Semaste const_iterator end = m_pairs.end(); 340254721Semaste 341254721Semaste for (pos = begin; pos != end; ++pos) 342254721Semaste { 343254721Semaste if (pos->first == path) 344254721Semaste return std::distance (begin, pos); 345254721Semaste } 346254721Semaste return UINT32_MAX; 347254721Semaste} 348254721Semaste 349