Browse code

Add greatest test lib

John Hawthorn authored on 03/04/2017 05:24:41
Showing 3 changed files

... ...
@@ -1,7 +1,7 @@
1 1
 VERSION=0.8
2 2
 
3 3
 CPPFLAGS=-DVERSION=\"${VERSION}\" -D_GNU_SOURCE
4
-CFLAGS+=-Wall -Wextra -g -std=c99 -O3 -pedantic
4
+CFLAGS+=-Wall -Wextra -g -std=c99 -O3 -pedantic -Ideps
5 5
 PREFIX?=/usr/local
6 6
 MANDIR?=$(PREFIX)/share/man
7 7
 BINDIR?=$(PREFIX)/bin
8 8
new file mode 100644
... ...
@@ -0,0 +1,1035 @@
1
+/*
2
+ * Copyright (c) 2011-2016 Scott Vokes <vokes.s@gmail.com>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+#ifndef GREATEST_H
18
+#define GREATEST_H
19
+
20
+#ifdef __cplusplus
21
+extern "C" {
22
+#endif
23
+
24
+/* 1.2.1 */
25
+#define GREATEST_VERSION_MAJOR 1
26
+#define GREATEST_VERSION_MINOR 2
27
+#define GREATEST_VERSION_PATCH 1
28
+
29
+/* A unit testing system for C, contained in 1 file.
30
+ * It doesn't use dynamic allocation or depend on anything
31
+ * beyond ANSI C89.
32
+ *
33
+ * An up-to-date version can be found at:
34
+ *     https://github.com/silentbicycle/greatest/
35
+ */
36
+
37
+
38
+/*********************************************************************
39
+ * Minimal test runner template
40
+ *********************************************************************/
41
+#if 0
42
+
43
+#include "greatest.h"
44
+
45
+TEST foo_should_foo(void) {
46
+    PASS();
47
+}
48
+
49
+static void setup_cb(void *data) {
50
+    printf("setup callback for each test case\n");
51
+}
52
+
53
+static void teardown_cb(void *data) {
54
+    printf("teardown callback for each test case\n");
55
+}
56
+
57
+SUITE(suite) {
58
+    /* Optional setup/teardown callbacks which will be run before/after
59
+     * every test case. If using a test suite, they will be cleared when
60
+     * the suite finishes. */
61
+    SET_SETUP(setup_cb, voidp_to_callback_data);
62
+    SET_TEARDOWN(teardown_cb, voidp_to_callback_data);
63
+
64
+    RUN_TEST(foo_should_foo);
65
+}
66
+
67
+/* Add definitions that need to be in the test runner's main file. */
68
+GREATEST_MAIN_DEFS();
69
+
70
+/* Set up, run suite(s) of tests, report pass/fail/skip stats. */
71
+int run_tests(void) {
72
+    GREATEST_INIT();            /* init. greatest internals */
73
+    /* List of suites to run (if any). */
74
+    RUN_SUITE(suite);
75
+
76
+    /* Tests can also be run directly, without using test suites. */
77
+    RUN_TEST(foo_should_foo);
78
+
79
+    GREATEST_PRINT_REPORT();          /* display results */
80
+    return greatest_all_passed();
81
+}
82
+
83
+/* main(), for a standalone command-line test runner.
84
+ * This replaces run_tests above, and adds command line option
85
+ * handling and exiting with a pass/fail status. */
86
+int main(int argc, char **argv) {
87
+    GREATEST_MAIN_BEGIN();      /* init & parse command-line args */
88
+    RUN_SUITE(suite);
89
+    GREATEST_MAIN_END();        /* display results */
90
+}
91
+
92
+#endif
93
+/*********************************************************************/
94
+
95
+
96
+#include <stdlib.h>
97
+#include <stdio.h>
98
+#include <string.h>
99
+#include <ctype.h>
100
+
101
+/***********
102
+ * Options *
103
+ ***********/
104
+
105
+/* Default column width for non-verbose output. */
106
+#ifndef GREATEST_DEFAULT_WIDTH
107
+#define GREATEST_DEFAULT_WIDTH 72
108
+#endif
109
+
110
+/* FILE *, for test logging. */
111
+#ifndef GREATEST_STDOUT
112
+#define GREATEST_STDOUT stdout
113
+#endif
114
+
115
+/* Remove GREATEST_ prefix from most commonly used symbols? */
116
+#ifndef GREATEST_USE_ABBREVS
117
+#define GREATEST_USE_ABBREVS 1
118
+#endif
119
+
120
+/* Set to 0 to disable all use of setjmp/longjmp. */
121
+#ifndef GREATEST_USE_LONGJMP
122
+#define GREATEST_USE_LONGJMP 1
123
+#endif
124
+
125
+#if GREATEST_USE_LONGJMP
126
+#include <setjmp.h>
127
+#endif
128
+
129
+/* Set to 0 to disable all use of time.h / clock(). */
130
+#ifndef GREATEST_USE_TIME
131
+#define GREATEST_USE_TIME 1
132
+#endif
133
+
134
+#if GREATEST_USE_TIME
135
+#include <time.h>
136
+#endif
137
+
138
+/* Floating point type, for ASSERT_IN_RANGE. */
139
+#ifndef GREATEST_FLOAT
140
+#define GREATEST_FLOAT double
141
+#define GREATEST_FLOAT_FMT "%g"
142
+#endif
143
+
144
+/*********
145
+ * Types *
146
+ *********/
147
+
148
+/* Info for the current running suite. */
149
+typedef struct greatest_suite_info {
150
+    unsigned int tests_run;
151
+    unsigned int passed;
152
+    unsigned int failed;
153
+    unsigned int skipped;
154
+
155
+#if GREATEST_USE_TIME
156
+    /* timers, pre/post running suite and individual tests */
157
+    clock_t pre_suite;
158
+    clock_t post_suite;
159
+    clock_t pre_test;
160
+    clock_t post_test;
161
+#endif
162
+} greatest_suite_info;
163
+
164
+/* Type for a suite function. */
165
+typedef void (greatest_suite_cb)(void);
166
+
167
+/* Types for setup/teardown callbacks. If non-NULL, these will be run
168
+ * and passed the pointer to their additional data. */
169
+typedef void (greatest_setup_cb)(void *udata);
170
+typedef void (greatest_teardown_cb)(void *udata);
171
+
172
+/* Type for an equality comparison between two pointers of the same type.
173
+ * Should return non-0 if equal, otherwise 0.
174
+ * UDATA is a closure value, passed through from ASSERT_EQUAL_T[m]. */
175
+typedef int greatest_equal_cb(const void *exp, const void *got, void *udata);
176
+
177
+/* Type for a callback that prints a value pointed to by T.
178
+ * Return value has the same meaning as printf's.
179
+ * UDATA is a closure value, passed through from ASSERT_EQUAL_T[m]. */
180
+typedef int greatest_printf_cb(const void *t, void *udata);
181
+
182
+/* Callbacks for an arbitrary type; needed for type-specific
183
+ * comparisons via GREATEST_ASSERT_EQUAL_T[m].*/
184
+typedef struct greatest_type_info {
185
+    greatest_equal_cb *equal;
186
+    greatest_printf_cb *print;
187
+} greatest_type_info;
188
+
189
+typedef struct greatest_memory_cmp_env {
190
+    const unsigned char *exp;
191
+    const unsigned char *got;
192
+    size_t size;
193
+} greatest_memory_cmp_env;
194
+
195
+/* Callbacks for string and raw memory types. */
196
+extern greatest_type_info greatest_type_info_string;
197
+extern greatest_type_info greatest_type_info_memory;
198
+
199
+typedef enum {
200
+    GREATEST_FLAG_FIRST_FAIL = 0x01,
201
+    GREATEST_FLAG_LIST_ONLY = 0x02
202
+} greatest_flag_t;
203
+
204
+/* Struct containing all test runner state. */
205
+typedef struct greatest_run_info {
206
+    unsigned char flags;
207
+    unsigned char verbosity;
208
+    unsigned int tests_run;     /* total test count */
209
+
210
+    /* overall pass/fail/skip counts */
211
+    unsigned int passed;
212
+    unsigned int failed;
213
+    unsigned int skipped;
214
+    unsigned int assertions;
215
+
216
+    /* currently running test suite */
217
+    greatest_suite_info suite;
218
+
219
+    /* info to print about the most recent failure */
220
+    const char *fail_file;
221
+    unsigned int fail_line;
222
+    const char *msg;
223
+
224
+    /* current setup/teardown hooks and userdata */
225
+    greatest_setup_cb *setup;
226
+    void *setup_udata;
227
+    greatest_teardown_cb *teardown;
228
+    void *teardown_udata;
229
+
230
+    /* formatting info for ".....s...F"-style output */
231
+    unsigned int col;
232
+    unsigned int width;
233
+
234
+    /* only run a specific suite or test */
235
+    const char *suite_filter;
236
+    const char *test_filter;
237
+
238
+#if GREATEST_USE_TIME
239
+    /* overall timers */
240
+    clock_t begin;
241
+    clock_t end;
242
+#endif
243
+
244
+#if GREATEST_USE_LONGJMP
245
+    jmp_buf jump_dest;
246
+#endif
247
+} greatest_run_info;
248
+
249
+struct greatest_report_t {
250
+    /* overall pass/fail/skip counts */
251
+    unsigned int passed;
252
+    unsigned int failed;
253
+    unsigned int skipped;
254
+    unsigned int assertions;
255
+};
256
+
257
+/* Global var for the current testing context.
258
+ * Initialized by GREATEST_MAIN_DEFS(). */
259
+extern greatest_run_info greatest_info;
260
+
261
+/* Type for ASSERT_ENUM_EQ's ENUM_STR argument. */
262
+typedef const char *greatest_enum_str_fun(int value);
263
+
264
+/**********************
265
+ * Exported functions *
266
+ **********************/
267
+
268
+/* These are used internally by greatest. */
269
+void greatest_do_pass(const char *name);
270
+void greatest_do_fail(const char *name);
271
+void greatest_do_skip(const char *name);
272
+int greatest_pre_test(const char *name);
273
+void greatest_post_test(const char *name, int res);
274
+void greatest_usage(const char *name);
275
+int greatest_do_assert_equal_t(const void *exp, const void *got,
276
+    greatest_type_info *type_info, void *udata);
277
+
278
+/* These are part of the public greatest API. */
279
+void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata);
280
+void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata);
281
+int greatest_all_passed(void);
282
+void greatest_set_test_filter(const char *name);
283
+void greatest_set_suite_filter(const char *name);
284
+void greatest_get_report(struct greatest_report_t *report);
285
+unsigned int greatest_get_verbosity(void);
286
+void greatest_set_verbosity(unsigned int verbosity);
287
+void greatest_set_flag(greatest_flag_t flag);
288
+
289
+
290
+/********************
291
+* Language Support *
292
+********************/
293
+
294
+/* If __VA_ARGS__ (C99) is supported, allow parametric testing
295
+* without needing to manually manage the argument struct. */
296
+#if __STDC_VERSION__ >= 19901L || _MSC_VER >= 1800
297
+#define GREATEST_VA_ARGS
298
+#endif
299
+
300
+
301
+/**********
302
+ * Macros *
303
+ **********/
304
+
305
+/* Define a suite. */
306
+#define GREATEST_SUITE(NAME) void NAME(void); void NAME(void)
307
+
308
+/* Declare a suite, provided by another compilation unit. */
309
+#define GREATEST_SUITE_EXTERN(NAME) void NAME(void)
310
+
311
+/* Start defining a test function.
312
+ * The arguments are not included, to allow parametric testing. */
313
+#define GREATEST_TEST static enum greatest_test_res
314
+
315
+/* PASS/FAIL/SKIP result from a test. Used internally. */
316
+typedef enum greatest_test_res {
317
+    GREATEST_TEST_RES_PASS = 0,
318
+    GREATEST_TEST_RES_FAIL = -1,
319
+    GREATEST_TEST_RES_SKIP = 1
320
+} greatest_test_res;
321
+
322
+/* Run a suite. */
323
+#define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME)
324
+
325
+/* Run a test in the current suite. */
326
+#define GREATEST_RUN_TEST(TEST)                                         \
327
+    do {                                                                \
328
+        if (greatest_pre_test(#TEST) == 1) {                            \
329
+            enum greatest_test_res res = GREATEST_SAVE_CONTEXT();       \
330
+            if (res == GREATEST_TEST_RES_PASS) {                        \
331
+                res = TEST();                                           \
332
+            }                                                           \
333
+            greatest_post_test(#TEST, res);                             \
334
+        } else if (GREATEST_LIST_ONLY()) {                              \
335
+            fprintf(GREATEST_STDOUT, "  %s\n", #TEST);                  \
336
+        }                                                               \
337
+    } while (0)
338
+
339
+/* Ignore a test, don't warn about it being unused. */
340
+#define GREATEST_IGNORE_TEST(TEST) (void)TEST
341
+
342
+/* Run a test in the current suite with one void * argument,
343
+ * which can be a pointer to a struct with multiple arguments. */
344
+#define GREATEST_RUN_TEST1(TEST, ENV)                                   \
345
+    do {                                                                \
346
+        if (greatest_pre_test(#TEST) == 1) {                            \
347
+            int res = TEST(ENV);                                        \
348
+            greatest_post_test(#TEST, res);                             \
349
+        } else if (GREATEST_LIST_ONLY()) {                              \
350
+            fprintf(GREATEST_STDOUT, "  %s\n", #TEST);                  \
351
+        }                                                               \
352
+    } while (0)
353
+
354
+#ifdef GREATEST_VA_ARGS
355
+#define GREATEST_RUN_TESTp(TEST, ...)                                   \
356
+    do {                                                                \
357
+        if (greatest_pre_test(#TEST) == 1) {                            \
358
+            int res = TEST(__VA_ARGS__);                                \
359
+            greatest_post_test(#TEST, res);                             \
360
+        } else if (GREATEST_LIST_ONLY()) {                              \
361
+            fprintf(GREATEST_STDOUT, "  %s\n", #TEST);                  \
362
+        }                                                               \
363
+    } while (0)
364
+#endif
365
+
366
+
367
+/* Check if the test runner is in verbose mode. */
368
+#define GREATEST_IS_VERBOSE() ((greatest_info.verbosity) > 0)
369
+#define GREATEST_LIST_ONLY()                                            \
370
+    (greatest_info.flags & GREATEST_FLAG_LIST_ONLY)
371
+#define GREATEST_FIRST_FAIL()                                           \
372
+    (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL)
373
+#define GREATEST_FAILURE_ABORT()                                        \
374
+    (greatest_info.suite.failed > 0 && GREATEST_FIRST_FAIL())
375
+
376
+/* Message-less forms of tests defined below. */
377
+#define GREATEST_PASS() GREATEST_PASSm(NULL)
378
+#define GREATEST_FAIL() GREATEST_FAILm(NULL)
379
+#define GREATEST_SKIP() GREATEST_SKIPm(NULL)
380
+#define GREATEST_ASSERT(COND)                                           \
381
+    GREATEST_ASSERTm(#COND, COND)
382
+#define GREATEST_ASSERT_OR_LONGJMP(COND)                                \
383
+    GREATEST_ASSERT_OR_LONGJMPm(#COND, COND)
384
+#define GREATEST_ASSERT_FALSE(COND)                                     \
385
+    GREATEST_ASSERT_FALSEm(#COND, COND)
386
+#define GREATEST_ASSERT_EQ(EXP, GOT)                                    \
387
+    GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT)
388
+#define GREATEST_ASSERT_EQ_FMT(EXP, GOT, FMT)                           \
389
+    GREATEST_ASSERT_EQ_FMTm(#EXP " != " #GOT, EXP, GOT, FMT)
390
+#define GREATEST_ASSERT_IN_RANGE(EXP, GOT, TOL)                         \
391
+    GREATEST_ASSERT_IN_RANGEm(#EXP " != " #GOT " +/- " #TOL, EXP, GOT, TOL)
392
+#define GREATEST_ASSERT_EQUAL_T(EXP, GOT, TYPE_INFO, UDATA)             \
393
+    GREATEST_ASSERT_EQUAL_Tm(#EXP " != " #GOT, EXP, GOT, TYPE_INFO, UDATA)
394
+#define GREATEST_ASSERT_STR_EQ(EXP, GOT)                                \
395
+    GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT)
396
+#define GREATEST_ASSERT_STRN_EQ(EXP, GOT, SIZE)                         \
397
+    GREATEST_ASSERT_STRN_EQm(#EXP " != " #GOT, EXP, GOT, SIZE)
398
+#define GREATEST_ASSERT_MEM_EQ(EXP, GOT, SIZE)                          \
399
+    GREATEST_ASSERT_MEM_EQm(#EXP " != " #GOT, EXP, GOT, SIZE)
400
+#define GREATEST_ASSERT_ENUM_EQ(EXP, GOT, ENUM_STR)                     \
401
+    GREATEST_ASSERT_ENUM_EQm(#EXP " != " #GOT, EXP, GOT, ENUM_STR)
402
+
403
+/* The following forms take an additional message argument first,
404
+ * to be displayed by the test runner. */
405
+
406
+/* Fail if a condition is not true, with message. */
407
+#define GREATEST_ASSERTm(MSG, COND)                                     \
408
+    do {                                                                \
409
+        greatest_info.assertions++;                                     \
410
+        if (!(COND)) { GREATEST_FAILm(MSG); }                           \
411
+    } while (0)
412
+
413
+/* Fail if a condition is not true, longjmping out of test. */
414
+#define GREATEST_ASSERT_OR_LONGJMPm(MSG, COND)                          \
415
+    do {                                                                \
416
+        greatest_info.assertions++;                                     \
417
+        if (!(COND)) { GREATEST_FAIL_WITH_LONGJMPm(MSG); }              \
418
+    } while (0)
419
+
420
+/* Fail if a condition is not false, with message. */
421
+#define GREATEST_ASSERT_FALSEm(MSG, COND)                               \
422
+    do {                                                                \
423
+        greatest_info.assertions++;                                     \
424
+        if ((COND)) { GREATEST_FAILm(MSG); }                            \
425
+    } while (0)
426
+
427
+/* Fail if EXP != GOT (equality comparison by ==). */
428
+#define GREATEST_ASSERT_EQm(MSG, EXP, GOT)                              \
429
+    do {                                                                \
430
+        greatest_info.assertions++;                                     \
431
+        if ((EXP) != (GOT)) { GREATEST_FAILm(MSG); }                    \
432
+    } while (0)
433
+
434
+/* Fail if EXP != GOT (equality comparison by ==).
435
+ * Warning: EXP and GOT will be evaluated more than once on failure. */
436
+#define GREATEST_ASSERT_EQ_FMTm(MSG, EXP, GOT, FMT)                     \
437
+    do {                                                                \
438
+        const char *greatest_FMT = ( FMT );                             \
439
+        greatest_info.assertions++;                                     \
440
+        if ((EXP) != (GOT)) {                                           \
441
+            fprintf(GREATEST_STDOUT, "\nExpected: ");                   \
442
+            fprintf(GREATEST_STDOUT, greatest_FMT, EXP);                \
443
+            fprintf(GREATEST_STDOUT, "\n     Got: ");                   \
444
+            fprintf(GREATEST_STDOUT, greatest_FMT, GOT);                \
445
+            fprintf(GREATEST_STDOUT, "\n");                             \
446
+            GREATEST_FAILm(MSG);                                        \
447
+        }                                                               \
448
+    } while (0)
449
+
450
+/* Fail if EXP is not equal to GOT, printing enum IDs. */
451
+#define GREATEST_ASSERT_ENUM_EQm(MSG, EXP, GOT, ENUM_STR)               \
452
+    do {                                                                \
453
+        int greatest_EXP = (int)(EXP);                                  \
454
+        int greatest_GOT = (int)(GOT);                                  \
455
+        greatest_enum_str_fun *greatest_ENUM_STR = ENUM_STR;            \
456
+        if (greatest_EXP != greatest_GOT) {                             \
457
+            fprintf(GREATEST_STDOUT, "\nExpected: %s",                  \
458
+                greatest_ENUM_STR(greatest_EXP));                       \
459
+            fprintf(GREATEST_STDOUT, "\n     Got: %s\n",                \
460
+                greatest_ENUM_STR(greatest_GOT));                       \
461
+            GREATEST_FAILm(MSG);                                        \
462
+        }                                                               \
463
+    } while (0)                                                         \
464
+
465
+/* Fail if GOT not in range of EXP +|- TOL. */
466
+#define GREATEST_ASSERT_IN_RANGEm(MSG, EXP, GOT, TOL)                   \
467
+    do {                                                                \
468
+        GREATEST_FLOAT greatest_EXP = (EXP);                            \
469
+        GREATEST_FLOAT greatest_GOT = (GOT);                            \
470
+        GREATEST_FLOAT greatest_TOL = (TOL);                            \
471
+        greatest_info.assertions++;                                     \
472
+        if ((greatest_EXP > greatest_GOT &&                             \
473
+                greatest_EXP - greatest_GOT > greatest_TOL) ||          \
474
+            (greatest_EXP < greatest_GOT &&                             \
475
+                greatest_GOT - greatest_EXP > greatest_TOL)) {          \
476
+            fprintf(GREATEST_STDOUT,                                    \
477
+                "\nExpected: " GREATEST_FLOAT_FMT                       \
478
+                " +/- " GREATEST_FLOAT_FMT                              \
479
+                "\n     Got: " GREATEST_FLOAT_FMT                       \
480
+                "\n",                                                   \
481
+                greatest_EXP, greatest_TOL, greatest_GOT);              \
482
+            GREATEST_FAILm(MSG);                                        \
483
+        }                                                               \
484
+    } while (0)
485
+
486
+/* Fail if EXP is not equal to GOT, according to strcmp. */
487
+#define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT)                          \
488
+    do {                                                                \
489
+        GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT,                         \
490
+            &greatest_type_info_string, NULL);                          \
491
+    } while (0)                                                         \
492
+
493
+/* Fail if EXP is not equal to GOT, according to strcmp. */
494
+#define GREATEST_ASSERT_STRN_EQm(MSG, EXP, GOT, SIZE)                   \
495
+    do {                                                                \
496
+        size_t size = SIZE;                                             \
497
+        GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT,                         \
498
+            &greatest_type_info_string, &size);                         \
499
+    } while (0)                                                         \
500
+
501
+/* Fail if EXP is not equal to GOT, according to memcmp. */
502
+#define GREATEST_ASSERT_MEM_EQm(MSG, EXP, GOT, SIZE)                    \
503
+    do {                                                                \
504
+        greatest_memory_cmp_env env;                                    \
505
+        env.exp = (const unsigned char *)EXP;                           \
506
+        env.got = (const unsigned char *)GOT;                           \
507
+        env.size = SIZE;                                                \
508
+        GREATEST_ASSERT_EQUAL_Tm(MSG, env.exp, env.got,                 \
509
+            &greatest_type_info_memory, &env);                          \
510
+    } while (0)                                                         \
511
+
512
+/* Fail if EXP is not equal to GOT, according to a comparison
513
+ * callback in TYPE_INFO. If they are not equal, optionally use a
514
+ * print callback in TYPE_INFO to print them. */
515
+#define GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT, TYPE_INFO, UDATA)       \
516
+    do {                                                                \
517
+        greatest_type_info *type_info = (TYPE_INFO);                    \
518
+        greatest_info.assertions++;                                     \
519
+        if (!greatest_do_assert_equal_t(EXP, GOT,                       \
520
+                type_info, UDATA)) {                                    \
521
+            if (type_info == NULL || type_info->equal == NULL) {        \
522
+                GREATEST_FAILm("type_info->equal callback missing!");   \
523
+            } else {                                                    \
524
+                GREATEST_FAILm(MSG);                                    \
525
+            }                                                           \
526
+        }                                                               \
527
+    } while (0)                                                         \
528
+
529
+/* Pass. */
530
+#define GREATEST_PASSm(MSG)                                             \
531
+    do {                                                                \
532
+        greatest_info.msg = MSG;                                        \
533
+        return GREATEST_TEST_RES_PASS;                                  \
534
+    } while (0)
535
+
536
+/* Fail. */
537
+#define GREATEST_FAILm(MSG)                                             \
538
+    do {                                                                \
539
+        greatest_info.fail_file = __FILE__;                             \
540
+        greatest_info.fail_line = __LINE__;                             \
541
+        greatest_info.msg = MSG;                                        \
542
+        return GREATEST_TEST_RES_FAIL;                                  \
543
+    } while (0)
544
+
545
+/* Optional GREATEST_FAILm variant that longjmps. */
546
+#if GREATEST_USE_LONGJMP
547
+#define GREATEST_FAIL_WITH_LONGJMP() GREATEST_FAIL_WITH_LONGJMPm(NULL)
548
+#define GREATEST_FAIL_WITH_LONGJMPm(MSG)                                \
549
+    do {                                                                \
550
+        greatest_info.fail_file = __FILE__;                             \
551
+        greatest_info.fail_line = __LINE__;                             \
552
+        greatest_info.msg = MSG;                                        \
553
+        longjmp(greatest_info.jump_dest, GREATEST_TEST_RES_FAIL);       \
554
+    } while (0)
555
+#endif
556
+
557
+/* Skip the current test. */
558
+#define GREATEST_SKIPm(MSG)                                             \
559
+    do {                                                                \
560
+        greatest_info.msg = MSG;                                        \
561
+        return GREATEST_TEST_RES_SKIP;                                  \
562
+    } while (0)
563
+
564
+/* Check the result of a subfunction using ASSERT, etc. */
565
+#define GREATEST_CHECK_CALL(RES)                                        \
566
+    do {                                                                \
567
+        enum greatest_test_res greatest_RES = RES;                      \
568
+        if (greatest_RES != GREATEST_TEST_RES_PASS) {                   \
569
+            return greatest_RES;                                        \
570
+        }                                                               \
571
+    } while (0)                                                         \
572
+
573
+#if GREATEST_USE_TIME
574
+#define GREATEST_SET_TIME(NAME)                                         \
575
+    NAME = clock();                                                     \
576
+    if (NAME == (clock_t) -1) {                                         \
577
+        fprintf(GREATEST_STDOUT,                                        \
578
+            "clock error: %s\n", #NAME);                                \
579
+        exit(EXIT_FAILURE);                                             \
580
+    }
581
+
582
+#define GREATEST_CLOCK_DIFF(C1, C2)                                     \
583
+    fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)",                  \
584
+        (long unsigned int) (C2) - (long unsigned int)(C1),             \
585
+        (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC))
586
+#else
587
+#define GREATEST_SET_TIME(UNUSED)
588
+#define GREATEST_CLOCK_DIFF(UNUSED1, UNUSED2)
589
+#endif
590
+
591
+#if GREATEST_USE_LONGJMP
592
+#define GREATEST_SAVE_CONTEXT()                                         \
593
+        /* setjmp returns 0 (GREATEST_TEST_RES_PASS) on first call */   \
594
+        /* so the test runs, then RES_FAIL from FAIL_WITH_LONGJMP. */   \
595
+        ((enum greatest_test_res)(setjmp(greatest_info.jump_dest)))
596
+#else
597
+#define GREATEST_SAVE_CONTEXT()                                         \
598
+    /*a no-op, since setjmp/longjmp aren't being used */                \
599
+    GREATEST_TEST_RES_PASS
600
+#endif
601
+
602
+/* Include several function definitions in the main test file. */
603
+#define GREATEST_MAIN_DEFS()                                            \
604
+                                                                        \
605
+/* Is FILTER a subset of NAME? */                                       \
606
+static int greatest_name_match(const char *name,                        \
607
+    const char *filter) {                                               \
608
+    size_t offset = 0;                                                  \
609
+    size_t filter_len = strlen(filter);                                 \
610
+    while (name[offset] != '\0') {                                      \
611
+        if (name[offset] == filter[0]) {                                \
612
+            if (0 == strncmp(&name[offset], filter, filter_len)) {      \
613
+                return 1;                                               \
614
+            }                                                           \
615
+        }                                                               \
616
+        offset++;                                                       \
617
+    }                                                                   \
618
+                                                                        \
619
+    return 0;                                                           \
620
+}                                                                       \
621
+                                                                        \
622
+int greatest_pre_test(const char *name) {                               \
623
+    if (!GREATEST_LIST_ONLY()                                           \
624
+        && (!GREATEST_FIRST_FAIL() || greatest_info.suite.failed == 0)  \
625
+        && (greatest_info.test_filter == NULL ||                        \
626
+            greatest_name_match(name, greatest_info.test_filter))) {    \
627
+        GREATEST_SET_TIME(greatest_info.suite.pre_test);                \
628
+        if (greatest_info.setup) {                                      \
629
+            greatest_info.setup(greatest_info.setup_udata);             \
630
+        }                                                               \
631
+        return 1;               /* test should be run */                \
632
+    } else {                                                            \
633
+        return 0;               /* skipped */                           \
634
+    }                                                                   \
635
+}                                                                       \
636
+                                                                        \
637
+void greatest_post_test(const char *name, int res) {                    \
638
+    GREATEST_SET_TIME(greatest_info.suite.post_test);                   \
639
+    if (greatest_info.teardown) {                                       \
640
+        void *udata = greatest_info.teardown_udata;                     \
641
+        greatest_info.teardown(udata);                                  \
642
+    }                                                                   \
643
+                                                                        \
644
+    if (res <= GREATEST_TEST_RES_FAIL) {                                \
645
+        greatest_do_fail(name);                                         \
646
+    } else if (res >= GREATEST_TEST_RES_SKIP) {                         \
647
+        greatest_do_skip(name);                                         \
648
+    } else if (res == GREATEST_TEST_RES_PASS) {                         \
649
+        greatest_do_pass(name);                                         \
650
+    }                                                                   \
651
+    greatest_info.suite.tests_run++;                                    \
652
+    greatest_info.col++;                                                \
653
+    if (GREATEST_IS_VERBOSE()) {                                        \
654
+        GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test,               \
655
+            greatest_info.suite.post_test);                             \
656
+        fprintf(GREATEST_STDOUT, "\n");                                 \
657
+    } else if (greatest_info.col % greatest_info.width == 0) {          \
658
+        fprintf(GREATEST_STDOUT, "\n");                                 \
659
+        greatest_info.col = 0;                                          \
660
+    }                                                                   \
661
+    if (GREATEST_STDOUT == stdout) fflush(stdout);                      \
662
+}                                                                       \
663
+                                                                        \
664
+static void report_suite(void) {                                        \
665
+    if (greatest_info.suite.tests_run > 0) {                            \
666
+        fprintf(GREATEST_STDOUT,                                        \
667
+            "\n%u test%s - %u passed, %u failed, %u skipped",           \
668
+            greatest_info.suite.tests_run,                              \
669
+            greatest_info.suite.tests_run == 1 ? "" : "s",              \
670
+            greatest_info.suite.passed,                                 \
671
+            greatest_info.suite.failed,                                 \
672
+            greatest_info.suite.skipped);                               \
673
+        GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite,              \
674
+            greatest_info.suite.post_suite);                            \
675
+        fprintf(GREATEST_STDOUT, "\n");                                 \
676
+    }                                                                   \
677
+}                                                                       \
678
+                                                                        \
679
+static void update_counts_and_reset_suite(void) {                       \
680
+    greatest_info.setup = NULL;                                         \
681
+    greatest_info.setup_udata = NULL;                                   \
682
+    greatest_info.teardown = NULL;                                      \
683
+    greatest_info.teardown_udata = NULL;                                \
684
+    greatest_info.passed += greatest_info.suite.passed;                 \
685
+    greatest_info.failed += greatest_info.suite.failed;                 \
686
+    greatest_info.skipped += greatest_info.suite.skipped;               \
687
+    greatest_info.tests_run += greatest_info.suite.tests_run;           \
688
+    memset(&greatest_info.suite, 0, sizeof(greatest_info.suite));       \
689
+    greatest_info.col = 0;                                              \
690
+}                                                                       \
691
+                                                                        \
692
+static void greatest_run_suite(greatest_suite_cb *suite_cb,             \
693
+                               const char *suite_name) {                \
694
+    if (greatest_info.suite_filter &&                                   \
695
+        !greatest_name_match(suite_name, greatest_info.suite_filter)) { \
696
+        return;                                                         \
697
+    }                                                                   \
698
+    update_counts_and_reset_suite();                                    \
699
+    if (GREATEST_FIRST_FAIL() && greatest_info.failed > 0) { return; }  \
700
+    fprintf(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name);            \
701
+    GREATEST_SET_TIME(greatest_info.suite.pre_suite);                   \
702
+    suite_cb();                                                         \
703
+    GREATEST_SET_TIME(greatest_info.suite.post_suite);                  \
704
+    report_suite();                                                     \
705
+}                                                                       \
706
+                                                                        \
707
+void greatest_do_pass(const char *name) {                               \
708
+    if (GREATEST_IS_VERBOSE()) {                                        \
709
+        fprintf(GREATEST_STDOUT, "PASS %s: %s",                         \
710
+            name, greatest_info.msg ? greatest_info.msg : "");          \
711
+    } else {                                                            \
712
+        fprintf(GREATEST_STDOUT, ".");                                  \
713
+    }                                                                   \
714
+    greatest_info.suite.passed++;                                       \
715
+}                                                                       \
716
+                                                                        \
717
+void greatest_do_fail(const char *name) {                               \
718
+    if (GREATEST_IS_VERBOSE()) {                                        \
719
+        fprintf(GREATEST_STDOUT,                                        \
720
+            "FAIL %s: %s (%s:%u)",                                      \
721
+            name, greatest_info.msg ? greatest_info.msg : "",           \
722
+            greatest_info.fail_file, greatest_info.fail_line);          \
723
+    } else {                                                            \
724
+        fprintf(GREATEST_STDOUT, "F");                                  \
725
+        greatest_info.col++;                                            \
726
+        /* add linebreak if in line of '.'s */                          \
727
+        if (greatest_info.col != 0) {                                   \
728
+            fprintf(GREATEST_STDOUT, "\n");                             \
729
+            greatest_info.col = 0;                                      \
730
+        }                                                               \
731
+        fprintf(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n",               \
732
+            name,                                                       \
733
+            greatest_info.msg ? greatest_info.msg : "",                 \
734
+            greatest_info.fail_file, greatest_info.fail_line);          \
735
+    }                                                                   \
736
+    greatest_info.suite.failed++;                                       \
737
+}                                                                       \
738
+                                                                        \
739
+void greatest_do_skip(const char *name) {                               \
740
+    if (GREATEST_IS_VERBOSE()) {                                        \
741
+        fprintf(GREATEST_STDOUT, "SKIP %s: %s",                         \
742
+            name,                                                       \
743
+            greatest_info.msg ?                                         \
744
+            greatest_info.msg : "" );                                   \
745
+    } else {                                                            \
746
+        fprintf(GREATEST_STDOUT, "s");                                  \
747
+    }                                                                   \
748
+    greatest_info.suite.skipped++;                                      \
749
+}                                                                       \
750
+                                                                        \
751
+int greatest_do_assert_equal_t(const void *exp, const void *got,        \
752
+        greatest_type_info *type_info, void *udata) {                   \
753
+    int eq = 0;                                                         \
754
+    if (type_info == NULL || type_info->equal == NULL) {                \
755
+        return 0;                                                       \
756
+    }                                                                   \
757
+    eq = type_info->equal(exp, got, udata);                             \
758
+    if (!eq) {                                                          \
759
+        if (type_info->print != NULL) {                                 \
760
+            fprintf(GREATEST_STDOUT, "\nExpected: ");                   \
761
+            (void)type_info->print(exp, udata);                         \
762
+            fprintf(GREATEST_STDOUT, "\n     Got: ");                   \
763
+            (void)type_info->print(got, udata);                         \
764
+            fprintf(GREATEST_STDOUT, "\n");                             \
765
+        } else {                                                        \
766
+            fprintf(GREATEST_STDOUT,                                    \
767
+                "GREATEST_ASSERT_EQUAL_T failure at %s:%u\n",           \
768
+                greatest_info.fail_file,                                \
769
+                greatest_info.fail_line);                               \
770
+        }                                                               \
771
+    }                                                                   \
772
+    return eq;                                                          \
773
+}                                                                       \
774
+                                                                        \
775
+void greatest_usage(const char *name) {                                 \
776
+    fprintf(GREATEST_STDOUT,                                            \
777
+        "Usage: %s [-hlfv] [-s SUITE] [-t TEST]\n"                      \
778
+        "  -h, --help  print this Help\n"                               \
779
+        "  -l          List suites and their tests, then exit\n"        \
780
+        "  -f          Stop runner after first failure\n"               \
781
+        "  -v          Verbose output\n"                                \
782
+        "  -s SUITE    only run suites containing string SUITE\n"       \
783
+        "  -t TEST     only run tests containing string TEST\n",        \
784
+        name);                                                          \
785
+}                                                                       \
786
+                                                                        \
787
+static void greatest_parse_args(int argc, char **argv) {                \
788
+    int i = 0;                                                          \
789
+    for (i = 1; i < argc; i++) {                                        \
790
+        if (0 == strncmp("-t", argv[i], 2)) {                           \
791
+            if (argc <= i + 1) {                                        \
792
+                greatest_usage(argv[0]);                                \
793
+                exit(EXIT_FAILURE);                                     \
794
+            }                                                           \
795
+            greatest_info.test_filter = argv[i+1];                      \
796
+            i++;                                                        \
797
+        } else if (0 == strncmp("-s", argv[i], 2)) {                    \
798
+            if (argc <= i + 1) {                                        \
799
+                greatest_usage(argv[0]);                                \
800
+                exit(EXIT_FAILURE);                                     \
801
+            }                                                           \
802
+            greatest_info.suite_filter = argv[i+1];                     \
803
+            i++;                                                        \
804
+        } else if (0 == strncmp("-f", argv[i], 2)) {                    \
805
+            greatest_info.flags |= GREATEST_FLAG_FIRST_FAIL;            \
806
+        } else if (0 == strncmp("-v", argv[i], 2)) {                    \
807
+            greatest_info.verbosity++;                                  \
808
+        } else if (0 == strncmp("-l", argv[i], 2)) {                    \
809
+            greatest_info.flags |= GREATEST_FLAG_LIST_ONLY;             \
810
+        } else if (0 == strncmp("-h", argv[i], 2) ||                    \
811
+                   0 == strncmp("--help", argv[i], 6)) {                \
812
+            greatest_usage(argv[0]);                                    \
813
+            exit(EXIT_SUCCESS);                                         \
814
+        } else if (0 == strncmp("--", argv[i], 2)) {                    \
815
+            break;                                                      \
816
+        } else {                                                        \
817
+            fprintf(GREATEST_STDOUT,                                    \
818
+                "Unknown argument '%s'\n", argv[i]);                    \
819
+            greatest_usage(argv[0]);                                    \
820
+            exit(EXIT_FAILURE);                                         \
821
+        }                                                               \
822
+    }                                                                   \
823
+}                                                                       \
824
+                                                                        \
825
+int greatest_all_passed(void) { return (greatest_info.failed == 0); }   \
826
+                                                                        \
827
+void greatest_set_test_filter(const char *name) {                       \
828
+    greatest_info.test_filter = name;                                   \
829
+}                                                                       \
830
+                                                                        \
831
+void greatest_set_suite_filter(const char *name) {                      \
832
+    greatest_info.suite_filter = name;                                  \
833
+}                                                                       \
834
+                                                                        \
835
+void greatest_get_report(struct greatest_report_t *report) {            \
836
+    if (report) {                                                       \
837
+        report->passed = greatest_info.passed;                          \
838
+        report->failed = greatest_info.failed;                          \
839
+        report->skipped = greatest_info.skipped;                        \
840
+        report->assertions = greatest_info.assertions;                  \
841
+    }                                                                   \
842
+}                                                                       \
843
+                                                                        \
844
+unsigned int greatest_get_verbosity(void) {                             \
845
+    return greatest_info.verbosity;                                     \
846
+}                                                                       \
847
+                                                                        \
848
+void greatest_set_verbosity(unsigned int verbosity) {                   \
849
+    greatest_info.verbosity = (unsigned char)verbosity;                 \
850
+}                                                                       \
851
+                                                                        \
852
+void greatest_set_flag(greatest_flag_t flag) {                          \
853
+    greatest_info.flags |= flag;                                        \
854
+}                                                                       \
855
+                                                                        \
856
+void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) {        \
857
+    greatest_info.setup = cb;                                           \
858
+    greatest_info.setup_udata = udata;                                  \
859
+}                                                                       \
860
+                                                                        \
861
+void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb,                 \
862
+                                    void *udata) {                      \
863
+    greatest_info.teardown = cb;                                        \
864
+    greatest_info.teardown_udata = udata;                               \
865
+}                                                                       \
866
+                                                                        \
867
+static int greatest_string_equal_cb(const void *exp, const void *got,   \
868
+    void *udata) {                                                      \
869
+    size_t *size = (size_t *)udata;                                     \
870
+    return (size != NULL                                                \
871
+        ? (0 == strncmp((const char *)exp, (const char *)got, *size))   \
872
+        : (0 == strcmp((const char *)exp, (const char *)got)));         \
873
+}                                                                       \
874
+                                                                        \
875
+static int greatest_string_printf_cb(const void *t, void *udata) {      \
876
+    (void)udata; /* note: does not check \0 termination. */             \
877
+    return fprintf(GREATEST_STDOUT, "%s", (const char *)t);             \
878
+}                                                                       \
879
+                                                                        \
880
+greatest_type_info greatest_type_info_string = {                        \
881
+    greatest_string_equal_cb,                                           \
882
+    greatest_string_printf_cb,                                          \
883
+};                                                                      \
884
+                                                                        \
885
+static int greatest_memory_equal_cb(const void *exp, const void *got,   \
886
+    void *udata) {                                                      \
887
+    greatest_memory_cmp_env *env = (greatest_memory_cmp_env *)udata;    \
888
+    return (0 == memcmp(exp, got, env->size));                          \
889
+}                                                                       \
890
+                                                                        \
891
+static int greatest_memory_printf_cb(const void *t, void *udata) {      \
892
+    greatest_memory_cmp_env *env = (greatest_memory_cmp_env *)udata;    \
893
+    unsigned char *buf = (unsigned char *)t, diff_mark = ' ';           \
894
+    FILE *out = GREATEST_STDOUT;                                        \
895
+    size_t i, line_i, line_len = 0;                                     \
896
+    int len = 0;   /* format hexdump with differences highlighted */    \
897
+    for (i = 0; i < env->size; i+= line_len) {                          \
898
+        diff_mark = ' ';                                                \
899
+        line_len = env->size - i;                                       \
900
+        if (line_len > 16) { line_len = 16; }                           \
901
+        for (line_i = i; line_i < i + line_len; line_i++) {             \
902
+            if (env->exp[line_i] != env->got[line_i]) diff_mark = 'X';  \
903
+        }                                                               \
904
+        len += fprintf(out, "\n%04x %c ", (unsigned int)i, diff_mark);  \
905
+        for (line_i = i; line_i < i + line_len; line_i++) {             \
906
+            int m = env->exp[line_i] == env->got[line_i]; /* match? */  \
907
+            len += fprintf(out, "%02x%c", buf[line_i], m ? ' ' : '<');  \
908
+        }                                                               \
909
+        for (line_i = 0; line_i < 16 - line_len; line_i++) {            \
910
+            len += fprintf(out, "   ");                                 \
911
+        }                                                               \
912
+        fprintf(out, " ");                                              \
913
+        for (line_i = i; line_i < i + line_len; line_i++) {             \
914
+            unsigned char c = buf[line_i];                              \
915
+            len += fprintf(out, "%c", isprint(c) ? c : '.');            \
916
+        }                                                               \
917
+    }                                                                   \
918
+    len += fprintf(out, "\n");                                          \
919
+    return len;                                                         \
920
+}                                                                       \
921
+                                                                        \
922
+greatest_type_info greatest_type_info_memory = {                        \
923
+    greatest_memory_equal_cb,                                           \
924
+    greatest_memory_printf_cb,                                          \
925
+};                                                                      \
926
+                                                                        \
927
+greatest_run_info greatest_info
928
+
929
+/* Init internals. */
930
+#define GREATEST_INIT()                                                 \
931
+    do {                                                                \
932
+        /* Suppress unused function warning if features aren't used */  \
933
+        (void)greatest_run_suite;                                       \
934
+        (void)greatest_parse_args;                                      \
935
+                                                                        \
936
+        memset(&greatest_info, 0, sizeof(greatest_info));               \
937
+        greatest_info.width = GREATEST_DEFAULT_WIDTH;                   \
938
+        GREATEST_SET_TIME(greatest_info.begin);                         \
939
+    } while (0)                                                         \
940
+
941
+/* Handle command-line arguments, etc. */
942
+#define GREATEST_MAIN_BEGIN()                                           \
943
+    do {                                                                \
944
+        GREATEST_INIT();                                                \
945
+        greatest_parse_args(argc, argv);                                \
946
+    } while (0)
947
+
948
+/* Report passes, failures, skipped tests, the number of
949
+ * assertions, and the overall run time. */
950
+#define GREATEST_PRINT_REPORT()                                         \
951
+    do {                                                                \
952
+        if (!GREATEST_LIST_ONLY()) {                                    \
953
+            update_counts_and_reset_suite();                            \
954
+            GREATEST_SET_TIME(greatest_info.end);                       \
955
+            fprintf(GREATEST_STDOUT,                                    \
956
+                "\nTotal: %u test%s",                                   \
957
+                greatest_info.tests_run,                                \
958
+                greatest_info.tests_run == 1 ? "" : "s");               \
959
+            GREATEST_CLOCK_DIFF(greatest_info.begin,                    \
960
+                greatest_info.end);                                     \
961
+            fprintf(GREATEST_STDOUT, ", %u assertion%s\n",              \
962
+                greatest_info.assertions,                               \
963
+                greatest_info.assertions == 1 ? "" : "s");              \
964
+            fprintf(GREATEST_STDOUT,                                    \
965
+                "Pass: %u, fail: %u, skip: %u.\n",                      \
966
+                greatest_info.passed,                                   \
967
+                greatest_info.failed, greatest_info.skipped);           \
968
+        }                                                               \
969
+    } while (0)
970
+
971
+/* Report results, exit with exit status based on results. */
972
+#define GREATEST_MAIN_END()                                             \
973
+    do {                                                                \
974
+        GREATEST_PRINT_REPORT();                                        \
975
+        return (greatest_all_passed() ? EXIT_SUCCESS : EXIT_FAILURE);   \
976
+    } while (0)
977
+
978
+/* Make abbreviations without the GREATEST_ prefix for the
979
+ * most commonly used symbols. */
980
+#if GREATEST_USE_ABBREVS
981
+#define TEST           GREATEST_TEST
982
+#define SUITE          GREATEST_SUITE
983
+#define SUITE_EXTERN   GREATEST_SUITE_EXTERN
984
+#define RUN_TEST       GREATEST_RUN_TEST
985
+#define RUN_TEST1      GREATEST_RUN_TEST1
986
+#define RUN_SUITE      GREATEST_RUN_SUITE
987
+#define IGNORE_TEST    GREATEST_IGNORE_TEST
988
+#define ASSERT         GREATEST_ASSERT
989
+#define ASSERTm        GREATEST_ASSERTm
990
+#define ASSERT_FALSE   GREATEST_ASSERT_FALSE
991
+#define ASSERT_EQ      GREATEST_ASSERT_EQ
992
+#define ASSERT_EQ_FMT  GREATEST_ASSERT_EQ_FMT
993
+#define ASSERT_IN_RANGE GREATEST_ASSERT_IN_RANGE
994
+#define ASSERT_EQUAL_T GREATEST_ASSERT_EQUAL_T
995
+#define ASSERT_STR_EQ  GREATEST_ASSERT_STR_EQ
996
+#define ASSERT_STRN_EQ GREATEST_ASSERT_STRN_EQ
997
+#define ASSERT_MEM_EQ  GREATEST_ASSERT_MEM_EQ
998
+#define ASSERT_ENUM_EQ GREATEST_ASSERT_ENUM_EQ
999
+#define ASSERT_FALSEm  GREATEST_ASSERT_FALSEm
1000
+#define ASSERT_EQm     GREATEST_ASSERT_EQm
1001
+#define ASSERT_EQ_FMTm GREATEST_ASSERT_EQ_FMTm
1002
+#define ASSERT_IN_RANGEm GREATEST_ASSERT_IN_RANGEm
1003
+#define ASSERT_EQUAL_Tm GREATEST_ASSERT_EQUAL_Tm
1004
+#define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm
1005
+#define ASSERT_STRN_EQm GREATEST_ASSERT_STRN_EQm
1006
+#define ASSERT_MEM_EQm GREATEST_ASSERT_MEM_EQm
1007
+#define ASSERT_ENUM_EQm GREATEST_ASSERT_ENUM_EQm
1008
+#define PASS           GREATEST_PASS
1009
+#define FAIL           GREATEST_FAIL
1010
+#define SKIP           GREATEST_SKIP
1011
+#define PASSm          GREATEST_PASSm
1012
+#define FAILm          GREATEST_FAILm
1013
+#define SKIPm          GREATEST_SKIPm
1014
+#define SET_SETUP      GREATEST_SET_SETUP_CB
1015
+#define SET_TEARDOWN   GREATEST_SET_TEARDOWN_CB
1016
+#define CHECK_CALL     GREATEST_CHECK_CALL
1017
+
1018
+#ifdef GREATEST_VA_ARGS
1019
+#define RUN_TESTp      GREATEST_RUN_TESTp
1020
+#endif
1021
+
1022
+#if GREATEST_USE_LONGJMP
1023
+#define ASSERT_OR_LONGJMP  GREATEST_ASSERT_OR_LONGJMP
1024
+#define ASSERT_OR_LONGJMPm GREATEST_ASSERT_OR_LONGJMPm
1025
+#define FAIL_WITH_LONGJMP  GREATEST_FAIL_WITH_LONGJMP
1026
+#define FAIL_WITH_LONGJMPm GREATEST_FAIL_WITH_LONGJMPm
1027
+#endif
1028
+
1029
+#endif /* USE_ABBREVS */
1030
+
1031
+#ifdef __cplusplus
1032
+}
1033
+#endif
1034
+
1035
+#endif
0 1036
new file mode 100644
... ...
@@ -0,0 +1,9 @@
1
+{
2
+  "name": "greatest",
3
+  "version": "v1.2.1",
4
+  "repo": "silentbicycle/greatest",
5
+  "src": ["greatest.h"],
6
+  "description": "A C testing library in 1 file. No dependencies, no dynamic allocation.",
7
+  "license": "ISC",
8
+  "keywords": ["test", "unit", "testing"]
9
+}