1 //===-- SBFileSpec.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 #include <inttypes.h> // PRIu64
11 #include <limits.h>
12 
13 #include "lldb/API/SBFileSpec.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/Host/FileSystem.h"
16 #include "lldb/Host/PosixApi.h"
17 #include "lldb/Utility/FileSpec.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/Stream.h"
20 
21 #include "llvm/ADT/SmallString.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 SBFileSpec::SBFileSpec() : m_opaque_ap(new lldb_private::FileSpec()) {}
27 
28 SBFileSpec::SBFileSpec(const SBFileSpec &rhs)
29     : m_opaque_ap(new lldb_private::FileSpec(*rhs.m_opaque_ap)) {}
30 
31 SBFileSpec::SBFileSpec(const lldb_private::FileSpec &fspec)
32     : m_opaque_ap(new lldb_private::FileSpec(fspec)) {}
33 
34 // Deprecated!!!
35 SBFileSpec::SBFileSpec(const char *path)
36     : m_opaque_ap(new FileSpec(path, true)) {}
37 
38 SBFileSpec::SBFileSpec(const char *path, bool resolve)
39     : m_opaque_ap(new FileSpec(path, resolve)) {}
40 
41 SBFileSpec::~SBFileSpec() {}
42 
43 const SBFileSpec &SBFileSpec::operator=(const SBFileSpec &rhs) {
44   if (this != &rhs)
45     *m_opaque_ap = *rhs.m_opaque_ap;
46   return *this;
47 }
48 
49 bool SBFileSpec::IsValid() const { return m_opaque_ap->operator bool(); }
50 
51 bool SBFileSpec::Exists() const {
52   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
53 
54   bool result = m_opaque_ap->Exists();
55 
56   if (log)
57     log->Printf("SBFileSpec(%p)::Exists () => %s",
58                 static_cast<void *>(m_opaque_ap.get()),
59                 (result ? "true" : "false"));
60 
61   return result;
62 }
63 
64 bool SBFileSpec::ResolveExecutableLocation() {
65   return FileSystem::Instance().ResolveExecutableLocation(*m_opaque_ap);
66 }
67 
68 int SBFileSpec::ResolvePath(const char *src_path, char *dst_path,
69                             size_t dst_len) {
70   llvm::SmallString<64> result(src_path);
71   lldb_private::FileSpec::Resolve(result);
72   ::snprintf(dst_path, dst_len, "%s", result.c_str());
73   return std::min(dst_len - 1, result.size());
74 }
75 
76 const char *SBFileSpec::GetFilename() const {
77   const char *s = m_opaque_ap->GetFilename().AsCString();
78 
79   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
80   if (log) {
81     if (s)
82       log->Printf("SBFileSpec(%p)::GetFilename () => \"%s\"",
83                   static_cast<void *>(m_opaque_ap.get()), s);
84     else
85       log->Printf("SBFileSpec(%p)::GetFilename () => NULL",
86                   static_cast<void *>(m_opaque_ap.get()));
87   }
88 
89   return s;
90 }
91 
92 const char *SBFileSpec::GetDirectory() const {
93   FileSpec directory{*m_opaque_ap};
94   directory.GetFilename().Clear();
95   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
96   if (log) {
97     if (directory)
98       log->Printf("SBFileSpec(%p)::GetDirectory () => \"%s\"",
99                   static_cast<void *>(m_opaque_ap.get()),
100                   directory.GetCString());
101     else
102       log->Printf("SBFileSpec(%p)::GetDirectory () => NULL",
103                   static_cast<void *>(m_opaque_ap.get()));
104   }
105   return directory.GetCString();
106 }
107 
108 void SBFileSpec::SetFilename(const char *filename) {
109   if (filename && filename[0])
110     m_opaque_ap->GetFilename().SetCString(filename);
111   else
112     m_opaque_ap->GetFilename().Clear();
113 }
114 
115 void SBFileSpec::SetDirectory(const char *directory) {
116   if (directory && directory[0])
117     m_opaque_ap->GetDirectory().SetCString(directory);
118   else
119     m_opaque_ap->GetDirectory().Clear();
120 }
121 
122 uint32_t SBFileSpec::GetPath(char *dst_path, size_t dst_len) const {
123   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
124 
125   uint32_t result = m_opaque_ap->GetPath(dst_path, dst_len);
126 
127   if (log)
128     log->Printf("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64
129                 ") => %u",
130                 static_cast<void *>(m_opaque_ap.get()), result, dst_path,
131                 static_cast<uint64_t>(dst_len), result);
132 
133   if (result == 0 && dst_path && dst_len > 0)
134     *dst_path = '\0';
135   return result;
136 }
137 
138 const lldb_private::FileSpec *SBFileSpec::operator->() const {
139   return m_opaque_ap.get();
140 }
141 
142 const lldb_private::FileSpec *SBFileSpec::get() const {
143   return m_opaque_ap.get();
144 }
145 
146 const lldb_private::FileSpec &SBFileSpec::operator*() const {
147   return *m_opaque_ap.get();
148 }
149 
150 const lldb_private::FileSpec &SBFileSpec::ref() const {
151   return *m_opaque_ap.get();
152 }
153 
154 void SBFileSpec::SetFileSpec(const lldb_private::FileSpec &fs) {
155   *m_opaque_ap = fs;
156 }
157 
158 bool SBFileSpec::GetDescription(SBStream &description) const {
159   Stream &strm = description.ref();
160   char path[PATH_MAX];
161   if (m_opaque_ap->GetPath(path, sizeof(path)))
162     strm.PutCString(path);
163   return true;
164 }
165 
166 void SBFileSpec::AppendPathComponent(const char *fn) {
167   m_opaque_ap->AppendPathComponent(fn);
168 }
169