1 //===-- SBCommandReturnObject.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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/API/SBCommandReturnObject.h"
15 #include "lldb/API/SBError.h"
16 #include "lldb/API/SBStream.h"
17 
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 SBCommandReturnObject::SBCommandReturnObject()
26     : m_opaque_ap(new CommandReturnObject()) {}
27 
28 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs)
29     : m_opaque_ap() {
30   if (rhs.m_opaque_ap)
31     m_opaque_ap.reset(new CommandReturnObject(*rhs.m_opaque_ap));
32 }
33 
34 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject *ptr)
35     : m_opaque_ap(ptr) {}
36 
37 SBCommandReturnObject::~SBCommandReturnObject() = default;
38 
39 CommandReturnObject *SBCommandReturnObject::Release() {
40   return m_opaque_ap.release();
41 }
42 
43 const SBCommandReturnObject &SBCommandReturnObject::
44 operator=(const SBCommandReturnObject &rhs) {
45   if (this != &rhs) {
46     if (rhs.m_opaque_ap)
47       m_opaque_ap.reset(new CommandReturnObject(*rhs.m_opaque_ap));
48     else
49       m_opaque_ap.reset();
50   }
51   return *this;
52 }
53 
54 bool SBCommandReturnObject::IsValid() const {
55   return m_opaque_ap.get() != nullptr;
56 }
57 
58 const char *SBCommandReturnObject::GetOutput() {
59   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
60 
61   if (m_opaque_ap) {
62     llvm::StringRef output = m_opaque_ap->GetOutputData();
63     ConstString result(output.empty() ? llvm::StringRef("") : output);
64 
65     if (log)
66       log->Printf("SBCommandReturnObject(%p)::GetOutput () => \"%s\"",
67                   static_cast<void *>(m_opaque_ap.get()), result.AsCString());
68 
69     return result.AsCString();
70   }
71 
72   if (log)
73     log->Printf("SBCommandReturnObject(%p)::GetOutput () => nullptr",
74                 static_cast<void *>(m_opaque_ap.get()));
75 
76   return nullptr;
77 }
78 
79 const char *SBCommandReturnObject::GetError() {
80   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
81 
82   if (m_opaque_ap) {
83     llvm::StringRef output = m_opaque_ap->GetErrorData();
84     ConstString result(output.empty() ? llvm::StringRef("") : output);
85     if (log)
86       log->Printf("SBCommandReturnObject(%p)::GetError () => \"%s\"",
87                   static_cast<void *>(m_opaque_ap.get()), result.AsCString());
88 
89     return result.AsCString();
90   }
91 
92   if (log)
93     log->Printf("SBCommandReturnObject(%p)::GetError () => nullptr",
94                 static_cast<void *>(m_opaque_ap.get()));
95 
96   return nullptr;
97 }
98 
99 size_t SBCommandReturnObject::GetOutputSize() {
100   return (m_opaque_ap ? m_opaque_ap->GetOutputData().size() : 0);
101 }
102 
103 size_t SBCommandReturnObject::GetErrorSize() {
104   return (m_opaque_ap ? m_opaque_ap->GetErrorData().size() : 0);
105 }
106 
107 size_t SBCommandReturnObject::PutOutput(FILE *fh) {
108   if (fh) {
109     size_t num_bytes = GetOutputSize();
110     if (num_bytes)
111       return ::fprintf(fh, "%s", GetOutput());
112   }
113   return 0;
114 }
115 
116 size_t SBCommandReturnObject::PutError(FILE *fh) {
117   if (fh) {
118     size_t num_bytes = GetErrorSize();
119     if (num_bytes)
120       return ::fprintf(fh, "%s", GetError());
121   }
122   return 0;
123 }
124 
125 void SBCommandReturnObject::Clear() {
126   if (m_opaque_ap)
127     m_opaque_ap->Clear();
128 }
129 
130 lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
131   return (m_opaque_ap ? m_opaque_ap->GetStatus() : lldb::eReturnStatusInvalid);
132 }
133 
134 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
135   if (m_opaque_ap)
136     m_opaque_ap->SetStatus(status);
137 }
138 
139 bool SBCommandReturnObject::Succeeded() {
140   return (m_opaque_ap ? m_opaque_ap->Succeeded() : false);
141 }
142 
143 bool SBCommandReturnObject::HasResult() {
144   return (m_opaque_ap ? m_opaque_ap->HasResult() : false);
145 }
146 
147 void SBCommandReturnObject::AppendMessage(const char *message) {
148   if (m_opaque_ap)
149     m_opaque_ap->AppendMessage(message);
150 }
151 
152 void SBCommandReturnObject::AppendWarning(const char *message) {
153   if (m_opaque_ap)
154     m_opaque_ap->AppendWarning(message);
155 }
156 
157 CommandReturnObject *SBCommandReturnObject::operator->() const {
158   return m_opaque_ap.get();
159 }
160 
161 CommandReturnObject *SBCommandReturnObject::get() const {
162   return m_opaque_ap.get();
163 }
164 
165 CommandReturnObject &SBCommandReturnObject::operator*() const {
166   assert(m_opaque_ap.get());
167   return *(m_opaque_ap.get());
168 }
169 
170 CommandReturnObject &SBCommandReturnObject::ref() const {
171   assert(m_opaque_ap.get());
172   return *(m_opaque_ap.get());
173 }
174 
175 void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) {
176   if (m_opaque_ap)
177     m_opaque_ap.reset(ptr);
178 }
179 
180 bool SBCommandReturnObject::GetDescription(SBStream &description) {
181   Stream &strm = description.ref();
182 
183   if (m_opaque_ap) {
184     description.Printf("Status:  ");
185     lldb::ReturnStatus status = m_opaque_ap->GetStatus();
186     if (status == lldb::eReturnStatusStarted)
187       strm.PutCString("Started");
188     else if (status == lldb::eReturnStatusInvalid)
189       strm.PutCString("Invalid");
190     else if (m_opaque_ap->Succeeded())
191       strm.PutCString("Success");
192     else
193       strm.PutCString("Fail");
194 
195     if (GetOutputSize() > 0)
196       strm.Printf("\nOutput Message:\n%s", GetOutput());
197 
198     if (GetErrorSize() > 0)
199       strm.Printf("\nError Message:\n%s", GetError());
200   } else
201     strm.PutCString("No value");
202 
203   return true;
204 }
205 
206 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
207   SetImmediateOutputFile(fh, false);
208 }
209 
210 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
211   SetImmediateErrorFile(fh, false);
212 }
213 
214 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
215                                                    bool transfer_ownership) {
216   if (m_opaque_ap)
217     m_opaque_ap->SetImmediateOutputFile(fh, transfer_ownership);
218 }
219 
220 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
221                                                   bool transfer_ownership) {
222   if (m_opaque_ap)
223     m_opaque_ap->SetImmediateErrorFile(fh, transfer_ownership);
224 }
225 
226 void SBCommandReturnObject::PutCString(const char *string, int len) {
227   if (m_opaque_ap) {
228     if (len == 0 || string == nullptr || *string == 0) {
229       return;
230     } else if (len > 0) {
231       std::string buffer(string, len);
232       m_opaque_ap->AppendMessage(buffer.c_str());
233     } else
234       m_opaque_ap->AppendMessage(string);
235   }
236 }
237 
238 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) {
239   if (!m_opaque_ap)
240     return nullptr;
241   if (!only_if_no_immediate ||
242       m_opaque_ap->GetImmediateOutputStream().get() == nullptr)
243     return GetOutput();
244   return nullptr;
245 }
246 
247 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) {
248   if (!m_opaque_ap)
249     return nullptr;
250   if (!only_if_no_immediate ||
251       m_opaque_ap->GetImmediateErrorStream().get() == nullptr)
252     return GetError();
253   return nullptr;
254 }
255 
256 size_t SBCommandReturnObject::Printf(const char *format, ...) {
257   if (m_opaque_ap) {
258     va_list args;
259     va_start(args, format);
260     size_t result = m_opaque_ap->GetOutputStream().PrintfVarArg(format, args);
261     va_end(args);
262     return result;
263   }
264   return 0;
265 }
266 
267 void SBCommandReturnObject::SetError(lldb::SBError &error,
268                                      const char *fallback_error_cstr) {
269   if (m_opaque_ap) {
270     if (error.IsValid())
271       m_opaque_ap->SetError(error.ref(), fallback_error_cstr);
272     else if (fallback_error_cstr)
273       m_opaque_ap->SetError(Error(), fallback_error_cstr);
274   }
275 }
276 
277 void SBCommandReturnObject::SetError(const char *error_cstr) {
278   if (m_opaque_ap && error_cstr)
279     m_opaque_ap->SetError(error_cstr);
280 }
281