blob: 0b14949e88f49d76e44328aafae23b8e260c835e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Error.cpp -----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
Charles Davis322fc842013-08-27 06:13:56 +000011#ifdef __APPLE__
Charles Davis510938e2013-08-27 05:04:57 +000012#include <mach/mach.h>
Charles Davis322fc842013-08-27 06:13:56 +000013#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
15// C++ Includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000016#include <cerrno>
17#include <cstdarg>
18
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019// Other libraries and framework includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000020#include "llvm/ADT/SmallVector.h"
21
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022// Project includes
Zachary Turnerbf9a7732017-02-02 21:39:50 +000023#include "lldb/Utility/Error.h"
Zachary Turner24ae6292017-02-16 19:38:21 +000024#include "lldb/Utility/VASPrintf.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026using namespace lldb;
27using namespace lldb_private;
28
Kate Stoneb9c1b512016-09-06 20:57:50 +000029Error::Error() : m_code(0), m_type(eErrorTypeInvalid), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000030
Kate Stoneb9c1b512016-09-06 20:57:50 +000031Error::Error(ValueType err, ErrorType type)
32 : m_code(err), m_type(type), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000033
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000034Error::Error(const Error &rhs) = default;
Greg Claytonca512b32011-01-14 04:54:56 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036Error::Error(const char *format, ...)
37 : m_code(0), m_type(eErrorTypeInvalid), m_string() {
38 va_list args;
39 va_start(args, format);
40 SetErrorToGenericError();
41 SetErrorStringWithVarArg(format, args);
42 va_end(args);
Enrico Granataf2bbf712011-07-15 02:26:42 +000043}
44
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045//----------------------------------------------------------------------
46// Assignment operator
47//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000048const Error &Error::operator=(const Error &rhs) {
49 if (this != &rhs) {
50 m_code = rhs.m_code;
51 m_type = rhs.m_type;
52 m_string = rhs.m_string;
53 }
54 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055}
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057//----------------------------------------------------------------------
58// Assignment operator
59//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000060const Error &Error::operator=(uint32_t err) {
61 m_code = err;
62 m_type = eErrorTypeMachKernel;
63 m_string.clear();
64 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065}
66
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000067Error::~Error() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
69//----------------------------------------------------------------------
70// Get the error value as a NULL C string. The error string will be
71// fetched and cached on demand. The cached error string value will
72// remain until the error value is changed or cleared.
73//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000074const char *Error::AsCString(const char *default_error_str) const {
75 if (Success())
76 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 if (m_string.empty()) {
79 const char *s = nullptr;
80 switch (m_type) {
81 case eErrorTypeMachKernel:
82#if defined(__APPLE__)
83 s = ::mach_error_string(m_code);
Eli Friedman6eb685c2010-06-10 23:45:58 +000084#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 case eErrorTypePOSIX:
88 s = ::strerror(m_code);
89 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 default:
92 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 if (s != nullptr)
95 m_string.assign(s);
96 }
97 if (m_string.empty()) {
98 if (default_error_str)
99 m_string.assign(default_error_str);
100 else
101 return nullptr; // User wanted a nullptr string back...
102 }
103 return m_string.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104}
105
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106//----------------------------------------------------------------------
107// Clear the error and any cached error string that it might contain.
108//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109void Error::Clear() {
110 m_code = 0;
111 m_type = eErrorTypeInvalid;
112 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113}
114
115//----------------------------------------------------------------------
116// Access the error value.
117//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118Error::ValueType Error::GetError() const { return m_code; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119
120//----------------------------------------------------------------------
121// Access the error type.
122//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123ErrorType Error::GetType() const { return m_type; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124
125//----------------------------------------------------------------------
Ed Maste75500e72016-07-19 15:28:02 +0000126// Returns true if this object contains a value that describes an
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127// error or otherwise non-success result.
128//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129bool Error::Fail() const { return m_code != 0; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130
131//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132// Set accesssor for the error value to "err" and the type to
133// "eErrorTypeMachKernel"
134//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135void Error::SetMachError(uint32_t err) {
136 m_code = err;
137 m_type = eErrorTypeMachKernel;
138 m_string.clear();
139}
140
141void Error::SetExpressionError(lldb::ExpressionResults result,
142 const char *mssg) {
143 m_code = result;
144 m_type = eErrorTypeExpression;
145 m_string = mssg;
146}
147
148int Error::SetExpressionErrorWithFormat(lldb::ExpressionResults result,
149 const char *format, ...) {
150 int length = 0;
151
152 if (format != nullptr && format[0]) {
153 va_list args;
154 va_start(args, format);
155 length = SetErrorStringWithVarArg(format, args);
156 va_end(args);
157 } else {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 m_string.clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 }
160 m_code = result;
161 m_type = eErrorTypeExpression;
162 return length;
Jim Ingham1624a2d2014-05-05 02:26:40 +0000163}
164
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165//----------------------------------------------------------------------
166// Set accesssor for the error value and type.
167//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168void Error::SetError(ValueType err, ErrorType type) {
169 m_code = err;
170 m_type = type;
171 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172}
173
174//----------------------------------------------------------------------
175// Update the error value to be "errno" and update the type to
176// be "POSIX".
177//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178void Error::SetErrorToErrno() {
179 m_code = errno;
180 m_type = eErrorTypePOSIX;
181 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182}
183
184//----------------------------------------------------------------------
185// Update the error value to be LLDB_GENERIC_ERROR and update the type
186// to be "Generic".
187//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188void Error::SetErrorToGenericError() {
189 m_code = LLDB_GENERIC_ERROR;
190 m_type = eErrorTypeGeneric;
191 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192}
193
194//----------------------------------------------------------------------
195// Set accessor for the error string value for a specific error.
196// This allows any string to be supplied as an error explanation.
197// The error string value will remain until the error value is
198// cleared or a new error value/type is assigned.
199//----------------------------------------------------------------------
Zachary Turnerc1564272016-11-16 21:15:24 +0000200void Error::SetErrorString(llvm::StringRef err_str) {
201 if (!err_str.empty()) {
202 // If we have an error string, we should always at least have an error
203 // set to a generic value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 if (Success())
205 SetErrorToGenericError();
Zachary Turnerc1564272016-11-16 21:15:24 +0000206 }
207 m_string = err_str;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208}
209
210//------------------------------------------------------------------
211/// Set the current error string to a formatted error string.
212///
213/// @param format
214/// A printf style format string
215//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216int Error::SetErrorStringWithFormat(const char *format, ...) {
217 if (format != nullptr && format[0]) {
218 va_list args;
219 va_start(args, format);
220 int length = SetErrorStringWithVarArg(format, args);
221 va_end(args);
222 return length;
223 } else {
224 m_string.clear();
225 }
226 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227}
228
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229int Error::SetErrorStringWithVarArg(const char *format, va_list args) {
230 if (format != nullptr && format[0]) {
231 // If we have an error string, we should always at least have
232 // an error set to a generic value.
233 if (Success())
234 SetErrorToGenericError();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235
Zachary Turner24ae6292017-02-16 19:38:21 +0000236 llvm::SmallString<1024> buf;
237 VASprintf(buf, format, args);
238 return buf.size();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239 } else {
240 m_string.clear();
241 }
242 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243}
244
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245//----------------------------------------------------------------------
246// Returns true if the error code in this object is considered a
247// successful return value.
248//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249bool Error::Success() const { return m_code == 0; }
Jim Ingham4e5c8212013-06-07 22:09:53 +0000250
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251bool Error::WasInterrupted() const {
252 return (m_type == eErrorTypePOSIX && m_code == EINTR);
Jim Ingham4e5c8212013-06-07 22:09:53 +0000253}
Zachary Turner33aba3c2017-02-06 18:31:44 +0000254
255void llvm::format_provider<lldb_private::Error>::format(
256 const lldb_private::Error &error, llvm::raw_ostream &OS,
257 llvm::StringRef Options) {
258 llvm::format_provider<llvm::StringRef>::format(error.AsCString(), OS,
259 Options);
260}