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
24using namespace lldb;
25using namespace lldb_private;
26
27class lldb_private::SBCommandReturnObjectImpl {
28public:
29 SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {}
30 SBCommandReturnObjectImpl(CommandReturnObject &ref)
31 : m_ptr(&ref), m_owned(false) {}
32 SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs)
33 : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {}
34 SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) {
35 SBCommandReturnObjectImpl copy(rhs);
36 std::swap(a&: *this, b&: copy);
37 return *this;
38 }
39 // rvalue ctor+assignment are not used by SBCommandReturnObject.
40 ~SBCommandReturnObjectImpl() {
41 if (m_owned)
42 delete m_ptr;
43 }
44
45 CommandReturnObject &operator*() const { return *m_ptr; }
46
47private:
48 CommandReturnObject *m_ptr;
49 bool m_owned = true;
50};
51
52SBCommandReturnObject::SBCommandReturnObject()
53 : m_opaque_up(new SBCommandReturnObjectImpl()) {
54 LLDB_INSTRUMENT_VA(this);
55}
56
57SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref)
58 : m_opaque_up(new SBCommandReturnObjectImpl(ref)) {
59 LLDB_INSTRUMENT_VA(this, ref);
60}
61
62SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) {
63 LLDB_INSTRUMENT_VA(this, rhs);
64
65 m_opaque_up = clone(src: rhs.m_opaque_up);
66}
67
68SBCommandReturnObject &SBCommandReturnObject::
69operator=(const SBCommandReturnObject &rhs) {
70 LLDB_INSTRUMENT_VA(this, rhs);
71
72 if (this != &rhs)
73 m_opaque_up = clone(src: rhs.m_opaque_up);
74 return *this;
75}
76
77SBCommandReturnObject::~SBCommandReturnObject() = default;
78
79bool SBCommandReturnObject::IsValid() const {
80 LLDB_INSTRUMENT_VA(this);
81 return this->operator bool();
82}
83SBCommandReturnObject::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
90const char *SBCommandReturnObject::GetCommand() {
91 LLDB_INSTRUMENT_VA(this);
92
93 ConstString output(ref().GetCommand());
94 return output.AsCString(/*value_if_empty*/ "");
95}
96
97const char *SBCommandReturnObject::GetOutput() {
98 LLDB_INSTRUMENT_VA(this);
99
100 ConstString output(ref().GetOutputString());
101 return output.AsCString(/*value_if_empty*/ "");
102}
103
104const char *SBCommandReturnObject::GetError() {
105 LLDB_INSTRUMENT_VA(this);
106
107 ConstString output(ref().GetErrorString());
108 return output.AsCString(/*value_if_empty*/ "");
109}
110
111SBStructuredData 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
120size_t SBCommandReturnObject::GetOutputSize() {
121 LLDB_INSTRUMENT_VA(this);
122
123 return ref().GetOutputString().size();
124}
125
126size_t SBCommandReturnObject::GetErrorSize() {
127 LLDB_INSTRUMENT_VA(this);
128
129 return ref().GetErrorString().size();
130}
131
132size_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(stream: fh, format: "%s", GetOutput());
138 }
139 return 0;
140}
141
142size_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(format: "%s", GetOutput());
147}
148
149size_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(format: "%s", GetOutput());
154}
155
156size_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(stream: fh, format: "%s", GetError());
162 }
163 return 0;
164}
165
166size_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(format: "%s", GetError());
171}
172
173size_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(format: "%s", GetError());
178}
179
180void SBCommandReturnObject::Clear() {
181 LLDB_INSTRUMENT_VA(this);
182
183 ref().Clear();
184}
185
186lldb::ReturnStatus SBCommandReturnObject::GetStatus() {
187 LLDB_INSTRUMENT_VA(this);
188
189 return ref().GetStatus();
190}
191
192void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) {
193 LLDB_INSTRUMENT_VA(this, status);
194
195 ref().SetStatus(status);
196}
197
198bool SBCommandReturnObject::Succeeded() {
199 LLDB_INSTRUMENT_VA(this);
200
201 return ref().Succeeded();
202}
203
204bool SBCommandReturnObject::HasResult() {
205 LLDB_INSTRUMENT_VA(this);
206
207 return ref().HasResult();
208}
209
210void SBCommandReturnObject::AppendMessage(const char *message) {
211 LLDB_INSTRUMENT_VA(this, message);
212
213 ref().AppendMessage(in_string: message);
214}
215
216void SBCommandReturnObject::AppendWarning(const char *message) {
217 LLDB_INSTRUMENT_VA(this, message);
218
219 ref().AppendWarning(in_string: message);
220}
221
222CommandReturnObject *SBCommandReturnObject::operator->() const {
223 return &**m_opaque_up;
224}
225
226CommandReturnObject *SBCommandReturnObject::get() const {
227 return &**m_opaque_up;
228}
229
230CommandReturnObject &SBCommandReturnObject::operator*() const {
231 return **m_opaque_up;
232}
233
234CommandReturnObject &SBCommandReturnObject::ref() const {
235 return **m_opaque_up;
236}
237
238bool SBCommandReturnObject::GetDescription(SBStream &description) {
239 LLDB_INSTRUMENT_VA(this, description);
240
241 Stream &strm = description.ref();
242
243 description.Printf(format: "Error: ");
244 lldb::ReturnStatus status = ref().GetStatus();
245 if (status == lldb::eReturnStatusStarted)
246 strm.PutCString(cstr: "Started");
247 else if (status == lldb::eReturnStatusInvalid)
248 strm.PutCString(cstr: "Invalid");
249 else if (ref().Succeeded())
250 strm.PutCString(cstr: "Success");
251 else
252 strm.PutCString(cstr: "Fail");
253
254 if (GetOutputSize() > 0)
255 strm.Printf(format: "\nOutput Message:\n%s", GetOutput());
256
257 if (GetErrorSize() > 0)
258 strm.Printf(format: "\nError Message:\n%s", GetError());
259
260 return true;
261}
262
263void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) {
264 LLDB_INSTRUMENT_VA(this, fh);
265
266 SetImmediateOutputFile(fh, transfer_ownership: false);
267}
268
269void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) {
270 LLDB_INSTRUMENT_VA(this, fh);
271
272 SetImmediateErrorFile(fh, transfer_ownership: false);
273}
274
275void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh,
276 bool transfer_ownership) {
277 LLDB_INSTRUMENT_VA(this, fh, transfer_ownership);
278 FileSP file = std::make_shared<NativeFile>(args&: fh, args&: transfer_ownership);
279 ref().SetImmediateOutputFile(file);
280}
281
282void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
283 bool transfer_ownership) {
284 LLDB_INSTRUMENT_VA(this, fh, transfer_ownership);
285 FileSP file = std::make_shared<NativeFile>(args&: fh, args&: transfer_ownership);
286 ref().SetImmediateErrorFile(file);
287}
288
289void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) {
290 LLDB_INSTRUMENT_VA(this, file);
291 ref().SetImmediateOutputFile(file.m_opaque_sp);
292}
293
294void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) {
295 LLDB_INSTRUMENT_VA(this, file);
296 ref().SetImmediateErrorFile(file.m_opaque_sp);
297}
298
299void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) {
300 LLDB_INSTRUMENT_VA(this, file_sp);
301 SetImmediateOutputFile(SBFile(file_sp));
302}
303
304void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) {
305 LLDB_INSTRUMENT_VA(this, file_sp);
306 SetImmediateErrorFile(SBFile(file_sp));
307}
308
309void 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(in_string: buffer.c_str());
317 } else
318 ref().AppendMessage(in_string: string);
319}
320
321const 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
330const 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
338size_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
346void 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(str: fallback_error_cstr));
354}
355
356void SBCommandReturnObject::SetError(const char *error_cstr) {
357 LLDB_INSTRUMENT_VA(this, error_cstr);
358
359 if (error_cstr)
360 ref().AppendError(in_string: error_cstr);
361}
362
363SBValueList
364SBCommandReturnObject::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(sp: value_object_sp, use_dynamic);
372 value_list.Append(val_obj: value_sb);
373 }
374
375 return value_list;
376}
377

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/source/API/SBCommandReturnObject.cpp