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 | |
22 | 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: s); |
73 | } |
74 | if (m_str.empty()) |
75 | return NULL; |
76 | return m_str.c_str(); |
77 | } |
78 | |
79 | 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(ptr: &arg_msg, f: format, arg: 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(ptr: arg_msg); |
93 | } |
94 | } |
95 | } |
96 | |
97 | void DNBError::LogThreaded(const char *format, ...) const { |
98 | char *arg_msg = NULL; |
99 | va_list args; |
100 | va_start(args, format); |
101 | ::vasprintf(ptr: &arg_msg, f: format, arg: 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(ptr: arg_msg); |
114 | } |
115 | } |
116 | |