Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

greatest.h 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. /*
  2. * Copyright (c) 2011 Scott Vokes <vokes.s@gmail.com>
  3. *
  4. * Modified 2014 by Thomas Buck <xythobuz@xythobuz.de>
  5. * --> C++ support
  6. * --> Included janoskk color output patch
  7. * --> Modified it so a tty output is detected at runtime (now unix only)
  8. *
  9. * Permission to use, copy, modify, and/or distribute this software for any
  10. * purpose with or without fee is hereby granted, provided that the above
  11. * copyright notice and this permission notice appear in all copies.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  14. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  15. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  16. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  18. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  19. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20. */
  21. #ifndef GREATEST_H
  22. #define GREATEST_H
  23. #ifdef __cplusplus
  24. extern "C"
  25. {
  26. #endif
  27. #define GREATEST_VERSION_MAJOR 0
  28. #define GREATEST_VERSION_MINOR 9
  29. #define GREATEST_VERSION_PATCH 3
  30. /* A unit testing system for C, contained in 1 file.
  31. * It doesn't use dynamic allocation or depend on anything
  32. * beyond ANSI C89. */
  33. /*********************************************************************
  34. * Minimal test runner template
  35. *********************************************************************/
  36. #if 0
  37. #include "greatest.h"
  38. TEST foo_should_foo() {
  39. PASS();
  40. }
  41. static void setup_cb(void *data) {
  42. printf("setup callback for each test case\n");
  43. }
  44. static void teardown_cb(void *data) {
  45. printf("teardown callback for each test case\n");
  46. }
  47. SUITE(suite) {
  48. /* Optional setup/teardown callbacks which will be run before/after
  49. * every test case in the suite.
  50. * Cleared when the suite finishes. */
  51. SET_SETUP(setup_cb, voidp_to_callback_data);
  52. SET_TEARDOWN(teardown_cb, voidp_to_callback_data);
  53. RUN_TEST(foo_should_foo);
  54. }
  55. /* Add all the definitions that need to be in the test runner's main file. */
  56. GREATEST_MAIN_DEFS();
  57. int main(int argc, char **argv) {
  58. GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */
  59. RUN_SUITE(suite);
  60. GREATEST_MAIN_END(); /* display results */
  61. }
  62. #endif
  63. /*********************************************************************/
  64. #include <stdlib.h>
  65. #include <stdio.h>
  66. #include <string.h>
  67. #include <time.h>
  68. #include <unistd.h>
  69. /***********
  70. * Options *
  71. ***********/
  72. /* Default column width for non-verbose output. */
  73. #ifndef GREATEST_DEFAULT_WIDTH
  74. #define GREATEST_DEFAULT_WIDTH 72
  75. #endif
  76. /* FILE *, for test logging. */
  77. #ifndef GREATEST_STDOUT
  78. #define GREATEST_STDOUT stdout
  79. #endif
  80. /* Remove GREATEST_ prefix from most commonly used symbols? */
  81. #ifndef GREATEST_USE_ABBREVS
  82. #define GREATEST_USE_ABBREVS 1
  83. #endif
  84. /* Colorize the passed/failed results */
  85. #ifndef COLOR_FAIL
  86. #define COLOR_FAIL "\033[22;31;1m"
  87. #endif
  88. #ifndef COLOR_PASS
  89. #define COLOR_PASS "\033[22;32m"
  90. #endif
  91. #define COLOR_RESET "\033[22;0m"
  92. /*********
  93. * Types *
  94. *********/
  95. /* Info for the current running suite. */
  96. typedef struct greatest_suite_info {
  97. unsigned int tests_run;
  98. unsigned int passed;
  99. unsigned int failed;
  100. unsigned int skipped;
  101. /* timers, pre/post running suite and individual tests */
  102. clock_t pre_suite;
  103. clock_t post_suite;
  104. clock_t pre_test;
  105. clock_t post_test;
  106. } greatest_suite_info;
  107. /* Type for a suite function. */
  108. typedef void (greatest_suite_cb)(void);
  109. /* Types for setup/teardown callbacks. If non-NULL, these will be run
  110. * and passed the pointer to their additional data. */
  111. typedef void (greatest_setup_cb)(void *udata);
  112. typedef void (greatest_teardown_cb)(void *udata);
  113. typedef enum {
  114. GREATEST_FLAG_VERBOSE = 0x01,
  115. GREATEST_FLAG_FIRST_FAIL = 0x02,
  116. GREATEST_FLAG_LIST_ONLY = 0x04
  117. } GREATEST_FLAG;
  118. typedef struct greatest_run_info {
  119. unsigned int flags;
  120. unsigned int tests_run; /* total test count */
  121. /* Overall pass/fail/skip counts. */
  122. unsigned int passed;
  123. unsigned int failed;
  124. unsigned int skipped;
  125. /* currently running test suite */
  126. greatest_suite_info suite;
  127. /* info to print about the most recent failure */
  128. const char *fail_file;
  129. unsigned int fail_line;
  130. const char *msg;
  131. /* current setup/teardown hooks and userdata */
  132. greatest_setup_cb *setup;
  133. void *setup_udata;
  134. greatest_teardown_cb *teardown;
  135. void *teardown_udata;
  136. /* formatting info for ".....s...F"-style output */
  137. unsigned int col;
  138. unsigned int width;
  139. /* only run a specific suite or test */
  140. char *suite_filter;
  141. char *test_filter;
  142. /* overall timers */
  143. clock_t begin;
  144. clock_t end;
  145. } greatest_run_info;
  146. /* Global var for the current testing context.
  147. * Initialized by GREATEST_MAIN_DEFS(). */
  148. extern greatest_run_info greatest_info;
  149. /**********************
  150. * Exported functions *
  151. **********************/
  152. void greatest_do_pass(const char *name);
  153. void greatest_do_fail(const char *name);
  154. void greatest_do_skip(const char *name);
  155. int greatest_pre_test(const char *name);
  156. void greatest_post_test(const char *name, int res);
  157. void greatest_usage(const char *name);
  158. void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata);
  159. void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata);
  160. /**********
  161. * Macros *
  162. **********/
  163. /* Define a suite. */
  164. #define GREATEST_SUITE(NAME) void NAME(void)
  165. /* Start defining a test function.
  166. * The arguments are not included, to allow parametric testing. */
  167. #define GREATEST_TEST static int
  168. /* Run a suite. */
  169. #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME)
  170. /* Run a test in the current suite. */
  171. #define GREATEST_RUN_TEST(TEST) \
  172. do { \
  173. if (greatest_pre_test(#TEST) == 1) { \
  174. int res = TEST(); \
  175. greatest_post_test(#TEST, res); \
  176. } else if (GREATEST_LIST_ONLY()) { \
  177. fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
  178. } \
  179. } while (0)
  180. /* Run a test in the current suite with one void* argument,
  181. * which can be a pointer to a struct with multiple arguments. */
  182. #define GREATEST_RUN_TEST1(TEST, ENV) \
  183. do { \
  184. if (greatest_pre_test(#TEST) == 1) { \
  185. int res = TEST(ENV); \
  186. greatest_post_test(#TEST, res); \
  187. } else if (GREATEST_LIST_ONLY()) { \
  188. fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
  189. } \
  190. } while (0)
  191. /* If __VA_ARGS__ (C99) is supported, allow parametric testing
  192. * without needing to manually manage the argument struct. */
  193. #if defined __cplusplus || (__STDC_VERSION__ >= 19901L)
  194. #define GREATEST_RUN_TESTp(TEST, ...) \
  195. do { \
  196. if (greatest_pre_test(#TEST) == 1) { \
  197. int res = TEST(__VA_ARGS__); \
  198. greatest_post_test(#TEST, res); \
  199. } else if (GREATEST_LIST_ONLY()) { \
  200. fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
  201. } \
  202. } while (0)
  203. #endif
  204. /* Check if the test runner is in verbose mode. */
  205. #define GREATEST_IS_VERBOSE() (greatest_info.flags & GREATEST_FLAG_VERBOSE)
  206. #define GREATEST_LIST_ONLY() (greatest_info.flags & GREATEST_FLAG_LIST_ONLY)
  207. #define GREATEST_FIRST_FAIL() (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL)
  208. #define GREATEST_FAILURE_ABORT() (greatest_info.suite.failed > 0 && GREATEST_FIRST_FAIL())
  209. /* Message-less forms. */
  210. #define GREATEST_PASS() GREATEST_PASSm(NULL)
  211. #define GREATEST_FAIL() GREATEST_FAILm(NULL)
  212. #define GREATEST_SKIP() GREATEST_SKIPm(NULL)
  213. #define GREATEST_ASSERT(COND) GREATEST_ASSERTm(#COND, COND)
  214. #define GREATEST_ASSERT_FALSE(COND) GREATEST_ASSERT_FALSEm(#COND, COND)
  215. #define GREATEST_ASSERT_EQ(EXP, GOT) GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT)
  216. #define GREATEST_ASSERT_STR_EQ(EXP, GOT) GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT)
  217. /* The following forms take an additional message argument first,
  218. * to be displayed by the test runner. */
  219. /* Fail if a condition is not true, with message. */
  220. #define GREATEST_ASSERTm(MSG, COND) \
  221. do { \
  222. greatest_info.msg = MSG; \
  223. greatest_info.fail_file = __FILE__; \
  224. greatest_info.fail_line = __LINE__; \
  225. if (!(COND)) return -1; \
  226. greatest_info.msg = NULL; \
  227. } while (0)
  228. #define GREATEST_ASSERT_FALSEm(MSG, COND) \
  229. do { \
  230. greatest_info.msg = MSG; \
  231. greatest_info.fail_file = __FILE__; \
  232. greatest_info.fail_line = __LINE__; \
  233. if ((COND)) return -1; \
  234. greatest_info.msg = NULL; \
  235. } while (0)
  236. #define GREATEST_ASSERT_EQm(MSG, EXP, GOT) \
  237. do { \
  238. greatest_info.msg = MSG; \
  239. greatest_info.fail_file = __FILE__; \
  240. greatest_info.fail_line = __LINE__; \
  241. if ((EXP) != (GOT)) return -1; \
  242. greatest_info.msg = NULL; \
  243. } while (0)
  244. #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \
  245. do { \
  246. const char *exp_s = (EXP); \
  247. const char *got_s = (GOT); \
  248. greatest_info.msg = MSG; \
  249. greatest_info.fail_file = __FILE__; \
  250. greatest_info.fail_line = __LINE__; \
  251. if (0 != strcmp(exp_s, got_s)) { \
  252. fprintf(GREATEST_STDOUT, \
  253. "Expected:\n####\n%s\n####\n", exp_s); \
  254. fprintf(GREATEST_STDOUT, \
  255. "Got:\n####\n%s\n####\n", got_s); \
  256. return -1; \
  257. } \
  258. greatest_info.msg = NULL; \
  259. } while (0)
  260. #define GREATEST_PASSm(MSG) \
  261. do { \
  262. greatest_info.msg = MSG; \
  263. return 0; \
  264. } while (0)
  265. #define GREATEST_FAILm(MSG) \
  266. do { \
  267. greatest_info.fail_file = __FILE__; \
  268. greatest_info.fail_line = __LINE__; \
  269. greatest_info.msg = MSG; \
  270. return -1; \
  271. } while (0)
  272. #define GREATEST_SKIPm(MSG) \
  273. do { \
  274. greatest_info.msg = MSG; \
  275. return 1; \
  276. } while (0)
  277. #define GREATEST_SET_TIME(NAME) \
  278. NAME = clock(); \
  279. if (NAME == (clock_t) -1) { \
  280. fprintf(GREATEST_STDOUT, \
  281. "clock error: %s\n", #NAME); \
  282. exit(EXIT_FAILURE); \
  283. }
  284. #define GREATEST_CLOCK_DIFF(C1, C2) \
  285. fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \
  286. (long unsigned int) (C2) - (C1), \
  287. (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC)) \
  288. /* Include several function definitions in the main test file. */
  289. #define GREATEST_MAIN_DEFS() \
  290. \
  291. /* Is FILTER a subset of NAME? */ \
  292. static int greatest_name_match(const char *name, \
  293. const char *filter) { \
  294. size_t offset = 0; \
  295. size_t filter_len = strlen(filter); \
  296. while (name[offset] != '\0') { \
  297. if (name[offset] == filter[0]) { \
  298. if (0 == strncmp(&name[offset], filter, filter_len)) { \
  299. return 1; \
  300. } \
  301. } \
  302. offset++; \
  303. } \
  304. \
  305. return 0; \
  306. } \
  307. \
  308. int greatest_pre_test(const char *name) { \
  309. if (!GREATEST_LIST_ONLY() \
  310. && (!GREATEST_FIRST_FAIL() || greatest_info.suite.failed == 0) \
  311. && (greatest_info.test_filter == NULL || \
  312. greatest_name_match(name, greatest_info.test_filter))) { \
  313. GREATEST_SET_TIME(greatest_info.suite.pre_test); \
  314. if (greatest_info.setup) { \
  315. greatest_info.setup(greatest_info.setup_udata); \
  316. } \
  317. return 1; /* test should be run */ \
  318. } else { \
  319. return 0; /* skipped */ \
  320. } \
  321. } \
  322. \
  323. void greatest_post_test(const char *name, int res) { \
  324. GREATEST_SET_TIME(greatest_info.suite.post_test); \
  325. if (greatest_info.teardown) { \
  326. void *udata = greatest_info.teardown_udata; \
  327. greatest_info.teardown(udata); \
  328. } \
  329. \
  330. if (res < 0) { \
  331. greatest_do_fail(name); \
  332. } else if (res > 0) { \
  333. greatest_do_skip(name); \
  334. } else if (res == 0) { \
  335. greatest_do_pass(name); \
  336. } \
  337. greatest_info.suite.tests_run++; \
  338. greatest_info.col++; \
  339. if (GREATEST_IS_VERBOSE()) { \
  340. GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \
  341. greatest_info.suite.post_test); \
  342. fprintf(GREATEST_STDOUT, "\n"); \
  343. } else if (greatest_info.col % greatest_info.width == 0) { \
  344. fprintf(GREATEST_STDOUT, "\n"); \
  345. greatest_info.col = 0; \
  346. } \
  347. if (GREATEST_STDOUT == stdout) fflush(stdout); \
  348. } \
  349. \
  350. static void greatest_run_suite(greatest_suite_cb *suite_cb, \
  351. const char *suite_name) { \
  352. if (greatest_info.suite_filter && \
  353. !greatest_name_match(suite_name, greatest_info.suite_filter)) \
  354. return; \
  355. if (GREATEST_FIRST_FAIL() && greatest_info.failed > 0) 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 %spass%s, %u %sfail%s, %u skipped", \
  372. greatest_info.suite.tests_run, \
  373. greatest_info.suite.passed, \
  374. (isatty(fileno(GREATEST_STDOUT))) ? ( \
  375. (!greatest_info.suite.failed) ? COLOR_PASS : COLOR_RESET \
  376. ) : "", \
  377. (isatty(fileno(GREATEST_STDOUT))) ? COLOR_RESET : "", \
  378. greatest_info.suite.failed, \
  379. (isatty(fileno(GREATEST_STDOUT))) ? ( \
  380. (greatest_info.suite.failed) ? COLOR_FAIL : COLOR_RESET \
  381. ) : "", \
  382. (isatty(fileno(GREATEST_STDOUT))) ? COLOR_RESET : "", \
  383. greatest_info.suite.skipped); \
  384. GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \
  385. greatest_info.suite.post_suite); \
  386. fprintf(GREATEST_STDOUT, "\n"); \
  387. } \
  388. greatest_info.setup = NULL; \
  389. greatest_info.setup_udata = NULL; \
  390. greatest_info.teardown = NULL; \
  391. greatest_info.teardown_udata = NULL; \
  392. greatest_info.passed += greatest_info.suite.passed; \
  393. greatest_info.failed += greatest_info.suite.failed; \
  394. greatest_info.skipped += greatest_info.suite.skipped; \
  395. greatest_info.tests_run += greatest_info.suite.tests_run; \
  396. } \
  397. \
  398. void greatest_do_pass(const char *name) { \
  399. if (GREATEST_IS_VERBOSE()) { \
  400. fprintf(GREATEST_STDOUT, \
  401. (isatty(fileno(GREATEST_STDOUT))) ? \
  402. COLOR_PASS "PASS" COLOR_RESET " %s: %s" : \
  403. "PASS %s: %s", \
  404. name, greatest_info.msg ? greatest_info.msg : ""); \
  405. } else { \
  406. fprintf(GREATEST_STDOUT, "."); \
  407. } \
  408. greatest_info.suite.passed++; \
  409. } \
  410. \
  411. void greatest_do_fail(const char *name) { \
  412. if (GREATEST_IS_VERBOSE()) { \
  413. fprintf(GREATEST_STDOUT, \
  414. (isatty(fileno(GREATEST_STDOUT))) ? \
  415. COLOR_FAIL "FAIL" COLOR_RESET " %s: %s (%s:%u)" : \
  416. "FAIL %s: %s (%s:%u)", \
  417. name, greatest_info.msg ? greatest_info.msg : "", \
  418. greatest_info.fail_file, greatest_info.fail_line); \
  419. } else { \
  420. fprintf(GREATEST_STDOUT, "F"); \
  421. /* add linebreak if in line of '.'s */ \
  422. if (greatest_info.col % greatest_info.width != 0) \
  423. fprintf(GREATEST_STDOUT, "\n"); \
  424. greatest_info.col = 0; \
  425. fprintf(GREATEST_STDOUT, \
  426. (isatty(fileno(GREATEST_STDOUT))) ? \
  427. COLOR_FAIL "FAIL" COLOR_RESET " %s: %s (%s:%u)\n" : \
  428. "FAIL %s: %s (%s:%u)\n", \
  429. name, \
  430. greatest_info.msg ? greatest_info.msg : "", \
  431. greatest_info.fail_file, greatest_info.fail_line); \
  432. } \
  433. greatest_info.suite.failed++; \
  434. } \
  435. \
  436. void greatest_do_skip(const char *name) { \
  437. if (GREATEST_IS_VERBOSE()) { \
  438. fprintf(GREATEST_STDOUT, "SKIP %s: %s", \
  439. name, \
  440. greatest_info.msg ? \
  441. greatest_info.msg : "" ); \
  442. } else { \
  443. fprintf(GREATEST_STDOUT, "s"); \
  444. } \
  445. greatest_info.suite.skipped++; \
  446. } \
  447. \
  448. void greatest_usage(const char *name) { \
  449. fprintf(GREATEST_STDOUT, \
  450. "Usage: %s [-hlfv] [-s SUITE] [-t TEST]\n" \
  451. " -h print this Help\n" \
  452. " -l List suites and their tests, then exit\n" \
  453. " -f Stop runner after first failure\n" \
  454. " -v Verbose output\n" \
  455. " -s SUITE only run suite named SUITE\n" \
  456. " -t TEST only run test named TEST\n", \
  457. name); \
  458. } \
  459. \
  460. void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) { \
  461. greatest_info.setup = cb; \
  462. greatest_info.setup_udata = udata; \
  463. } \
  464. \
  465. void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, \
  466. void *udata) { \
  467. greatest_info.teardown = cb; \
  468. greatest_info.teardown_udata = udata; \
  469. } \
  470. \
  471. greatest_run_info greatest_info
  472. /* Handle command-line arguments, etc. */
  473. #define GREATEST_MAIN_BEGIN() \
  474. do { \
  475. int _i = 0; \
  476. memset(&greatest_info, 0, sizeof(greatest_info)); \
  477. if (greatest_info.width == 0) { \
  478. greatest_info.width = GREATEST_DEFAULT_WIDTH; \
  479. } \
  480. for (_i = 1; _i < argc; _i++) { \
  481. if (0 == strcmp("-t", argv[_i])) { \
  482. if (argc <= _i + 1) { \
  483. greatest_usage(argv[0]); \
  484. exit(EXIT_FAILURE); \
  485. } \
  486. greatest_info.test_filter = argv[_i+1]; \
  487. _i++; \
  488. } else if (0 == strcmp("-s", argv[_i])) { \
  489. if (argc <= _i + 1) { \
  490. greatest_usage(argv[0]); \
  491. exit(EXIT_FAILURE); \
  492. } \
  493. greatest_info.suite_filter = argv[_i+1]; \
  494. _i++; \
  495. } else if (0 == strcmp("-f", argv[_i])) { \
  496. greatest_info.flags |= GREATEST_FLAG_FIRST_FAIL; \
  497. } else if (0 == strcmp("-v", argv[_i])) { \
  498. greatest_info.flags |= GREATEST_FLAG_VERBOSE; \
  499. } else if (0 == strcmp("-l", argv[_i])) { \
  500. greatest_info.flags |= GREATEST_FLAG_LIST_ONLY; \
  501. } else if (0 == strcmp("-h", argv[_i])) { \
  502. greatest_usage(argv[0]); \
  503. exit(EXIT_SUCCESS); \
  504. } else { \
  505. fprintf(GREATEST_STDOUT, \
  506. "Unknown argument '%s'\n", argv[_i]); \
  507. greatest_usage(argv[0]); \
  508. exit(EXIT_FAILURE); \
  509. } \
  510. } \
  511. } while (0); \
  512. GREATEST_SET_TIME(greatest_info.begin)
  513. #define GREATEST_MAIN_END() \
  514. do { \
  515. if (!GREATEST_LIST_ONLY()) { \
  516. GREATEST_SET_TIME(greatest_info.end); \
  517. fprintf(GREATEST_STDOUT, \
  518. "\nTotal: %u tests", greatest_info.tests_run); \
  519. GREATEST_CLOCK_DIFF(greatest_info.begin, \
  520. greatest_info.end); \
  521. fprintf(GREATEST_STDOUT, "\n"); \
  522. fprintf(GREATEST_STDOUT, \
  523. "%sPass: %u, fail: %u, " \
  524. "skip: %u.%s\n", \
  525. (isatty(fileno(GREATEST_STDOUT))) ? \
  526. ((greatest_info.failed) ? COLOR_FAIL : COLOR_PASS) : \
  527. "", greatest_info.passed, \
  528. greatest_info.failed, \
  529. greatest_info.skipped, \
  530. (isatty(fileno(GREATEST_STDOUT))) ? COLOR_RESET : ""); \
  531. } \
  532. return (greatest_info.failed > 0 \
  533. ? EXIT_FAILURE : EXIT_SUCCESS); \
  534. } while (0)
  535. /* Make abbreviations without the GREATEST_ prefix for the
  536. * most commonly used symbols. */
  537. #if GREATEST_USE_ABBREVS
  538. #define TEST GREATEST_TEST
  539. #define SUITE GREATEST_SUITE
  540. #define RUN_TEST GREATEST_RUN_TEST
  541. #define RUN_TEST1 GREATEST_RUN_TEST1
  542. #define RUN_SUITE GREATEST_RUN_SUITE
  543. #define ASSERT GREATEST_ASSERT
  544. #define ASSERTm GREATEST_ASSERTm
  545. #define ASSERT_FALSE GREATEST_ASSERT_FALSE
  546. #define ASSERT_EQ GREATEST_ASSERT_EQ
  547. #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ
  548. #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm
  549. #define ASSERT_EQm GREATEST_ASSERT_EQm
  550. #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm
  551. #define PASS GREATEST_PASS
  552. #define FAIL GREATEST_FAIL
  553. #define SKIP GREATEST_SKIP
  554. #define PASSm GREATEST_PASSm
  555. #define FAILm GREATEST_FAILm
  556. #define SKIPm GREATEST_SKIPm
  557. #define SET_SETUP GREATEST_SET_SETUP_CB
  558. #define SET_TEARDOWN GREATEST_SET_TEARDOWN_CB
  559. #if defined __cplusplus || (__STDC_VERSION__ >= 19901L)
  560. #define RUN_TESTp GREATEST_RUN_TESTp
  561. #endif
  562. #endif /* USE_ABBREVS */
  563. #ifdef __cplusplus
  564. }
  565. #endif
  566. #endif