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