1 //===-- SBCommandReturnObject.cpp -----------------------------------------===//
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"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBFile.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/Interpreter/CommandReturnObject.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/Utility/Instrumentation.h"
17 #include "lldb/Utility/Status.h"
20 using namespace lldb_private
;
22 class lldb_private::SBCommandReturnObjectImpl
{
24 SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {}
25 SBCommandReturnObjectImpl(CommandReturnObject
&ref
)
26 : m_ptr(&ref
), m_owned(false) {}
27 SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl
&rhs
)
28 : m_ptr(new CommandReturnObject(*rhs
.m_ptr
)), m_owned(rhs
.m_owned
) {}
29 SBCommandReturnObjectImpl
&operator=(const SBCommandReturnObjectImpl
&rhs
) {
30 SBCommandReturnObjectImpl
copy(rhs
);
31 std::swap(*this, copy
);
34 // rvalue ctor+assignment are not used by SBCommandReturnObject.
35 ~SBCommandReturnObjectImpl() {
40 CommandReturnObject
&operator*() const { return *m_ptr
; }
43 CommandReturnObject
*m_ptr
;
47 SBCommandReturnObject::SBCommandReturnObject()
48 : m_opaque_up(new SBCommandReturnObjectImpl()) {
49 LLDB_INSTRUMENT_VA(this);
52 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject
&ref
)
53 : m_opaque_up(new SBCommandReturnObjectImpl(ref
)) {
54 LLDB_INSTRUMENT_VA(this, ref
);
57 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject
&rhs
) {
58 LLDB_INSTRUMENT_VA(this, rhs
);
60 m_opaque_up
= clone(rhs
.m_opaque_up
);
63 SBCommandReturnObject
&SBCommandReturnObject::
64 operator=(const SBCommandReturnObject
&rhs
) {
65 LLDB_INSTRUMENT_VA(this, rhs
);
68 m_opaque_up
= clone(rhs
.m_opaque_up
);
72 SBCommandReturnObject::~SBCommandReturnObject() = default;
74 bool SBCommandReturnObject::IsValid() const {
75 LLDB_INSTRUMENT_VA(this);
76 return this->operator bool();
78 SBCommandReturnObject::operator bool() const {
79 LLDB_INSTRUMENT_VA(this);
81 // This method is not useful but it needs to stay to keep SB API stable.
85 const char *SBCommandReturnObject::GetOutput() {
86 LLDB_INSTRUMENT_VA(this);
88 ConstString
output(ref().GetOutputData());
89 return output
.AsCString(/*value_if_empty*/ "");
92 const char *SBCommandReturnObject::GetError() {
93 LLDB_INSTRUMENT_VA(this);
95 ConstString
output(ref().GetErrorData());
96 return output
.AsCString(/*value_if_empty*/ "");
99 size_t SBCommandReturnObject::GetOutputSize() {
100 LLDB_INSTRUMENT_VA(this);
102 return ref().GetOutputData().size();
105 size_t SBCommandReturnObject::GetErrorSize() {
106 LLDB_INSTRUMENT_VA(this);
108 return ref().GetErrorData().size();
111 size_t SBCommandReturnObject::PutOutput(FILE *fh
) {
112 LLDB_INSTRUMENT_VA(this, fh
);
114 size_t num_bytes
= GetOutputSize();
116 return ::fprintf(fh
, "%s", GetOutput());
121 size_t SBCommandReturnObject::PutOutput(FileSP file_sp
) {
122 LLDB_INSTRUMENT_VA(this, file_sp
);
125 return file_sp
->Printf("%s", GetOutput());
128 size_t SBCommandReturnObject::PutOutput(SBFile file
) {
129 LLDB_INSTRUMENT_VA(this, file
);
130 if (!file
.m_opaque_sp
)
132 return file
.m_opaque_sp
->Printf("%s", GetOutput());
135 size_t SBCommandReturnObject::PutError(FILE *fh
) {
136 LLDB_INSTRUMENT_VA(this, fh
);
138 size_t num_bytes
= GetErrorSize();
140 return ::fprintf(fh
, "%s", GetError());
145 size_t SBCommandReturnObject::PutError(FileSP file_sp
) {
146 LLDB_INSTRUMENT_VA(this, file_sp
);
149 return file_sp
->Printf("%s", GetError());
152 size_t SBCommandReturnObject::PutError(SBFile file
) {
153 LLDB_INSTRUMENT_VA(this, file
);
154 if (!file
.m_opaque_sp
)
156 return file
.m_opaque_sp
->Printf("%s", GetError());
159 void SBCommandReturnObject::Clear() {
160 LLDB_INSTRUMENT_VA(this);
165 lldb::ReturnStatus
SBCommandReturnObject::GetStatus() {
166 LLDB_INSTRUMENT_VA(this);
168 return ref().GetStatus();
171 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status
) {
172 LLDB_INSTRUMENT_VA(this, status
);
174 ref().SetStatus(status
);
177 bool SBCommandReturnObject::Succeeded() {
178 LLDB_INSTRUMENT_VA(this);
180 return ref().Succeeded();
183 bool SBCommandReturnObject::HasResult() {
184 LLDB_INSTRUMENT_VA(this);
186 return ref().HasResult();
189 void SBCommandReturnObject::AppendMessage(const char *message
) {
190 LLDB_INSTRUMENT_VA(this, message
);
192 ref().AppendMessage(message
);
195 void SBCommandReturnObject::AppendWarning(const char *message
) {
196 LLDB_INSTRUMENT_VA(this, message
);
198 ref().AppendWarning(message
);
201 CommandReturnObject
*SBCommandReturnObject::operator->() const {
202 return &**m_opaque_up
;
205 CommandReturnObject
*SBCommandReturnObject::get() const {
206 return &**m_opaque_up
;
209 CommandReturnObject
&SBCommandReturnObject::operator*() const {
210 return **m_opaque_up
;
213 CommandReturnObject
&SBCommandReturnObject::ref() const {
214 return **m_opaque_up
;
217 bool SBCommandReturnObject::GetDescription(SBStream
&description
) {
218 LLDB_INSTRUMENT_VA(this, description
);
220 Stream
&strm
= description
.ref();
222 description
.Printf("Error: ");
223 lldb::ReturnStatus status
= ref().GetStatus();
224 if (status
== lldb::eReturnStatusStarted
)
225 strm
.PutCString("Started");
226 else if (status
== lldb::eReturnStatusInvalid
)
227 strm
.PutCString("Invalid");
228 else if (ref().Succeeded())
229 strm
.PutCString("Success");
231 strm
.PutCString("Fail");
233 if (GetOutputSize() > 0)
234 strm
.Printf("\nOutput Message:\n%s", GetOutput());
236 if (GetErrorSize() > 0)
237 strm
.Printf("\nError Message:\n%s", GetError());
242 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh
) {
243 LLDB_INSTRUMENT_VA(this, fh
);
245 SetImmediateOutputFile(fh
, false);
248 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh
) {
249 LLDB_INSTRUMENT_VA(this, fh
);
251 SetImmediateErrorFile(fh
, false);
254 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh
,
255 bool transfer_ownership
) {
256 LLDB_INSTRUMENT_VA(this, fh
, transfer_ownership
);
257 FileSP file
= std::make_shared
<NativeFile
>(fh
, transfer_ownership
);
258 ref().SetImmediateOutputFile(file
);
261 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh
,
262 bool transfer_ownership
) {
263 LLDB_INSTRUMENT_VA(this, fh
, transfer_ownership
);
264 FileSP file
= std::make_shared
<NativeFile
>(fh
, transfer_ownership
);
265 ref().SetImmediateErrorFile(file
);
268 void SBCommandReturnObject::SetImmediateOutputFile(SBFile file
) {
269 LLDB_INSTRUMENT_VA(this, file
);
270 ref().SetImmediateOutputFile(file
.m_opaque_sp
);
273 void SBCommandReturnObject::SetImmediateErrorFile(SBFile file
) {
274 LLDB_INSTRUMENT_VA(this, file
);
275 ref().SetImmediateErrorFile(file
.m_opaque_sp
);
278 void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp
) {
279 LLDB_INSTRUMENT_VA(this, file_sp
);
280 SetImmediateOutputFile(SBFile(file_sp
));
283 void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp
) {
284 LLDB_INSTRUMENT_VA(this, file_sp
);
285 SetImmediateErrorFile(SBFile(file_sp
));
288 void SBCommandReturnObject::PutCString(const char *string
, int len
) {
289 LLDB_INSTRUMENT_VA(this, string
, len
);
291 if (len
== 0 || string
== nullptr || *string
== 0) {
293 } else if (len
> 0) {
294 std::string
buffer(string
, len
);
295 ref().AppendMessage(buffer
.c_str());
297 ref().AppendMessage(string
);
300 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate
) {
301 LLDB_INSTRUMENT_VA(this, only_if_no_immediate
);
303 if (!only_if_no_immediate
||
304 ref().GetImmediateOutputStream().get() == nullptr)
309 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate
) {
310 LLDB_INSTRUMENT_VA(this, only_if_no_immediate
);
312 if (!only_if_no_immediate
|| ref().GetImmediateErrorStream().get() == nullptr)
317 size_t SBCommandReturnObject::Printf(const char *format
, ...) {
319 va_start(args
, format
);
320 size_t result
= ref().GetOutputStream().PrintfVarArg(format
, args
);
325 void SBCommandReturnObject::SetError(lldb::SBError
&error
,
326 const char *fallback_error_cstr
) {
327 LLDB_INSTRUMENT_VA(this, error
, fallback_error_cstr
);
330 ref().SetError(error
.ref(), fallback_error_cstr
);
331 else if (fallback_error_cstr
)
332 ref().SetError(Status(), fallback_error_cstr
);
335 void SBCommandReturnObject::SetError(const char *error_cstr
) {
336 LLDB_INSTRUMENT_VA(this, error_cstr
);
339 ref().AppendError(error_cstr
);