1 //===-- SBCommandReturnObject.cpp -------------------------------*- C++ -*-===// 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 "SBReproducerPrivate.h" 11 #include "Utils.h" 12 #include "lldb/API/SBError.h" 13 #include "lldb/API/SBStream.h" 14 #include "lldb/Interpreter/CommandReturnObject.h" 15 #include "lldb/Utility/ConstString.h" 16 #include "lldb/Utility/Status.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 SBCommandReturnObject::SBCommandReturnObject() 22 : m_opaque_up(new CommandReturnObject()) { 23 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject); 24 } 25 26 SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) 27 : m_opaque_up() { 28 LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, 29 (const lldb::SBCommandReturnObject &), rhs); 30 31 m_opaque_up = clone(rhs.m_opaque_up); 32 } 33 34 SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject *ptr) 35 : m_opaque_up(ptr) { 36 LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, 37 (lldb_private::CommandReturnObject *), ptr); 38 } 39 40 SBCommandReturnObject::~SBCommandReturnObject() = default; 41 42 CommandReturnObject *SBCommandReturnObject::Release() { 43 LLDB_RECORD_METHOD_NO_ARGS(lldb_private::CommandReturnObject *, 44 SBCommandReturnObject, Release); 45 46 return m_opaque_up.release(); 47 } 48 49 const SBCommandReturnObject &SBCommandReturnObject:: 50 operator=(const SBCommandReturnObject &rhs) { 51 LLDB_RECORD_METHOD( 52 const lldb::SBCommandReturnObject &, 53 SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &), 54 rhs); 55 56 if (this != &rhs) 57 m_opaque_up = clone(rhs.m_opaque_up); 58 return *this; 59 } 60 61 bool SBCommandReturnObject::IsValid() const { 62 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid); 63 return this->operator bool(); 64 } 65 SBCommandReturnObject::operator bool() const { 66 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool); 67 68 return m_opaque_up != nullptr; 69 } 70 71 const char *SBCommandReturnObject::GetOutput() { 72 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput); 73 74 if (m_opaque_up) { 75 llvm::StringRef output = m_opaque_up->GetOutputData(); 76 ConstString result(output.empty() ? llvm::StringRef("") : output); 77 78 return result.AsCString(); 79 } 80 81 return nullptr; 82 } 83 84 const char *SBCommandReturnObject::GetError() { 85 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError); 86 87 if (m_opaque_up) { 88 llvm::StringRef output = m_opaque_up->GetErrorData(); 89 ConstString result(output.empty() ? llvm::StringRef("") : output); 90 return result.AsCString(); 91 } 92 93 return nullptr; 94 } 95 96 size_t SBCommandReturnObject::GetOutputSize() { 97 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize); 98 99 return (m_opaque_up ? m_opaque_up->GetOutputData().size() : 0); 100 } 101 102 size_t SBCommandReturnObject::GetErrorSize() { 103 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize); 104 105 return (m_opaque_up ? m_opaque_up->GetErrorData().size() : 0); 106 } 107 108 size_t SBCommandReturnObject::PutOutput(FILE *fh) { 109 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh); 110 111 if (fh) { 112 size_t num_bytes = GetOutputSize(); 113 if (num_bytes) 114 return ::fprintf(fh, "%s", GetOutput()); 115 } 116 return 0; 117 } 118 119 size_t SBCommandReturnObject::PutError(FILE *fh) { 120 LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *), fh); 121 122 if (fh) { 123 size_t num_bytes = GetErrorSize(); 124 if (num_bytes) 125 return ::fprintf(fh, "%s", GetError()); 126 } 127 return 0; 128 } 129 130 void SBCommandReturnObject::Clear() { 131 LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear); 132 133 if (m_opaque_up) 134 m_opaque_up->Clear(); 135 } 136 137 lldb::ReturnStatus SBCommandReturnObject::GetStatus() { 138 LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject, 139 GetStatus); 140 141 return (m_opaque_up ? m_opaque_up->GetStatus() : lldb::eReturnStatusInvalid); 142 } 143 144 void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { 145 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus, 146 (lldb::ReturnStatus), status); 147 148 if (m_opaque_up) 149 m_opaque_up->SetStatus(status); 150 } 151 152 bool SBCommandReturnObject::Succeeded() { 153 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded); 154 155 return (m_opaque_up ? m_opaque_up->Succeeded() : false); 156 } 157 158 bool SBCommandReturnObject::HasResult() { 159 LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult); 160 161 return (m_opaque_up ? m_opaque_up->HasResult() : false); 162 } 163 164 void SBCommandReturnObject::AppendMessage(const char *message) { 165 LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *), 166 message); 167 168 if (m_opaque_up) 169 m_opaque_up->AppendMessage(message); 170 } 171 172 void SBCommandReturnObject::AppendWarning(const char *message) { 173 LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *), 174 message); 175 176 if (m_opaque_up) 177 m_opaque_up->AppendWarning(message); 178 } 179 180 CommandReturnObject *SBCommandReturnObject::operator->() const { 181 return m_opaque_up.get(); 182 } 183 184 CommandReturnObject *SBCommandReturnObject::get() const { 185 return m_opaque_up.get(); 186 } 187 188 CommandReturnObject &SBCommandReturnObject::operator*() const { 189 assert(m_opaque_up.get()); 190 return *(m_opaque_up.get()); 191 } 192 193 CommandReturnObject &SBCommandReturnObject::ref() const { 194 assert(m_opaque_up.get()); 195 return *(m_opaque_up.get()); 196 } 197 198 void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) { 199 if (m_opaque_up) 200 m_opaque_up.reset(ptr); 201 } 202 203 bool SBCommandReturnObject::GetDescription(SBStream &description) { 204 LLDB_RECORD_METHOD(bool, SBCommandReturnObject, GetDescription, 205 (lldb::SBStream &), description); 206 207 Stream &strm = description.ref(); 208 209 if (m_opaque_up) { 210 description.Printf("Error: "); 211 lldb::ReturnStatus status = m_opaque_up->GetStatus(); 212 if (status == lldb::eReturnStatusStarted) 213 strm.PutCString("Started"); 214 else if (status == lldb::eReturnStatusInvalid) 215 strm.PutCString("Invalid"); 216 else if (m_opaque_up->Succeeded()) 217 strm.PutCString("Success"); 218 else 219 strm.PutCString("Fail"); 220 221 if (GetOutputSize() > 0) 222 strm.Printf("\nOutput Message:\n%s", GetOutput()); 223 224 if (GetErrorSize() > 0) 225 strm.Printf("\nError Message:\n%s", GetError()); 226 } else 227 strm.PutCString("No value"); 228 229 return true; 230 } 231 232 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { 233 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 234 (FILE *), fh); 235 236 SetImmediateOutputFile(fh, false); 237 } 238 239 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { 240 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 241 (FILE *), fh); 242 243 SetImmediateErrorFile(fh, false); 244 } 245 246 void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, 247 bool transfer_ownership) { 248 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 249 (FILE *, bool), fh, transfer_ownership); 250 251 if (m_opaque_up) 252 m_opaque_up->SetImmediateOutputFile(fh, transfer_ownership); 253 } 254 255 void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, 256 bool transfer_ownership) { 257 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 258 (FILE *, bool), fh, transfer_ownership); 259 260 if (m_opaque_up) 261 m_opaque_up->SetImmediateErrorFile(fh, transfer_ownership); 262 } 263 264 void SBCommandReturnObject::PutCString(const char *string, int len) { 265 LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString, 266 (const char *, int), string, len); 267 268 if (m_opaque_up) { 269 if (len == 0 || string == nullptr || *string == 0) { 270 return; 271 } else if (len > 0) { 272 std::string buffer(string, len); 273 m_opaque_up->AppendMessage(buffer.c_str()); 274 } else 275 m_opaque_up->AppendMessage(string); 276 } 277 } 278 279 const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) { 280 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool), 281 only_if_no_immediate); 282 283 if (!m_opaque_up) 284 return nullptr; 285 if (!only_if_no_immediate || 286 m_opaque_up->GetImmediateOutputStream().get() == nullptr) 287 return GetOutput(); 288 return nullptr; 289 } 290 291 const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) { 292 LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool), 293 only_if_no_immediate); 294 295 if (!m_opaque_up) 296 return nullptr; 297 if (!only_if_no_immediate || 298 m_opaque_up->GetImmediateErrorStream().get() == nullptr) 299 return GetError(); 300 return nullptr; 301 } 302 303 size_t SBCommandReturnObject::Printf(const char *format, ...) { 304 if (m_opaque_up) { 305 va_list args; 306 va_start(args, format); 307 size_t result = m_opaque_up->GetOutputStream().PrintfVarArg(format, args); 308 va_end(args); 309 return result; 310 } 311 return 0; 312 } 313 314 void SBCommandReturnObject::SetError(lldb::SBError &error, 315 const char *fallback_error_cstr) { 316 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, 317 (lldb::SBError &, const char *), error, 318 fallback_error_cstr); 319 320 if (m_opaque_up) { 321 if (error.IsValid()) 322 m_opaque_up->SetError(error.ref(), fallback_error_cstr); 323 else if (fallback_error_cstr) 324 m_opaque_up->SetError(Status(), fallback_error_cstr); 325 } 326 } 327 328 void SBCommandReturnObject::SetError(const char *error_cstr) { 329 LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *), 330 error_cstr); 331 332 if (m_opaque_up && error_cstr) 333 m_opaque_up->SetError(error_cstr); 334 } 335 336 namespace lldb_private { 337 namespace repro { 338 339 template <> 340 void RegisterMethods<SBCommandReturnObject>(Registry &R) { 341 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ()); 342 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, 343 (const lldb::SBCommandReturnObject &)); 344 LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, 345 (lldb_private::CommandReturnObject *)); 346 LLDB_REGISTER_METHOD(lldb_private::CommandReturnObject *, 347 SBCommandReturnObject, Release, ()); 348 LLDB_REGISTER_METHOD( 349 const lldb::SBCommandReturnObject &, 350 SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &)); 351 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ()); 352 LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ()); 353 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, ()); 354 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, ()); 355 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetOutputSize, ()); 356 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ()); 357 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *)); 358 LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *)); 359 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ()); 360 LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus, 361 ()); 362 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetStatus, 363 (lldb::ReturnStatus)); 364 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, Succeeded, ()); 365 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, HasResult, ()); 366 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendMessage, 367 (const char *)); 368 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendWarning, 369 (const char *)); 370 LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, GetDescription, 371 (lldb::SBStream &)); 372 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 373 (FILE *)); 374 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 375 (FILE *)); 376 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, 377 (FILE *, bool)); 378 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, 379 (FILE *, bool)); 380 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, PutCString, 381 (const char *, int)); 382 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, 383 (bool)); 384 LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, (bool)); 385 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, 386 (lldb::SBError &, const char *)); 387 LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, (const char *)); 388 } 389 390 } 391 } 392