Skip to content

Commit 6d908aa

Browse files
mlib_check supports an explanatory string with all assertions
1 parent 0540e99 commit 6d908aa

File tree

2 files changed

+104
-41
lines changed

2 files changed

+104
-41
lines changed

src/common/src/mlib/test.h

Lines changed: 101 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -129,56 +129,98 @@ typedef struct mlib_source_location {
129129
#define mlib_check(...) MLIB_ARGC_PICK(_mlib_check, #__VA_ARGS__, __VA_ARGS__)
130130
// One arg:
131131
#define _mlib_check_argc_2(ArgString, Condition) \
132-
_mlibCheckConditionSimple(Condition, ArgString, mlib_this_source_location())
132+
_mlibCheckConditionSimple(Condition, ArgString, NULL, mlib_this_source_location())
133133
// Three args:
134134
#define _mlib_check_argc_4(ArgString, A, Operator, B) \
135-
MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B)
135+
MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B, NULL)
136+
// Five args:
137+
#define _mlib_check_argc_6(ArgString, A, Operator, B, Infix, Reason) \
138+
MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlib_check_with_suffix_, Infix)(A, Operator, B, Reason)
139+
#define _mlib_check_with_suffix_because(A, Operator, B, Reason) \
140+
MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B, Reason)
136141
// String-compare:
137-
#define _mlibCheckCondition_str_eq(A, B) _mlibCheckStrEq(A, B, #A, #B, mlib_this_source_location())
142+
#define _mlibCheckCondition_str_eq(A, B, Reason) _mlibCheckStrEq(A, B, #A, #B, Reason, mlib_this_source_location())
138143
// Pointer-compare:
139-
#define _mlibCheckCondition_ptr_eq(A, B) _mlibCheckPtrEq(A, B, #A, #B, mlib_this_source_location())
144+
#define _mlibCheckCondition_ptr_eq(A, B, Reason) _mlibCheckPtrEq(A, B, #A, #B, Reason, mlib_this_source_location())
140145
// Integer-equal:
141-
#define _mlibCheckCondition_eq(A, B) \
142-
_mlibCheckIntCmp( \
143-
mlib_equal, true, "==", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
146+
#define _mlibCheckCondition_eq(A, B, Reason) \
147+
_mlibCheckIntCmp(mlib_equal, \
148+
true, \
149+
"==", \
150+
mlib_upsize_integer(A), \
151+
mlib_upsize_integer(B), \
152+
#A, \
153+
#B, \
154+
Reason, \
155+
mlib_this_source_location())
144156
// Integer not-equal:
145-
#define _mlibCheckCondition_neq(A, B) \
146-
_mlibCheckIntCmp( \
147-
mlib_equal, false, "≠", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
148-
// Simple assertion with an explanatory string
149-
#define _mlibCheckCondition_because(Cond, Msg) _mlibCheckConditionBecause(Cond, #Cond, Msg, mlib_this_source_location())
157+
#define _mlibCheckCondition_neq(A, B, Reason) \
158+
_mlibCheckIntCmp(mlib_equal, \
159+
false, \
160+
"!=", \
161+
mlib_upsize_integer(A), \
162+
mlib_upsize_integer(B), \
163+
#A, \
164+
#B, \
165+
Reason, \
166+
mlib_this_source_location())
150167
// Integer comparisons:
151-
#define _mlibCheckCondition_lt(A, B) \
152-
_mlibCheckIntCmp( \
153-
mlib_less, true, "<", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
154-
#define _mlibCheckCondition_lte(A, B) \
155-
_mlibCheckIntCmp( \
156-
mlib_greater, false, "≤", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
157-
#define _mlibCheckCondition_gt(A, B) \
158-
_mlibCheckIntCmp( \
159-
mlib_greater, true, ">", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
160-
#define _mlibCheckCondition_gte(A, B) \
161-
_mlibCheckIntCmp( \
162-
mlib_less, false, "≥", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location())
168+
#define _mlibCheckCondition_lt(A, B, Reason) \
169+
_mlibCheckIntCmp(mlib_less, \
170+
true, \
171+
"<", \
172+
mlib_upsize_integer(A), \
173+
mlib_upsize_integer(B), \
174+
#A, \
175+
#B, \
176+
Reason, \
177+
mlib_this_source_location())
178+
#define _mlibCheckCondition_lte(A, B, Reason) \
179+
_mlibCheckIntCmp(mlib_greater, \
180+
false, \
181+
"≤", \
182+
mlib_upsize_integer(A), \
183+
mlib_upsize_integer(B), \
184+
#A, \
185+
#B, \
186+
Reason, \
187+
mlib_this_source_location())
188+
#define _mlibCheckCondition_gt(A, B, Reason) \
189+
_mlibCheckIntCmp(mlib_greater, \
190+
true, \
191+
">", \
192+
mlib_upsize_integer(A), \
193+
mlib_upsize_integer(B), \
194+
#A, \
195+
#B, \
196+
Reason, \
197+
mlib_this_source_location())
198+
#define _mlibCheckCondition_gte(A, B, Reason) \
199+
_mlibCheckIntCmp(mlib_less, \
200+
false, \
201+
"≥", \
202+
mlib_upsize_integer(A), \
203+
mlib_upsize_integer(B), \
204+
#A, \
205+
#B, \
206+
Reason, \
207+
mlib_this_source_location())
208+
163209

210+
// Simple assertion with an explanatory string
211+
#define _mlibCheckCondition_because(Cond, Reason, _null) \
212+
_mlibCheckConditionSimple(Cond, #Cond, Reason, mlib_this_source_location())
164213

165214
/// Check evaluator when given a single boolean
166215
static inline void
167-
_mlibCheckConditionSimple(bool c, const char *expr, struct mlib_source_location here)
216+
_mlibCheckConditionSimple(bool c, const char *expr, const char *reason, struct mlib_source_location here)
168217
{
169218
if (!c) {
170-
fprintf(stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed\n", here.file, here.lineno, here.func, expr);
171-
fflush(stderr);
172-
abort();
173-
}
174-
}
175-
176-
static inline void
177-
_mlibCheckConditionBecause(bool cond, const char *expr, const char *reason, mlib_source_location here)
178-
{
179-
if (!cond) {
180-
fprintf(
181-
stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed (%s)\n", here.file, here.lineno, here.func, expr, reason);
219+
fprintf(stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed", here.file, here.lineno, here.func, expr);
220+
if (reason) {
221+
fprintf(stderr, " (%s)", reason);
222+
}
223+
fprintf(stderr, "\n");
182224
fflush(stderr);
183225
abort();
184226
}
@@ -193,6 +235,7 @@ _mlibCheckIntCmp(enum mlib_cmp_result cres, // The cmp result to check
193235
struct mlib_upsized_integer right,
194236
const char *left_expr,
195237
const char *right_expr,
238+
const char *reason,
196239
struct mlib_source_location here)
197240
{
198241
if (((mlib_cmp)(left, right, 0) == cres) != cond) {
@@ -218,15 +261,22 @@ _mlibCheckIntCmp(enum mlib_cmp_result cres, // The cmp result to check
218261
fprintf(stderr, "%llu", (unsigned long long)right.bits.as_unsigned);
219262
}
220263
fprintf(stderr, " ⟨%s⟩\n", right_expr);
264+
if (reason) {
265+
fprintf(stderr, "Because: %s\n", reason);
266+
}
221267
fflush(stderr);
222268
abort();
223269
}
224270
}
225271

226272
// Pointer-comparison
227273
static inline void
228-
_mlibCheckPtrEq(
229-
const void *left, const void *right, const char *left_expr, const char *right_expr, struct mlib_source_location here)
274+
_mlibCheckPtrEq(const void *left,
275+
const void *right,
276+
const char *left_expr,
277+
const char *right_expr,
278+
const char *reason,
279+
struct mlib_source_location here)
230280
{
231281
if (left != right) {
232282
fprintf(stderr,
@@ -243,15 +293,22 @@ _mlibCheckPtrEq(
243293
left_expr,
244294
right,
245295
right_expr);
296+
if (reason) {
297+
fprintf(stderr, "Because: %s\n", reason);
298+
}
246299
fflush(stderr);
247300
abort();
248301
}
249302
}
250303

251304
// String-comparison
252305
static inline void
253-
_mlibCheckStrEq(
254-
const char *left, const char *right, const char *left_expr, const char *right_expr, struct mlib_source_location here)
306+
_mlibCheckStrEq(const char *left,
307+
const char *right,
308+
const char *left_expr,
309+
const char *right_expr,
310+
const char *reason,
311+
struct mlib_source_location here)
255312
{
256313
if (strcmp(left, right)) {
257314
fprintf(stderr,
@@ -268,6 +325,9 @@ _mlibCheckStrEq(
268325
left_expr,
269326
right,
270327
right_expr);
328+
if (reason) {
329+
fprintf(stderr, "Because: %s\n", reason);
330+
}
271331
fflush(stderr);
272332
abort();
273333
}

src/common/tests/test-mlib.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ _test_checks(void)
7575
mlib_assert_aborts () {
7676
mlib_check(3, gte, 5);
7777
}
78+
79+
// An infix with a reason string
80+
mlib_check(1, eq, 1, because, "1 = 1");
7881
}
7982

8083
static void

0 commit comments

Comments
 (0)