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