xref: /freebsd/contrib/llvm-project/lldb/source/API/SBCommandReturnObject.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- SBCommandReturnObject.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBCommandReturnObject.h"
10 #include "Utils.h"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBFile.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStructuredData.h"
15 #include "lldb/API/SBValue.h"
16 #include "lldb/API/SBValueList.h"
17 #include "lldb/Core/StructuredDataImpl.h"
18 #include "lldb/Interpreter/CommandReturnObject.h"
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/Utility/Instrumentation.h"
21 #include "lldb/Utility/Status.h"
22 #include "lldb/lldb-forward.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 class lldb_private::SBCommandReturnObjectImpl {
28 public:
SBCommandReturnObjectImpl()29   SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {}
SBCommandReturnObjectImpl(CommandReturnObject & ref)30   SBCommandReturnObjectImpl(CommandReturnObject &ref)
31       : m_ptr(&ref), m_owned(false) {}
SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl & rhs)32   SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs)
33       : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {}
operator =(const SBCommandReturnObjectImpl & rhs)34   SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) {
35     SBCommandReturnObjectImpl copy(rhs);
36     std::swap(*this, copy);
37     return *this;
38   }
39   // rvalue ctor+assignment are not used by SBCommandReturnObject.
~SBCommandReturnObjectImpl()40   ~SBCommandReturnObjectImpl() {
41     if (m_owned)
42       delete m_ptr;
43   }
44 
operator *() const45   CommandReturnObject &operator*() const { return *m_ptr; }
46 
47 private:
48   CommandReturnObject *m_ptr;
49   bool m_owned = true;
50 };
51 
SBCommandReturnObject()52 SBCommandReturnObject::SBCommandReturnObject()
53     : m_opaque_up(new SBCommandReturnObjectImpl()) {
54   LLDB_INSTRUMENT_VA(this);
55 }
56 
SBCommandReturnObject(CommandReturnObject & ref)57 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref)
58     : m_opaque_up(new SBCommandReturnObjectImpl(ref)) {
59   LLDB_INSTRUMENT_VA(this, ref);
60 }
61 
SBCommandReturnObject(const SBCommandReturnObject & rhs)62 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) {
63   LLDB_INSTRUMENT_VA(this, rhs);
64 
65   m_opaque_up = clone(rhs.m_opaque_up);
66 }
67 
68 SBCommandReturnObject &SBCommandReturnObject::
operator =(const SBCommandReturnObject & rhs)69 operator=(const SBCommandReturnObject &rhs) {
70   LLDB_INSTRUMENT_VA(this, rhs);
71 
72   if (this != &rhs)
73     m_opaque_up = clone(rhs.m_opaque_up);
74   return *this;
75 }
76 
77 SBCommandReturnObject::~SBCommandReturnObject() = default;
78 
IsValid() const79 bool SBCommandReturnObject::IsValid() const {
80   LLDB_INSTRUMENT_VA(this);
81   return this->operator bool();
82 }
operator bool() const83 SBCommandReturnObject::operator bool() const {
84   LLDB_INSTRUMENT_VA(this);
85 
86   // This method is not useful but it needs to stay to keep SB API stable.
87   return true;
88 }
89 
GetCommand()90 const char *SBCommandReturnObject::GetCommand() {
91   LLDB_INSTRUMENT_VA(this);
92 
93   ConstString output(ref().GetCommand());
94   return output.AsCString(/*value_if_empty*/ "");
95 }
96 
GetOutput()97 const char *SBCommandReturnObject::GetOutput() {
98   LLDB_INSTRUMENT_VA(this);
99 
100   ConstString output(ref().GetOutputString());
101   return output.AsCString(/*value_if_empty*/ "");
102 }
103 
GetError()104 const char *SBCommandReturnObject::GetError() {
105   LLDB_INSTRUMENT_VA(this);
106 
107   ConstString output(ref().GetErrorString());
108   return output.AsCString(/*value_if_empty*/ "");
109 }
110 
GetErrorData()111 SBStructuredData SBCommandReturnObject::GetErrorData() {
112   LLDB_INSTRUMENT_VA(this);
113 
114   StructuredData::ObjectSP data(ref().GetErrorData());
115   SBStructuredData sb_data;
116   sb_data.m_impl_up->SetObjectSP(data);
117   return sb_data;
118 }
119 
GetOutputSize()120 size_t SBCommandReturnObject::GetOutputSize() {
121   LLDB_INSTRUMENT_VA(this);
122 
123   return ref().GetOutputString().size();
124 }
125 
GetErrorSize()126 size_t SBCommandReturnObject::GetErrorSize() {
127   LLDB_INSTRUMENT_VA(this);
128 
129   return ref().GetErrorString().size();
130 }
131 
PutOutput(FILE * fh)132 size_t SBCommandReturnObject::PutOutput(FILE *fh) {
133   LLDB_INSTRUMENT_VA(this, fh);
134   if (fh) {
135     size_t num_bytes = GetOutputSize();
136     if (num_bytes)
137       return ::fprintf(fh, "%s", GetOutput());
138   }
139   return 0;
140 }
141 
PutOutput(FileSP file_sp)142 size_t SBCommandReturnObject::PutOutput(FileSP file_sp) {
143   LLDB_INSTRUMENT_VA(this, file_sp);
144   if (!file_sp)
145     return 0;
146   return file_sp->Printf("%s", GetOutput());
147 }
148 
PutOutput(SBFile file)149 size_t SBCommandReturnObject::PutOutput(SBFile file) {
150   LLDB_INSTRUMENT_VA(this, file);
151   if (!file.m_opaque_sp)
152     return 0;
153   return file.m_opaque_sp->Printf("%s", GetOutput());
154 }
155 
PutError(FILE * fh)156 size_t SBCommandReturnObject::PutError(FILE *fh) {
157   LLDB_INSTRUMENT_VA(this, fh);
158   if (fh) {
159     size_t num_bytes = GetErrorSize();
160     if (num_bytes)
161       return ::fprintf(fh, "%s", GetError());
162   }
163   return 0;
164 }
165 
PutError(FileSP file_sp)166 size_t SBCommandReturnObject::PutError(FileSP file_sp) {
167   LLDB_INSTRUMENT_VA(this, file_sp);
168   if (!file_sp)
169     return 0;
170   return file_sp->Printf("%s", GetError());
171 }
172 
PutError(SBFile file)173 size_t SBCommandReturnObject::PutError(SBFile file) {
174   LLDB_INSTRUMENT_VA(this, file);
175   if (!file.m_opaque_sp)
176     return 0;
177   return file.m_opaque_sp->Printf("%s", GetError());
178 }
179 
Clear()180 void SBCommandReturnObject::Clear() {
181   LLDB_INSTRUMENT_VA(this);
182 
183   ref().Clear();
184 }
185 
GetStatus()186 lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
187   LLDB_INSTRUMENT_VA(this);
188 
189   return ref().GetStatus();
190 }
191 
SetStatus(lldb::ReturnStatus status)192 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
193   LLDB_INSTRUMENT_VA(this, status);
194 
195   ref().SetStatus(status);
196 }
197 
Succeeded()198 bool SBCommandReturnObject::Succeeded() {
199   LLDB_INSTRUMENT_VA(this);
200 
201   return ref().Succeeded();
202 }
203 
HasResult()204 bool SBCommandReturnObject::HasResult() {
205   LLDB_INSTRUMENT_VA(this);
206 
207   return ref().HasResult();
208 }
209 
AppendMessage(const char * message)210 void SBCommandReturnObject::AppendMessage(const char *message) {
211   LLDB_INSTRUMENT_VA(this, message);
212 
213   ref().AppendMessage(message);
214 }
215 
AppendWarning(const char * message)216 void SBCommandReturnObject::AppendWarning(const char *message) {
217   LLDB_INSTRUMENT_VA(this, message);
218 
219   ref().AppendWarning(message);
220 }
221 
operator ->() const222 CommandReturnObject *SBCommandReturnObject::operator->() const {
223   return &**m_opaque_up;
224 }
225 
get() const226 CommandReturnObject *SBCommandReturnObject::get() const {
227   return &**m_opaque_up;
228 }
229 
operator *() const230 CommandReturnObject &SBCommandReturnObject::operator*() const {
231   return **m_opaque_up;
232 }
233 
ref() const234 CommandReturnObject &SBCommandReturnObject::ref() const {
235   return **m_opaque_up;
236 }
237 
GetDescription(SBStream & description)238 bool SBCommandReturnObject::GetDescription(SBStream &description) {
239   LLDB_INSTRUMENT_VA(this, description);
240 
241   Stream &strm = description.ref();
242 
243   description.Printf("Error:  ");
244   lldb::ReturnStatus status = ref().GetStatus();
245   if (status == lldb::eReturnStatusStarted)
246     strm.PutCString("Started");
247   else if (status == lldb::eReturnStatusInvalid)
248     strm.PutCString("Invalid");
249   else if (ref().Succeeded())
250     strm.PutCString("Success");
251   else
252     strm.PutCString("Fail");
253 
254   if (GetOutputSize() > 0)
255     strm.Printf("\nOutput Message:\n%s", GetOutput());
256 
257   if (GetErrorSize() > 0)
258     strm.Printf("\nError Message:\n%s", GetError());
259 
260   return true;
261 }
262 
SetImmediateOutputFile(FILE * fh)263 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
264   LLDB_INSTRUMENT_VA(this, fh);
265 
266   SetImmediateOutputFile(fh, false);
267 }
268 
SetImmediateErrorFile(FILE * fh)269 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
270   LLDB_INSTRUMENT_VA(this, fh);
271 
272   SetImmediateErrorFile(fh, false);
273 }
274 
SetImmediateOutputFile(FILE * fh,bool transfer_ownership)275 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
276                                                    bool transfer_ownership) {
277   LLDB_INSTRUMENT_VA(this, fh, transfer_ownership);
278   FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
279   ref().SetImmediateOutputFile(file);
280 }
281 
SetImmediateErrorFile(FILE * fh,bool transfer_ownership)282 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
283                                                   bool transfer_ownership) {
284   LLDB_INSTRUMENT_VA(this, fh, transfer_ownership);
285   FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
286   ref().SetImmediateErrorFile(file);
287 }
288 
SetImmediateOutputFile(SBFile file)289 void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) {
290   LLDB_INSTRUMENT_VA(this, file);
291   ref().SetImmediateOutputFile(file.m_opaque_sp);
292 }
293 
SetImmediateErrorFile(SBFile file)294 void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) {
295   LLDB_INSTRUMENT_VA(this, file);
296   ref().SetImmediateErrorFile(file.m_opaque_sp);
297 }
298 
SetImmediateOutputFile(FileSP file_sp)299 void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) {
300   LLDB_INSTRUMENT_VA(this, file_sp);
301   SetImmediateOutputFile(SBFile(file_sp));
302 }
303 
SetImmediateErrorFile(FileSP file_sp)304 void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) {
305   LLDB_INSTRUMENT_VA(this, file_sp);
306   SetImmediateErrorFile(SBFile(file_sp));
307 }
308 
PutCString(const char * string,int len)309 void SBCommandReturnObject::PutCString(const char *string, int len) {
310   LLDB_INSTRUMENT_VA(this, string, len);
311 
312   if (len == 0 || string == nullptr || *string == 0) {
313     return;
314   } else if (len > 0) {
315     std::string buffer(string, len);
316     ref().AppendMessage(buffer.c_str());
317   } else
318     ref().AppendMessage(string);
319 }
320 
GetOutput(bool only_if_no_immediate)321 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) {
322   LLDB_INSTRUMENT_VA(this, only_if_no_immediate);
323 
324   if (!only_if_no_immediate ||
325       ref().GetImmediateOutputStream().get() == nullptr)
326     return GetOutput();
327   return nullptr;
328 }
329 
GetError(bool only_if_no_immediate)330 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) {
331   LLDB_INSTRUMENT_VA(this, only_if_no_immediate);
332 
333   if (!only_if_no_immediate || ref().GetImmediateErrorStream().get() == nullptr)
334     return GetError();
335   return nullptr;
336 }
337 
Printf(const char * format,...)338 size_t SBCommandReturnObject::Printf(const char *format, ...) {
339   va_list args;
340   va_start(args, format);
341   size_t result = ref().GetOutputStream().PrintfVarArg(format, args);
342   va_end(args);
343   return result;
344 }
345 
SetError(lldb::SBError & error,const char * fallback_error_cstr)346 void SBCommandReturnObject::SetError(lldb::SBError &error,
347                                      const char *fallback_error_cstr) {
348   LLDB_INSTRUMENT_VA(this, error, fallback_error_cstr);
349 
350   if (error.IsValid() && !error.Fail())
351     ref().SetError(error.ref().Clone());
352   else if (fallback_error_cstr)
353     ref().SetError(Status::FromErrorString(fallback_error_cstr));
354 }
355 
SetError(const char * error_cstr)356 void SBCommandReturnObject::SetError(const char *error_cstr) {
357   LLDB_INSTRUMENT_VA(this, error_cstr);
358 
359   if (error_cstr)
360     ref().AppendError(error_cstr);
361 }
362 
363 SBValueList
GetValues(lldb::DynamicValueType use_dynamic)364 SBCommandReturnObject::GetValues(lldb::DynamicValueType use_dynamic) {
365   LLDB_INSTRUMENT_VA(this, use_dynamic);
366 
367   SBValueList value_list;
368   for (ValueObjectSP value_object_sp :
369        ref().GetValueObjectList().GetObjects()) {
370     SBValue value_sb;
371     value_sb.SetSP(value_object_sp, use_dynamic);
372     value_list.Append(value_sb);
373   }
374 
375   return value_list;
376 }
377