| //===-- SBCommandReturnObject.cpp -----------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "lldb/API/SBCommandReturnObject.h" |
| #include "SBReproducerPrivate.h" |
| #include "Utils.h" |
| #include "lldb/API/SBError.h" |
| #include "lldb/API/SBFile.h" |
| #include "lldb/API/SBStream.h" |
| #include "lldb/Interpreter/CommandReturnObject.h" |
| #include "lldb/Utility/ConstString.h" |
| #include "lldb/Utility/Status.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| class lldb_private::SBCommandReturnObjectImpl { |
| public: |
| SBCommandReturnObjectImpl() : m_ptr(new CommandReturnObject(false)) {} |
| SBCommandReturnObjectImpl(CommandReturnObject &ref) |
| : m_ptr(&ref), m_owned(false) {} |
| SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs) |
| : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {} |
| SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) { |
| SBCommandReturnObjectImpl copy(rhs); |
| std::swap(*this, copy); |
| return *this; |
| } |
| // rvalue ctor+assignment are not used by SBCommandReturnObject. |
| ~SBCommandReturnObjectImpl() { |
| if (m_owned) |
| delete m_ptr; |
| } |
| |
| CommandReturnObject &operator*() const { return *m_ptr; } |
| |
| private: |
| CommandReturnObject *m_ptr; |
| bool m_owned = true; |
| }; |
| |
| SBCommandReturnObject::SBCommandReturnObject() |
| : m_opaque_up(new SBCommandReturnObjectImpl()) { |
| LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject); |
| } |
| |
| SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref) |
| : m_opaque_up(new SBCommandReturnObjectImpl(ref)) { |
| LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, |
| (lldb_private::CommandReturnObject &), ref); |
| } |
| |
| SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) |
| : m_opaque_up() { |
| LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, |
| (const lldb::SBCommandReturnObject &), rhs); |
| |
| m_opaque_up = clone(rhs.m_opaque_up); |
| } |
| |
| SBCommandReturnObject &SBCommandReturnObject:: |
| operator=(const SBCommandReturnObject &rhs) { |
| LLDB_RECORD_METHOD( |
| lldb::SBCommandReturnObject &, |
| SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &), |
| rhs); |
| |
| if (this != &rhs) |
| m_opaque_up = clone(rhs.m_opaque_up); |
| return LLDB_RECORD_RESULT(*this); |
| } |
| |
| SBCommandReturnObject::~SBCommandReturnObject() = default; |
| |
| bool SBCommandReturnObject::IsValid() const { |
| LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid); |
| return this->operator bool(); |
| } |
| SBCommandReturnObject::operator bool() const { |
| LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool); |
| |
| // This method is not useful but it needs to stay to keep SB API stable. |
| return true; |
| } |
| |
| const char *SBCommandReturnObject::GetOutput() { |
| LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput); |
| |
| ConstString output(ref().GetOutputData()); |
| return output.AsCString(/*value_if_empty*/ ""); |
| } |
| |
| const char *SBCommandReturnObject::GetError() { |
| LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError); |
| |
| ConstString output(ref().GetErrorData()); |
| return output.AsCString(/*value_if_empty*/ ""); |
| } |
| |
| size_t SBCommandReturnObject::GetOutputSize() { |
| LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize); |
| |
| return ref().GetOutputData().size(); |
| } |
| |
| size_t SBCommandReturnObject::GetErrorSize() { |
| LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize); |
| |
| return ref().GetErrorData().size(); |
| } |
| |
| size_t SBCommandReturnObject::PutOutput(FILE *fh) { |
| LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh); |
| if (fh) { |
| size_t num_bytes = GetOutputSize(); |
| if (num_bytes) |
| return ::fprintf(fh, "%s", GetOutput()); |
| } |
| return 0; |
| } |
| |
| size_t SBCommandReturnObject::PutOutput(FileSP file_sp) { |
| LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP), |
| file_sp); |
| if (!file_sp) |
| return 0; |
| return file_sp->Printf("%s", GetOutput()); |
| } |
| |
| size_t SBCommandReturnObject::PutOutput(SBFile file) { |
| LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile), file); |
| if (!file.m_opaque_sp) |
| return 0; |
| return file.m_opaque_sp->Printf("%s", GetOutput()); |
| } |
| |
| size_t SBCommandReturnObject::PutError(FILE *fh) { |
| LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutError, (FILE *), fh); |
| if (fh) { |
| size_t num_bytes = GetErrorSize(); |
| if (num_bytes) |
| return ::fprintf(fh, "%s", GetError()); |
| } |
| return 0; |
| } |
| |
| size_t SBCommandReturnObject::PutError(FileSP file_sp) { |
| LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP), |
| file_sp); |
| if (!file_sp) |
| return 0; |
| return file_sp->Printf("%s", GetError()); |
| } |
| |
| size_t SBCommandReturnObject::PutError(SBFile file) { |
| LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile), file); |
| if (!file.m_opaque_sp) |
| return 0; |
| return file.m_opaque_sp->Printf("%s", GetError()); |
| } |
| |
| void SBCommandReturnObject::Clear() { |
| LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear); |
| |
| ref().Clear(); |
| } |
| |
| lldb::ReturnStatus SBCommandReturnObject::GetStatus() { |
| LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject, |
| GetStatus); |
| |
| return ref().GetStatus(); |
| } |
| |
| void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus, |
| (lldb::ReturnStatus), status); |
| |
| ref().SetStatus(status); |
| } |
| |
| bool SBCommandReturnObject::Succeeded() { |
| LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded); |
| |
| return ref().Succeeded(); |
| } |
| |
| bool SBCommandReturnObject::HasResult() { |
| LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult); |
| |
| return ref().HasResult(); |
| } |
| |
| void SBCommandReturnObject::AppendMessage(const char *message) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *), |
| message); |
| |
| ref().AppendMessage(message); |
| } |
| |
| void SBCommandReturnObject::AppendWarning(const char *message) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *), |
| message); |
| |
| ref().AppendWarning(message); |
| } |
| |
| CommandReturnObject *SBCommandReturnObject::operator->() const { |
| return &**m_opaque_up; |
| } |
| |
| CommandReturnObject *SBCommandReturnObject::get() const { |
| return &**m_opaque_up; |
| } |
| |
| CommandReturnObject &SBCommandReturnObject::operator*() const { |
| return **m_opaque_up; |
| } |
| |
| CommandReturnObject &SBCommandReturnObject::ref() const { |
| return **m_opaque_up; |
| } |
| |
| bool SBCommandReturnObject::GetDescription(SBStream &description) { |
| LLDB_RECORD_METHOD(bool, SBCommandReturnObject, GetDescription, |
| (lldb::SBStream &), description); |
| |
| Stream &strm = description.ref(); |
| |
| description.Printf("Error: "); |
| lldb::ReturnStatus status = ref().GetStatus(); |
| if (status == lldb::eReturnStatusStarted) |
| strm.PutCString("Started"); |
| else if (status == lldb::eReturnStatusInvalid) |
| strm.PutCString("Invalid"); |
| else if (ref().Succeeded()) |
| strm.PutCString("Success"); |
| else |
| strm.PutCString("Fail"); |
| |
| if (GetOutputSize() > 0) |
| strm.Printf("\nOutput Message:\n%s", GetOutput()); |
| |
| if (GetErrorSize() > 0) |
| strm.Printf("\nError Message:\n%s", GetError()); |
| |
| return true; |
| } |
| |
| void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { |
| LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FILE *), fh); |
| |
| SetImmediateOutputFile(fh, false); |
| } |
| |
| void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { |
| LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FILE *), fh); |
| |
| SetImmediateErrorFile(fh, false); |
| } |
| |
| void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, |
| bool transfer_ownership) { |
| LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FILE *, bool), fh, transfer_ownership); |
| FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership); |
| ref().SetImmediateOutputFile(file); |
| } |
| |
| void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, |
| bool transfer_ownership) { |
| LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FILE *, bool), fh, transfer_ownership); |
| FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership); |
| ref().SetImmediateErrorFile(file); |
| } |
| |
| void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (SBFile), file); |
| ref().SetImmediateOutputFile(file.m_opaque_sp); |
| } |
| |
| void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (SBFile), file); |
| ref().SetImmediateErrorFile(file.m_opaque_sp); |
| } |
| |
| void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FileSP), file_sp); |
| SetImmediateOutputFile(SBFile(file_sp)); |
| } |
| |
| void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FileSP), file_sp); |
| SetImmediateErrorFile(SBFile(file_sp)); |
| } |
| |
| void SBCommandReturnObject::PutCString(const char *string, int len) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString, |
| (const char *, int), string, len); |
| |
| if (len == 0 || string == nullptr || *string == 0) { |
| return; |
| } else if (len > 0) { |
| std::string buffer(string, len); |
| ref().AppendMessage(buffer.c_str()); |
| } else |
| ref().AppendMessage(string); |
| } |
| |
| const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) { |
| LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool), |
| only_if_no_immediate); |
| |
| if (!only_if_no_immediate || |
| ref().GetImmediateOutputStream().get() == nullptr) |
| return GetOutput(); |
| return nullptr; |
| } |
| |
| const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) { |
| LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool), |
| only_if_no_immediate); |
| |
| if (!only_if_no_immediate || ref().GetImmediateErrorStream().get() == nullptr) |
| return GetError(); |
| return nullptr; |
| } |
| |
| size_t SBCommandReturnObject::Printf(const char *format, ...) { |
| va_list args; |
| va_start(args, format); |
| size_t result = ref().GetOutputStream().PrintfVarArg(format, args); |
| va_end(args); |
| return result; |
| } |
| |
| void SBCommandReturnObject::SetError(lldb::SBError &error, |
| const char *fallback_error_cstr) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, |
| (lldb::SBError &, const char *), error, |
| fallback_error_cstr); |
| |
| if (error.IsValid()) |
| ref().SetError(error.ref(), fallback_error_cstr); |
| else if (fallback_error_cstr) |
| ref().SetError(Status(), fallback_error_cstr); |
| } |
| |
| void SBCommandReturnObject::SetError(const char *error_cstr) { |
| LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *), |
| error_cstr); |
| |
| if (error_cstr) |
| ref().AppendError(error_cstr); |
| } |
| |
| namespace lldb_private { |
| namespace repro { |
| |
| template <> |
| void RegisterMethods<SBCommandReturnObject>(Registry &R) { |
| LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ()); |
| LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, |
| (lldb_private::CommandReturnObject &)); |
| LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, |
| (const lldb::SBCommandReturnObject &)); |
| LLDB_REGISTER_METHOD( |
| lldb::SBCommandReturnObject &, |
| SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &)); |
| LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ()); |
| LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ()); |
| LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, ()); |
| LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, ()); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetOutputSize, ()); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ()); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *)); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *)); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile)); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile)); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP)); |
| LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ()); |
| LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus, |
| ()); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetStatus, |
| (lldb::ReturnStatus)); |
| LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, Succeeded, ()); |
| LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, HasResult, ()); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendMessage, |
| (const char *)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, AppendWarning, |
| (const char *)); |
| LLDB_REGISTER_METHOD(bool, SBCommandReturnObject, GetDescription, |
| (lldb::SBStream &)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FILE *)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FILE *)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (SBFile)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (SBFile)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FileSP)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FileSP)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, |
| (FILE *, bool)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, |
| (FILE *, bool)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, PutCString, |
| (const char *, int)); |
| LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetOutput, |
| (bool)); |
| LLDB_REGISTER_METHOD(const char *, SBCommandReturnObject, GetError, (bool)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, |
| (lldb::SBError &, const char *)); |
| LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetError, (const char *)); |
| } |
| |
| } |
| } |