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: |
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 | |
47 | private: |
48 | CommandReturnObject *m_ptr; |
49 | bool m_owned = true; |
50 | }; |
51 | |
52 | SBCommandReturnObject::SBCommandReturnObject() |
53 | : m_opaque_up(new SBCommandReturnObjectImpl()) { |
54 | LLDB_INSTRUMENT_VA(this); |
55 | } |
56 | |
57 | SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref) |
58 | : m_opaque_up(new SBCommandReturnObjectImpl(ref)) { |
59 | LLDB_INSTRUMENT_VA(this, ref); |
60 | } |
61 | |
62 | SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) { |
63 | LLDB_INSTRUMENT_VA(this, rhs); |
64 | |
65 | m_opaque_up = clone(src: rhs.m_opaque_up); |
66 | } |
67 | |
68 | SBCommandReturnObject &SBCommandReturnObject:: |
69 | operator=(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 | |
77 | SBCommandReturnObject::~SBCommandReturnObject() = default; |
78 | |
79 | bool SBCommandReturnObject::IsValid() const { |
80 | LLDB_INSTRUMENT_VA(this); |
81 | return this->operator bool(); |
82 | } |
83 | 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 | |
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 | |
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 | |
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 | |
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 | |
120 | size_t SBCommandReturnObject::GetOutputSize() { |
121 | LLDB_INSTRUMENT_VA(this); |
122 | |
123 | return ref().GetOutputString().size(); |
124 | } |
125 | |
126 | size_t SBCommandReturnObject::GetErrorSize() { |
127 | LLDB_INSTRUMENT_VA(this); |
128 | |
129 | return ref().GetErrorString().size(); |
130 | } |
131 | |
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(stream: fh, format: "%s", GetOutput()); |
138 | } |
139 | return 0; |
140 | } |
141 | |
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(format: "%s", GetOutput()); |
147 | } |
148 | |
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(format: "%s", GetOutput()); |
154 | } |
155 | |
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(stream: fh, format: "%s", GetError()); |
162 | } |
163 | return 0; |
164 | } |
165 | |
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(format: "%s", GetError()); |
171 | } |
172 | |
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(format: "%s", GetError()); |
178 | } |
179 | |
180 | void SBCommandReturnObject::Clear() { |
181 | LLDB_INSTRUMENT_VA(this); |
182 | |
183 | ref().Clear(); |
184 | } |
185 | |
186 | lldb::ReturnStatus SBCommandReturnObject::GetStatus() { |
187 | LLDB_INSTRUMENT_VA(this); |
188 | |
189 | return ref().GetStatus(); |
190 | } |
191 | |
192 | void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { |
193 | LLDB_INSTRUMENT_VA(this, status); |
194 | |
195 | ref().SetStatus(status); |
196 | } |
197 | |
198 | bool SBCommandReturnObject::Succeeded() { |
199 | LLDB_INSTRUMENT_VA(this); |
200 | |
201 | return ref().Succeeded(); |
202 | } |
203 | |
204 | bool SBCommandReturnObject::HasResult() { |
205 | LLDB_INSTRUMENT_VA(this); |
206 | |
207 | return ref().HasResult(); |
208 | } |
209 | |
210 | void SBCommandReturnObject::AppendMessage(const char *message) { |
211 | LLDB_INSTRUMENT_VA(this, message); |
212 | |
213 | ref().AppendMessage(in_string: message); |
214 | } |
215 | |
216 | void SBCommandReturnObject::AppendWarning(const char *message) { |
217 | LLDB_INSTRUMENT_VA(this, message); |
218 | |
219 | ref().AppendWarning(in_string: message); |
220 | } |
221 | |
222 | CommandReturnObject *SBCommandReturnObject::operator->() const { |
223 | return &**m_opaque_up; |
224 | } |
225 | |
226 | CommandReturnObject *SBCommandReturnObject::get() const { |
227 | return &**m_opaque_up; |
228 | } |
229 | |
230 | CommandReturnObject &SBCommandReturnObject::operator*() const { |
231 | return **m_opaque_up; |
232 | } |
233 | |
234 | CommandReturnObject &SBCommandReturnObject::ref() const { |
235 | return **m_opaque_up; |
236 | } |
237 | |
238 | bool 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 | |
263 | void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { |
264 | LLDB_INSTRUMENT_VA(this, fh); |
265 | |
266 | SetImmediateOutputFile(fh, transfer_ownership: false); |
267 | } |
268 | |
269 | void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { |
270 | LLDB_INSTRUMENT_VA(this, fh); |
271 | |
272 | SetImmediateErrorFile(fh, transfer_ownership: false); |
273 | } |
274 | |
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>(args&: fh, args&: transfer_ownership); |
279 | ref().SetImmediateOutputFile(file); |
280 | } |
281 | |
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>(args&: fh, args&: transfer_ownership); |
286 | ref().SetImmediateErrorFile(file); |
287 | } |
288 | |
289 | void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) { |
290 | LLDB_INSTRUMENT_VA(this, file); |
291 | ref().SetImmediateOutputFile(file.m_opaque_sp); |
292 | } |
293 | |
294 | void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) { |
295 | LLDB_INSTRUMENT_VA(this, file); |
296 | ref().SetImmediateErrorFile(file.m_opaque_sp); |
297 | } |
298 | |
299 | void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) { |
300 | LLDB_INSTRUMENT_VA(this, file_sp); |
301 | SetImmediateOutputFile(SBFile(file_sp)); |
302 | } |
303 | |
304 | void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) { |
305 | LLDB_INSTRUMENT_VA(this, file_sp); |
306 | SetImmediateErrorFile(SBFile(file_sp)); |
307 | } |
308 | |
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(in_string: buffer.c_str()); |
317 | } else |
318 | ref().AppendMessage(in_string: string); |
319 | } |
320 | |
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 | |
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 | |
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 | |
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(str: fallback_error_cstr)); |
354 | } |
355 | |
356 | void 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 | |
363 | SBValueList |
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(sp: value_object_sp, use_dynamic); |
372 | value_list.Append(val_obj: value_sb); |
373 | } |
374 | |
375 | return value_list; |
376 | } |
377 |
Definitions
- SBCommandReturnObjectImpl
- SBCommandReturnObjectImpl
- SBCommandReturnObjectImpl
- SBCommandReturnObjectImpl
- operator=
- ~SBCommandReturnObjectImpl
- operator*
- SBCommandReturnObject
- SBCommandReturnObject
- SBCommandReturnObject
- operator=
- ~SBCommandReturnObject
- IsValid
- operator bool
- GetCommand
- GetOutput
- GetError
- GetErrorData
- GetOutputSize
- GetErrorSize
- PutOutput
- PutOutput
- PutOutput
- PutError
- PutError
- PutError
- Clear
- GetStatus
- SetStatus
- Succeeded
- HasResult
- AppendMessage
- AppendWarning
- operator->
- get
- operator*
- ref
- GetDescription
- SetImmediateOutputFile
- SetImmediateErrorFile
- SetImmediateOutputFile
- SetImmediateErrorFile
- SetImmediateOutputFile
- SetImmediateErrorFile
- SetImmediateOutputFile
- SetImmediateErrorFile
- PutCString
- GetOutput
- GetError
- Printf
- SetError
- SetError
Improve your Profiling and Debugging skills
Find out more