cauterize 0.0.1.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +24 -0
  2. data/.rspec +1 -0
  3. data/.travisci.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +152 -0
  7. data/Rakefile +38 -0
  8. data/bin/cauterize +53 -0
  9. data/c/src/cauterize.c +74 -0
  10. data/c/src/cauterize.h +46 -0
  11. data/c/src/cauterize_debug.h +29 -0
  12. data/c/src/cauterize_util.h +7 -0
  13. data/c/test/greatest.h +536 -0
  14. data/c/test/test.c +166 -0
  15. data/cauterize.gemspec +26 -0
  16. data/example/Cauterize +44 -0
  17. data/example/build.sh +4 -0
  18. data/lib/cauterize/base_type.rb +96 -0
  19. data/lib/cauterize/builders.rb +27 -0
  20. data/lib/cauterize/builders/c/buildable.rb +59 -0
  21. data/lib/cauterize/builders/c/composite.rb +55 -0
  22. data/lib/cauterize/builders/c/enumeration.rb +41 -0
  23. data/lib/cauterize/builders/c/fixed_array.rb +62 -0
  24. data/lib/cauterize/builders/c/group.rb +95 -0
  25. data/lib/cauterize/builders/c/scalar.rb +31 -0
  26. data/lib/cauterize/builders/c/variable_array.rb +90 -0
  27. data/lib/cauterize/c_builder.rb +63 -0
  28. data/lib/cauterize/cauterize.rb +33 -0
  29. data/lib/cauterize/composite.rb +50 -0
  30. data/lib/cauterize/enumeration.rb +77 -0
  31. data/lib/cauterize/fixed_array.rb +43 -0
  32. data/lib/cauterize/formatter.rb +59 -0
  33. data/lib/cauterize/group.rb +56 -0
  34. data/lib/cauterize/scalar.rb +38 -0
  35. data/lib/cauterize/snake_case.rb +21 -0
  36. data/lib/cauterize/variable_array.rb +56 -0
  37. data/lib/cauterize/version.rb +3 -0
  38. data/spec/base_type_spec.rb +167 -0
  39. data/spec/builders/c/buildable_spec.rb +25 -0
  40. data/spec/builders/c/composite_spec.rb +46 -0
  41. data/spec/builders/c/enumeration_spec.rb +32 -0
  42. data/spec/builders/c/fixed_array_spec.rb +36 -0
  43. data/spec/builders/c/group_spec.rb +112 -0
  44. data/spec/builders/c/scalar_spec.rb +8 -0
  45. data/spec/builders/c/variable_array_spec.rb +50 -0
  46. data/spec/builders_spec.rb +51 -0
  47. data/spec/c_builder_spec.rb +133 -0
  48. data/spec/cauterize_spec.rb +8 -0
  49. data/spec/composite_spec.rb +62 -0
  50. data/spec/enumeration_spec.rb +104 -0
  51. data/spec/fixed_array_spec.rb +62 -0
  52. data/spec/group_spec.rb +104 -0
  53. data/spec/scalar_spec.rb +36 -0
  54. data/spec/spec_helper.rb +115 -0
  55. data/spec/support/shared_examples_for_array_buildables.rb +22 -0
  56. data/spec/support/shared_examples_for_c_buildables.rb +91 -0
  57. data/spec/support/shared_examples_for_sane_c_buildables.rb +22 -0
  58. data/spec/support/shared_examples_for_stubbed_functions.rb +18 -0
  59. data/spec/test_main.c +13 -0
  60. data/spec/variable_array_spec.rb +92 -0
  61. metadata +212 -0
@@ -0,0 +1,7 @@
1
+ #ifndef CAUTERIZE_UTIL_H
2
+ #define CAUTERIZE_UTIL_H
3
+
4
+ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
5
+ #define MIN(a, b) (((a) < (b)) ? (a) : (b))
6
+
7
+ #endif /* CAUTERIZE_UTIL_H */
data/c/test/greatest.h ADDED
@@ -0,0 +1,536 @@
1
+ /*
2
+ * Copyright (c) 2011 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
+ #define GREATEST_VERSION 0.8
21
+
22
+ /* A unit testing system for C, contained in 1 file.
23
+ * It doesn't use dynamic allocation or depend on anything
24
+ * beyond ANSI C89.
25
+ *
26
+ * If C99 is available, then suites can pass arguments to tests for
27
+ * parametric testing. */
28
+
29
+
30
+ /*********************************************************************
31
+ * Minimal test runner template
32
+ *********************************************************************/
33
+ #if 0
34
+
35
+ #include "greatest.h"
36
+
37
+ TEST foo() {
38
+ PASS();
39
+ }
40
+
41
+ SUITE(suite) {
42
+ RUN_TEST(foo);
43
+ }
44
+
45
+ /* Add all the definitions that need to be in the test runner's main file. */
46
+ GREATEST_MAIN_DEFS();
47
+
48
+ int main(int argc, char **argv) {
49
+ GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */
50
+ RUN_SUITE(suite);
51
+ GREATEST_MAIN_END(); /* display results */
52
+ }
53
+
54
+ #endif
55
+ /*********************************************************************/
56
+
57
+
58
+ #include <stdlib.h>
59
+ #include <stdio.h>
60
+ #include <string.h>
61
+ #include <time.h>
62
+
63
+
64
+ /***********
65
+ * Options *
66
+ ***********/
67
+
68
+ /* Default column width for non-verbose output. */
69
+ #ifndef GREATEST_DEFAULT_WIDTH
70
+ #define GREATEST_DEFAULT_WIDTH 72
71
+ #endif
72
+
73
+ /* FILE *, for test logging. */
74
+ #ifndef GREATEST_STDOUT
75
+ #define GREATEST_STDOUT stdout
76
+ #endif
77
+
78
+ /* Remove GREATEST_ prefix from most commonly used symbols? */
79
+ #ifndef GREATEST_USE_ABBREVS
80
+ #define GREATEST_USE_ABBREVS 1
81
+ #endif
82
+
83
+
84
+ /*********
85
+ * Types *
86
+ *********/
87
+
88
+ /* Info for the current running suite. */
89
+ typedef struct greatest_suite_info {
90
+ unsigned int tests_run;
91
+ unsigned int passed;
92
+ unsigned int failed;
93
+ unsigned int skipped;
94
+
95
+ /* timers, pre/post running suite and individual tests */
96
+ clock_t pre_suite;
97
+ clock_t post_suite;
98
+ clock_t pre_test;
99
+ clock_t post_test;
100
+ } greatest_suite_info;
101
+
102
+ /* Type for a suite function. */
103
+ typedef void (greatest_suite_cb)(void);
104
+
105
+ /* Type for a teardown callback. If non-NULL, this will be
106
+ * run after the current test case finishes (and then set to NULL). */
107
+ typedef void (greatest_teardown_cb)(void *udata);
108
+
109
+ typedef struct greatest_run_info {
110
+ unsigned int verbose; /* verbose flag */
111
+ unsigned int list_only; /* list suite/tests only flag */
112
+ unsigned int tests_run; /* total test count */
113
+
114
+ /* Overall pass/fail/skip counts. */
115
+ unsigned int passed;
116
+ unsigned int failed;
117
+ unsigned int skipped;
118
+
119
+ /* currently running test suite */
120
+ greatest_suite_info suite;
121
+
122
+ /* info to print about the most recent failure */
123
+ char *fail_file;
124
+ unsigned int fail_line;
125
+ char *msg;
126
+
127
+ /* current teardown hook and userdata */
128
+ greatest_teardown_cb *teardown;
129
+ void *teardown_udata;
130
+
131
+ /* formatting info for ".....s...F"-style output */
132
+ unsigned int col;
133
+ unsigned int width;
134
+
135
+ /* only run a specific suite or test */
136
+ char *suite_filter;
137
+ char *test_filter;
138
+
139
+ /* overall timers */
140
+ clock_t begin;
141
+ clock_t end;
142
+ } greatest_run_info;
143
+
144
+ /* Global var for the current testing context.
145
+ * Initialized by GREATEST_MAIN_DEFS(). */
146
+ extern greatest_run_info greatest_info;
147
+
148
+
149
+ /**********************
150
+ * Exported functions *
151
+ **********************/
152
+
153
+ void greatest_do_pass(const char *name);
154
+ void greatest_do_fail(const char *name);
155
+ void greatest_do_skip(const char *name);
156
+ int greatest_pre_test(const char *name);
157
+ void greatest_post_test(const char *name, int res);
158
+ void greatest_usage(const char *name);
159
+ void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata);
160
+
161
+
162
+ /**********
163
+ * Macros *
164
+ **********/
165
+
166
+ /* Define a suite. */
167
+ #define GREATEST_SUITE(NAME) void NAME()
168
+
169
+ /* Start defining a test function.
170
+ * The arguments are not included, to allow parametric testing. */
171
+ #define GREATEST_TEST static int
172
+
173
+ /* Run a suite. */
174
+ #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME)
175
+
176
+ /* Run a test in the current suite.
177
+ * If __VA_ARGS__ (C99) is supported, allow parametric testing. */
178
+ #if __STDC_VERSION__ >= 19901L
179
+ #define GREATEST_RUN_TESTp(TEST, ...) \
180
+ do { \
181
+ if (greatest_pre_test(#TEST) == 1) { \
182
+ int res = TEST(__VA_ARGS__); \
183
+ greatest_post_test(#TEST, res); \
184
+ } else if (greatest_info.list_only) { \
185
+ fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
186
+ } \
187
+ } while (0)
188
+ #endif
189
+
190
+ #define GREATEST_RUN_TEST(TEST) \
191
+ do { \
192
+ if (greatest_pre_test(#TEST) == 1) { \
193
+ int res = TEST(); \
194
+ greatest_post_test(#TEST, res); \
195
+ } else if (greatest_info.list_only) { \
196
+ fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
197
+ } \
198
+ } while (0)
199
+
200
+ /* Check if the test runner is in verbose mode. */
201
+ #define GREATEST_IS_VERBOSE() (greatest_info.verbose)
202
+
203
+ /* Message-less forms. */
204
+ #define GREATEST_PASS() GREATEST_PASSm(NULL)
205
+ #define GREATEST_FAIL() GREATEST_FAILm(NULL)
206
+ #define GREATEST_SKIP() GREATEST_SKIPm(NULL)
207
+ #define GREATEST_ASSERT(COND) GREATEST_ASSERTm(#COND, COND)
208
+ #define GREATEST_ASSERT_FALSE(COND) GREATEST_ASSERT_FALSEm(#COND, COND)
209
+ #define GREATEST_ASSERT_EQ(EXP, GOT) GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT)
210
+ #define GREATEST_ASSERT_STR_EQ(EXP, GOT) GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT)
211
+
212
+ /* If set, call and clear the teardown callback. */
213
+ #define GREATEST_CALL_TEARDOWN() \
214
+ do { \
215
+ if (greatest_info.teardown) { \
216
+ greatest_info.teardown(greatest_info.teardown_udata); \
217
+ greatest_info.teardown = NULL; \
218
+ greatest_info.teardown_udata = NULL; \
219
+ } \
220
+ } while (0) \
221
+
222
+ /* The following forms take an additional message argument first,
223
+ * to be displayed by the test runner. */
224
+
225
+ /* Fail if a condition is not true, with message. */
226
+ #define GREATEST_ASSERTm(MSG, COND) \
227
+ do { \
228
+ greatest_info.msg = MSG; \
229
+ greatest_info.fail_file = __FILE__; \
230
+ greatest_info.fail_line = __LINE__; \
231
+ if (!(COND)) { \
232
+ GREATEST_CALL_TEARDOWN(); \
233
+ return -1; \
234
+ } \
235
+ greatest_info.msg = NULL; \
236
+ } while (0)
237
+
238
+ #define GREATEST_ASSERT_FALSEm(MSG, COND) \
239
+ do { \
240
+ greatest_info.msg = MSG; \
241
+ greatest_info.fail_file = __FILE__; \
242
+ greatest_info.fail_line = __LINE__; \
243
+ if ((COND)) { \
244
+ GREATEST_CALL_TEARDOWN(); \
245
+ return -1; \
246
+ } \
247
+ greatest_info.msg = NULL; \
248
+ } while (0)
249
+
250
+ #define GREATEST_ASSERT_EQm(MSG, EXP, GOT) \
251
+ do { \
252
+ greatest_info.msg = MSG; \
253
+ greatest_info.fail_file = __FILE__; \
254
+ greatest_info.fail_line = __LINE__; \
255
+ if ((EXP) != (GOT)) { \
256
+ GREATEST_CALL_TEARDOWN(); \
257
+ return -1; \
258
+ } \
259
+ greatest_info.msg = NULL; \
260
+ } while (0)
261
+
262
+ #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \
263
+ do { \
264
+ char *exp_s = (EXP); \
265
+ char *got_s = (GOT); \
266
+ greatest_info.msg = MSG; \
267
+ greatest_info.fail_file = __FILE__; \
268
+ greatest_info.fail_line = __LINE__; \
269
+ if (0 != strcmp(exp_s, got_s)) { \
270
+ GREATEST_CALL_TEARDOWN(); \
271
+ fprintf(GREATEST_STDOUT, \
272
+ "Expected:\n####\n%s\n####\n", exp_s); \
273
+ fprintf(GREATEST_STDOUT, \
274
+ "Got:\n####\n%s\n####\n", got_s); \
275
+ return -1; \
276
+ } \
277
+ greatest_info.msg = NULL; \
278
+ } while (0)
279
+
280
+ #define GREATEST_PASSm(MSG) \
281
+ do { \
282
+ GREATEST_CALL_TEARDOWN(); \
283
+ greatest_info.msg = MSG; \
284
+ return 0; \
285
+ } while (0)
286
+
287
+ #define GREATEST_FAILm(MSG) \
288
+ do { \
289
+ GREATEST_CALL_TEARDOWN(); \
290
+ greatest_info.fail_file = __FILE__; \
291
+ greatest_info.fail_line = __LINE__; \
292
+ greatest_info.msg = MSG; \
293
+ return -1; \
294
+ } while (0)
295
+
296
+ #define GREATEST_SKIPm(MSG) \
297
+ do { \
298
+ GREATEST_CALL_TEARDOWN(); \
299
+ greatest_info.msg = MSG; \
300
+ return 1; \
301
+ } while (0)
302
+
303
+ #define GREATEST_SET_TIME(NAME) \
304
+ NAME = clock(); \
305
+ if (NAME == (clock_t) -1) { \
306
+ fprintf(GREATEST_STDOUT, \
307
+ "clock error: %s\n", #NAME); \
308
+ exit(EXIT_FAILURE); \
309
+ }
310
+
311
+ #define GREATEST_CLOCK_DIFF(C1, C2) \
312
+ fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \
313
+ (long unsigned int) (C2) - (C1), \
314
+ ((C2) - (C1))/ (1.0 * CLOCKS_PER_SEC)) \
315
+
316
+ /* Include several function definitions in the main test file. */
317
+ #define GREATEST_MAIN_DEFS() \
318
+ int greatest_pre_test(const char *name) { \
319
+ if (!greatest_info.list_only \
320
+ && (greatest_info.test_filter == NULL || \
321
+ 0 == strcmp(name, greatest_info.test_filter))) { \
322
+ GREATEST_SET_TIME(greatest_info.suite.pre_test); \
323
+ return 1; /* test should be run */ \
324
+ } else { \
325
+ return 0; /* skipped */ \
326
+ } \
327
+ } \
328
+ \
329
+ void greatest_post_test(const char *name, int res) { \
330
+ GREATEST_SET_TIME(greatest_info.suite.post_test); \
331
+ if (res < 0) { \
332
+ greatest_do_fail(name); \
333
+ } else if (res > 0) { \
334
+ greatest_do_skip(name); \
335
+ } else if (res == 0) { \
336
+ greatest_do_pass(name); \
337
+ } \
338
+ greatest_info.suite.tests_run++; \
339
+ greatest_info.col++; \
340
+ if (greatest_info.verbose) { \
341
+ GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \
342
+ greatest_info.suite.post_test); \
343
+ fprintf(GREATEST_STDOUT, "\n"); \
344
+ } else if (greatest_info.col % greatest_info.width == 0) { \
345
+ fprintf(GREATEST_STDOUT, "\n"); \
346
+ greatest_info.col = 0; \
347
+ } \
348
+ if (GREATEST_STDOUT == stdout) fflush(stdout); \
349
+ } \
350
+ \
351
+ static void greatest_run_suite(greatest_suite_cb *suite_cb, \
352
+ char *suite_name) { \
353
+ if (greatest_info.suite_filter && \
354
+ 0 != strcmp(suite_name, greatest_info.suite_filter)) \
355
+ return; \
356
+ greatest_info.suite.tests_run = 0; \
357
+ greatest_info.suite.failed = 0; \
358
+ greatest_info.suite.passed = 0; \
359
+ greatest_info.suite.skipped = 0; \
360
+ greatest_info.suite.pre_suite = 0; \
361
+ greatest_info.suite.post_suite = 0; \
362
+ greatest_info.suite.pre_test = 0; \
363
+ greatest_info.suite.post_test = 0; \
364
+ greatest_info.col = 0; \
365
+ fprintf(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name); \
366
+ GREATEST_SET_TIME(greatest_info.suite.pre_suite); \
367
+ suite_cb(); \
368
+ GREATEST_SET_TIME(greatest_info.suite.post_suite); \
369
+ if (greatest_info.suite.tests_run > 0) { \
370
+ fprintf(GREATEST_STDOUT, \
371
+ "\n%u tests - %u pass, %u fail, %u skipped", \
372
+ greatest_info.suite.tests_run, \
373
+ greatest_info.suite.passed, \
374
+ greatest_info.suite.failed, \
375
+ greatest_info.suite.skipped); \
376
+ GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \
377
+ greatest_info.suite.post_suite); \
378
+ fprintf(GREATEST_STDOUT, "\n"); \
379
+ } \
380
+ greatest_info.passed += greatest_info.suite.passed; \
381
+ greatest_info.failed += greatest_info.suite.failed; \
382
+ greatest_info.skipped += greatest_info.suite.skipped; \
383
+ greatest_info.tests_run += greatest_info.suite.tests_run; \
384
+ } \
385
+ \
386
+ void greatest_do_pass(const char *name) { \
387
+ if (greatest_info.verbose) { \
388
+ fprintf(GREATEST_STDOUT, "PASS %s: %s", \
389
+ name, greatest_info.msg ? greatest_info.msg : ""); \
390
+ } else { \
391
+ fprintf(GREATEST_STDOUT, "."); \
392
+ } \
393
+ greatest_info.suite.passed++; \
394
+ } \
395
+ \
396
+ void greatest_do_fail(const char *name) { \
397
+ if (greatest_info.verbose) { \
398
+ fprintf(GREATEST_STDOUT, \
399
+ "FAIL %s: %s (%s:%u)", \
400
+ name, greatest_info.msg ? greatest_info.msg : "", \
401
+ greatest_info.fail_file, greatest_info.fail_line); \
402
+ } else { \
403
+ fprintf(GREATEST_STDOUT, "F"); \
404
+ /* add linebreak if in line of '.'s */ \
405
+ if (greatest_info.col % greatest_info.width != 0) \
406
+ fprintf(GREATEST_STDOUT, "\n"); \
407
+ greatest_info.col = 0; \
408
+ fprintf(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n", \
409
+ name, \
410
+ greatest_info.msg ? greatest_info.msg : "", \
411
+ greatest_info.fail_file, greatest_info.fail_line); \
412
+ } \
413
+ greatest_info.suite.failed++; \
414
+ } \
415
+ \
416
+ void greatest_do_skip(const char *name) { \
417
+ if (greatest_info.verbose) { \
418
+ fprintf(GREATEST_STDOUT, "SKIP %s: %s", \
419
+ name, \
420
+ greatest_info.msg ? \
421
+ greatest_info.msg : "" ); \
422
+ } else { \
423
+ fprintf(GREATEST_STDOUT, "s"); \
424
+ } \
425
+ greatest_info.suite.skipped++; \
426
+ } \
427
+ \
428
+ void greatest_usage(const char *name) { \
429
+ fprintf(GREATEST_STDOUT, \
430
+ "Usage: %s [-hlv] [-s SUITE] [-t TEST]\n" \
431
+ " -h print this Help\n" \
432
+ " -l List suites and their tests, then exit\n" \
433
+ " -v Verbose output\n" \
434
+ " -s SUITE only run suite named SUITE\n" \
435
+ " -t TEST only run test named TEST\n", \
436
+ name); \
437
+ } \
438
+ \
439
+ /* Set the teardown callback. \
440
+ * (Uppercase because it's part of the user interface.) */ \
441
+ void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata) { \
442
+ greatest_info.teardown = cb; \
443
+ greatest_info.teardown_udata = udata; \
444
+ } \
445
+ \
446
+ greatest_run_info greatest_info = {0, 0, 0, \
447
+ 0, 0, 0, \
448
+ {0, 0, 0, 0, \
449
+ 0, 0, 0, 0}, \
450
+ NULL, 0, NULL, NULL, NULL, \
451
+ 0, GREATEST_DEFAULT_WIDTH, \
452
+ NULL, NULL, \
453
+ 0, 0}
454
+
455
+ /* Handle command-line arguments, etc. */
456
+ #define GREATEST_MAIN_BEGIN() \
457
+ do { \
458
+ int i = 0; \
459
+ for (i = 1; i < argc; i++) { \
460
+ if (0 == strcmp("-t", argv[i])) { \
461
+ if (argc <= i + 1) { \
462
+ greatest_usage(argv[0]); \
463
+ exit(EXIT_FAILURE); \
464
+ } \
465
+ greatest_info.test_filter = argv[i+1]; \
466
+ i++; \
467
+ } else if (0 == strcmp("-s", argv[i])) { \
468
+ if (argc <= i + 1) { \
469
+ greatest_usage(argv[0]); \
470
+ exit(EXIT_FAILURE); \
471
+ } \
472
+ greatest_info.suite_filter = argv[i+1]; \
473
+ i++; \
474
+ } else if (0 == strcmp("-v", argv[i])) { \
475
+ greatest_info.verbose = 1; \
476
+ } else if (0 == strcmp("-l", argv[i])) { \
477
+ greatest_info.list_only = 1; \
478
+ } else if (0 == strcmp("-h", argv[i])) { \
479
+ greatest_usage(argv[0]); \
480
+ exit(EXIT_SUCCESS); \
481
+ } else { \
482
+ fprintf(GREATEST_STDOUT, \
483
+ "Unknown argument '%s'\n", argv[i]); \
484
+ greatest_usage(argv[0]); \
485
+ exit(EXIT_FAILURE); \
486
+ } \
487
+ } \
488
+ } while (0); \
489
+ GREATEST_SET_TIME(greatest_info.begin)
490
+
491
+ #define GREATEST_MAIN_END() \
492
+ do { \
493
+ if (!greatest_info.list_only) { \
494
+ GREATEST_SET_TIME(greatest_info.end); \
495
+ fprintf(GREATEST_STDOUT, \
496
+ "\nTotal: %u tests", greatest_info.tests_run); \
497
+ GREATEST_CLOCK_DIFF(greatest_info.begin, \
498
+ greatest_info.end); \
499
+ fprintf(GREATEST_STDOUT, "\n"); \
500
+ fprintf(GREATEST_STDOUT, \
501
+ "Pass: %u, fail: %u, skip: %u.\n", \
502
+ greatest_info.passed, \
503
+ greatest_info.failed, greatest_info.skipped); \
504
+ } \
505
+ return (greatest_info.failed > 0 \
506
+ ? EXIT_FAILURE : EXIT_SUCCESS); \
507
+ } while (0)
508
+
509
+ /* Make abbreviations without the GREATEST_ prefix for the
510
+ * most commonly used symbols. */
511
+ #if GREATEST_USE_ABBREVS
512
+ #define TEST GREATEST_TEST
513
+ #define SUITE GREATEST_SUITE
514
+ #define RUN_TEST GREATEST_RUN_TEST
515
+ #define RUN_SUITE GREATEST_RUN_SUITE
516
+ #define ASSERT GREATEST_ASSERT
517
+ #define ASSERTm GREATEST_ASSERTm
518
+ #define ASSERT_FALSE GREATEST_ASSERT_FALSE
519
+ #define ASSERT_EQ GREATEST_ASSERT_EQ
520
+ #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ
521
+ #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm
522
+ #define ASSERT_EQm GREATEST_ASSERT_EQm
523
+ #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm
524
+ #define PASS GREATEST_PASS
525
+ #define FAIL GREATEST_FAIL
526
+ #define SKIP GREATEST_SKIP
527
+ #define PASSm GREATEST_PASSm
528
+ #define FAILm GREATEST_FAILm
529
+ #define SKIPm GREATEST_SKIPm
530
+
531
+ #if __STDC_VERSION__ >= 19901L
532
+ #endif /* C99 */
533
+ #define RUN_TESTp GREATEST_RUN_TESTp
534
+ #endif /* USE_ABBREVS */
535
+
536
+ #endif