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