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