QP/C
7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qassert.h
Go to the documentation of this file.
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 #QP_NSSM disables the QP Software Self-
48
* Monitoring (SSM). However, it is generally **not** advisable to disable
49
* SSM **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
55
#ifdef __cplusplus
56
extern
"C"
{
57
#endif
58
59
#ifndef QP_NSSM
60
/*$declare${DbC::active} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
61
62
/*${DbC::active::Q_DEFINE_THIS_MODULE} .....................................*/
63
/*! Define the user-specified module name for assertions in this file.
64
*
65
* @details
66
* Macro to be placed at the top of each C/C++ module to define the
67
* single instance of the module name string to be used in reporting
68
* assertions in this module. This macro takes the user-supplied parameter
69
* `name_` instead of `__FILE__` to precisely control the name of the
70
* module.
71
*
72
* @param[in] name_ string constant representing the module name
73
*
74
* @note
75
* This macro should **not** be terminated by a semicolon.
76
*
77
* @trace
78
* - @tr{DVP-QP-PCLP-823}
79
*/
80
#define Q_DEFINE_THIS_MODULE(name_) \
81
static char const Q_this_module_[] = name_;
82
83
/*${DbC::active::Q_ASSERT_ID} ..............................................*/
84
/*! General-purpose assertion with user-specified ID number.
85
*
86
* @details
87
* Evaluates the Boolean expression `expr_` and does nothing else when
88
* it evaluates to 'true'. However, when `expr_` evaluates to 'false',
89
* the Q_ASSERT_ID() macro calls the no-return function Q_onAssert().
90
*
91
* @param[in] id_ ID number (unique within the module) of the assertion
92
* @param[in] expr_ Boolean expression to check
93
*
94
* @attention
95
* When QP Software Self-Monitoring (SSM) is disabled (by defining
96
* the macro #QP_NSSM), the Q_ASSERT_ID() macro expands to nothing, and
97
* consequently the Boolean expression `expr_` is **not** evaluated and
98
* the callback function Q_onAssert() is **not** called.
99
*
100
* @trace
101
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
102
*/
103
#define Q_ASSERT_ID(id_, expr_) ((expr_) \
104
? ((void)0) : Q_onAssert(&Q_this_module_[0], (id_)))
105
106
/*${DbC::active::Q_ERROR_ID} ...............................................*/
107
/*! Assertion with user-specified ID for a wrong path through the code
108
*
109
* @details
110
* Calls the Q_onAssert() callback if ever executed. This assertion
111
* takes the user-supplied parameter `id_` to identify the location of
112
* this assertion within the file. This avoids the volatility of using
113
* line numbers, which change whenever a line of code is added or removed
114
* upstream from the assertion.
115
*
116
* @param[in] id_ ID number (unique within the module) of the assertion
117
*
118
* @note
119
* Does noting when QP Software Self-Monitoring (SSM) is disabled
120
* (by defining the macro #QP_NSSM).
121
*
122
* @trace
123
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
124
*/
125
#define Q_ERROR_ID(id_) Q_onAssert(&Q_this_module_[0], (id_))
126
127
/*${DbC::active::Q_ALLEGE_ID} ..............................................*/
128
/*! General purpose assertion with user-specified ID number that
129
* **always** evaluates the `expr_` expression.
130
*
131
* @details
132
* Like the Q_ASSERT_ID() macro, except it **always** evaluates the
133
* `expr_` expression even when assertions are disabled with the
134
* #QP_NSSM macro. However, when the #QP_NSSM macro is defined, the
135
* Q_onAssert() callback is **not** called, even if `expr_` evaluates
136
* to FALSE.
137
*
138
* @param[in] id_ ID number (unique within the module) of the assertion
139
* @param[in] expr_ Boolean expression to check
140
*
141
* @trace
142
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
143
*/
144
#define Q_ALLEGE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
145
/*$enddecl${DbC::active} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
146
#else
147
/*$declare${DbC::inactive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
148
149
/*${DbC::inactive::Q_DEFINE_THIS_MODULE} ...................................*/
150
/*! inactive version of Q_DEFINE_THIS_MODULE() */
151
#define Q_DEFINE_THIS_MODULE(name_)
152
153
/*${DbC::inactive::Q_ASSERT_ID} ............................................*/
154
/*! inactive version of Q_ASSERT_ID() */
155
#define Q_ASSERT_ID(id_, expr_) ((void)0)
156
157
/*${DbC::inactive::Q_ERROR_ID} .............................................*/
158
/*! inactive version of Q_ERROR_ID() */
159
#define Q_ERROR_ID(id_) ((void)0)
160
161
/*${DbC::inactive::Q_ALLEGE_ID} ............................................*/
162
/*! inactive version of Q_ALLEGE_ID()
163
*
164
* @attention
165
* The expression `expr_` **is** evaluated, even though assertion
166
* callback Q_onAssert() is NOT called when `expr_` evaluates to
167
* false.
168
*/
169
#define Q_ALLEGE_ID(id_, expr_) ((void)(expr_))
170
/*$enddecl${DbC::inactive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
171
#endif
172
173
/*$declare1${DbC} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
174
175
/*${DbC::Q_DEFINE_THIS_FILE} ...............................................*/
176
/*! Define the file name (with `__FILE__`) for assertions in this file
177
*
178
* @details
179
* Macro to be placed at the top of each C/C++ module to define the
180
* single instance of the file name string to be used in reporting
181
* assertions in this module.
182
*
183
* @note
184
* The file name string literal is defined by means of the standard
185
* preprocessor macro `__FILE__`. However, please note that, depending
186
* on the compiler, the `__FILE__` macro might contain the whole path name
187
* to the file, which might be inconvenient to log assertions.
188
*
189
* @attention
190
* This macro should **not** be terminated by a semicolon.
191
*
192
* @trace
193
* - @tr{DVP-QP-PCLP-823}
194
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
195
*/
196
#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__)
197
198
/*${DbC::Q_ASSERT} .........................................................*/
199
/*! General-purpose assertion (with __LINE__ used as location in the file)
200
*
201
* @details
202
* Equivalent to Q_ASSERT_ID(), except it uses __LINE__ to identify the
203
* assertion within a file.
204
*
205
* @param[in] expr_ Boolean expression to check
206
*
207
* @trace
208
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
209
*/
210
#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_))
211
212
/*${DbC::Q_ERROR} ..........................................................*/
213
/*! Assertion for a wrong path through the code
214
*
215
* @details
216
* Calls the Q_onAssert() callback if ever executed.
217
*
218
* @note
219
* This macro identifies the problem location with the line number,
220
* which might change as the code is modified.
221
*
222
* @trace
223
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
224
*/
225
#define Q_ERROR() Q_ERROR_ID(__LINE__)
226
227
/*${DbC::Q_REQUIRE_ID} .....................................................*/
228
/*! Assertion for checking **preconditions**.
229
*
230
* @details
231
* Equivalent to Q_ASSERT_ID(), except the name provides a better
232
* documentation of the intention of this assertion.
233
*
234
* @param[in] id_ ID number (unique within the module) of the assertion
235
* @param[in] expr_ Boolean expression
236
*
237
* @trace
238
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
239
*/
240
#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
241
242
/*${DbC::Q_REQUIRE} ........................................................*/
243
/*! Assertion for checking preconditions (based on __LINE__).
244
*
245
* @details
246
* Equivalent to Q_ASSERT(), except the name provides a better documentation
247
* of the intention of this assertion.
248
*
249
* @param[in] expr_ Boolean expression
250
*
251
* @trace
252
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
253
*/
254
#define Q_REQUIRE(expr_) Q_ASSERT(expr_)
255
256
/*${DbC::Q_ENSURE_ID} ......................................................*/
257
/*! Assertion for checking postconditions.
258
*
259
* @details
260
* Equivalent to Q_ASSERT_ID(), except the name provides a better documentation
261
* of the intention of this assertion.
262
*
263
* @param[in] id_ ID number (unique within the module) of the assertion
264
* @param[in] expr_ Boolean expression
265
*/
266
#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
267
268
/*${DbC::Q_ENSURE} .........................................................*/
269
/*! Assertion for checking postconditions.
270
*
271
* @details
272
* Equivalent to Q_ASSERT(), except the name provides a better documentation
273
* of the intention of this assertion.
274
*
275
* @param[in] expr_ Boolean expression
276
*
277
* @trace
278
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
279
*/
280
#define Q_ENSURE(expr_) Q_ASSERT(expr_)
281
282
/*${DbC::Q_INVARIANT_ID} ...................................................*/
283
/*! Assertion for checking invariants.
284
*
285
* @details
286
* Equivalent to Q_ASSERT_ID(), except the name provides a better
287
* documentation of the intention of this assertion.
288
*
289
* @param[in] id_ ID number (unique within the module) of the assertion
290
* @param[in] expr_ Boolean expression
291
*
292
* @trace
293
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
294
*/
295
#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_))
296
297
/*${DbC::Q_INVARIANT} ......................................................*/
298
/*! Assertion for checking invariants.
299
*
300
* @details
301
* Equivalent to Q_ASSERT(), except the name provides a better documentation
302
* of the intention of this assertion.
303
*
304
* @param[in] expr_ Boolean expression
305
*
306
* @trace
307
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
308
*/
309
#define Q_INVARIANT(expr_) Q_ASSERT(expr_)
310
311
/*${DbC::Q_ALLEGE} .........................................................*/
312
/*! General purpose assertion with user-specified ID number that
313
* **always** evaluates the `expr_` expression.
314
*
315
* @details
316
* Equivalent to Q_ALLEGE_ID(), except it identifies the problem location
317
* with the line number `__LINE__`, which might change as the code is modified.
318
*
319
* @param[in] expr_ Boolean expression to check
320
*
321
* @trace
322
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
323
*/
324
#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_))
325
326
/*${DbC::Q_ASSERT_STATIC} ..................................................*/
327
/*! Static (compile-time) assertion.
328
*
329
* @details
330
* This type of assertion deliberately causes a compile-time error when
331
* the `expr_` Boolean expression evaluates to FALSE. The macro exploits
332
* the fact that in C/C++ a dimension of an array cannot be negative.
333
* The compile-time assertion has no runtime side effects.
334
*
335
* @param[in] expr_ Compile-time Boolean expression
336
*
337
* @note
338
* The static assertion macro is provided for backwards compatibility with
339
* older C standards. Newer C11 supports `_Static_assert()`, which should
340
* be used instead of Q_ASSERT_STATIC().
341
*
342
* @trace
343
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
344
*/
345
#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1]
346
347
/*${DbC::Q_NORETURN} .......................................................*/
348
#ifndef Q_NORETURN
349
/*! No-return function specifier for the Q_onAssert() callback function.
350
*
351
* @details
352
* If the `Q_NORETURN` macro is undefined, the default definition uses
353
* the C99 specifier `_Noreturn`.
354
*
355
* @note
356
* The `Q_NORETURN` macro can be defined in the QP port (typically in
357
* `qep_port.h` or `qep_port.hpp`). If such definition is porvided
358
* the default won't be used.
359
*
360
* @trace
361
* - @tr{DVP-QP-MC3-R01_04}
362
*/
363
#define Q_NORETURN _Noreturn void
364
#endif
/* ndef Q_NORETURN */
365
366
/*${DbC::int_t} ............................................................*/
367
#ifndef QP_VERSION
368
/*! typedef for assertions-ids and line numbers in assertions.
369
*
370
* @details
371
* This typedef specifies integer type for exclusive use in assertions.
372
* Use of this type, rather than plain 'int', is in compliance
373
* with the MISRA-C:2012 Directive 4.6 (Advisory).
374
*/
375
typedef
int
int_t
;
376
#endif
/* ndef QP_VERSION */
377
378
/*${DbC::Q_onAssert} .......................................................*/
379
/*! Callback function invoked in case of an assertion failure.
380
*
381
* @details
382
* This callback function needs to be defined in the application to perform
383
* any corrective action after a non-recoverable error has been detected.
384
* The Q_onAssert() function is the last line of defense after the
385
* system failure and its implementation shouild be very **carefully**
386
* designed and **tested** under various fault conditions, including but
387
* not limited to: stack overflow, stack corruption, or calling Q_onAssert()
388
* from an interrupt.
389
*
390
* @param[in] module name of the file/module in which the assertion failed
391
* (constant, zero-terminated C string)
392
* @param[in] location location of the assertion within the module. This could
393
* be a line number or a user-specified ID-number.
394
*
395
* @returns
396
* This callback function should **not return** (see ::Q_NORETURN),
397
* as continuation after an assertion failure does not make sense.
398
*
399
* @note
400
* During debugging, Q_onAssert() is an ideal place to put a breakpoint.
401
* For deployment, tt is typically a **bad idea** to implement Q_onAssert()
402
* as an endless loop that ties up the CPU (denial of service).
403
*
404
* Called by the following: Q_ASSERT_ID(), Q_ERROR_ID(), Q_REQUIRE_ID(),
405
* Q_ENSURE_ID(), Q_INVARIANT_ID() and Q_ALLEGE_ID() as well as:
406
* Q_ASSERT(), Q_ERROR(), Q_REQUIRE(), Q_ENSURE(), Q_INVARIANT(),
407
* and Q_ALLEGE().
408
*/
409
Q_NORETURN
Q_onAssert
(
410
char
const
* module,
411
int_t
location);
412
413
/*${DbC::Q_DIM} ............................................................*/
414
#ifndef QP_VERSION
415
/*! Helper macro to calculate static dimension of a 1-dim `array_`
416
*
417
* @param array_ 1-dimensional array
418
*
419
* @returns
420
* The length of the array (number of elements it can hold)
421
*
422
* @trace
423
* - @tr{DVP-QP-MC3-D04_09A} (false-positive)
424
*/
425
#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
426
#endif
/* ndef QP_VERSION */
427
/*$enddecl${DbC} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
428
429
#ifdef __cplusplus
430
}
431
#endif
432
433
#endif
/* QASSERT_H_ */
Q_NORETURN
#define Q_NORETURN
Definition:
qassert.h:363
Q_onAssert
Q_NORETURN Q_onAssert(char const *module, int_t location)
Definition:
qutest.c:112
int_t
int int_t
Definition:
qassert.h:375
include
qassert.h
© 2005-2023 Quantum Leaps
|
Using Online Help
|
QP/C 7.2.2
| Updated on Sat May 13 2023
© 2005-2023 Quantum Leaps
|
Using Online Help
|
QP/C 7.2.2
| Updated on Sat May 13 2023