1 //===-- SBCommandReturnObject.cpp -------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBCommandReturnObject.h"
10 #include "SBReproducerPrivate.h"
12 #include "lldb/API/SBError.h"
13 #include "lldb/API/SBFile.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/Interpreter/CommandReturnObject.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/Status.h"
20 using namespace lldb_private
;
22 class lldb_private::SBCommandReturnObjectImpl
{
24 SBCommandReturnObjectImpl()
25 : m_ptr(new CommandReturnObject()), m_owned(true) {}
26 SBCommandReturnObjectImpl(CommandReturnObject
&ref
)
27 : m_ptr(&ref
), m_owned(false) {}
28 SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl
&rhs
)
29 : m_ptr(new CommandReturnObject(*rhs
.m_ptr
)), m_owned(rhs
.m_owned
) {}
30 SBCommandReturnObjectImpl
&operator=(const SBCommandReturnObjectImpl
&rhs
) {
31 SBCommandReturnObjectImpl
copy(rhs
);
32 std::swap(*this, copy
);
35 // rvalue ctor+assignment are not used by SBCommandReturnObject.
36 ~SBCommandReturnObjectImpl() {
41 CommandReturnObject
&operator*() const { return *m_ptr
; }
44 CommandReturnObject
*m_ptr
;
48 SBCommandReturnObject::SBCommandReturnObject()
49 : m_opaque_up(new SBCommandReturnObjectImpl()) {
50 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject
);
53 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject
&ref
)
54 : m_opaque_up(new SBCommandReturnObjectImpl(ref
)) {
55 LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject
,
56 (lldb_private::CommandReturnObject
&), ref
);
59 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject
&rhs
)
61 LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject
,
62 (const lldb::SBCommandReturnObject
&), rhs
);
64 m_opaque_up
= clone(rhs
.m_opaque_up
);
67 SBCommandReturnObject
&SBCommandReturnObject::
68 operator=(const SBCommandReturnObject
&rhs
) {
70 lldb::SBCommandReturnObject
&,
71 SBCommandReturnObject
, operator=,(const lldb::SBCommandReturnObject
&),
75 m_opaque_up
= clone(rhs
.m_opaque_up
);
76 return LLDB_RECORD_RESULT(*this);
79 SBCommandReturnObject::~SBCommandReturnObject() = default;
81 bool SBCommandReturnObject::IsValid() const {
82 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject
, IsValid
);
83 return this->operator bool();
85 SBCommandReturnObject::operator bool() const {
86 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject
, operator bool);
88 // This method is not useful but it needs to stay to keep SB API stable.
92 const char *SBCommandReturnObject::GetOutput() {
93 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject
, GetOutput
);
95 ConstString
output(ref().GetOutputData());
96 return output
.AsCString(/*value_if_empty*/ "");
99 const char *SBCommandReturnObject::GetError() {
100 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject
, GetError
);
102 ConstString
output(ref().GetErrorData());
103 return output
.AsCString(/*value_if_empty*/ "");
106 size_t SBCommandReturnObject::GetOutputSize() {
107 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject
, GetOutputSize
);
109 return ref().GetOutputData().size();
112 size_t SBCommandReturnObject::GetErrorSize() {
113 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject
, GetErrorSize
);
115 return ref().GetErrorData().size();
118 size_t SBCommandReturnObject::PutOutput(FILE *fh
) {
119 LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject
, PutOutput
, (FILE *), fh
);
121 size_t num_bytes
= GetOutputSize();
123 return ::fprintf(fh
, "%s", GetOutput());
128 size_t SBCommandReturnObject::PutOutput(FileSP file_sp
) {
129 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject
, PutOutput
, (FileSP
),
133 return file_sp
->Printf("%s", GetOutput());
136 size_t SBCommandReturnObject::PutOutput(SBFile file
) {
137 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject
, PutOutput
, (SBFile
), file
);
138 if (!file
.m_opaque_sp
)
140 return file
.m_opaque_sp
->Printf("%s", GetOutput());
143 size_t SBCommandReturnObject::PutError(FILE *fh
) {
144 LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject
, PutError
, (FILE *), fh
);
146 size_t num_bytes
= GetErrorSize();
148 return ::fprintf(fh
, "%s", GetError());
153 size_t SBCommandReturnObject::PutError(FileSP file_sp
) {
154 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject
, PutError
, (FileSP
),
158 return file_sp
->Printf("%s", GetError());
161 size_t SBCommandReturnObject::PutError(SBFile file
) {
162 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject
, PutError
, (SBFile
), file
);
163 if (!file
.m_opaque_sp
)
165 return file
.m_opaque_sp
->Printf("%s", GetError());
168 void SBCommandReturnObject::Clear() {
169 LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject
, Clear
);
174 lldb::ReturnStatus
SBCommandReturnObject::GetStatus() {
175 LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus
, SBCommandReturnObject
,
178 return ref().GetStatus();
181 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status
) {
182 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetStatus
,
183 (lldb::ReturnStatus
), status
);
185 ref().SetStatus(status
);
188 bool SBCommandReturnObject::Succeeded() {
189 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject
, Succeeded
);
191 return ref().Succeeded();
194 bool SBCommandReturnObject::HasResult() {
195 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject
, HasResult
);
197 return ref().HasResult();
200 void SBCommandReturnObject::AppendMessage(const char *message
) {
201 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, AppendMessage
, (const char *),
204 ref().AppendMessage(message
);
207 void SBCommandReturnObject::AppendWarning(const char *message
) {
208 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, AppendWarning
, (const char *),
211 ref().AppendWarning(message
);
214 CommandReturnObject
*SBCommandReturnObject::operator->() const {
215 return &**m_opaque_up
;
218 CommandReturnObject
*SBCommandReturnObject::get() const {
219 return &**m_opaque_up
;
222 CommandReturnObject
&SBCommandReturnObject::operator*() const {
223 return **m_opaque_up
;
226 CommandReturnObject
&SBCommandReturnObject::ref() const {
227 return **m_opaque_up
;
230 bool SBCommandReturnObject::GetDescription(SBStream
&description
) {
231 LLDB_RECORD_METHOD(bool, SBCommandReturnObject
, GetDescription
,
232 (lldb::SBStream
&), description
);
234 Stream
&strm
= description
.ref();
236 description
.Printf("Error: ");
237 lldb::ReturnStatus status
= ref().GetStatus();
238 if (status
== lldb::eReturnStatusStarted
)
239 strm
.PutCString("Started");
240 else if (status
== lldb::eReturnStatusInvalid
)
241 strm
.PutCString("Invalid");
242 else if (ref().Succeeded())
243 strm
.PutCString("Success");
245 strm
.PutCString("Fail");
247 if (GetOutputSize() > 0)
248 strm
.Printf("\nOutput Message:\n%s", GetOutput());
250 if (GetErrorSize() > 0)
251 strm
.Printf("\nError Message:\n%s", GetError());
256 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh
) {
257 LLDB_RECORD_DUMMY(void, SBCommandReturnObject
, SetImmediateOutputFile
,
260 SetImmediateOutputFile(fh
, false);
263 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh
) {
264 LLDB_RECORD_DUMMY(void, SBCommandReturnObject
, SetImmediateErrorFile
,
267 SetImmediateErrorFile(fh
, false);
270 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh
,
271 bool transfer_ownership
) {
272 LLDB_RECORD_DUMMY(void, SBCommandReturnObject
, SetImmediateOutputFile
,
273 (FILE *, bool), fh
, transfer_ownership
);
274 FileSP file
= std::make_shared
<NativeFile
>(fh
, transfer_ownership
);
275 ref().SetImmediateOutputFile(file
);
278 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh
,
279 bool transfer_ownership
) {
280 LLDB_RECORD_DUMMY(void, SBCommandReturnObject
, SetImmediateErrorFile
,
281 (FILE *, bool), fh
, transfer_ownership
);
282 FileSP file
= std::make_shared
<NativeFile
>(fh
, transfer_ownership
);
283 ref().SetImmediateErrorFile(file
);
286 void SBCommandReturnObject::SetImmediateOutputFile(SBFile file
) {
287 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
289 ref().SetImmediateOutputFile(file
.m_opaque_sp
);
292 void SBCommandReturnObject::SetImmediateErrorFile(SBFile file
) {
293 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
295 ref().SetImmediateErrorFile(file
.m_opaque_sp
);
298 void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp
) {
299 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
301 SetImmediateOutputFile(SBFile(file_sp
));
304 void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp
) {
305 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
307 SetImmediateErrorFile(SBFile(file_sp
));
310 void SBCommandReturnObject::PutCString(const char *string
, int len
) {
311 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, PutCString
,
312 (const char *, int), string
, len
);
314 if (len
== 0 || string
== nullptr || *string
== 0) {
316 } else if (len
> 0) {
317 std::string
buffer(string
, len
);
318 ref().AppendMessage(buffer
.c_str());
320 ref().AppendMessage(string
);
323 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate
) {
324 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject
, GetOutput
, (bool),
325 only_if_no_immediate
);
327 if (!only_if_no_immediate
||
328 ref().GetImmediateOutputStream().get() == nullptr)
333 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate
) {
334 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject
, GetError
, (bool),
335 only_if_no_immediate
);
337 if (!only_if_no_immediate
|| ref().GetImmediateErrorStream().get() == nullptr)
342 size_t SBCommandReturnObject::Printf(const char *format
, ...) {
344 va_start(args
, format
);
345 size_t result
= ref().GetOutputStream().PrintfVarArg(format
, args
);
350 void SBCommandReturnObject::SetError(lldb::SBError
&error
,
351 const char *fallback_error_cstr
) {
352 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetError
,
353 (lldb::SBError
&, const char *), error
,
354 fallback_error_cstr
);
357 ref().SetError(error
.ref(), fallback_error_cstr
);
358 else if (fallback_error_cstr
)
359 ref().SetError(Status(), fallback_error_cstr
);
362 void SBCommandReturnObject::SetError(const char *error_cstr
) {
363 LLDB_RECORD_METHOD(void, SBCommandReturnObject
, SetError
, (const char *),
367 ref().SetError(error_cstr
);
370 namespace lldb_private
{
374 void RegisterMethods
<SBCommandReturnObject
>(Registry
&R
) {
375 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject
, ());
376 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject
,
377 (lldb_private::CommandReturnObject
&));
378 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject
,
379 (const lldb::SBCommandReturnObject
&));
380 LLDB_REGISTER_METHOD(
381 lldb::SBCommandReturnObject
&,
382 SBCommandReturnObject
, operator=,(const lldb::SBCommandReturnObject
&));
383 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject
, IsValid
, ());
384 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject
, operator bool, ());
385 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject
, GetOutput
, ());
386 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject
, GetError
, ());
387 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, GetOutputSize
, ());
388 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, GetErrorSize
, ());
389 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutOutput
, (FILE *));
390 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutError
, (FILE *));
391 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutOutput
, (SBFile
));
392 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutError
, (SBFile
));
393 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutOutput
, (FileSP
));
394 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject
, PutError
, (FileSP
));
395 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, Clear
, ());
396 LLDB_REGISTER_METHOD(lldb::ReturnStatus
, SBCommandReturnObject
, GetStatus
,
398 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetStatus
,
399 (lldb::ReturnStatus
));
400 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject
, Succeeded
, ());
401 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject
, HasResult
, ());
402 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, AppendMessage
,
404 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, AppendWarning
,
406 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject
, GetDescription
,
408 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
410 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
412 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
414 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
416 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
418 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
420 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateOutputFile
,
422 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetImmediateErrorFile
,
424 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, PutCString
,
425 (const char *, int));
426 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject
, GetOutput
,
428 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject
, GetError
, (bool));
429 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetError
,
430 (lldb::SBError
&, const char *));
431 LLDB_REGISTER_METHOD(void, SBCommandReturnObject
, SetError
, (const char *));