1 //===-- DNBError.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 //  Created by Greg Clayton on 6/26/07.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "DNBError.h"
15 #include "CFString.h"
16 #include "DNBLog.h"
17 #include "PThreadMutex.h"
18 
19 #ifdef WITH_SPRINGBOARD
20 #include <SpringBoardServices/SpringBoardServer.h>
21 #endif
22 
23 const char *
24 DNBError::AsString() const
25 {
26     if (Success())
27         return NULL;
28 
29     if (m_str.empty())
30     {
31         const char *s = NULL;
32         switch (m_flavor)
33         {
34         case MachKernel:
35             s = ::mach_error_string (m_err);
36             break;
37 
38         case POSIX:
39             s = ::strerror (m_err);
40             break;
41 
42 #ifdef WITH_SPRINGBOARD
43         case SpringBoard:
44             {
45                 CFStringRef statusStr = SBSApplicationLaunchingErrorString (m_err);
46                 if (CFString::UTF8 (statusStr, m_str) == NULL)
47                     m_str.clear();
48             }
49             break;
50 #endif
51 #ifdef WITH_BKS
52         case BackBoard:
53             {
54                 // You have to call ObjC routines to get the error string from BackBoardServices.
55                 // Not sure I want to make DNBError.cpp an .mm file.  For now just make sure you
56                 // pre-populate the error string when you make the DNBError of type BackBoard.
57                 m_str.assign("Should have set Backboard error when making the error string.");
58             }
59             break;
60 #endif
61         default:
62             break;
63         }
64         if (s)
65             m_str.assign(s);
66     }
67     if (m_str.empty())
68         return NULL;
69     return m_str.c_str();
70 }
71 
72 void
73 DNBError::LogThreadedIfError(const char *format, ...) const
74 {
75     if (Fail())
76     {
77         char *arg_msg = NULL;
78         va_list args;
79         va_start (args, format);
80         ::vasprintf (&arg_msg, format, args);
81         va_end (args);
82 
83         if (arg_msg != NULL)
84         {
85             const char *err_str = AsString();
86             if (err_str == NULL)
87                 err_str = "???";
88             DNBLogThreaded ("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
89             free (arg_msg);
90         }
91     }
92 }
93 
94 void
95 DNBError::LogThreaded(const char *format, ...) const
96 {
97     char *arg_msg = NULL;
98     va_list args;
99     va_start (args, format);
100     ::vasprintf (&arg_msg, format, args);
101     va_end (args);
102 
103     if (arg_msg != NULL)
104     {
105         if (Fail())
106         {
107             const char *err_str = AsString();
108             if (err_str == NULL)
109                 err_str = "???";
110             DNBLogThreaded ("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
111         }
112         else
113         {
114             DNBLogThreaded ("%s err = 0x%8.8x", arg_msg, m_err);
115         }
116         free (arg_msg);
117     }
118 }
119