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