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