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.
- data/.gitignore +24 -0
- data/.rspec +1 -0
- data/.travisci.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +152 -0
- data/Rakefile +38 -0
- data/bin/cauterize +53 -0
- data/c/src/cauterize.c +74 -0
- data/c/src/cauterize.h +46 -0
- data/c/src/cauterize_debug.h +29 -0
- data/c/src/cauterize_util.h +7 -0
- data/c/test/greatest.h +536 -0
- data/c/test/test.c +166 -0
- data/cauterize.gemspec +26 -0
- data/example/Cauterize +44 -0
- data/example/build.sh +4 -0
- data/lib/cauterize/base_type.rb +96 -0
- data/lib/cauterize/builders.rb +27 -0
- data/lib/cauterize/builders/c/buildable.rb +59 -0
- data/lib/cauterize/builders/c/composite.rb +55 -0
- data/lib/cauterize/builders/c/enumeration.rb +41 -0
- data/lib/cauterize/builders/c/fixed_array.rb +62 -0
- data/lib/cauterize/builders/c/group.rb +95 -0
- data/lib/cauterize/builders/c/scalar.rb +31 -0
- data/lib/cauterize/builders/c/variable_array.rb +90 -0
- data/lib/cauterize/c_builder.rb +63 -0
- data/lib/cauterize/cauterize.rb +33 -0
- data/lib/cauterize/composite.rb +50 -0
- data/lib/cauterize/enumeration.rb +77 -0
- data/lib/cauterize/fixed_array.rb +43 -0
- data/lib/cauterize/formatter.rb +59 -0
- data/lib/cauterize/group.rb +56 -0
- data/lib/cauterize/scalar.rb +38 -0
- data/lib/cauterize/snake_case.rb +21 -0
- data/lib/cauterize/variable_array.rb +56 -0
- data/lib/cauterize/version.rb +3 -0
- data/spec/base_type_spec.rb +167 -0
- data/spec/builders/c/buildable_spec.rb +25 -0
- data/spec/builders/c/composite_spec.rb +46 -0
- data/spec/builders/c/enumeration_spec.rb +32 -0
- data/spec/builders/c/fixed_array_spec.rb +36 -0
- data/spec/builders/c/group_spec.rb +112 -0
- data/spec/builders/c/scalar_spec.rb +8 -0
- data/spec/builders/c/variable_array_spec.rb +50 -0
- data/spec/builders_spec.rb +51 -0
- data/spec/c_builder_spec.rb +133 -0
- data/spec/cauterize_spec.rb +8 -0
- data/spec/composite_spec.rb +62 -0
- data/spec/enumeration_spec.rb +104 -0
- data/spec/fixed_array_spec.rb +62 -0
- data/spec/group_spec.rb +104 -0
- data/spec/scalar_spec.rb +36 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/support/shared_examples_for_array_buildables.rb +22 -0
- data/spec/support/shared_examples_for_c_buildables.rb +91 -0
- data/spec/support/shared_examples_for_sane_c_buildables.rb +22 -0
- data/spec/support/shared_examples_for_stubbed_functions.rb +18 -0
- data/spec/test_main.c +13 -0
- data/spec/variable_array_spec.rb +92 -0
- metadata +212 -0
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
|