]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Core/Error.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Core / Error.cpp
1 //===-- 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
11 #ifdef __APPLE__
12 #include <mach/mach.h>
13 #endif
14
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include <cerrno>
22 #include <cstdarg>
23
24 #if defined (__arm__) && defined (__APPLE__)
25 #include <SpringBoardServices/SpringBoardServer.h>
26 #endif
27
28 using namespace lldb;
29 using namespace lldb_private;
30
31 Error::Error ():
32     m_code (0),
33     m_type (eErrorTypeInvalid),
34     m_string ()
35 {
36 }
37
38 //----------------------------------------------------------------------
39 // Default constructor
40 //----------------------------------------------------------------------
41 Error::Error(ValueType err, ErrorType type) :
42     m_code (err),
43     m_type (type),
44     m_string ()
45 {
46 }
47
48 Error::Error (const Error &rhs) :
49     m_code (rhs.m_code),
50     m_type (rhs.m_type),
51     m_string (rhs.m_string)
52 {
53 }
54
55 Error::Error (const char* format, ...):
56     m_code (0),
57     m_type (eErrorTypeInvalid),
58     m_string ()
59 {
60     va_list args;
61     va_start (args, format);
62     SetErrorToGenericError ();
63     SetErrorStringWithVarArg (format, args);
64     va_end (args);
65 }
66
67 //----------------------------------------------------------------------
68 // Assignment operator
69 //----------------------------------------------------------------------
70 const Error&
71 Error::operator = (const Error& rhs)
72 {
73     if (this != &rhs)
74     {
75         m_code = rhs.m_code;
76         m_type = rhs.m_type;
77         m_string = rhs.m_string;
78     }
79     return *this;
80 }
81
82
83 //----------------------------------------------------------------------
84 // Assignment operator
85 //----------------------------------------------------------------------
86 const Error&
87 Error::operator = (uint32_t err)
88 {
89     m_code = err;
90     m_type = eErrorTypeMachKernel;
91     m_string.clear();
92     return *this;
93 }
94
95 Error::~Error()
96 {
97 }
98
99 //----------------------------------------------------------------------
100 // Get the error value as a NULL C string. The error string will be
101 // fetched and cached on demand. The cached error string value will
102 // remain until the error value is changed or cleared.
103 //----------------------------------------------------------------------
104 const char *
105 Error::AsCString(const char *default_error_str) const
106 {
107     if (Success())
108         return NULL;
109
110     if (m_string.empty())
111     {
112         const char *s = NULL;
113         switch (m_type)
114         {
115         case eErrorTypeMachKernel:
116 #if defined (__APPLE__)
117             s = ::mach_error_string (m_code);
118 #endif
119             break;
120
121         case eErrorTypePOSIX:
122             s = ::strerror (m_code);
123             break;
124
125         default:
126             break;
127         }
128         if (s)
129             m_string.assign(s);
130     }
131     if (m_string.empty())
132     {
133         if (default_error_str)
134             m_string.assign(default_error_str);
135         else
136             return NULL;    // User wanted a NULL string back...
137     }
138     return m_string.c_str();
139 }
140
141
142 //----------------------------------------------------------------------
143 // Clear the error and any cached error string that it might contain.
144 //----------------------------------------------------------------------
145 void
146 Error::Clear ()
147 {
148     m_code = 0;
149     m_type = eErrorTypeGeneric;
150     m_string.clear();
151 }
152
153 //----------------------------------------------------------------------
154 // Access the error value.
155 //----------------------------------------------------------------------
156 Error::ValueType
157 Error::GetError () const
158 {
159     return m_code;
160 }
161
162 //----------------------------------------------------------------------
163 // Access the error type.
164 //----------------------------------------------------------------------
165 ErrorType
166 Error::GetType () const
167 {
168     return m_type;
169 }
170
171 //----------------------------------------------------------------------
172 // Retuns true if this object contains an value that describes an
173 // error or otherwise non-success result.
174 //----------------------------------------------------------------------
175 bool
176 Error::Fail () const
177 {
178     return m_code != 0;
179 }
180
181 //----------------------------------------------------------------------
182 // Log the error given a string with format. If the this object
183 // contains an error code, update the error string to contain the
184 // "error: " followed by the formatted string, followed by the error
185 // value and any string that describes the current error. This
186 // allows more context to be given to an error string that remains
187 // cached in this object. Logging always occurs even when the error
188 // code contains a non-error value.
189 //----------------------------------------------------------------------
190 void
191 Error::PutToLog (Log *log, const char *format, ...)
192 {
193     char *arg_msg = NULL;
194     va_list args;
195     va_start (args, format);
196     ::vasprintf (&arg_msg, format, args);
197     va_end (args);
198
199     if (arg_msg != NULL)
200     {
201         if (Fail())
202         {
203             const char *err_str = AsCString();
204             if (err_str == NULL)
205                 err_str = "???";
206
207             SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
208             if (log)
209                 log->Error("%s", m_string.c_str());
210         }
211         else
212         {
213             if (log)
214                 log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
215         }
216         ::free (arg_msg);
217     }
218 }
219
220 //----------------------------------------------------------------------
221 // Log the error given a string with format. If the this object
222 // contains an error code, update the error string to contain the
223 // "error: " followed by the formatted string, followed by the error
224 // value and any string that describes the current error. This
225 // allows more context to be given to an error string that remains
226 // cached in this object. Logging only occurs even when the error
227 // code contains a error value.
228 //----------------------------------------------------------------------
229 void
230 Error::LogIfError (Log *log, const char *format, ...)
231 {
232     if (Fail())
233     {
234         char *arg_msg = NULL;
235         va_list args;
236         va_start (args, format);
237         ::vasprintf (&arg_msg, format, args);
238         va_end (args);
239
240         if (arg_msg != NULL)
241         {
242             const char *err_str = AsCString();
243             if (err_str == NULL)
244                 err_str = "???";
245
246             SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
247             if (log)
248                 log->Error("%s", m_string.c_str());
249
250             ::free (arg_msg);
251         }
252     }
253 }
254
255 //----------------------------------------------------------------------
256 // Set accesssor for the error value to "err" and the type to
257 // "eErrorTypeMachKernel"
258 //----------------------------------------------------------------------
259 void
260 Error::SetMachError (uint32_t err)
261 {
262     m_code = err;
263     m_type = eErrorTypeMachKernel;
264     m_string.clear();
265 }
266
267 //----------------------------------------------------------------------
268 // Set accesssor for the error value and type.
269 //----------------------------------------------------------------------
270 void
271 Error::SetError (ValueType err, ErrorType type)
272 {
273     m_code = err;
274     m_type = type;
275     m_string.clear();
276 }
277
278 //----------------------------------------------------------------------
279 // Update the error value to be "errno" and update the type to
280 // be "POSIX".
281 //----------------------------------------------------------------------
282 void
283 Error::SetErrorToErrno()
284 {
285     m_code = errno;
286     m_type = eErrorTypePOSIX;
287     m_string.clear();
288 }
289
290 //----------------------------------------------------------------------
291 // Update the error value to be LLDB_GENERIC_ERROR and update the type
292 // to be "Generic".
293 //----------------------------------------------------------------------
294 void
295 Error::SetErrorToGenericError ()
296 {
297     m_code = LLDB_GENERIC_ERROR;
298     m_type = eErrorTypeGeneric;
299     m_string.clear();
300 }
301
302 //----------------------------------------------------------------------
303 // Set accessor for the error string value for a specific error.
304 // This allows any string to be supplied as an error explanation.
305 // The error string value will remain until the error value is
306 // cleared or a new error value/type is assigned.
307 //----------------------------------------------------------------------
308 void
309 Error::SetErrorString (const char *err_str)
310 {
311     if (err_str && err_str[0])
312     {
313         // If we have an error string, we should always at least have
314         // an error set to a generic value.
315         if (Success())
316             SetErrorToGenericError();
317         m_string = err_str;
318     }
319     else
320         m_string.clear();
321 }
322
323 //------------------------------------------------------------------
324 /// Set the current error string to a formatted error string.
325 ///
326 /// @param format
327 ///     A printf style format string
328 //------------------------------------------------------------------
329 int
330 Error::SetErrorStringWithFormat (const char *format, ...)
331 {
332     if (format && format[0])
333     {
334         va_list args;
335         va_start (args, format);
336         int length = SetErrorStringWithVarArg (format, args);
337         va_end (args);
338         return length;
339     }
340     else
341     {
342         m_string.clear();
343     }
344     return 0;
345 }
346
347 int
348 Error::SetErrorStringWithVarArg (const char *format, va_list args)
349 {
350     if (format && format[0])
351     {
352         // If we have an error string, we should always at least have
353         // an error set to a generic value.
354         if (Success())
355             SetErrorToGenericError();
356
357         // Try and fit our error into a 1024 byte buffer first...
358         llvm::SmallVector<char, 1024> buf;
359         buf.resize(1024);
360         // Copy in case our first call to vsnprintf doesn't fit into our
361         // allocated buffer above
362         va_list copy_args;
363         va_copy (copy_args, args);
364         unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
365         if (length >= buf.size())
366         {
367             // The error formatted string didn't fit into our buffer, resize it
368             // to the exact needed size, and retry
369             buf.resize(length + 1);
370             length = ::vsnprintf (buf.data(), buf.size(), format, copy_args);
371             va_end (copy_args);
372             assert (length < buf.size());
373         }
374         m_string.assign(buf.data(), length);
375         va_end (args);
376         return length;
377     }
378     else
379     {
380         m_string.clear();
381     }
382     return 0;
383 }
384
385
386 //----------------------------------------------------------------------
387 // Returns true if the error code in this object is considered a
388 // successful return value.
389 //----------------------------------------------------------------------
390 bool
391 Error::Success() const
392 {
393     return m_code == 0;
394 }
395
396 bool
397 Error::WasInterrupted() const
398 {
399     if (m_type == eErrorTypePOSIX && m_code == EINTR)
400         return true;
401     else
402         return false;
403 }
404