cauterize 0.0.1.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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