1 //===-- SBError.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/SBError.h"
10 #include "Utils.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/Utility/Instrumentation.h"
13 #include "lldb/Utility/Status.h"
14 
15 #include <cstdarg>
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 SBError::SBError() { LLDB_INSTRUMENT_VA(this); }
21 
22 SBError::SBError(const SBError &rhs) {
23   LLDB_INSTRUMENT_VA(this, rhs);
24 
25   m_opaque_up = clone(rhs.m_opaque_up);
26 }
27 
28 SBError::SBError(const lldb_private::Status &status)
29     : m_opaque_up(new Status(status)) {
30   LLDB_INSTRUMENT_VA(this, status);
31 }
32 
33 SBError::~SBError() = default;
34 
35 const SBError &SBError::operator=(const SBError &rhs) {
36   LLDB_INSTRUMENT_VA(this, rhs);
37 
38   if (this != &rhs)
39     m_opaque_up = clone(rhs.m_opaque_up);
40   return *this;
41 }
42 
43 const char *SBError::GetCString() const {
44   LLDB_INSTRUMENT_VA(this);
45 
46   if (m_opaque_up)
47     return m_opaque_up->AsCString();
48   return nullptr;
49 }
50 
51 void SBError::Clear() {
52   LLDB_INSTRUMENT_VA(this);
53 
54   if (m_opaque_up)
55     m_opaque_up->Clear();
56 }
57 
58 bool SBError::Fail() const {
59   LLDB_INSTRUMENT_VA(this);
60 
61   bool ret_value = false;
62   if (m_opaque_up)
63     ret_value = m_opaque_up->Fail();
64 
65 
66   return ret_value;
67 }
68 
69 bool SBError::Success() const {
70   LLDB_INSTRUMENT_VA(this);
71 
72   bool ret_value = true;
73   if (m_opaque_up)
74     ret_value = m_opaque_up->Success();
75 
76   return ret_value;
77 }
78 
79 uint32_t SBError::GetError() const {
80   LLDB_INSTRUMENT_VA(this);
81 
82   uint32_t err = 0;
83   if (m_opaque_up)
84     err = m_opaque_up->GetError();
85 
86 
87   return err;
88 }
89 
90 ErrorType SBError::GetType() const {
91   LLDB_INSTRUMENT_VA(this);
92 
93   ErrorType err_type = eErrorTypeInvalid;
94   if (m_opaque_up)
95     err_type = m_opaque_up->GetType();
96 
97   return err_type;
98 }
99 
100 void SBError::SetError(uint32_t err, ErrorType type) {
101   LLDB_INSTRUMENT_VA(this, err, type);
102 
103   CreateIfNeeded();
104   m_opaque_up->SetError(err, type);
105 }
106 
107 void SBError::SetError(const Status &lldb_error) {
108   CreateIfNeeded();
109   *m_opaque_up = lldb_error;
110 }
111 
112 void SBError::SetErrorToErrno() {
113   LLDB_INSTRUMENT_VA(this);
114 
115   CreateIfNeeded();
116   m_opaque_up->SetErrorToErrno();
117 }
118 
119 void SBError::SetErrorToGenericError() {
120   LLDB_INSTRUMENT_VA(this);
121 
122   CreateIfNeeded();
123   m_opaque_up->SetErrorToGenericError();
124 }
125 
126 void SBError::SetErrorString(const char *err_str) {
127   LLDB_INSTRUMENT_VA(this, err_str);
128 
129   CreateIfNeeded();
130   m_opaque_up->SetErrorString(err_str);
131 }
132 
133 int SBError::SetErrorStringWithFormat(const char *format, ...) {
134   CreateIfNeeded();
135   va_list args;
136   va_start(args, format);
137   int num_chars = m_opaque_up->SetErrorStringWithVarArg(format, args);
138   va_end(args);
139   return num_chars;
140 }
141 
142 bool SBError::IsValid() const {
143   LLDB_INSTRUMENT_VA(this);
144   return this->operator bool();
145 }
146 SBError::operator bool() const {
147   LLDB_INSTRUMENT_VA(this);
148 
149   return m_opaque_up != nullptr;
150 }
151 
152 void SBError::CreateIfNeeded() {
153   if (m_opaque_up == nullptr)
154     m_opaque_up = std::make_unique<Status>();
155 }
156 
157 lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); }
158 
159 lldb_private::Status *SBError::get() { return m_opaque_up.get(); }
160 
161 lldb_private::Status &SBError::ref() {
162   CreateIfNeeded();
163   return *m_opaque_up;
164 }
165 
166 const lldb_private::Status &SBError::operator*() const {
167   // Be sure to call "IsValid()" before calling this function or it will crash
168   return *m_opaque_up;
169 }
170 
171 bool SBError::GetDescription(SBStream &description) {
172   LLDB_INSTRUMENT_VA(this, description);
173 
174   if (m_opaque_up) {
175     if (m_opaque_up->Success())
176       description.Printf("success");
177     else {
178       const char *err_string = GetCString();
179       description.Printf("error: %s",
180                          (err_string != nullptr ? err_string : ""));
181     }
182   } else
183     description.Printf("error: <NULL>");
184 
185   return true;
186 }
187