-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathassert_engine.c
256 lines (220 loc) · 10.9 KB
/
assert_engine.c
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
#include "assert_engine.h"
#include <stdio.h>
#include <stdarg.h>
#ifndef NDEBUG /* ---------------------------------------------------------------------------------------------------------- */
#include <assert.h>
#define __M_IF_ASSERT_ADDITION_DATA(msg) (((msg)[0] == '[') && ((msg)[2] == ']'))
#define __M_ASSERT_DATA(msg) ((msg)[1])
static inline void __M_SEND_ASSERT_MSG(const char* const header,
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, va_list args)
{
#if !defined(M_ASSERT_MSG_TEXT_DISABLE)
int assertEna = 1;
char* descr = 0;
const int _additional_data_ex = __M_IF_ASSERT_ADDITION_DATA(msg);
if(_additional_data_ex) {
switch(__M_ASSERT_DATA(msg)) {
case 'd':
// get library info
assertEna = va_arg(args, const int);
descr = va_arg(args, char*);
break;
case 's':
// get library info
assertEna = 1;
descr = va_arg(args, char*);
break;
case 'e':
// get library info
assertEna = va_arg(args, const int);
descr = 0;
break;
case '0':
descr = va_arg(args, char*);
# if !defined(M_MESSAGE_ALWAYS_ENABLE)
(void)descr;
return;
# endif /* !defined(M_MESSAGE_ALWAYS_ENABLE) */
break;
default: descr = va_arg(args, char*); break;
}
}
(void)assertEna;
#endif /* defined(M_ASSERT_MSG_TEXT_DISABLE) */
#if !defined(M_MESSAGE_ALWAYS_ENABLE) && !defined(M_ASSERT_MSG_TEXT_DISABLE)
// send message if enabled message
if(assertEna) {
#endif /* !defined(M_MESSAGE_ALWAYS_ENABLE) && !defined(M_ASSERT_MSG_TEXT_DISABLE) */
// print header-------------------------------------------------------
fprintf(stderr, "\n%s\n", header);
// print function if enable ------------------------------------------
#if !defined(M_ASSERT_FUNCTION_NAME_TEXT_DISABLE)
fprintf(stderr, "Function:\t\t%s\n", func_name);
#endif /* !defined(M_ASSERT_FUNCTION_NAME_TEXT_DISABLE) */
#if !defined(M_ASSERT_MSG_TEXT_DISABLE)
// print library name if exists and enable ------------------------------------------
if(descr) {
fprintf(stderr, "Library Name:\t%s\n", descr);
}
// print msg text if enable ------------------------------------------
fprintf(stderr, "Assert failed:\t");
if(_additional_data_ex) {
vfprintf(stderr, &msg[3], args);
} else {
vfprintf(stderr, msg, args);
}
fprintf(stderr, "\n");
#endif /* defined(M_ASSERT_MSG_TEXT_DISABLE) */
// print expression text if enable ------------------------------------------
#if !defined(M_ASSERT_EXPR_DISABLE)
fprintf(stderr, "Expression:\t%s, value: %d\n", expr_str, expr);
#endif /* defined(M_ASSERT_EXPR_TEXT_DISABLE) */
// print file & line if enable ------------------------------------------
#if !defined(M_ASSERT_FILE_LINE_TEXT_DISABLE)
fprintf(stderr, "Source:\t\t%s, line: %d\n", file, line);
#endif /* defined(M_ASSERT_FILE_LINE_TEXT_DISABLE) */
fflush(stderr);
#if !defined(M_MESSAGE_ALWAYS_ENABLE) && !defined(M_ASSERT_MSG_TEXT_DISABLE)
}
#endif /* !defined(M_MESSAGE_ALWAYS_ENABLE) && !defined(M_ASSERT_MSG_TEXT_DISABLE) */
(void)header;
(void)expr_str;
(void)expr;
(void)file;
(void)line;
(void)func_name;
(void)msg;
(void)args;
}
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, ...)
{
va_list args;
va_start(args, msg);
__M_SEND_ASSERT_MSG("PROGRAMM EXIT WITH ERROR!!!", expr_str, expr, file, line, func_name, msg, args);
va_end(args);
//abort(); // exit programm
}
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, ...)
{
va_list args;
va_start(args, msg);
__M_SEND_ASSERT_MSG("WARNING!!!", expr_str, expr, file, line, func_name, msg, args);
va_end(args);
}
#undef __M_IF_ASSERT_ADDITION_DATA
#undef __M_ASSERT_DATA
#endif /* NDEBUG ---------------------------------------------------------------------------------------------------------- */
void __M_DBG(const char* const msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stdout, msg, args);
fprintf(stdout, "\n");
fflush(stdout);
va_end(args);
}
void __M_DBG_ERR(const char* const msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
fflush(stderr);
va_end(args);
}
void __M_DBG_FILE(FILE * file, const char* const msg, ...)
{
va_list args;
va_start(args, msg);
vfprintf(file, msg, args);
fprintf(file, "\n");
fflush(file);
va_end(args);
}
void __M_assert_test()
{
int i = 1;
// Test M_Assert_Break without parameters
M_Assert_Break(1, M_EMPTY, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_Break without parameters");
// Test M_Assert_Break with one parameter
M_Assert_Break(1, M_EMPTY, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_Break with parameter: %d", 123);
// Test M_Assert_Break with two parameters
M_Assert_Break(1, M_EMPTY, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_Break with two parameters: %d, %d", 123, 456);
// Test M_Assert_Warning without parameters
M_Assert_Warning(1, M_EMPTY, M_EMPTY, "RUNTIME WARNING Assert test: M_Assert_Warning without parameters");
// Test M_Assert_Warning with one parameter
M_Assert_Warning(1, ++i, M_EMPTY, "RUNTIME WARNING Assert test: M_Assert_Warning with parameter: %d", i);
// Test M_Assert_Warning with two parameters
M_Assert_Warning(1, M_EMPTY, ++i, "RUNTIME WARNING Assert test: M_Assert_Warning with two parameters: %d, %d", i, 456);
// Test M_Assert_Warning with two parameters and different formatting
M_Assert_Warning(1, M_EMPTY, M_EMPTY, "RUNTIME WARNING Assert test:" "M_Assert_Warning with two parameters: %d, %d", i, 456);
// Test M_Assert_Break with two parameters and increment
M_Assert_Break(1, ++i, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_Break with two parameters: %d, %d", i, 456);
// Test M_Assert_Break with library data
M_Assert_Break(1, ++i, M_EMPTY, M_LIB_DATA_DEF"With library: M_Assert_Break with two parameters: %d, %d", 0, "lib_name", i, 456);
// Test M_Assert_BreakSaveCheck
M_Assert_BreakSaveCheck(1, ++i, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_BreakSaveCheck with parameter: %d", i);
// Test M_Assert_WarningSaveCheck
M_Assert_WarningSaveCheck(1, ++i, M_EMPTY, "RUNTIME WARNING Assert test: M_Assert_WarningSaveCheck with parameter: %d", i);
// Test M_Assert_BreakElse
//M_Assert_WarningElse(i == 0, M_EMPTY, M_EMPTY, M_EMPTY, "RUNTIME ERROR Assert test: M_Assert_BreakElse");
M_Assert_BreakElse(i == 0, M_EMPTY, M_EMPTY, M_EMPTY, "sfsagsdggdgsg");
// Test M_Assert_WarningElse
M_Assert_WarningElse(i != 0, M_EMPTY, M_EMPTY, M_EMPTY, "RUNTIME WARNING Assert test: M_Assert_WarningElse");
// Test M_Assert_SafeFunctionCall
i = 0;
M_Assert_SafeFunctionCall(i, printf("hello "));
// Test M_Assert_Break with custom message
M_Assert_Break(1, ++i, M_EMPTY, "[s]With library: Custom assert message with two parameters: %d, %d", "hhhh",i, 456);
// Test M_Assert_Warning with custom message
M_Assert_Warning(1, ++i, M_EMPTY, "[s]With library: Custom warning message with two parameters: %d, %d", "hhhh", i, 456);
// Test M_Assert_Break with error code
M_Assert_Break(1, ++i, M_EMPTY, "[e]With error code: Assert with two parameters: %d, %d",1, i, 123);
// Test M_Assert_Warning with disabled message
M_Assert_Warning(1, ++i, M_EMPTY, "[0]With disabled message: %d, %d", i, 456);
(void)i;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int test_value = 0;
// Test error assertion without additional data
M_Assert_Break(test_value == 0, M_EMPTY, M_EMPTY, "Test case 1: Assertion failed without additional data");
// Test error assertion with one additional parameter
M_Assert_Break(test_value == 0, M_EMPTY, M_EMPTY, "Test case 2: Assertion failed with one parameter: %d", test_value);
// Test error assertion with two additional parameters
M_Assert_Break(test_value == 0, M_EMPTY, M_EMPTY, "Test case 3: Assertion failed with two parameters: %d, %d", test_value, 123);
// Test warning assertion without additional data
M_Assert_Warning(test_value == 0, M_EMPTY, M_EMPTY, "Test case 4: Warning without additional data");
// Test warning assertion with one additional parameter
M_Assert_Warning(test_value == 0, M_EMPTY, M_EMPTY, "Test case 5: Warning with one parameter: %d", test_value);
// Test warning assertion with two additional parameters
M_Assert_Warning(test_value == 0, M_EMPTY, M_EMPTY, "Test case 6: Warning with two parameters: %d, %d", test_value, 123);
// Test error assertion with library data
M_Assert_Break(test_value == 0, M_EMPTY, M_EMPTY, "[d]Test case 7: Assertion with library data", 1, "lib_name");
// Test warning assertion with library data
M_Assert_Warning(test_value == 0, M_EMPTY, M_EMPTY, "[s]Test case 8: Warning with library data: %s", "lib_name");
// Test error assertion with error code
M_Assert_Break(test_value == 0, M_EMPTY, M_EMPTY, "[e]Test case 9: Assertion with enable code: %d", 1);
// Test warning assertion with disabled message
M_Assert_Warning(test_value == 0, M_EMPTY, M_EMPTY, "[0]Test case 10: Disabled message");
// Test M_Assert_BreakSaveCheck
M_Assert_BreakSaveCheck(test_value == 0, M_EMPTY, M_EMPTY, "Test case 11: M_Assert_BreakSaveCheck");
// Test M_Assert_WarningSaveCheck
M_Assert_WarningSaveCheck(test_value == 0, M_EMPTY, M_EMPTY, "Test case 12: M_Assert_WarningSaveCheck");
// Test M_Assert_BreakElse
M_Assert_BreakElse(test_value == 0, M_EMPTY, M_EMPTY, M_EMPTY, "Test case 13: M_Assert_BreakElse");
// Test M_Assert_WarningElse
M_Assert_WarningElse(test_value != 0, M_EMPTY, M_EMPTY, M_EMPTY, "Test case 14: M_Assert_WarningElse");
// Test M_Assert_SafeFunctionCall
M_Assert_SafeFunctionCall(test_value == 0, printf("Test case 15: Safe function call\n"));
// Test debug messages
__M_DBG("Test case 16: Debug message without parameters");
__M_DBG("Test case 17: Debug message with one parameter: %d", test_value);
__M_DBG_ERR("Test case 18: Debug error message with two parameters: %d, %s", test_value, "error");
__M_DBG_FILE(stdout, "Test case 19: Debug message to file: %d", test_value);
(void)test_value;
}