1 //===-- SBFileSpec.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBFileSpec.h" 10 #include "SBReproducerPrivate.h" 11 #include "Utils.h" 12 #include "lldb/API/SBStream.h" 13 #include "lldb/Host/FileSystem.h" 14 #include "lldb/Host/PosixApi.h" 15 #include "lldb/Utility/FileSpec.h" 16 #include "lldb/Utility/Log.h" 17 #include "lldb/Utility/Stream.h" 18 19 #include "llvm/ADT/SmallString.h" 20 21 #include <inttypes.h> 22 #include <limits.h> 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 SBFileSpec::SBFileSpec() : m_opaque_up(new lldb_private::FileSpec()) { 28 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFileSpec); 29 } 30 31 SBFileSpec::SBFileSpec(const SBFileSpec &rhs) : m_opaque_up() { 32 LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const lldb::SBFileSpec &), rhs); 33 34 m_opaque_up = clone(rhs.m_opaque_up); 35 } 36 37 SBFileSpec::SBFileSpec(const lldb_private::FileSpec &fspec) 38 : m_opaque_up(new lldb_private::FileSpec(fspec)) {} 39 40 // Deprecated!!! 41 SBFileSpec::SBFileSpec(const char *path) : m_opaque_up(new FileSpec(path)) { 42 LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const char *), path); 43 44 FileSystem::Instance().Resolve(*m_opaque_up); 45 } 46 47 SBFileSpec::SBFileSpec(const char *path, bool resolve) 48 : m_opaque_up(new FileSpec(path)) { 49 LLDB_RECORD_CONSTRUCTOR(SBFileSpec, (const char *, bool), path, resolve); 50 51 if (resolve) 52 FileSystem::Instance().Resolve(*m_opaque_up); 53 } 54 55 SBFileSpec::~SBFileSpec() {} 56 57 const SBFileSpec &SBFileSpec::operator=(const SBFileSpec &rhs) { 58 LLDB_RECORD_METHOD(const lldb::SBFileSpec &, 59 SBFileSpec, operator=,(const lldb::SBFileSpec &), rhs); 60 61 if (this != &rhs) 62 m_opaque_up = clone(rhs.m_opaque_up); 63 return *this; 64 } 65 66 bool SBFileSpec::IsValid() const { 67 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFileSpec, IsValid); 68 69 return m_opaque_up->operator bool(); 70 } 71 72 bool SBFileSpec::Exists() const { 73 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFileSpec, Exists); 74 75 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 76 77 bool result = FileSystem::Instance().Exists(*m_opaque_up); 78 79 if (log) 80 log->Printf("SBFileSpec(%p)::Exists () => %s", 81 static_cast<void *>(m_opaque_up.get()), 82 (result ? "true" : "false")); 83 84 return result; 85 } 86 87 bool SBFileSpec::ResolveExecutableLocation() { 88 LLDB_RECORD_METHOD_NO_ARGS(bool, SBFileSpec, ResolveExecutableLocation); 89 90 return FileSystem::Instance().ResolveExecutableLocation(*m_opaque_up); 91 } 92 93 int SBFileSpec::ResolvePath(const char *src_path, char *dst_path, 94 size_t dst_len) { 95 LLDB_RECORD_STATIC_METHOD(int, SBFileSpec, ResolvePath, 96 (const char *, char *, size_t), src_path, dst_path, 97 dst_len); 98 99 llvm::SmallString<64> result(src_path); 100 FileSystem::Instance().Resolve(result); 101 ::snprintf(dst_path, dst_len, "%s", result.c_str()); 102 return std::min(dst_len - 1, result.size()); 103 } 104 105 const char *SBFileSpec::GetFilename() const { 106 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFileSpec, GetFilename); 107 108 const char *s = m_opaque_up->GetFilename().AsCString(); 109 110 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 111 if (log) { 112 if (s) 113 log->Printf("SBFileSpec(%p)::GetFilename () => \"%s\"", 114 static_cast<void *>(m_opaque_up.get()), s); 115 else 116 log->Printf("SBFileSpec(%p)::GetFilename () => NULL", 117 static_cast<void *>(m_opaque_up.get())); 118 } 119 120 return s; 121 } 122 123 const char *SBFileSpec::GetDirectory() const { 124 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFileSpec, GetDirectory); 125 126 FileSpec directory{*m_opaque_up}; 127 directory.GetFilename().Clear(); 128 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 129 if (log) { 130 if (directory) 131 log->Printf("SBFileSpec(%p)::GetDirectory () => \"%s\"", 132 static_cast<void *>(m_opaque_up.get()), 133 directory.GetCString()); 134 else 135 log->Printf("SBFileSpec(%p)::GetDirectory () => NULL", 136 static_cast<void *>(m_opaque_up.get())); 137 } 138 return directory.GetCString(); 139 } 140 141 void SBFileSpec::SetFilename(const char *filename) { 142 LLDB_RECORD_METHOD(void, SBFileSpec, SetFilename, (const char *), filename); 143 144 if (filename && filename[0]) 145 m_opaque_up->GetFilename().SetCString(filename); 146 else 147 m_opaque_up->GetFilename().Clear(); 148 } 149 150 void SBFileSpec::SetDirectory(const char *directory) { 151 LLDB_RECORD_METHOD(void, SBFileSpec, SetDirectory, (const char *), directory); 152 153 if (directory && directory[0]) 154 m_opaque_up->GetDirectory().SetCString(directory); 155 else 156 m_opaque_up->GetDirectory().Clear(); 157 } 158 159 uint32_t SBFileSpec::GetPath(char *dst_path, size_t dst_len) const { 160 LLDB_RECORD_METHOD_CONST(uint32_t, SBFileSpec, GetPath, (char *, size_t), 161 dst_path, dst_len); 162 163 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 164 165 uint32_t result = m_opaque_up->GetPath(dst_path, dst_len); 166 167 if (log) 168 log->Printf("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64 169 ") => %u", 170 static_cast<void *>(m_opaque_up.get()), result, dst_path, 171 static_cast<uint64_t>(dst_len), result); 172 173 if (result == 0 && dst_path && dst_len > 0) 174 *dst_path = '\0'; 175 return result; 176 } 177 178 const lldb_private::FileSpec *SBFileSpec::operator->() const { 179 return m_opaque_up.get(); 180 } 181 182 const lldb_private::FileSpec *SBFileSpec::get() const { 183 return m_opaque_up.get(); 184 } 185 186 const lldb_private::FileSpec &SBFileSpec::operator*() const { 187 return *m_opaque_up; 188 } 189 190 const lldb_private::FileSpec &SBFileSpec::ref() const { return *m_opaque_up; } 191 192 void SBFileSpec::SetFileSpec(const lldb_private::FileSpec &fs) { 193 *m_opaque_up = fs; 194 } 195 196 bool SBFileSpec::GetDescription(SBStream &description) const { 197 LLDB_RECORD_METHOD_CONST(bool, SBFileSpec, GetDescription, (lldb::SBStream &), 198 description); 199 200 Stream &strm = description.ref(); 201 char path[PATH_MAX]; 202 if (m_opaque_up->GetPath(path, sizeof(path))) 203 strm.PutCString(path); 204 return true; 205 } 206 207 void SBFileSpec::AppendPathComponent(const char *fn) { 208 LLDB_RECORD_METHOD(void, SBFileSpec, AppendPathComponent, (const char *), fn); 209 210 m_opaque_up->AppendPathComponent(fn); 211 } 212