Add DaliPrintBackTrace for common
[platform/core/uifw/dali-core.git] / dali / public-api / common / dali-common.h
1 #ifndef DALI_COMMON_H
2 #define DALI_COMMON_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22
23 /*
24  * Definitions for shared library support.
25  *
26  * If a library is built with -DENABLE_EXPORTALL=ON or -DENABLE_DEBUG=ON
27  * then HIDE_DALI_INTERNALS is not defined, and nothing is hidden.
28  * If it is built without these options (the default), then HIDE_INTERNALS
29  * is defined when building the library, visibility is automatically hidden, and the explicit
30  * defines below come into use.
31  * When building a library that uses DALI, HIDE_DALI_INTERNALS.
32  */
33 #if __GNUC__ >= 4
34 #ifndef HIDE_DALI_INTERNALS
35 #define DALI_EXPORT_API
36 #define DALI_NO_EXPORT_API
37 #define DALI_IMPORT_API
38 #define DALI_CORE_API
39 #define DALI_INTERNAL
40 #else
41 #define DALI_EXPORT_API __attribute__((visibility("default")))
42 #define DALI_NO_EXPORT_API __attribute__((visibility("hidden")))
43 #define DALI_IMPORT_API __attribute__((visibility("default")))
44 #define DALI_CORE_API __attribute__((visibility("default")))
45 #define DALI_INTERNAL __attribute__((visibility("hidden")))
46 #endif
47 #else
48 #ifdef WIN32
49 /** Visibility attribute to show declarations */
50 #define DALI_EXPORT_API __declspec(dllexport)
51
52 #ifdef BUILDING_DALI_CORE
53 /** Visibility attribute to hide declarations */
54 #define DALI_CORE_API __declspec(dllexport)
55 #else
56 /** Visibility attribute to hide declarations */
57 #define DALI_CORE_API __declspec(dllimport)
58 #endif
59
60 #else
61 /** Visibility attribute to show declarations */
62 #define DALI_EXPORT_API
63 /** Visibility attribute to show declarations */
64 #define DALI_IMPORT_API
65 /** Visibility attribute to show declarations */
66 #define DALI_CORE_API
67 #endif
68 /** Visibility attribute to hide declarations */
69 #define DALI_INTERNAL
70 #define DALI_NO_EXPORT_API
71 #endif
72
73 #ifdef DEPRECATION_WARNING
74 #define DALI_DEPRECATED_API __attribute__((__visibility__("default"), deprecated))
75 #else
76 #define DALI_DEPRECATED_API
77 #endif
78
79 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
80 // C++0x support
81 #define _CPP11
82 #else
83 // C++0x not supported
84 #endif
85
86 /**
87  * @brief Two macros to provide branch predictor information.
88  * DALI_LIKELY should be used when a branch is taken in almost all cases so the
89  * branch predictor can avoid pre-fetching. The code for else branch
90  * DALI_UNLIKELY should be used when a branch is almost never taken.
91  * @SINCE_1_0.0
92  */
93 #ifdef __GNUC
94 #define DALI_LIKELY(expression) __builtin_expect(!!(expression), 1)
95 #define DALI_UNLIKELY(expression) __builtin_expect(!!(expression), 0)
96 #else
97 #define DALI_LIKELY(expression) !!(expression)
98 #define DALI_UNLIKELY(expression) !!(expression)
99 #endif
100
101 /**
102  * @brief The DALi namespace.
103  * @SINCE_1_0.0
104  */
105 namespace Dali
106 {
107 /**
108  * @addtogroup dali_core_common
109  * @{
110  */
111
112 /**
113  * @brief Method to log assertion message in DALI_ASSERT_ALWAYS macro below.
114  *
115  * @SINCE_1_0.0
116  * @param[in] location Where the assertion occurred
117  * @param[in] condition The assertion condition
118  */
119 DALI_CORE_API void DaliAssertMessage(const char* location, const char* condition);
120
121 /**
122  * @brief Print backtrace log if required.
123  * @note Do nothing if ENABLE_BACKTRACE option off.
124  *
125  * @SINCE_2_3.2
126  */
127 DALI_CORE_API void DaliPrintBackTrace();
128
129 /**
130  * @brief Exception class for Dali Core library - Raised by assertions in codebase.
131  * @SINCE_1_0.0
132  */
133 class DALI_CORE_API DaliException
134 {
135 public:
136   /**
137    * @brief Constructor.
138    *
139    * Will always display a backtrace when raised in a debug build.
140    *
141    * @SINCE_1_0.0
142    * @param[in] location The location of the assertion
143    * @param[in] condition The assertion condition
144    */
145   DaliException(const char* location, const char* condition);
146
147   const char* location;
148   const char* condition;
149 };
150
151 /**
152  * @}
153  */
154 } // namespace Dali
155
156 /**
157  * @brief An invariant concurrent assertion to ensure its argument always evaluates TRUE.
158  *
159  * Use this for rules that must always be true regardless of build options.
160  * For example, Actor must only ever have one parent.
161  * To be clear, this test remains compiled into release builds that are deployed
162  * on the platform.
163  * Semantically, a failure of this test is signalling that dali is giving up and
164  * quitting.
165  * Since we don't catch the exception, a failure on any thread other than event
166  * will propagate up the call stack and kill that thread.
167  * A failure on the event thread may give the application an opportunity to
168  * recover if there is an application-written exception handler on the call
169  * stack between the throw site and the thread root and the application is built
170  * with a compatible ABI.
171  * Handle this macro with care at the level you would if it expanded to:
172  *    if(!cond) { exit(EXIT_FAILURE); }
173  * (which it is often equivalent to in effect).
174  * It should not be used for simple parameter validation for instance.
175  */
176
177 /**
178  * @brief Strip assert location for release builds, assert text is descriptive enough.
179  * This is to save space for low spec devices.
180  * @SINCE_1_0.0
181  */
182 #if defined(DEBUG_ENABLED)
183 #if defined(WIN32)
184 #define ASSERT_LOCATION __FUNCSIG__
185 #else
186 #define ASSERT_LOCATION __PRETTY_FUNCTION__
187 #endif
188 #else
189 #define ASSERT_LOCATION NULL
190 #endif
191
192 #define DALI_ASSERT_ALWAYS(cond)                       \
193   if(DALI_UNLIKELY(!(cond)))                           \
194   {                                                    \
195     Dali::DaliAssertMessage(ASSERT_LOCATION, #cond);   \
196     throw Dali::DaliException(ASSERT_LOCATION, #cond); \
197   }
198
199 #define DALI_ABORT(message)                              \
200   {                                                      \
201     Dali::DaliAssertMessage(ASSERT_LOCATION, message);   \
202     throw Dali::DaliException(ASSERT_LOCATION, message); \
203   }
204
205 /**
206  * @brief An invariant concurrent assertion to ensure its argument evaluates TRUE in debug builds.
207  *
208  * Use this to sanity check algorithms and prevent internal programming errors.
209  * @SINCE_1_0.0
210  */
211 #if defined(DEBUG_ENABLED)
212 #define DALI_ASSERT_DEBUG(cond) DALI_ASSERT_ALWAYS(cond)
213 #else
214 #define DALI_ASSERT_DEBUG(cond)
215 #endif
216
217 /// Use DALI_FALLTHROUGH in switch statements where one case is supposed to fall through into another case
218 #define DALI_FALLTHROUGH
219 #if __GNUC__
220 #if __has_cpp_attribute(fallthrough)
221 #undef DALI_FALLTHROUGH
222 #define DALI_FALLTHROUGH [[fallthrough]]
223 #endif
224 #endif
225
226 #endif // DALI_COMMON_H