skip to content
==> include/mesh/check.h <==
1/* @ajax/mesh-check: Test checks for alpha-c-mesh's packages: CHECK, CHECK_U, CHECK_I, CHECK_S, then mesh_check_done(). */
2#ifndef MESH_CHECK_H
3#define MESH_CHECK_H
4
5/* Checks for this repo's tests: each failure prints where and what, and
6 * mesh_check_done() turns the tally into the exit status. Header-only. */
7#include <stdio.h>
8#include <string.h>
9
10static int mesh_check_failures;
11static long mesh_check_count;
12
13#define CHECK(c) mesh_check_(!!(c), __FILE__, __LINE__, #c)
14#define CHECK_U(a, b) mesh_check_u_((unsigned long long)(a), (unsigned long long)(b), __FILE__, __LINE__, #a, #b)
15#define CHECK_I(a, b) mesh_check_i_((long long)(a), (long long)(b), __FILE__, __LINE__, #a, #b)
16#define CHECK_S(a, b) mesh_check_s_((a), (b), __FILE__, __LINE__, #a)
17#define CHECK_F32_BITS(a, bits) mesh_check_u_(mesh_check_f32_bits_(a), (bits), __FILE__, __LINE__, #a, #bits)
18
19static inline int mesh_check_(int ok, const char *file, int line, const char *what) {
20    mesh_check_count++;
21    if (!ok) {
22        mesh_check_failures++;
23        fprintf(stderr, "%s:%d: check failed: %s\n", file, line, what);
24    }
25    return ok;
26}
27static inline int mesh_check_u_(unsigned long long a, unsigned long long b, const char *file, int line,
28                                const char *ea, const char *eb) {
29    mesh_check_count++;
30    if (a != b) {
31        mesh_check_failures++;
32        fprintf(stderr, "%s:%d: %s == %s: %llu (0x%llx) != %llu (0x%llx)\n", file, line, ea, eb, a, a, b, b);
33        return 0;
34    }
35    return 1;
36}
37static inline int mesh_check_i_(long long a, long long b, const char *file, int line, const char *ea, const char *eb) {
38    mesh_check_count++;
39    if (a != b) {
40        mesh_check_failures++;
41        fprintf(stderr, "%s:%d: %s == %s: %lld != %lld\n", file, line, ea, eb, a, b);
42        return 0;
43    }
44    return 1;
45}
46static inline int mesh_check_s_(const char *a, const char *b, const char *file, int line, const char *ea) {
47    mesh_check_count++;
48    if (!a || !b || strcmp(a, b) != 0) {
49        mesh_check_failures++;
50        fprintf(stderr, "%s:%d: %s: \"%s\" != \"%s\"\n", file, line, ea, a ? a : "(null)", b ? b : "(null)");
51        return 0;
52    }
53    return 1;
54}
55static inline unsigned long long mesh_check_f32_bits_(float f) {
56    unsigned int u;
57    memcpy(&u, &f, sizeof u);
58    return u;
59}
60/* The exit status: 0 when every check passed. */
61static inline int mesh_check_done(void) {
62    if (mesh_check_failures) fprintf(stderr, "%d of %ld checks failed\n", mesh_check_failures, mesh_check_count);
63    return mesh_check_failures ? 1 : 0;
64}
65
66#endif