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     if (log)
63       log->Printf("SBCommandReturnObject(%p)::GetOutput () => \"%s\"",
64                   static_cast<void *>(m_opaque_ap.get()),
65                   m_opaque_ap->GetOutputData());
66 
67     return m_opaque_ap->GetOutputData();
68   }
69 
70   if (log)
71     log->Printf("SBCommandReturnObject(%p)::GetOutput () => nullptr",
72                 static_cast<void *>(m_opaque_ap.get()));
73 
74   return nullptr;
75 }
76 
77 const char *SBCommandReturnObject::GetError() {
78   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
79 
80   if (m_opaque_ap) {
81     if (log)
82       log->Printf("SBCommandReturnObject(%p)::GetError () => \"%s\"",
83                   static_cast<void *>(m_opaque_ap.get()),
84                   m_opaque_ap->GetErrorData());
85 
86     return m_opaque_ap->GetErrorData();
87   }
88 
89   if (log)
90     log->Printf("SBCommandReturnObject(%p)::GetError () => nullptr",
91                 static_cast<void *>(m_opaque_ap.get()));
92 
93   return nullptr;
94 }
95 
96 size_t SBCommandReturnObject::GetOutputSize() {
97   return (m_opaque_ap ? strlen(m_opaque_ap->GetOutputData()) : 0);
98 }
99 
100 size_t SBCommandReturnObject::GetErrorSize() {
101   return (m_opaque_ap ? strlen(m_opaque_ap->GetErrorData()) : 0);
102 }
103 
104 size_t SBCommandReturnObject::PutOutput(FILE *fh) {
105   if (fh) {
106     size_t num_bytes = GetOutputSize();
107     if (num_bytes)
108       return ::fprintf(fh, "%s", GetOutput());
109   }
110   return 0;
111 }
112 
113 size_t SBCommandReturnObject::PutError(FILE *fh) {
114   if (fh) {
115     size_t num_bytes = GetErrorSize();
116     if (num_bytes)
117       return ::fprintf(fh, "%s", GetError());
118   }
119   return 0;
120 }
121 
122 void SBCommandReturnObject::Clear() {
123   if (m_opaque_ap)
124     m_opaque_ap->Clear();
125 }
126 
127 lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
128   return (m_opaque_ap ? m_opaque_ap->GetStatus() : lldb::eReturnStatusInvalid);
129 }
130 
131 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
132   if (m_opaque_ap)
133     m_opaque_ap->SetStatus(status);
134 }
135 
136 bool SBCommandReturnObject::Succeeded() {
137   return (m_opaque_ap ? m_opaque_ap->Succeeded() : false);
138 }
139 
140 bool SBCommandReturnObject::HasResult() {
141   return (m_opaque_ap ? m_opaque_ap->HasResult() : false);
142 }
143 
144 void SBCommandReturnObject::AppendMessage(const char *message) {
145   if (m_opaque_ap)
146     m_opaque_ap->AppendMessage(message);
147 }
148 
149 void SBCommandReturnObject::AppendWarning(const char *message) {
150   if (m_opaque_ap)
151     m_opaque_ap->AppendWarning(message);
152 }
153 
154 CommandReturnObject *SBCommandReturnObject::operator->() const {
155   return m_opaque_ap.get();
156 }
157 
158 CommandReturnObject *SBCommandReturnObject::get() const {
159   return m_opaque_ap.get();
160 }
161 
162 CommandReturnObject &SBCommandReturnObject::operator*() const {
163   assert(m_opaque_ap.get());
164   return *(m_opaque_ap.get());
165 }
166 
167 CommandReturnObject &SBCommandReturnObject::ref() const {
168   assert(m_opaque_ap.get());
169   return *(m_opaque_ap.get());
170 }
171 
172 void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) {
173   if (m_opaque_ap)
174     m_opaque_ap.reset(ptr);
175 }
176 
177 bool SBCommandReturnObject::GetDescription(SBStream &description) {
178   Stream &strm = description.ref();
179 
180   if (m_opaque_ap) {
181     description.Printf("Status:  ");
182     lldb::ReturnStatus status = m_opaque_ap->GetStatus();
183     if (status == lldb::eReturnStatusStarted)
184       strm.PutCString("Started");
185     else if (status == lldb::eReturnStatusInvalid)
186       strm.PutCString("Invalid");
187     else if (m_opaque_ap->Succeeded())
188       strm.PutCString("Success");
189     else
190       strm.PutCString("Fail");
191 
192     if (GetOutputSize() > 0)
193       strm.Printf("\nOutput Message:\n%s", GetOutput());
194 
195     if (GetErrorSize() > 0)
196       strm.Printf("\nError Message:\n%s", GetError());
197   } else
198     strm.PutCString("No value");
199 
200   return true;
201 }
202 
203 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
204   SetImmediateOutputFile(fh, false);
205 }
206 
207 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
208   SetImmediateErrorFile(fh, false);
209 }
210 
211 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
212                                                    bool transfer_ownership) {
213   if (m_opaque_ap)
214     m_opaque_ap->SetImmediateOutputFile(fh, transfer_ownership);
215 }
216 
217 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
218                                                   bool transfer_ownership) {
219   if (m_opaque_ap)
220     m_opaque_ap->SetImmediateErrorFile(fh, transfer_ownership);
221 }
222 
223 void SBCommandReturnObject::PutCString(const char *string, int len) {
224   if (m_opaque_ap) {
225     if (len == 0 || string == nullptr || *string == 0) {
226       return;
227     } else if (len > 0) {
228       std::string buffer(string, len);
229       m_opaque_ap->AppendMessage(buffer.c_str());
230     } else
231       m_opaque_ap->AppendMessage(string);
232   }
233 }
234 
235 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) {
236   if (!m_opaque_ap)
237     return nullptr;
238   if (!only_if_no_immediate ||
239       m_opaque_ap->GetImmediateOutputStream().get() == nullptr)
240     return GetOutput();
241   return nullptr;
242 }
243 
244 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) {
245   if (!m_opaque_ap)
246     return nullptr;
247   if (!only_if_no_immediate ||
248       m_opaque_ap->GetImmediateErrorStream().get() == nullptr)
249     return GetError();
250   return nullptr;
251 }
252 
253 size_t SBCommandReturnObject::Printf(const char *format, ...) {
254   if (m_opaque_ap) {
255     va_list args;
256     va_start(args, format);
257     size_t result = m_opaque_ap->GetOutputStream().PrintfVarArg(format, args);
258     va_end(args);
259     return result;
260   }
261   return 0;
262 }
263 
264 void SBCommandReturnObject::SetError(lldb::SBError &error,
265                                      const char *fallback_error_cstr) {
266   if (m_opaque_ap) {
267     if (error.IsValid())
268       m_opaque_ap->SetError(error.ref(), fallback_error_cstr);
269     else if (fallback_error_cstr)
270       m_opaque_ap->SetError(Error(), fallback_error_cstr);
271   }
272 }
273 
274 void SBCommandReturnObject::SetError(const char *error_cstr) {
275   if (m_opaque_ap && error_cstr)
276     m_opaque_ap->SetError(error_cstr);
277 }
278