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 {
52   return m_opaque_ap.get() != nullptr;
53 }
54 
55 const char *SBCommandReturnObject::GetOutput() {
56   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
57 
58   if (m_opaque_ap) {
59     llvm::StringRef output = m_opaque_ap->GetOutputData();
60     ConstString result(output.empty() ? llvm::StringRef("") : output);
61 
62     if (log)
63       log->Printf("SBCommandReturnObject(%p)::GetOutput () => \"%s\"",
64                   static_cast<void *>(m_opaque_ap.get()), result.AsCString());
65 
66     return result.AsCString();
67   }
68 
69   if (log)
70     log->Printf("SBCommandReturnObject(%p)::GetOutput () => nullptr",
71                 static_cast<void *>(m_opaque_ap.get()));
72 
73   return nullptr;
74 }
75 
76 const char *SBCommandReturnObject::GetError() {
77   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
78 
79   if (m_opaque_ap) {
80     llvm::StringRef output = m_opaque_ap->GetErrorData();
81     ConstString result(output.empty() ? llvm::StringRef("") : output);
82     if (log)
83       log->Printf("SBCommandReturnObject(%p)::GetError () => \"%s\"",
84                   static_cast<void *>(m_opaque_ap.get()), result.AsCString());
85 
86     return result.AsCString();
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 ? m_opaque_ap->GetOutputData().size() : 0);
98 }
99 
100 size_t SBCommandReturnObject::GetErrorSize() {
101   return (m_opaque_ap ? m_opaque_ap->GetErrorData().size() : 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("Error:  ");
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(Status(), 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