cauterize 0.0.1.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|