-
Notifications
You must be signed in to change notification settings - Fork 1
/
assert_engine.h
346 lines (304 loc) · 25 KB
/
assert_engine.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/**
* @file assert_engine.h
* @brief This library for check expressions and send message if expressions is true on RUNTIME and on DEBUG version.
* If NDEBUG is not defined some expressions has change to empty define. (programmer must uncommit NDEBUG if code version released)
*
* @date
* @author Shpegun60
*/
#ifndef __ASSERT_ENGINE_H_
#define __ASSERT_ENGINE_H_ 1
#
#// this library recomended include only .c or .cpp file!!!!!!!!!!!!!!!!
#
#// C++ linking for mixed C++/C code
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#
#include "assert_engine_port.h"
#include "assert_func.h"
#
#
#/*
# * *****************************************************************************************************************************************************************************
# * smart asserts settings
# * *****************************************************************************************************************************************************************************
# */
#
//#define NDEBUG // uncommit this if program in release version
// =====> if NDEBUG is uncommited bellow defines have no meaning!!!!! <=====================================
//#define M_MESSAGE_ALWAYS_ENABLE 1 // enabling runtime assert message filter and additon library information (see additional information macro)
//#define M_ASSERT_MSG_TEXT_DISABLE 1 // disabling sending assert message text and do not saving this in .text section
//#define M_ASSERT_EXPR_DISABLE 1 // disabling sending assert expression text, value and do not saving this in .text section
//#define M_ASSERT_FILE_LINE_TEXT_DISABLE 1 // disabling sending assert file, line text and do not saving this in .text section
//#define M_ASSERT_FUNCTION_NAME_TEXT_DISABLE 1 // disabling sending assert function-name text, value and do not saving this in .text section
//#define M_ASSERT_OPTIONAL_CHECKS_DISABLE 1 // disabling optional checks in user code
#/*
# * ***************** SETTINGS APPLYING (DO NOT CHANGE!!!) ******************************************************
# */
#
#/// ==========> M_ASSERT_MSG_TEXT_DISABLE <==================================
#if defined(M_ASSERT_MSG_TEXT_DISABLE)
# define ASSERT_MSG_TXT(...) 0 //"MSG"
#else
# define ASSERT_MSG_TXT(...) __VA_ARGS__
#endif /* defined(M_ASSERT_EXPR_TEXT_DISABLE) */
#
#
#//// ==========> M_ASSERT_EXPR_DISABLE <====================================
#if defined(M_ASSERT_EXPR_DISABLE)
# define ASSERT_EXPR_TXT(...) 0 //"EXPR"
#else
# define ASSERT_EXPR_TXT(...) __VA_ARGS__
#endif /* defined(M_ASSERT_EXPR_TEXT_DISABLE) */
#
#//// ==========> M_ASSERT_FILE_LINE_TEXT_DISABLE <==========================
#if defined(M_ASSERT_FILE_LINE_TEXT_DISABLE)
# define ASSERT_FILE(...) 0 //"FILE"
#else
# define ASSERT_FILE(...) __VA_ARGS__
#endif /* defined(M_ASSERT_FILE_LINE_TEXT_DISABLE) */
#
#//// ==========> M_ASSERT_FUNCTION_NAME_TEXT_DISABLE <==========================
#if defined(M_ASSERT_FUNCTION_NAME_TEXT_DISABLE)
# define ASSERT_FUNCTION(...) 0 //"FUNC"
#else
# define ASSERT_FUNCTION(...) __VA_ARGS__
#endif /* defined(M_ASSERT_FUNCTION_NAME_TEXT_DISABLE) */
#
#//// ==========> M_ASSERT_OPTIONAL_CHECKS_DISABLE <=========================
#if defined(M_ASSERT_OPTIONAL_CHECKS_DISABLE)
# define _OPTIONAL_CHECK_SWITCH(...)
#else
# define _OPTIONAL_CHECK_SWITCH(...) __VA_ARGS__
#endif /* defined(M_ASSERT_OPTIONAL_CHECKS_DISABLE) */
#
#
#
#/*
# * ***********************************************************************
# * smart asserts additional information macro
# * ***********************************************************************
# */
#define M_EMPTY /* ignored expression */
#define M_ALWAYS 1 /* always proceed expression */
#define M_LIB_DATA_DEF "[d]" /* adds text for some library data, user must adds to message list 0--> messageEna, 1-->libDescr (0|1, "descr") */
#define M_LIB_NAME_DEF "[s]" /* adds text for some library data, user must adds to message list 0--> libDescr ("descr") */
#define M_LIB_ENA_DEF "[e]" /* adds text for some library data, user must adds to message list 0--> messageEna (0|1) */
#define M_LIB_ALWAYS_DIS_DEF "[0]" /* always disable message in smart assert, nothing to adds list 0--> libDescr ("descr")*/
#define M_LIB_ALWAYS_ENA_DEF "[1]" /* always enable message in smart assert, nothing to adds list 0--> libDescr ("descr")*/
#
#
#
#
#/// ==========> APPLY MACRO <================================================
#define ASSERT_ERROR(Expr_txt, Expr, File, Line, Func, Msg, ...) __M_Error(ASSERT_EXPR_TXT(Expr_txt), Expr, ASSERT_FILE(File), Line, ASSERT_FUNCTION(Func), ASSERT_MSG_TXT(Msg, ##__VA_ARGS__))
#define ASSERT_WARNING(Expr_txt, Expr, File, Line, Func, Msg, ...) __M_Warning(ASSERT_EXPR_TXT(Expr_txt), Expr, ASSERT_FILE(File), Line, ASSERT_FUNCTION(Func), ASSERT_MSG_TXT(Msg, ##__VA_ARGS__))
#
#
#ifndef NDEBUG /* --------------------------------------------------------------------------------------------------------- */
void __M_Error(const char* const expr_str, const unsigned char expr,
const char* const file, const int line, const char* const func_name,
const char* const msg, ...);
void __M_Warning(const char* const expr_str, const unsigned char expr,
const char* const file, const int line, const char* const func_name,
const char* const msg, ...);
/*
* ***********************************************************************************************************************************************
* defines simple if NDEBUG disable this expression expr
* ***********************************************************************************************************************************************
*/
// this macros will disable if NDEBUG is defined
# define M_Assert_disableExpr(...) __VA_ARGS__
/*
* ***********************************************************************************************************************************************
* defines for break program
* ***********************************************************************************************************************************************
*/
# define M_Assert_Break(Expr, beforeExpr, afterExpr, Msg, ...) \
_OPTIONAL_CHECK_SWITCH(__M_Assert_Break(Expr, #Expr, beforeExpr, afterExpr, Msg, ##__VA_ARGS__))
# define __M_Assert_Break(Expr, Expr_txt, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
ASSERT_ERROR((Expr_txt), (1), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
afterExpr; /* ignored because programm is break, but compiler not known it */ \
} \
} while(0L)
# define M_Assert_BreakSaveCheck(Expr, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
ASSERT_ERROR((#Expr), (1), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
afterExpr; /* ignored because programm is break, but compiler not known it */ \
} \
} while(0L)
// else breaking asserts
# define M_Assert_BreakElse(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
_OPTIONAL_CHECK_SWITCH(__M_Assert_BreakElse(Expr, #Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ##__VA_ARGS__))
# define __M_Assert_BreakElse(Expr, Expr_txt, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} else { /* ignored else expression if NDEBUG */ \
falseBeforeExpr; \
ASSERT_ERROR("if " Expr_txt " not confirmed: passed to else", (0), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
falseAfterExpr; \
} \
} while(0L)
# define M_Assert_BreakElseSaveCheck(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} else { /* ignored else expression if NDEBUG */ \
falseBeforeExpr; \
ASSERT_ERROR("if " #Expr " not confirmed: passed to else", (0), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
falseAfterExpr; \
} \
} while(0L)
/*
* ***********************************************************************************************************************************************
* defines no break program
* ***********************************************************************************************************************************************
*/
# define M_Assert_Warning(Expr, beforeExpr, afterExpr, Msg, ...) \
_OPTIONAL_CHECK_SWITCH(__M_Assert_Warning(Expr, (#Expr), beforeExpr, afterExpr, Msg, ##__VA_ARGS__))
# define __M_Assert_Warning(Expr, Expr_txt, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
ASSERT_WARNING(Expr_txt, (1), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
afterExpr; \
} \
} while(0L)
# define M_Assert_WarningSaveCheck(Expr, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
ASSERT_WARNING((#Expr), (1), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
afterExpr; \
} \
} while(0L)
// else warning asserts
# define M_Assert_WarningElse(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
_OPTIONAL_CHECK_SWITCH(__M_Assert_WarningElse(Expr, #Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ##__VA_ARGS__))
# define __M_Assert_WarningElse(Expr, Expr_txt, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} else { /* ignored else expression if NDEBUG */ \
falseBeforeExpr; \
ASSERT_WARNING("if " #Expr " not confirmed: passed to else", (0), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
falseAfterExpr; \
} \
} while(0L)
#
# define M_Assert_WarningElseSaveCheck(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} else { /* ignored else expression if NDEBUG */ \
falseBeforeExpr; \
ASSERT_WARNING("if " #Expr " not confirmed: passed to else", (0), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), (Msg), ##__VA_ARGS__); \
falseAfterExpr; \
} \
} while(0L)
/*
* ***********************************************************************************************************************************************
* functions
* ***********************************************************************************************************************************************
*/
# define M_Assert_SafeFunctionCall(foo, true_expression) \
do { \
if(foo) { \
true_expression; \
} else { \
ASSERT_WARNING((#foo), (0), (__FILE__), (__LINE__), (CHAOS_FUNC_NAME), ("NO exists function")); \
} \
} while(0L)
#else
/*
* ***********************************************************************************************************************************************
* defines simple if NDEBUG disable expr
* ***********************************************************************************************************************************************
*/
# define M_Assert_disableExpr(...)
/*
* ***********************************************************************************************************************************************
* defines for break program
* ***********************************************************************************************************************************************
*/
# define M_Assert_Break(Expr, beforeExpr, afterExpr, Msg, ...)
# define M_Assert_BreakSaveCheck(Expr, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
afterExpr; \
} \
} while(0L)
// else breaking asserts
# define M_Assert_BreakElse(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
trueExpr; \
} while(0L)
# define M_Assert_BreakElseSaveCheck(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} \
} while(0L)
/*
* ***********************************************************************************************************************************************
* defines no break program
* ***********************************************************************************************************************************************
*/
# define M_Assert_Warning(Expr, beforeExpr, afterExpr, Msg, ...)
# define M_Assert_WarningSaveCheck(Expr, beforeExpr, afterExpr, Msg, ...) \
do { \
if (Expr) { \
beforeExpr; \
afterExpr; \
} \
} while(0L)
// else warning asserts
# define M_Assert_WarningElse(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
trueExpr; \
} while(0L)
# define M_Assert_WarningElseSaveCheck(Expr, trueExpr, falseBeforeExpr, falseAfterExpr, Msg, ...) \
do { \
if(Expr) { \
trueExpr; \
} \
} while(0L)
/*
* ***********************************************************************************************************************************************
* functions
* ***********************************************************************************************************************************************
*/
# define M_Assert_SafeFunctionCall(foo, true_expression) \
do { \
if(foo) { \
true_expression; \
} \
} while(0L)
#endif /* NDEBUG */
#include <stdio.h>
void __M_DBG(const char* const msg, ...);
void __M_DBG_ERR(const char* const msg, ...);
void __M_DBG_FILE(FILE * file, const char* const msg, ...);
void __M_assert_test();
#define PRINT_ONCE(...) \
do { \
static int __printed = 0; \
if(!__printed) { \
printf(__VA_ARGS__); \
__printed = 1; \
} \
} while(0L)
//#define TO_TXT(a) #a
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __ASSERT_ENGINE_H_ */