| /**************************************************************************** |
| * include/assert.h |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| #ifndef __INCLUDE_ASSERT_H |
| #define __INCLUDE_ASSERT_H |
| |
| #ifndef __ASSEMBLY__ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/compiler.h> |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| /* Macro Name: PANIC, ASSERT, VERIFY, et al. */ |
| |
| #undef PANIC /* Unconditional abort */ |
| #undef ASSERT /* Assert if the condition is not true */ |
| #undef VERIFY /* Assert if a function returns a negative value */ |
| #undef DEBUGPANIC /* Like PANIC, but only if CONFIG_DEBUG_ASSERTIONS is defined */ |
| #undef DEBUGASSERT /* Like ASSERT, but only if CONFIG_DEBUG_ASSERTIONS is defined */ |
| #undef DEBUGVERIFY /* Like VERIFY, but only if CONFIG_DEBUG_ASSERTIONS is defined */ |
| |
| /* Macro to define the assertions file name and file line |
| * | Function |CONFIG | Show name/line | |
| * | --- | --- | --- | |
| * |assert(), ASSERT()|CONFIG_ASSERTIONS_FILENAME=y | Yes | |
| * |assert(), ASSERT()|CONFIG_ASSERTIONS_FILENAME=n | No | |
| * |DEBUGASSERT() |CONFIG_DEBUG_ASSERTIONS_FILENAME=y| Yes | |
| * |DEBUGASSERT() |CONFIG_DEBUG_ASSERTIONS_FILENAME=n| No | |
| */ |
| |
| #ifdef CONFIG_HAVE_FILENAME |
| # ifdef CONFIG_DEBUG_ASSERTIONS_FILENAME |
| # define __DEBUG_ASSERT_FILE__ __FILE__ |
| # define __DEBUG_ASSERT_LINE__ __LINE__ |
| # endif |
| # ifdef CONFIG_ASSERTIONS_FILENAME |
| # define __ASSERT_FILE__ __FILE__ |
| # define __ASSERT_LINE__ __LINE__ |
| # endif |
| #endif |
| |
| #ifndef __DEBUG_ASSERT_FILE__ |
| # define __DEBUG_ASSERT_FILE__ 0 |
| # define __DEBUG_ASSERT_LINE__ 0 |
| #endif |
| |
| #ifndef __ASSERT_FILE__ |
| # define __ASSERT_FILE__ 0 |
| # define __ASSERT_LINE__ 0 |
| #endif |
| |
| #define PANIC() __assert(__ASSERT_FILE__, __ASSERT_LINE__, "panic") |
| #define PANIC_WITH_REGS(msg, regs) _assert(__ASSERT_FILE__, \ |
| __ASSERT_LINE__, msg, regs) |
| |
| #define __ASSERT__(f, file, line, _f) \ |
| do \ |
| { \ |
| if (predict_false(!(f))) \ |
| __assert(file, line, _f); \ |
| } \ |
| while (0) |
| |
| #define __VERIFY__(f, file, line, _f) \ |
| do \ |
| { \ |
| if (predict_false((f) < 0)) \ |
| __assert(file, line, _f); \ |
| } \ |
| while (0) |
| |
| #ifdef CONFIG_DEBUG_ASSERTIONS_EXPRESSION |
| # define _ASSERT(f,file,line) __ASSERT__(f, file, line, #f) |
| # define _VERIFY(f,file,line) __VERIFY__(f, file, line, #f) |
| #else |
| # define _ASSERT(f,file,line) __ASSERT__(f, file, line, NULL) |
| # define _VERIFY(f,file,line) __VERIFY__(f, file, line, NULL) |
| #endif |
| |
| #ifdef CONFIG_DEBUG_ASSERTIONS |
| # define DEBUGPANIC() __assert(__DEBUG_ASSERT_FILE__, __DEBUG_ASSERT_LINE__, "panic") |
| # define DEBUGASSERT(f) _ASSERT(f, __DEBUG_ASSERT_FILE__, __DEBUG_ASSERT_LINE__) |
| # define DEBUGVERIFY(f) _VERIFY(f, __DEBUG_ASSERT_FILE__, __DEBUG_ASSERT_LINE__) |
| #else |
| # define DEBUGPANIC() |
| # define DEBUGASSERT(f) ((void)(1 || (f))) |
| # define DEBUGVERIFY(f) ((void)(f)) |
| #endif |
| |
| /* The C standard states that if NDEBUG is defined, assert will do nothing. |
| * Users can define and undefine NDEBUG as they see fit to choose when assert |
| * does something or does not do anything. |
| * |
| * #define assert(ignore) ((void)0) |
| * |
| * Reference link: |
| * https://pubs.opengroup.org/onlinepubs/009695399/basedefs/assert.h.html |
| * |
| * ASSERT/VERIFY is a non-standard interface, implemented using internal |
| * |
| */ |
| |
| #ifdef NDEBUG |
| # define assert(f) ((void)0) |
| # define ASSERT(f) ((void)(1 || (f))) |
| # define VERIFY(f) ((void)(1 || (f))) |
| #else |
| # define assert(f) _ASSERT(f, __ASSERT_FILE__, __ASSERT_LINE__) |
| # define ASSERT(f) _ASSERT(f, __ASSERT_FILE__, __ASSERT_LINE__) |
| # define VERIFY(f) _VERIFY(f, __ASSERT_FILE__, __ASSERT_LINE__) |
| #endif |
| |
| /* Suppress 3rd party library redefine _assert/__assert */ |
| |
| #define _assert _assert |
| #define __assert __assert |
| |
| /* Definition required for C11 compile-time assertion checking. The |
| * static_assert macro simply expands to the _Static_assert keyword. |
| */ |
| |
| #ifndef __cplusplus |
| # if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199901L |
| # define static_assert _Static_assert |
| # else |
| # define static_assert(cond, msg) \ |
| extern int (*__static_assert_function (void)) \ |
| [!!sizeof (struct { int __error_if_negative: (cond) ? 2 : -1; })] |
| # endif |
| #endif |
| |
| /* Force a compilation error if condition is true, but also produce a |
| * result (of value 0 and type int), so the expression can be used |
| * e.g. in a structure initializer (or where-ever else comma expressions |
| * aren't permitted). |
| */ |
| |
| #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) |
| |
| /**************************************************************************** |
| * Public Data |
| ****************************************************************************/ |
| |
| #ifdef __cplusplus |
| #define EXTERN extern "C" |
| extern "C" |
| { |
| #else |
| #define EXTERN extern |
| #endif |
| |
| /**************************************************************************** |
| * Public Function Prototypes |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: _assert |
| * |
| * Description: |
| * This is the assert system call that performs the core dump etc. Function |
| * might not return if it is not safe to do so (in IRQ or in IDLE task). |
| * |
| ****************************************************************************/ |
| |
| void _assert(FAR const char *filename, int linenum, |
| FAR const char *msg, FAR void *regs); |
| |
| /**************************************************************************** |
| * Name: __assert |
| * |
| * Description: |
| * This is the user space assert procedure. |
| * |
| ****************************************************************************/ |
| |
| void __assert(FAR const char *filename, int linenum, |
| FAR const char *msg) noreturn_function; |
| |
| #undef EXTERN |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* __ASSEMBLY__ */ |
| #endif /* __INCLUDE_ASSERT_H */ |