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