1 /*
2  * Copyright (c) 2011-2014 Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_SYS___ASSERT_H_
8 #define ZEPHYR_INCLUDE_SYS___ASSERT_H_
9 
10 #include <stdbool.h>
11 #include <zephyr/toolchain.h>
12 
13 #ifdef CONFIG_ASSERT
14 #ifndef __ASSERT_ON
15 #ifdef CONFIG_ASSERT_LEVEL
16 #define __ASSERT_ON CONFIG_ASSERT_LEVEL
17 #endif
18 #endif
19 #endif
20 
21 #ifdef CONFIG_FORCE_NO_ASSERT
22 #undef __ASSERT_ON
23 #define __ASSERT_ON 0
24 #endif
25 
26 #ifndef __ASSERT_ON
27 #define __ASSERT_ON 0
28 #endif
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /* Wrapper around printk to avoid including printk.h in assert.h */
35 void __printf_like(1, 2) assert_print(const char *fmt, ...);
36 
37 #ifdef __cplusplus
38 }
39 #endif
40 
41 #if defined(CONFIG_ASSERT_VERBOSE)
42 #define __ASSERT_PRINT(fmt, ...) assert_print(fmt, ##__VA_ARGS__)
43 #else /* CONFIG_ASSERT_VERBOSE */
44 #define __ASSERT_PRINT(fmt, ...)
45 #endif /* CONFIG_ASSERT_VERBOSE */
46 
47 #ifdef CONFIG_ASSERT_NO_MSG_INFO
48 #define __ASSERT_MSG_INFO(fmt, ...)
49 #else  /* CONFIG_ASSERT_NO_MSG_INFO */
50 #define __ASSERT_MSG_INFO(fmt, ...) __ASSERT_PRINT("\t" fmt "\n", ##__VA_ARGS__)
51 #endif /* CONFIG_ASSERT_NO_MSG_INFO */
52 
53 #if !defined(CONFIG_ASSERT_NO_COND_INFO) && !defined(CONFIG_ASSERT_NO_FILE_INFO)
54 #define __ASSERT_LOC(test)                              \
55 	__ASSERT_PRINT("ASSERTION FAIL [%s] @ %s:%d\n", \
56 		Z_STRINGIFY(test),                      \
57 		__FILE__, __LINE__)
58 #endif
59 
60 #if defined(CONFIG_ASSERT_NO_COND_INFO) && !defined(CONFIG_ASSERT_NO_FILE_INFO)
61 #define __ASSERT_LOC(test)                         \
62 	__ASSERT_PRINT("ASSERTION FAIL @ %s:%d\n", \
63 		__FILE__, __LINE__)
64 #endif
65 
66 #if !defined(CONFIG_ASSERT_NO_COND_INFO) && defined(CONFIG_ASSERT_NO_FILE_INFO)
67 #define __ASSERT_LOC(test)                      \
68 	__ASSERT_PRINT("ASSERTION FAIL [%s]\n", \
69 		Z_STRINGIFY(test))
70 #endif
71 
72 #if defined(CONFIG_ASSERT_NO_COND_INFO) && defined(CONFIG_ASSERT_NO_FILE_INFO)
73 #define __ASSERT_LOC(test)                 \
74 	__ASSERT_PRINT("ASSERTION FAIL\n")
75 #endif
76 
77 #ifdef __ASSERT_ON
78 #if (__ASSERT_ON < 0) || (__ASSERT_ON > 2)
79 #error "Invalid __ASSERT() level: must be between 0 and 2"
80 #endif
81 
82 #if __ASSERT_ON
83 
84 #ifdef __cplusplus
85 extern "C" {
86 #endif
87 
88 #ifdef CONFIG_ASSERT_NO_FILE_INFO
89 void assert_post_action(void);
90 #define __ASSERT_POST_ACTION() assert_post_action()
91 #else  /* CONFIG_ASSERT_NO_FILE_INFO */
92 void assert_post_action(const char *file, unsigned int line);
93 #define __ASSERT_POST_ACTION() assert_post_action(__FILE__, __LINE__)
94 #endif /* CONFIG_ASSERT_NO_FILE_INFO */
95 
96 /*
97  * When the assert test mode is enabled, the default kernel fatal error handler
98  * and the custom assert hook function may return in order to allow the test to
99  * proceed.
100  */
101 #ifdef CONFIG_ASSERT_TEST
102 #define __ASSERT_UNREACHABLE
103 #else
104 #define __ASSERT_UNREACHABLE CODE_UNREACHABLE
105 #endif
106 
107 #ifdef __cplusplus
108 }
109 #endif
110 
111 #define __ASSERT_NO_MSG(test)                                             \
112 	do {                                                              \
113 		if (!(test)) {                                            \
114 			__ASSERT_LOC(test);                               \
115 			__ASSERT_POST_ACTION();                           \
116 			__ASSERT_UNREACHABLE;                             \
117 		}                                                         \
118 	} while (false)
119 
120 #define __ASSERT(test, fmt, ...)                                          \
121 	do {                                                              \
122 		if (!(test)) {                                            \
123 			__ASSERT_LOC(test);                               \
124 			__ASSERT_MSG_INFO(fmt, ##__VA_ARGS__);            \
125 			__ASSERT_POST_ACTION();                           \
126 			__ASSERT_UNREACHABLE;                             \
127 		}                                                         \
128 	} while (false)
129 
130 #define __ASSERT_EVAL(expr1, expr2, test, fmt, ...)                \
131 	do {                                                       \
132 		expr2;                                             \
133 		__ASSERT(test, fmt, ##__VA_ARGS__);                \
134 	} while (false)
135 
136 #if (__ASSERT_ON == 1)
137 #warning "__ASSERT() statements are ENABLED"
138 #endif
139 #else
140 #define __ASSERT(test, fmt, ...) { }
141 #define __ASSERT_EVAL(expr1, expr2, test, fmt, ...) expr1
142 #define __ASSERT_NO_MSG(test) { }
143 #define __ASSERT_POST_ACTION() { }
144 #endif
145 #else
146 #define __ASSERT(test, fmt, ...) { }
147 #define __ASSERT_EVAL(expr1, expr2, test, fmt, ...) expr1
148 #define __ASSERT_NO_MSG(test) { }
149 #define __ASSERT_POST_ACTION() { }
150 #endif
151 
152 #endif /* ZEPHYR_INCLUDE_SYS___ASSERT_H_ */
153