1 /* 2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #pragma once 7 8 #include "esp_err.h" 9 #include "esp_log.h" 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 15 /** 16 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns. 17 */ 18 #if defined(CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT) 19 #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \ 20 (void)log_tag; \ 21 esp_err_t err_rc_ = (x); \ 22 if (unlikely(err_rc_ != ESP_OK)) { \ 23 return err_rc_; \ 24 } \ 25 } while(0) 26 27 /** 28 * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR. 29 */ 30 #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \ 31 (void)log_tag; \ 32 esp_err_t err_rc_ = (x); \ 33 if (unlikely(err_rc_ != ESP_OK)) { \ 34 return err_rc_; \ 35 } \ 36 } while(0) 37 38 /** 39 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message, 40 * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'. 41 */ 42 #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \ 43 (void)log_tag; \ 44 esp_err_t err_rc_ = (x); \ 45 if (unlikely(err_rc_ != ESP_OK)) { \ 46 ret = err_rc_; \ 47 goto goto_tag; \ 48 } \ 49 } while(0) 50 51 /** 52 * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR. 53 */ 54 #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \ 55 (void)log_tag; \ 56 esp_err_t err_rc_ = (x); \ 57 if (unlikely(err_rc_ != ESP_OK)) { \ 58 ret = err_rc_; \ 59 goto goto_tag; \ 60 } \ 61 } while(0) 62 63 /** 64 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message 65 * and returns with the supplied 'err_code'. 66 */ 67 #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \ 68 (void)log_tag; \ 69 if (unlikely(!(a))) { \ 70 return err_code; \ 71 } \ 72 } while(0) 73 74 /** 75 * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR. 76 */ 77 #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \ 78 (void)log_tag; \ 79 if (unlikely(!(a))) { \ 80 return err_code; \ 81 } \ 82 } while(0) 83 84 /** 85 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message, 86 * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'. 87 */ 88 #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \ 89 (void)log_tag; \ 90 if (unlikely(!(a))) { \ 91 ret = err_code; \ 92 goto goto_tag; \ 93 } \ 94 } while (0) 95 96 /** 97 * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR. 98 */ 99 #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \ 100 (void)log_tag; \ 101 if (unlikely(!(a))) { \ 102 ret = err_code; \ 103 goto goto_tag; \ 104 } \ 105 } while (0) 106 107 #else // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT 108 109 /** 110 * In the future, we want to switch to C++20. We also want to become compatible with clang. 111 * Hence, we provide two versions of the following macros. The first one is using the GNU extension \#\#__VA_ARGS__. 112 * The second one is using the C++20 feature __VA_OPT__(,). This allows users to compile their code with 113 * standard C++20 enabled instead of the GNU extension. Below C++20, we haven't found any good alternative to 114 * using \#\#__VA_ARGS__. 115 */ 116 #if defined(__cplusplus) && (__cplusplus > 201703L) 117 118 /** 119 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns. 120 */ 121 #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \ 122 esp_err_t err_rc_ = (x); \ 123 if (unlikely(err_rc_ != ESP_OK)) { \ 124 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 125 return err_rc_; \ 126 } \ 127 } while(0) 128 129 /** 130 * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR. 131 */ 132 #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \ 133 esp_err_t err_rc_ = (x); \ 134 if (unlikely(err_rc_ != ESP_OK)) { \ 135 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 136 return err_rc_; \ 137 } \ 138 } while(0) 139 140 /** 141 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message, 142 * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'. 143 */ 144 #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \ 145 esp_err_t err_rc_ = (x); \ 146 if (unlikely(err_rc_ != ESP_OK)) { \ 147 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 148 ret = err_rc_; \ 149 goto goto_tag; \ 150 } \ 151 } while(0) 152 153 /** 154 * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR. 155 */ 156 #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \ 157 esp_err_t err_rc_ = (x); \ 158 if (unlikely(err_rc_ != ESP_OK)) { \ 159 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 160 ret = err_rc_; \ 161 goto goto_tag; \ 162 } \ 163 } while(0) 164 165 /** 166 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message 167 * and returns with the supplied 'err_code'. 168 */ 169 #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \ 170 if (unlikely(!(a))) { \ 171 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 172 return err_code; \ 173 } \ 174 } while(0) 175 176 /** 177 * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR. 178 */ 179 #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \ 180 if (unlikely(!(a))) { \ 181 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 182 return err_code; \ 183 } \ 184 } while(0) 185 186 /** 187 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message, 188 * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'. 189 */ 190 #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \ 191 if (unlikely(!(a))) { \ 192 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 193 ret = err_code; \ 194 goto goto_tag; \ 195 } \ 196 } while (0) 197 198 /** 199 * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR. 200 */ 201 #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \ 202 if (unlikely(!(a))) { \ 203 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \ 204 ret = err_code; \ 205 goto goto_tag; \ 206 } \ 207 } while (0) 208 209 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 210 211 /** 212 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message and returns. 213 */ 214 #define ESP_RETURN_ON_ERROR(x, log_tag, format, ...) do { \ 215 esp_err_t err_rc_ = (x); \ 216 if (unlikely(err_rc_ != ESP_OK)) { \ 217 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 218 return err_rc_; \ 219 } \ 220 } while(0) 221 222 /** 223 * A version of ESP_RETURN_ON_ERROR() macro that can be called from ISR. 224 */ 225 #define ESP_RETURN_ON_ERROR_ISR(x, log_tag, format, ...) do { \ 226 esp_err_t err_rc_ = (x); \ 227 if (unlikely(err_rc_ != ESP_OK)) { \ 228 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 229 return err_rc_; \ 230 } \ 231 } while(0) 232 233 /** 234 * Macro which can be used to check the error code. If the code is not ESP_OK, it prints the message, 235 * sets the local variable 'ret' to the code, and then exits by jumping to 'goto_tag'. 236 */ 237 #define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format, ...) do { \ 238 esp_err_t err_rc_ = (x); \ 239 if (unlikely(err_rc_ != ESP_OK)) { \ 240 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 241 ret = err_rc_; \ 242 goto goto_tag; \ 243 } \ 244 } while(0) 245 246 /** 247 * A version of ESP_GOTO_ON_ERROR() macro that can be called from ISR. 248 */ 249 #define ESP_GOTO_ON_ERROR_ISR(x, goto_tag, log_tag, format, ...) do { \ 250 esp_err_t err_rc_ = (x); \ 251 if (unlikely(err_rc_ != ESP_OK)) { \ 252 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 253 ret = err_rc_; \ 254 goto goto_tag; \ 255 } \ 256 } while(0) 257 258 /** 259 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message 260 * and returns with the supplied 'err_code'. 261 */ 262 #define ESP_RETURN_ON_FALSE(a, err_code, log_tag, format, ...) do { \ 263 if (unlikely(!(a))) { \ 264 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 265 return err_code; \ 266 } \ 267 } while(0) 268 269 /** 270 * A version of ESP_RETURN_ON_FALSE() macro that can be called from ISR. 271 */ 272 #define ESP_RETURN_ON_FALSE_ISR(a, err_code, log_tag, format, ...) do { \ 273 if (unlikely(!(a))) { \ 274 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 275 return err_code; \ 276 } \ 277 } while(0) 278 279 /** 280 * Macro which can be used to check the condition. If the condition is not 'true', it prints the message, 281 * sets the local variable 'ret' to the supplied 'err_code', and then exits by jumping to 'goto_tag'. 282 */ 283 #define ESP_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) do { \ 284 if (unlikely(!(a))) { \ 285 ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 286 ret = err_code; \ 287 goto goto_tag; \ 288 } \ 289 } while (0) 290 291 /** 292 * A version of ESP_GOTO_ON_FALSE() macro that can be called from ISR. 293 */ 294 #define ESP_GOTO_ON_FALSE_ISR(a, err_code, goto_tag, log_tag, format, ...) do { \ 295 if (unlikely(!(a))) { \ 296 ESP_EARLY_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 297 ret = err_code; \ 298 goto goto_tag; \ 299 } \ 300 } while (0) 301 302 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 303 304 #endif // !CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT 305 306 307 #ifdef __cplusplus 308 } 309 #endif 310