15ffd83dbSDimitry Andric //===-- SBError.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/API/SBError.h"
100b57cec5SDimitry Andric #include "Utils.h"
110b57cec5SDimitry Andric #include "lldb/API/SBStream.h"
1204eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h"
130b57cec5SDimitry Andric #include "lldb/Utility/Status.h"
140b57cec5SDimitry Andric 
15fe6060f1SDimitry Andric #include <cstdarg>
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric using namespace lldb;
180b57cec5SDimitry Andric using namespace lldb_private;
190b57cec5SDimitry Andric 
SBError()2004eeddc0SDimitry Andric SBError::SBError() { LLDB_INSTRUMENT_VA(this); }
210b57cec5SDimitry Andric 
SBError(const SBError & rhs)2204eeddc0SDimitry Andric SBError::SBError(const SBError &rhs) {
2304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric   m_opaque_up = clone(rhs.m_opaque_up);
260b57cec5SDimitry Andric }
270b57cec5SDimitry Andric 
SBError(const char * message)28*fe013be4SDimitry Andric SBError::SBError(const char *message) {
29*fe013be4SDimitry Andric   LLDB_INSTRUMENT_VA(this, message);
30*fe013be4SDimitry Andric 
31*fe013be4SDimitry Andric   SetErrorString(message);
32*fe013be4SDimitry Andric }
33*fe013be4SDimitry Andric 
SBError(const lldb_private::Status & status)34bdd1243dSDimitry Andric SBError::SBError(const lldb_private::Status &status)
35bdd1243dSDimitry Andric     : m_opaque_up(new Status(status)) {
36bdd1243dSDimitry Andric   LLDB_INSTRUMENT_VA(this, status);
37bdd1243dSDimitry Andric }
38bdd1243dSDimitry Andric 
395ffd83dbSDimitry Andric SBError::~SBError() = default;
400b57cec5SDimitry Andric 
operator =(const SBError & rhs)410b57cec5SDimitry Andric const SBError &SBError::operator=(const SBError &rhs) {
4204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   if (this != &rhs)
450b57cec5SDimitry Andric     m_opaque_up = clone(rhs.m_opaque_up);
4604eeddc0SDimitry Andric   return *this;
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
GetCString() const490b57cec5SDimitry Andric const char *SBError::GetCString() const {
5004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   if (m_opaque_up)
530b57cec5SDimitry Andric     return m_opaque_up->AsCString();
540b57cec5SDimitry Andric   return nullptr;
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
Clear()570b57cec5SDimitry Andric void SBError::Clear() {
5804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   if (m_opaque_up)
610b57cec5SDimitry Andric     m_opaque_up->Clear();
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
Fail() const640b57cec5SDimitry Andric bool SBError::Fail() const {
6504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   bool ret_value = false;
680b57cec5SDimitry Andric   if (m_opaque_up)
690b57cec5SDimitry Andric     ret_value = m_opaque_up->Fail();
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   return ret_value;
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
Success() const750b57cec5SDimitry Andric bool SBError::Success() const {
7604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   bool ret_value = true;
790b57cec5SDimitry Andric   if (m_opaque_up)
800b57cec5SDimitry Andric     ret_value = m_opaque_up->Success();
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   return ret_value;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
GetError() const850b57cec5SDimitry Andric uint32_t SBError::GetError() const {
8604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   uint32_t err = 0;
890b57cec5SDimitry Andric   if (m_opaque_up)
900b57cec5SDimitry Andric     err = m_opaque_up->GetError();
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   return err;
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
GetType() const960b57cec5SDimitry Andric ErrorType SBError::GetType() const {
9704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   ErrorType err_type = eErrorTypeInvalid;
1000b57cec5SDimitry Andric   if (m_opaque_up)
1010b57cec5SDimitry Andric     err_type = m_opaque_up->GetType();
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   return err_type;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
SetError(uint32_t err,ErrorType type)1060b57cec5SDimitry Andric void SBError::SetError(uint32_t err, ErrorType type) {
10704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, err, type);
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   CreateIfNeeded();
1100b57cec5SDimitry Andric   m_opaque_up->SetError(err, type);
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
SetError(const Status & lldb_error)1130b57cec5SDimitry Andric void SBError::SetError(const Status &lldb_error) {
1140b57cec5SDimitry Andric   CreateIfNeeded();
1150b57cec5SDimitry Andric   *m_opaque_up = lldb_error;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
SetErrorToErrno()1180b57cec5SDimitry Andric void SBError::SetErrorToErrno() {
11904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   CreateIfNeeded();
1220b57cec5SDimitry Andric   m_opaque_up->SetErrorToErrno();
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
SetErrorToGenericError()1250b57cec5SDimitry Andric void SBError::SetErrorToGenericError() {
12604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   CreateIfNeeded();
129e8d8bef9SDimitry Andric   m_opaque_up->SetErrorToGenericError();
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
SetErrorString(const char * err_str)1320b57cec5SDimitry Andric void SBError::SetErrorString(const char *err_str) {
13304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, err_str);
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   CreateIfNeeded();
1360b57cec5SDimitry Andric   m_opaque_up->SetErrorString(err_str);
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
SetErrorStringWithFormat(const char * format,...)1390b57cec5SDimitry Andric int SBError::SetErrorStringWithFormat(const char *format, ...) {
1400b57cec5SDimitry Andric   CreateIfNeeded();
1410b57cec5SDimitry Andric   va_list args;
1420b57cec5SDimitry Andric   va_start(args, format);
1430b57cec5SDimitry Andric   int num_chars = m_opaque_up->SetErrorStringWithVarArg(format, args);
1440b57cec5SDimitry Andric   va_end(args);
1450b57cec5SDimitry Andric   return num_chars;
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric 
IsValid() const1480b57cec5SDimitry Andric bool SBError::IsValid() const {
14904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1500b57cec5SDimitry Andric   return this->operator bool();
1510b57cec5SDimitry Andric }
operator bool() const1520b57cec5SDimitry Andric SBError::operator bool() const {
15304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   return m_opaque_up != nullptr;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric 
CreateIfNeeded()1580b57cec5SDimitry Andric void SBError::CreateIfNeeded() {
1590b57cec5SDimitry Andric   if (m_opaque_up == nullptr)
1605ffd83dbSDimitry Andric     m_opaque_up = std::make_unique<Status>();
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
operator ->()1630b57cec5SDimitry Andric lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); }
1640b57cec5SDimitry Andric 
get()1650b57cec5SDimitry Andric lldb_private::Status *SBError::get() { return m_opaque_up.get(); }
1660b57cec5SDimitry Andric 
ref()1670b57cec5SDimitry Andric lldb_private::Status &SBError::ref() {
1680b57cec5SDimitry Andric   CreateIfNeeded();
1690b57cec5SDimitry Andric   return *m_opaque_up;
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
operator *() const1720b57cec5SDimitry Andric const lldb_private::Status &SBError::operator*() const {
1730b57cec5SDimitry Andric   // Be sure to call "IsValid()" before calling this function or it will crash
1740b57cec5SDimitry Andric   return *m_opaque_up;
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
GetDescription(SBStream & description)1770b57cec5SDimitry Andric bool SBError::GetDescription(SBStream &description) {
17804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   if (m_opaque_up) {
1810b57cec5SDimitry Andric     if (m_opaque_up->Success())
1820b57cec5SDimitry Andric       description.Printf("success");
1830b57cec5SDimitry Andric     else {
1840b57cec5SDimitry Andric       const char *err_string = GetCString();
1850b57cec5SDimitry Andric       description.Printf("error: %s",
1860b57cec5SDimitry Andric                          (err_string != nullptr ? err_string : ""));
1870b57cec5SDimitry Andric     }
1880b57cec5SDimitry Andric   } else
1890b57cec5SDimitry Andric     description.Printf("error: <NULL>");
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   return true;
1920b57cec5SDimitry Andric }
193