qassert.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /*$file${include::qassert.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: qpc.qm
  4. * File: ${include::qassert.h}
  5. *
  6. * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * This code is covered by the following QP license:
  10. * License # : LicenseRef-QL-dual
  11. * Issued to : Any user of the QP/C real-time embedded framework
  12. * Framework(s) : qpc
  13. * Support ends : 2023-12-31
  14. * License scope:
  15. *
  16. * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
  17. *
  18. * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
  19. *
  20. * This software is dual-licensed under the terms of the open source GNU
  21. * General Public License version 3 (or any later version), or alternatively,
  22. * under the terms of one of the closed source Quantum Leaps commercial
  23. * licenses.
  24. *
  25. * The terms of the open source GNU General Public License version 3
  26. * can be found at: <www.gnu.org/licenses/gpl-3.0>
  27. *
  28. * The terms of the closed source Quantum Leaps commercial licenses
  29. * can be found at: <www.state-machine.com/licensing>
  30. *
  31. * Redistributions in source code must retain this top-level comment block.
  32. * Plagiarizing this software to sidestep the license obligations is illegal.
  33. *
  34. * Contact information:
  35. * <www.state-machine.com/licensing>
  36. * <info@state-machine.com>
  37. */
  38. /*$endhead${include::qassert.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  39. /*! @file
  40. * @brief Customizable and memory-efficient Design by Contract (DbC)
  41. * for embedded systems
  42. *
  43. * @note
  44. * This header file can be used in C, C++, and mixed C/C++ programs.
  45. *
  46. * @note
  47. * The preprocessor switch #Q_NASSERT disables checking assertions.
  48. * However, it is generally **not** advisable to disable assertions,
  49. * **especially** in the production code. Instead, the assertion
  50. * handler Q_onAssert() should be very carefully designed and tested.
  51. */
  52. #ifndef QASSERT_H_
  53. #define QASSERT_H_
  54. #ifdef __cplusplus
  55. extern "C" {
  56. #endif
  57. #ifndef Q_NASSERT
  58. /*$declare${DbC::active} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  59. /*${DbC::active::Q_DEFINE_THIS_MODULE} .....................................*/
  60. /*! Define the user-specified module name for assertions in this file.
  61. *
  62. * @details
  63. * Macro to be placed at the top of each C/C++ module to define the
  64. * single instance of the module name string to be used in reporting
  65. * assertions in this module. This macro takes the user-supplied parameter
  66. * `name_` instead of `__FILE__` to precisely control the name of the
  67. * module.
  68. *
  69. * @param[in] name_ string constant representing the module name
  70. *
  71. * @note
  72. * This macro should **not** be terminated by a semicolon.
  73. */
  74. #define Q_DEFINE_THIS_MODULE(name_) \
  75. static char const Q_this_module_[] = name_;
  76. /*${DbC::active::Q_ASSERT_ID} ..............................................*/
  77. /*! General-purpose assertion with user-specified ID number.
  78. *
  79. * @details
  80. * Evaluates the Boolean expression `expr_` and does nothing else when
  81. * it evaluates to 'true'. However, when `expr_` evaluates to 'false',
  82. * the Q_ASSERT_ID() macro calls the no-return function Q_onAssert().
  83. *
  84. * @param[in] id_ ID number (unique within the module) of the assertion
  85. * @param[in] expr_ Boolean expression to check
  86. *
  87. * @attention
  88. * When assertions are disabled (by defining the ::Q_NASSERT macro), the
  89. * Q_ASSERT_ID() macro expands to nothing, and consequently the Boolean
  90. * expression `expr_` is **not** evaluated and the callback function
  91. * Q_onAssert() is **not** called.
  92. */
  93. #define Q_ASSERT_ID(id_, expr_) ((expr_) \
  94. ? ((void)0) : Q_onAssert(&Q_this_module_[0], (id_)))
  95. /*${DbC::active::Q_ERROR_ID} ...............................................*/
  96. /*! Assertion with user-specified ID for a wrong path through the code
  97. *
  98. * @details
  99. * Calls the Q_onAssert() callback if ever executed. This assertion
  100. * takes the user-supplied parameter `id_` to identify the location of
  101. * this assertion within the file. This avoids the volatility of using
  102. * line numbers, which change whenever a line of code is added or removed
  103. * upstream from the assertion.
  104. *
  105. * @param[in] id_ ID number (unique within the module) of the assertion
  106. *
  107. * @note
  108. * Does noting if assertions are disabled with the ::Q_NASSERT switch.
  109. */
  110. #define Q_ERROR_ID(id_) Q_onAssert(&Q_this_module_[0], (id_))
  111. /*${DbC::active::Q_ALLEGE_ID} ..............................................*/
  112. /*! General purpose assertion with user-specified ID number that
  113. * **always** evaluates the `expr_` expression.
  114. *
  115. * @details
  116. * Like the Q_ASSERT_ID() macro, except it **always** evaluates the
  117. * `expr_` expression even when assertions are disabled with the
  118. * ::Q_NASSERT macro. However, when the ::Q_NASSERT macro is defined, the
  119. * Q_onAssert() callback is **not** called, even if `expr_` evaluates
  120. * to FALSE.
  121. *
  122. * @param[in] id_ ID number (unique within the module) of the assertion
  123. * @param[in] expr_ Boolean expression to check
  124. */
  125. #define Q_ALLEGE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
  126. /*$enddecl${DbC::active} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  127. #else
  128. /*$declare${DbC::inactive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  129. /*${DbC::inactive::Q_DEFINE_THIS_MODULE} ...................................*/
  130. /*! inactive version of Q_DEFINE_THIS_MODULE() */
  131. #define Q_DEFINE_THIS_MODULE(name_)
  132. /*${DbC::inactive::Q_ASSERT_ID} ............................................*/
  133. /*! inactive version of Q_ASSERT_ID() */
  134. #define Q_ASSERT_ID(id_, expr_) ((void)0)
  135. /*${DbC::inactive::Q_ERROR_ID} .............................................*/
  136. /*! inactive version of Q_ERROR_ID() */
  137. #define Q_ERROR_ID(id_) ((void)0)
  138. /*${DbC::inactive::Q_ALLEGE_ID} ............................................*/
  139. /*! inactive version of Q_ALLEGE_ID()
  140. *
  141. * @attention
  142. * The expression `expr_` **is** evaluated, even though assertion
  143. * callback Q_onAssert() is NOT called when `expr_` evaluates to
  144. * false.
  145. */
  146. #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_))
  147. /*$enddecl${DbC::inactive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  148. #endif
  149. /*$declare1${DbC} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  150. /*${DbC::Q_DEFINE_THIS_FILE} ...............................................*/
  151. /*! Define the file name (with `__FILE__`) for assertions in this file
  152. *
  153. * @details
  154. * Macro to be placed at the top of each C/C++ module to define the
  155. * single instance of the file name string to be used in reporting
  156. * assertions in this module.
  157. *
  158. * @note
  159. * The file name string literal is defined by means of the standard
  160. * preprocessor macro `__FILE__`. However, please note that, depending
  161. * on the compiler, the `__FILE__` macro might contain the whole path name
  162. * to the file, which might be inconvenient to log assertions.
  163. *
  164. * @attention
  165. * This macro should **not** be terminated by a semicolon.
  166. *
  167. * @sa Q_DEFINE_THIS_MODULE()
  168. */
  169. #define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__)
  170. /*${DbC::Q_ASSERT} .........................................................*/
  171. /*! General-purpose assertion (with __LINE__ used as location in the file)
  172. *
  173. * @details
  174. * Equivalent to Q_ASSERT_ID(), except it uses __LINE__ to identify the
  175. * assertion within a file.
  176. *
  177. * @param[in] expr_ Boolean expression to check
  178. *
  179. * @sa Q_ASSERT_ID()
  180. */
  181. #define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_))
  182. /*${DbC::Q_ERROR} ..........................................................*/
  183. /*! Assertion for a wrong path through the code
  184. *
  185. * @details
  186. * Calls the Q_onAssert() callback if ever executed.
  187. *
  188. * @note
  189. * This macro identifies the problem location with the line number,
  190. * which might change as the code is modified.
  191. *
  192. * @sa Q_ERROR_ID()
  193. */
  194. #define Q_ERROR() Q_ERROR_ID(__LINE__)
  195. /*${DbC::Q_REQUIRE_ID} .....................................................*/
  196. /*! Assertion for checking **preconditions**.
  197. *
  198. * @details
  199. * Equivalent to Q_ASSERT_ID(), except the name provides a better
  200. * documentation of the intention of this assertion.
  201. *
  202. * @param[in] id_ ID number (unique within the module) of the assertion
  203. * @param[in] expr_ Boolean expression
  204. */
  205. #define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
  206. /*${DbC::Q_REQUIRE} ........................................................*/
  207. /*! Assertion for checking preconditions (based on __LINE__).
  208. *
  209. * @details
  210. * Equivalent to Q_ASSERT(), except the name provides a better documentation
  211. * of the intention of this assertion.
  212. *
  213. * @param[in] expr_ Boolean expression
  214. */
  215. #define Q_REQUIRE(expr_) Q_ASSERT(expr_)
  216. /*${DbC::Q_ENSURE_ID} ......................................................*/
  217. /*! Assertion for checking postconditions.
  218. *
  219. * @details
  220. * Equivalent to Q_ASSERT_ID(), except the name provides a better documentation
  221. * of the intention of this assertion.
  222. *
  223. * @param[in] id_ ID number (unique within the module) of the assertion
  224. * @param[in] expr_ Boolean expression
  225. */
  226. #define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
  227. /*${DbC::Q_ENSURE} .........................................................*/
  228. /*! Assertion for checking postconditions.
  229. *
  230. * @details
  231. * Equivalent to Q_ASSERT(), except the name provides a better documentation
  232. * of the intention of this assertion.
  233. *
  234. * @param[in] expr_ Boolean expression
  235. */
  236. #define Q_ENSURE(expr_) Q_ASSERT(expr_)
  237. /*${DbC::Q_INVARIANT_ID} ...................................................*/
  238. /*! Assertion for checking invariants.
  239. *
  240. * @details
  241. * Equivalent to Q_ASSERT_ID(), except the name provides a better
  242. * documentation of the intention of this assertion.
  243. *
  244. * @param[in] id_ ID number (unique within the module) of the assertion
  245. * @param[in] expr_ Boolean expression
  246. */
  247. #define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
  248. /*${DbC::Q_INVARIANT} ......................................................*/
  249. /*! Assertion for checking invariants.
  250. *
  251. * @details
  252. * Equivalent to Q_ASSERT(), except the name provides a better documentation
  253. * of the intention of this assertion.
  254. *
  255. * @param[in] expr_ Boolean expression
  256. */
  257. #define Q_INVARIANT(expr_) Q_ASSERT(expr_)
  258. /*${DbC::Q_ALLEGE} .........................................................*/
  259. /*! General purpose assertion with user-specified ID number that
  260. * **always** evaluates the `expr_` expression.
  261. *
  262. * @details
  263. * Equivalent to Q_ALLEGE_ID(), except it identifies the problem location
  264. * with the line number `__LINE__`, which might change as the code is modified.
  265. *
  266. * @param[in] expr_ Boolean expression to check
  267. *
  268. * @sa Q_ALLEGE_ID()
  269. */
  270. #define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_))
  271. /*${DbC::Q_ASSERT_STATIC} ..................................................*/
  272. /*! Static (compile-time) assertion.
  273. *
  274. * @details
  275. * This type of assertion deliberately causes a compile-time error when
  276. * the `expr_` Boolean expression evaluates to FALSE. The macro exploits
  277. * the fact that in C/C++ a dimension of an array cannot be negative.
  278. * The compile-time assertion has no runtime side effects.
  279. *
  280. * @param[in] expr_ Compile-time Boolean expression
  281. *
  282. * @note
  283. * The static assertion macro is provided for backwards compatibility with
  284. * older C standards. Newer C11 supports `_Static_assert()`, which should
  285. * be used instead of Q_ASSERT_STATIC().
  286. */
  287. #define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1]
  288. /*${DbC::Q_NORETURN} .......................................................*/
  289. #ifndef Q_NORETURN
  290. /*! No-return function specifier for the Q_onAssert() callback function.
  291. *
  292. * @details
  293. * If the `Q_NORETURN` macro is undefined, the default definition uses
  294. * the C99 specifier `_Noreturn`.
  295. *
  296. * @note
  297. * The `Q_NORETURN` macro can be defined in the QP port (typically in
  298. * `qep_port.h` or `qep_port.hpp`). If such definition is porvided
  299. * the default won't be used.
  300. *
  301. * @trace
  302. * @tr{PQA01_4}
  303. */
  304. #define Q_NORETURN _Noreturn void
  305. #endif /* ndef Q_NORETURN */
  306. /*${DbC::int_t} ............................................................*/
  307. #ifndef QP_VERSION
  308. /*! typedef for assertions-ids and line numbers in assertions.
  309. *
  310. * @details
  311. * This typedef specifies integer type for exclusive use in assertions.
  312. * Use of this type, rather than plain 'int', is in compliance
  313. * with the MISRA-C 2012 Dir 4.6 (adv).
  314. */
  315. typedef int int_t;
  316. #endif /* ndef QP_VERSION */
  317. /*${DbC::Q_onAssert} .......................................................*/
  318. /*! Callback function invoked in case of an assertion failure.
  319. *
  320. * @details
  321. * This callback function needs to be defined in the application to perform
  322. * any corrective action after a non-recoverable error has been detected.
  323. * The Q_onAssert() function is the last line of defense after the
  324. * system failure and its implementation shouild be very **carefully**
  325. * designed and **tested** under various fault conditions, including but
  326. * not limited to: stack overflow, stack corruption, or calling Q_onAssert()
  327. * from an interrupt.
  328. *
  329. * @param[in] module name of the file/module in which the assertion failed
  330. * (constant, zero-terminated C string)
  331. * @param[in] location location of the assertion within the module. This could
  332. * be a line number or a user-specified ID-number.
  333. *
  334. * @returns
  335. * This callback function should **not return** (see ::Q_NORETURN),
  336. * as continuation after an assertion failure does not make sense.
  337. *
  338. * @note
  339. * During debugging, Q_onAssert() is an ideal place to put a breakpoint.
  340. * For deployment, tt is typically a **bad idea** to implement Q_onAssert()
  341. * as an endless loop that ties up the CPU (denial of service).
  342. *
  343. * Called by the following: Q_ASSERT_ID(), Q_ERROR_ID(), Q_REQUIRE_ID(),
  344. * Q_ENSURE_ID(), Q_INVARIANT_ID() and Q_ALLEGE_ID() as well as:
  345. * Q_ASSERT(), Q_ERROR(), Q_REQUIRE(), Q_ENSURE(), Q_INVARIANT(),
  346. * and Q_ALLEGE().
  347. *
  348. * @trace
  349. * @tr{PQA01_4}
  350. */
  351. Q_NORETURN Q_onAssert(
  352. char const * module,
  353. int_t location);
  354. /*${DbC::Q_DIM} ............................................................*/
  355. #ifndef QP_VERSION
  356. /*! Helper macro to calculate static dimension of a 1-dim `array_`
  357. *
  358. * @param array_ 1-dimensional array
  359. * @returns the length of the array (number of elements it can hold)
  360. */
  361. #define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
  362. #endif /* ndef QP_VERSION */
  363. /*$enddecl${DbC} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  364. #ifdef __cplusplus
  365. }
  366. #endif
  367. #endif /* QASSERT_H_ */