xref: /llvm-project/lldb/source/API/SBError.cpp (revision d9cc37fea7b02954079ca59e8f7f28cffacc7e9e)
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/API/SBStructuredData.h"
13 #include "lldb/Core/StructuredDataImpl.h"
14 #include "lldb/Utility/Instrumentation.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/Utility/VASPrintf.h"
17 
18 #include <cstdarg>
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 SBError::SBError() { LLDB_INSTRUMENT_VA(this); }
24 
25 SBError::SBError(const SBError &rhs) {
26   LLDB_INSTRUMENT_VA(this, rhs);
27 
28   if (rhs.m_opaque_up)
29     m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone());
30 }
31 
32 SBError::SBError(const char *message) {
33   LLDB_INSTRUMENT_VA(this, message);
34 
35   SetErrorString(message);
36 }
37 
38 SBError::SBError(lldb_private::Status &&status)
39     : m_opaque_up(new Status(std::move(status))) {
40   LLDB_INSTRUMENT_VA(this, status);
41 }
42 
43 SBError::~SBError() = default;
44 
45 const SBError &SBError::operator=(const SBError &rhs) {
46   LLDB_INSTRUMENT_VA(this, rhs);
47 
48   if (this != &rhs)
49     if (rhs.m_opaque_up)
50       m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone());
51 
52   return *this;
53 }
54 
55 const char *SBError::GetCString() const {
56   LLDB_INSTRUMENT_VA(this);
57 
58   if (m_opaque_up)
59     return m_opaque_up->AsCString();
60   return nullptr;
61 }
62 
63 void SBError::Clear() {
64   LLDB_INSTRUMENT_VA(this);
65 
66   if (m_opaque_up)
67     m_opaque_up->Clear();
68 }
69 
70 bool SBError::Fail() const {
71   LLDB_INSTRUMENT_VA(this);
72 
73   bool ret_value = false;
74   if (m_opaque_up)
75     ret_value = m_opaque_up->Fail();
76 
77 
78   return ret_value;
79 }
80 
81 bool SBError::Success() const {
82   LLDB_INSTRUMENT_VA(this);
83 
84   bool ret_value = true;
85   if (m_opaque_up)
86     ret_value = m_opaque_up->Success();
87 
88   return ret_value;
89 }
90 
91 uint32_t SBError::GetError() const {
92   LLDB_INSTRUMENT_VA(this);
93 
94   uint32_t err = 0;
95   if (m_opaque_up)
96     err = m_opaque_up->GetError();
97 
98 
99   return err;
100 }
101 
102 SBStructuredData SBError::GetErrorData() const {
103   LLDB_INSTRUMENT_VA(this);
104 
105   SBStructuredData sb_data;
106   if (!m_opaque_up)
107     return sb_data;
108 
109   StructuredData::ObjectSP data(m_opaque_up->GetAsStructuredData());
110   sb_data.m_impl_up->SetObjectSP(data);
111   return sb_data;
112 }
113 
114 ErrorType SBError::GetType() const {
115   LLDB_INSTRUMENT_VA(this);
116 
117   ErrorType err_type = eErrorTypeInvalid;
118   if (m_opaque_up)
119     err_type = m_opaque_up->GetType();
120 
121   return err_type;
122 }
123 
124 void SBError::SetError(uint32_t err, ErrorType type) {
125   LLDB_INSTRUMENT_VA(this, err, type);
126 
127   CreateIfNeeded();
128   *m_opaque_up = Status(err, type);
129 }
130 
131 void SBError::SetError(Status &&lldb_error) {
132   CreateIfNeeded();
133   *m_opaque_up = std::move(lldb_error);
134 }
135 
136 void SBError::SetErrorToErrno() {
137   LLDB_INSTRUMENT_VA(this);
138 
139   CreateIfNeeded();
140   *m_opaque_up = Status::FromErrno();
141 }
142 
143 void SBError::SetErrorToGenericError() {
144   LLDB_INSTRUMENT_VA(this);
145 
146   CreateIfNeeded();
147   *m_opaque_up = Status(std::string("generic error"));
148 }
149 
150 void SBError::SetErrorString(const char *err_str) {
151   LLDB_INSTRUMENT_VA(this, err_str);
152 
153   CreateIfNeeded();
154   *m_opaque_up = Status::FromErrorString(err_str);
155 }
156 
157 int SBError::SetErrorStringWithFormat(const char *format, ...) {
158   CreateIfNeeded();
159   std::string string;
160   va_list args;
161   va_start(args, format);
162   if (format != nullptr && format[0]) {
163     llvm::SmallString<1024> buf;
164     VASprintf(buf, format, args);
165     string = std::string(buf.str());
166     *m_opaque_up = Status(std::move(string));
167   }
168   va_end(args);
169   return string.size();
170 }
171 
172 bool SBError::IsValid() const {
173   LLDB_INSTRUMENT_VA(this);
174   return this->operator bool();
175 }
176 SBError::operator bool() const {
177   LLDB_INSTRUMENT_VA(this);
178 
179   return m_opaque_up != nullptr;
180 }
181 
182 void SBError::CreateIfNeeded() {
183   if (m_opaque_up == nullptr)
184     m_opaque_up = std::make_unique<Status>();
185 }
186 
187 lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); }
188 
189 lldb_private::Status *SBError::get() { return m_opaque_up.get(); }
190 
191 lldb_private::Status &SBError::ref() {
192   CreateIfNeeded();
193   return *m_opaque_up;
194 }
195 
196 const lldb_private::Status &SBError::operator*() const {
197   // Be sure to call "IsValid()" before calling this function or it will crash
198   return *m_opaque_up;
199 }
200 
201 bool SBError::GetDescription(SBStream &description) {
202   LLDB_INSTRUMENT_VA(this, description);
203 
204   if (m_opaque_up) {
205     if (m_opaque_up->Success())
206       description.Printf("success");
207     else {
208       const char *err_string = GetCString();
209       description.Printf("error: %s",
210                          (err_string != nullptr ? err_string : ""));
211     }
212   } else
213     description.Printf("error: <NULL>");
214 
215   return true;
216 }
217