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