greatest.h (68870B)
1 /* 2 * Copyright (c) 2011-2021 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 #if defined(__cplusplus) && !defined(GREATEST_NO_EXTERN_CPLUSPLUS) 21 extern "C" { 22 #endif 23 24 /* 1.5.0 */ 25 #define GREATEST_VERSION_MAJOR 1 26 #define GREATEST_VERSION_MINOR 5 27 #define GREATEST_VERSION_PATCH 0 28 29 /* A unit testing system for C, contained in 1 file. 30 * It doesn't use dynamic allocation or depend on anything 31 * beyond ANSI C89. 32 * 33 * An up-to-date version can be found at: 34 * https://github.com/silentbicycle/greatest/ 35 */ 36 37 38 /********************************************************************* 39 * Minimal test runner template 40 *********************************************************************/ 41 #if 0 42 43 #include "greatest.h" 44 45 TEST foo_should_foo(void) { 46 PASS(); 47 } 48 49 static void setup_cb(void *data) { 50 printf("setup callback for each test case\n"); 51 } 52 53 static void teardown_cb(void *data) { 54 printf("teardown callback for each test case\n"); 55 } 56 57 SUITE(suite) { 58 /* Optional setup/teardown callbacks which will be run before/after 59 * every test case. If using a test suite, they will be cleared when 60 * the suite finishes. */ 61 SET_SETUP(setup_cb, voidp_to_callback_data); 62 SET_TEARDOWN(teardown_cb, voidp_to_callback_data); 63 64 RUN_TEST(foo_should_foo); 65 } 66 67 /* Add definitions that need to be in the test runner's main file. */ 68 GREATEST_MAIN_DEFS(); 69 70 /* Set up, run suite(s) of tests, report pass/fail/skip stats. */ 71 int run_tests(void) { 72 GREATEST_INIT(); /* init. greatest internals */ 73 /* List of suites to run (if any). */ 74 RUN_SUITE(suite); 75 76 /* Tests can also be run directly, without using test suites. */ 77 RUN_TEST(foo_should_foo); 78 79 GREATEST_PRINT_REPORT(); /* display results */ 80 return greatest_all_passed(); 81 } 82 83 /* main(), for a standalone command-line test runner. 84 * This replaces run_tests above, and adds command line option 85 * handling and exiting with a pass/fail status. */ 86 int main(int argc, char **argv) { 87 GREATEST_MAIN_BEGIN(); /* init & parse command-line args */ 88 RUN_SUITE(suite); 89 GREATEST_MAIN_END(); /* display results */ 90 } 91 92 #endif 93 /*********************************************************************/ 94 95 96 #include <stdlib.h> 97 #include <stdio.h> 98 #include <string.h> 99 #include <ctype.h> 100 101 /*********** 102 * Options * 103 ***********/ 104 105 /* Default column width for non-verbose output. */ 106 #ifndef GREATEST_DEFAULT_WIDTH 107 #define GREATEST_DEFAULT_WIDTH 72 108 #endif 109 110 /* FILE *, for test logging. */ 111 #ifndef GREATEST_STDOUT 112 #define GREATEST_STDOUT stdout 113 #endif 114 115 /* Remove GREATEST_ prefix from most commonly used symbols? */ 116 #ifndef GREATEST_USE_ABBREVS 117 #define GREATEST_USE_ABBREVS 1 118 #endif 119 120 /* Set to 0 to disable all use of setjmp/longjmp. */ 121 #ifndef GREATEST_USE_LONGJMP 122 #define GREATEST_USE_LONGJMP 0 123 #endif 124 125 /* Make it possible to replace fprintf with another 126 * function with the same interface. */ 127 #ifndef GREATEST_FPRINTF 128 #define GREATEST_FPRINTF fprintf 129 #endif 130 131 #if GREATEST_USE_LONGJMP 132 #include <setjmp.h> 133 #endif 134 135 /* Set to 0 to disable all use of time.h / clock(). */ 136 #ifndef GREATEST_USE_TIME 137 #define GREATEST_USE_TIME 1 138 #endif 139 140 #if GREATEST_USE_TIME 141 #include <time.h> 142 #endif 143 144 /* Floating point type, for ASSERT_IN_RANGE. */ 145 #ifndef GREATEST_FLOAT 146 #define GREATEST_FLOAT double 147 #define GREATEST_FLOAT_FMT "%g" 148 #endif 149 150 /* Size of buffer for test name + optional '_' separator and suffix */ 151 #ifndef GREATEST_TESTNAME_BUF_SIZE 152 #define GREATEST_TESTNAME_BUF_SIZE 128 153 #endif 154 155 156 /********* 157 * Types * 158 *********/ 159 160 /* Info for the current running suite. */ 161 typedef struct greatest_suite_info { 162 unsigned int tests_run; 163 unsigned int passed; 164 unsigned int failed; 165 unsigned int skipped; 166 167 #if GREATEST_USE_TIME 168 /* timers, pre/post running suite and individual tests */ 169 clock_t pre_suite; 170 clock_t post_suite; 171 clock_t pre_test; 172 clock_t post_test; 173 #endif 174 } greatest_suite_info; 175 176 /* Type for a suite function. */ 177 typedef void greatest_suite_cb(void); 178 179 /* Types for setup/teardown callbacks. If non-NULL, these will be run 180 * and passed the pointer to their additional data. */ 181 typedef void greatest_setup_cb(void *udata); 182 typedef void greatest_teardown_cb(void *udata); 183 184 /* Type for an equality comparison between two pointers of the same type. 185 * Should return non-0 if equal, otherwise 0. 186 * UDATA is a closure value, passed through from ASSERT_EQUAL_T[m]. */ 187 typedef int greatest_equal_cb(const void *expd, const void *got, void *udata); 188 189 /* Type for a callback that prints a value pointed to by T. 190 * Return value has the same meaning as printf's. 191 * UDATA is a closure value, passed through from ASSERT_EQUAL_T[m]. */ 192 typedef int greatest_printf_cb(const void *t, void *udata); 193 194 /* Callbacks for an arbitrary type; needed for type-specific 195 * comparisons via GREATEST_ASSERT_EQUAL_T[m].*/ 196 typedef struct greatest_type_info { 197 greatest_equal_cb *equal; 198 greatest_printf_cb *print; 199 } greatest_type_info; 200 201 typedef struct greatest_memory_cmp_env { 202 const unsigned char *exp; 203 const unsigned char *got; 204 size_t size; 205 } greatest_memory_cmp_env; 206 207 /* Callbacks for string and raw memory types. */ 208 extern greatest_type_info greatest_type_info_string; 209 extern greatest_type_info greatest_type_info_memory; 210 211 typedef enum { 212 GREATEST_FLAG_FIRST_FAIL = 0x01, 213 GREATEST_FLAG_LIST_ONLY = 0x02, 214 GREATEST_FLAG_ABORT_ON_FAIL = 0x04 215 } greatest_flag_t; 216 217 /* Internal state for a PRNG, used to shuffle test order. */ 218 struct greatest_prng { 219 unsigned char random_order; /* use random ordering? */ 220 unsigned char initialized; /* is random ordering initialized? */ 221 unsigned char pad_0[6]; 222 unsigned long state; /* PRNG state */ 223 unsigned long count; /* how many tests, this pass */ 224 unsigned long count_ceil; /* total number of tests */ 225 unsigned long count_run; /* total tests run */ 226 unsigned long a; /* LCG multiplier */ 227 unsigned long c; /* LCG increment */ 228 unsigned long m; /* LCG modulus, based on count_ceil */ 229 }; 230 231 /* Struct containing all test runner state. */ 232 typedef struct greatest_run_info { 233 unsigned char flags; 234 unsigned char verbosity; 235 unsigned char running_test; /* guard for nested RUN_TEST calls */ 236 unsigned char exact_name_match; 237 238 unsigned int tests_run; /* total test count */ 239 240 /* currently running test suite */ 241 greatest_suite_info suite; 242 243 /* overall pass/fail/skip counts */ 244 unsigned int passed; 245 unsigned int failed; 246 unsigned int skipped; 247 unsigned int assertions; 248 249 /* info to print about the most recent failure */ 250 unsigned int fail_line; 251 unsigned int pad_1; 252 const char *fail_file; 253 const char *msg; 254 255 /* current setup/teardown hooks and userdata */ 256 greatest_setup_cb *setup; 257 void *setup_udata; 258 greatest_teardown_cb *teardown; 259 void *teardown_udata; 260 261 /* formatting info for ".....s...F"-style output */ 262 unsigned int col; 263 unsigned int width; 264 265 /* only run a specific suite or test */ 266 const char *suite_filter; 267 const char *test_filter; 268 const char *test_exclude; 269 const char *name_suffix; /* print suffix with test name */ 270 char name_buf[GREATEST_TESTNAME_BUF_SIZE]; 271 272 struct greatest_prng prng[2]; /* 0: suites, 1: tests */ 273 274 #if GREATEST_USE_TIME 275 /* overall timers */ 276 clock_t begin; 277 clock_t end; 278 #endif 279 280 #if GREATEST_USE_LONGJMP 281 int pad_jmp_buf; 282 unsigned char pad_2[4]; 283 jmp_buf jump_dest; 284 #endif 285 } greatest_run_info; 286 287 struct greatest_report_t { 288 /* overall pass/fail/skip counts */ 289 unsigned int passed; 290 unsigned int failed; 291 unsigned int skipped; 292 unsigned int assertions; 293 }; 294 295 /* Global var for the current testing context. 296 * Initialized by GREATEST_MAIN_DEFS(). */ 297 extern greatest_run_info greatest_info; 298 299 /* Type for ASSERT_ENUM_EQ's ENUM_STR argument. */ 300 typedef const char *greatest_enum_str_fun(int value); 301 302 303 /********************** 304 * Exported functions * 305 **********************/ 306 307 /* These are used internally by greatest macros. */ 308 int greatest_test_pre(const char *name); 309 void greatest_test_post(int res); 310 int greatest_do_assert_equal_t(const void *expd, const void *got, 311 greatest_type_info *type_info, void *udata); 312 void greatest_prng_init_first_pass(int id); 313 int greatest_prng_init_second_pass(int id, unsigned long seed); 314 void greatest_prng_step(int id); 315 316 /* These are part of the public greatest API. */ 317 void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata); 318 void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata); 319 void GREATEST_INIT(void); 320 void GREATEST_PRINT_REPORT(void); 321 int greatest_all_passed(void); 322 void greatest_set_suite_filter(const char *filter); 323 void greatest_set_test_filter(const char *filter); 324 void greatest_set_test_exclude(const char *filter); 325 void greatest_set_exact_name_match(void); 326 void greatest_stop_at_first_fail(void); 327 void greatest_abort_on_fail(void); 328 void greatest_list_only(void); 329 void greatest_get_report(struct greatest_report_t *report); 330 unsigned int greatest_get_verbosity(void); 331 void greatest_set_verbosity(unsigned int verbosity); 332 void greatest_set_flag(greatest_flag_t flag); 333 void greatest_set_test_suffix(const char *suffix); 334 335 336 /******************** 337 * Language Support * 338 ********************/ 339 340 /* If __VA_ARGS__ (C99) is supported, allow parametric testing 341 * without needing to manually manage the argument struct. */ 342 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 19901L) || \ 343 (defined(_MSC_VER) && _MSC_VER >= 1800) 344 #define GREATEST_VA_ARGS 345 #endif 346 347 348 /********** 349 * Macros * 350 **********/ 351 352 /* Define a suite. (The duplication is intentional -- it eliminates 353 * a warning from -Wmissing-declarations.) */ 354 #define GREATEST_SUITE(NAME) void NAME(void); void NAME(void) 355 356 /* Declare a suite, provided by another compilation unit. */ 357 #define GREATEST_SUITE_EXTERN(NAME) void NAME(void) 358 359 /* Start defining a test function. 360 * The arguments are not included, to allow parametric testing. */ 361 #define GREATEST_TEST static enum greatest_test_res 362 363 /* PASS/FAIL/SKIP result from a test. Used internally. */ 364 typedef enum greatest_test_res { 365 GREATEST_TEST_RES_PASS = 0, 366 GREATEST_TEST_RES_FAIL = -1, 367 GREATEST_TEST_RES_SKIP = 1 368 } greatest_test_res; 369 370 /* Run a suite. */ 371 #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME) 372 373 /* Run a test in the current suite. */ 374 #define GREATEST_RUN_TEST(TEST) \ 375 do { \ 376 if (greatest_test_pre(#TEST) == 1) { \ 377 enum greatest_test_res res = GREATEST_SAVE_CONTEXT(); \ 378 if (res == GREATEST_TEST_RES_PASS) { \ 379 res = TEST(); \ 380 } \ 381 greatest_test_post(res); \ 382 } \ 383 } while (0) 384 385 /* Ignore a test, don't warn about it being unused. */ 386 #define GREATEST_IGNORE_TEST(TEST) (void)TEST 387 388 /* Run a test in the current suite with one void * argument, 389 * which can be a pointer to a struct with multiple arguments. */ 390 #define GREATEST_RUN_TEST1(TEST, ENV) \ 391 do { \ 392 if (greatest_test_pre(#TEST) == 1) { \ 393 enum greatest_test_res res = GREATEST_SAVE_CONTEXT(); \ 394 if (res == GREATEST_TEST_RES_PASS) { \ 395 res = TEST(ENV); \ 396 } \ 397 greatest_test_post(res); \ 398 } \ 399 } while (0) 400 401 #ifdef GREATEST_VA_ARGS 402 #define GREATEST_RUN_TESTp(TEST, ...) \ 403 do { \ 404 if (greatest_test_pre(#TEST) == 1) { \ 405 enum greatest_test_res res = GREATEST_SAVE_CONTEXT(); \ 406 if (res == GREATEST_TEST_RES_PASS) { \ 407 res = TEST(__VA_ARGS__); \ 408 } \ 409 greatest_test_post(res); \ 410 } \ 411 } while (0) 412 #endif 413 414 415 /* Check if the test runner is in verbose mode. */ 416 #define GREATEST_IS_VERBOSE() ((greatest_info.verbosity) > 0) 417 #define GREATEST_LIST_ONLY() \ 418 (greatest_info.flags & GREATEST_FLAG_LIST_ONLY) 419 #define GREATEST_FIRST_FAIL() \ 420 (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL) 421 #define GREATEST_ABORT_ON_FAIL() \ 422 (greatest_info.flags & GREATEST_FLAG_ABORT_ON_FAIL) 423 #define GREATEST_FAILURE_ABORT() \ 424 (GREATEST_FIRST_FAIL() && \ 425 (greatest_info.suite.failed > 0 || greatest_info.failed > 0)) 426 427 /* Message-less forms of tests defined below. */ 428 #define GREATEST_PASS() GREATEST_PASSm(NULL) 429 #define GREATEST_FAIL() GREATEST_FAILm(NULL) 430 #define GREATEST_SKIP() GREATEST_SKIPm(NULL) 431 #define GREATEST_ASSERT(COND) \ 432 GREATEST_ASSERTm(#COND, COND) 433 #define GREATEST_ASSERT_OR_LONGJMP(COND) \ 434 GREATEST_ASSERT_OR_LONGJMPm(#COND, COND) 435 #define GREATEST_ASSERT_FALSE(COND) \ 436 GREATEST_ASSERT_FALSEm(#COND, COND) 437 #define GREATEST_ASSERT_EQ(EXP, GOT) \ 438 GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT) 439 #define GREATEST_ASSERT_NEQ(EXP, GOT) \ 440 GREATEST_ASSERT_NEQm(#EXP " == " #GOT, EXP, GOT) 441 #define GREATEST_ASSERT_GT(EXP, GOT) \ 442 GREATEST_ASSERT_GTm(#EXP " <= " #GOT, EXP, GOT) 443 #define GREATEST_ASSERT_GTE(EXP, GOT) \ 444 GREATEST_ASSERT_GTEm(#EXP " < " #GOT, EXP, GOT) 445 #define GREATEST_ASSERT_LT(EXP, GOT) \ 446 GREATEST_ASSERT_LTm(#EXP " >= " #GOT, EXP, GOT) 447 #define GREATEST_ASSERT_LTE(EXP, GOT) \ 448 GREATEST_ASSERT_LTEm(#EXP " > " #GOT, EXP, GOT) 449 #define GREATEST_ASSERT_EQ_FMT(EXP, GOT, FMT) \ 450 GREATEST_ASSERT_EQ_FMTm(#EXP " != " #GOT, EXP, GOT, FMT) 451 #define GREATEST_ASSERT_IN_RANGE(EXP, GOT, TOL) \ 452 GREATEST_ASSERT_IN_RANGEm(#EXP " != " #GOT " +/- " #TOL, EXP, GOT, TOL) 453 #define GREATEST_ASSERT_EQUAL_T(EXP, GOT, TYPE_INFO, UDATA) \ 454 GREATEST_ASSERT_EQUAL_Tm(#EXP " != " #GOT, EXP, GOT, TYPE_INFO, UDATA) 455 #define GREATEST_ASSERT_STR_EQ(EXP, GOT) \ 456 GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT) 457 #define GREATEST_ASSERT_STRN_EQ(EXP, GOT, SIZE) \ 458 GREATEST_ASSERT_STRN_EQm(#EXP " != " #GOT, EXP, GOT, SIZE) 459 #define GREATEST_ASSERT_MEM_EQ(EXP, GOT, SIZE) \ 460 GREATEST_ASSERT_MEM_EQm(#EXP " != " #GOT, EXP, GOT, SIZE) 461 #define GREATEST_ASSERT_ENUM_EQ(EXP, GOT, ENUM_STR) \ 462 GREATEST_ASSERT_ENUM_EQm(#EXP " != " #GOT, EXP, GOT, ENUM_STR) 463 464 /* The following forms take an additional message argument first, 465 * to be displayed by the test runner. */ 466 467 /* Fail if a condition is not true, with message. */ 468 #define GREATEST_ASSERTm(MSG, COND) \ 469 do { \ 470 greatest_info.assertions++; \ 471 if (!(COND)) { GREATEST_FAILm(MSG); } \ 472 } while (0) 473 474 /* Fail if a condition is not true, longjmping out of test. */ 475 #define GREATEST_ASSERT_OR_LONGJMPm(MSG, COND) \ 476 do { \ 477 greatest_info.assertions++; \ 478 if (!(COND)) { GREATEST_FAIL_WITH_LONGJMPm(MSG); } \ 479 } while (0) 480 481 /* Fail if a condition is not false, with message. */ 482 #define GREATEST_ASSERT_FALSEm(MSG, COND) \ 483 do { \ 484 greatest_info.assertions++; \ 485 if ((COND)) { GREATEST_FAILm(MSG); } \ 486 } while (0) 487 488 /* Internal macro for relational assertions */ 489 #define GREATEST__REL(REL, MSG, EXP, GOT) \ 490 do { \ 491 greatest_info.assertions++; \ 492 if (!((EXP) REL (GOT))) { GREATEST_FAILm(MSG); } \ 493 } while (0) 494 495 /* Fail if EXP is not ==, !=, >, <, >=, or <= to GOT. */ 496 #define GREATEST_ASSERT_EQm(MSG,E,G) GREATEST__REL(==, MSG,E,G) 497 #define GREATEST_ASSERT_NEQm(MSG,E,G) GREATEST__REL(!=, MSG,E,G) 498 #define GREATEST_ASSERT_GTm(MSG,E,G) GREATEST__REL(>, MSG,E,G) 499 #define GREATEST_ASSERT_GTEm(MSG,E,G) GREATEST__REL(>=, MSG,E,G) 500 #define GREATEST_ASSERT_LTm(MSG,E,G) GREATEST__REL(<, MSG,E,G) 501 #define GREATEST_ASSERT_LTEm(MSG,E,G) GREATEST__REL(<=, MSG,E,G) 502 503 /* Fail if EXP != GOT (equality comparison by ==). 504 * Warning: FMT, EXP, and GOT will be evaluated more 505 * than once on failure. */ 506 #define GREATEST_ASSERT_EQ_FMTm(MSG, EXP, GOT, FMT) \ 507 do { \ 508 greatest_info.assertions++; \ 509 if ((EXP) != (GOT)) { \ 510 GREATEST_FPRINTF(GREATEST_STDOUT, "\nExpected: "); \ 511 GREATEST_FPRINTF(GREATEST_STDOUT, FMT, EXP); \ 512 GREATEST_FPRINTF(GREATEST_STDOUT, "\n Got: "); \ 513 GREATEST_FPRINTF(GREATEST_STDOUT, FMT, GOT); \ 514 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 515 GREATEST_FAILm(MSG); \ 516 } \ 517 } while (0) 518 519 /* Fail if EXP is not equal to GOT, printing enum IDs. */ 520 #define GREATEST_ASSERT_ENUM_EQm(MSG, EXP, GOT, ENUM_STR) \ 521 do { \ 522 int greatest_EXP = (int)(EXP); \ 523 int greatest_GOT = (int)(GOT); \ 524 greatest_enum_str_fun *greatest_ENUM_STR = ENUM_STR; \ 525 if (greatest_EXP != greatest_GOT) { \ 526 GREATEST_FPRINTF(GREATEST_STDOUT, "\nExpected: %s", \ 527 greatest_ENUM_STR(greatest_EXP)); \ 528 GREATEST_FPRINTF(GREATEST_STDOUT, "\n Got: %s\n", \ 529 greatest_ENUM_STR(greatest_GOT)); \ 530 GREATEST_FAILm(MSG); \ 531 } \ 532 } while (0) \ 533 534 /* Fail if GOT not in range of EXP +|- TOL. */ 535 #define GREATEST_ASSERT_IN_RANGEm(MSG, EXP, GOT, TOL) \ 536 do { \ 537 GREATEST_FLOAT greatest_EXP = (EXP); \ 538 GREATEST_FLOAT greatest_GOT = (GOT); \ 539 GREATEST_FLOAT greatest_TOL = (TOL); \ 540 greatest_info.assertions++; \ 541 if ((greatest_EXP > greatest_GOT && \ 542 greatest_EXP - greatest_GOT > greatest_TOL) || \ 543 (greatest_EXP < greatest_GOT && \ 544 greatest_GOT - greatest_EXP > greatest_TOL)) { \ 545 GREATEST_FPRINTF(GREATEST_STDOUT, \ 546 "\nExpected: " GREATEST_FLOAT_FMT \ 547 " +/- " GREATEST_FLOAT_FMT \ 548 "\n Got: " GREATEST_FLOAT_FMT \ 549 "\n", \ 550 greatest_EXP, greatest_TOL, greatest_GOT); \ 551 GREATEST_FAILm(MSG); \ 552 } \ 553 } while (0) 554 555 /* Fail if EXP is not equal to GOT, according to strcmp. */ 556 #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \ 557 do { \ 558 GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT, \ 559 &greatest_type_info_string, NULL); \ 560 } while (0) \ 561 562 /* Fail if EXP is not equal to GOT, according to strncmp. */ 563 #define GREATEST_ASSERT_STRN_EQm(MSG, EXP, GOT, SIZE) \ 564 do { \ 565 size_t size = SIZE; \ 566 GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT, \ 567 &greatest_type_info_string, &size); \ 568 } while (0) \ 569 570 /* Fail if EXP is not equal to GOT, according to memcmp. */ 571 #define GREATEST_ASSERT_MEM_EQm(MSG, EXP, GOT, SIZE) \ 572 do { \ 573 greatest_memory_cmp_env env; \ 574 env.exp = (const unsigned char *)EXP; \ 575 env.got = (const unsigned char *)GOT; \ 576 env.size = SIZE; \ 577 GREATEST_ASSERT_EQUAL_Tm(MSG, env.exp, env.got, \ 578 &greatest_type_info_memory, &env); \ 579 } while (0) \ 580 581 /* Fail if EXP is not equal to GOT, according to a comparison 582 * callback in TYPE_INFO. If they are not equal, optionally use a 583 * print callback in TYPE_INFO to print them. */ 584 #define GREATEST_ASSERT_EQUAL_Tm(MSG, EXP, GOT, TYPE_INFO, UDATA) \ 585 do { \ 586 greatest_type_info *type_info = (TYPE_INFO); \ 587 greatest_info.assertions++; \ 588 if (!greatest_do_assert_equal_t(EXP, GOT, \ 589 type_info, UDATA)) { \ 590 if (type_info == NULL || type_info->equal == NULL) { \ 591 GREATEST_FAILm("type_info->equal callback missing!"); \ 592 } else { \ 593 GREATEST_FAILm(MSG); \ 594 } \ 595 } \ 596 } while (0) \ 597 598 /* Pass. */ 599 #define GREATEST_PASSm(MSG) \ 600 do { \ 601 greatest_info.msg = MSG; \ 602 return GREATEST_TEST_RES_PASS; \ 603 } while (0) 604 605 /* Fail. */ 606 #define GREATEST_FAILm(MSG) \ 607 do { \ 608 greatest_info.fail_file = __FILE__; \ 609 greatest_info.fail_line = __LINE__; \ 610 greatest_info.msg = MSG; \ 611 if (GREATEST_ABORT_ON_FAIL()) { abort(); } \ 612 return GREATEST_TEST_RES_FAIL; \ 613 } while (0) 614 615 /* Optional GREATEST_FAILm variant that longjmps. */ 616 #if GREATEST_USE_LONGJMP 617 #define GREATEST_FAIL_WITH_LONGJMP() GREATEST_FAIL_WITH_LONGJMPm(NULL) 618 #define GREATEST_FAIL_WITH_LONGJMPm(MSG) \ 619 do { \ 620 greatest_info.fail_file = __FILE__; \ 621 greatest_info.fail_line = __LINE__; \ 622 greatest_info.msg = MSG; \ 623 longjmp(greatest_info.jump_dest, GREATEST_TEST_RES_FAIL); \ 624 } while (0) 625 #endif 626 627 /* Skip the current test. */ 628 #define GREATEST_SKIPm(MSG) \ 629 do { \ 630 greatest_info.msg = MSG; \ 631 return GREATEST_TEST_RES_SKIP; \ 632 } while (0) 633 634 /* Check the result of a subfunction using ASSERT, etc. */ 635 #define GREATEST_CHECK_CALL(RES) \ 636 do { \ 637 enum greatest_test_res greatest_RES = RES; \ 638 if (greatest_RES != GREATEST_TEST_RES_PASS) { \ 639 return greatest_RES; \ 640 } \ 641 } while (0) \ 642 643 #if GREATEST_USE_TIME 644 #define GREATEST_SET_TIME(NAME) \ 645 NAME = clock(); \ 646 if (NAME == (clock_t) -1) { \ 647 GREATEST_FPRINTF(GREATEST_STDOUT, \ 648 "clock error: %s\n", #NAME); \ 649 exit(EXIT_FAILURE); \ 650 } 651 652 #define GREATEST_CLOCK_DIFF(C1, C2) \ 653 GREATEST_FPRINTF(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \ 654 (long unsigned int) (C2) - (long unsigned int)(C1), \ 655 (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC)) 656 #else 657 #define GREATEST_SET_TIME(UNUSED) 658 #define GREATEST_CLOCK_DIFF(UNUSED1, UNUSED2) 659 #endif 660 661 #if GREATEST_USE_LONGJMP 662 #define GREATEST_SAVE_CONTEXT() \ 663 /* setjmp returns 0 (GREATEST_TEST_RES_PASS) on first call * \ 664 * so the test runs, then RES_FAIL from FAIL_WITH_LONGJMP. */ \ 665 ((enum greatest_test_res)(setjmp(greatest_info.jump_dest))) 666 #else 667 #define GREATEST_SAVE_CONTEXT() \ 668 /*a no-op, since setjmp/longjmp aren't being used */ \ 669 GREATEST_TEST_RES_PASS 670 #endif 671 672 /* Run every suite / test function run within BODY in pseudo-random 673 * order, seeded by SEED. (The top 3 bits of the seed are ignored.) 674 * 675 * This should be called like: 676 * GREATEST_SHUFFLE_TESTS(seed, { 677 * GREATEST_RUN_TEST(some_test); 678 * GREATEST_RUN_TEST(some_other_test); 679 * GREATEST_RUN_TEST(yet_another_test); 680 * }); 681 * 682 * Note that the body of the second argument will be evaluated 683 * multiple times. */ 684 #define GREATEST_SHUFFLE_SUITES(SD, BODY) GREATEST_SHUFFLE(0, SD, BODY) 685 #define GREATEST_SHUFFLE_TESTS(SD, BODY) GREATEST_SHUFFLE(1, SD, BODY) 686 #define GREATEST_SHUFFLE(ID, SD, BODY) \ 687 do { \ 688 struct greatest_prng *prng = &greatest_info.prng[ID]; \ 689 greatest_prng_init_first_pass(ID); \ 690 do { \ 691 prng->count = 0; \ 692 if (prng->initialized) { greatest_prng_step(ID); } \ 693 BODY; \ 694 if (!prng->initialized) { \ 695 if (!greatest_prng_init_second_pass(ID, SD)) { break; } \ 696 } else if (prng->count_run == prng->count_ceil) { \ 697 break; \ 698 } \ 699 } while (!GREATEST_FAILURE_ABORT()); \ 700 prng->count_run = prng->random_order = prng->initialized = 0; \ 701 } while(0) 702 703 /* Include several function definitions in the main test file. */ 704 #define GREATEST_MAIN_DEFS() \ 705 \ 706 /* Is FILTER a subset of NAME? */ \ 707 static int greatest_name_match(const char *name, const char *filter, \ 708 int res_if_none) { \ 709 size_t offset = 0; \ 710 size_t filter_len = filter ? strlen(filter) : 0; \ 711 if (filter_len == 0) { return res_if_none; } /* no filter */ \ 712 if (greatest_info.exact_name_match && strlen(name) != filter_len) { \ 713 return 0; /* ignore substring matches */ \ 714 } \ 715 while (name[offset] != '\0') { \ 716 if (name[offset] == filter[0]) { \ 717 if (0 == strncmp(&name[offset], filter, filter_len)) { \ 718 return 1; \ 719 } \ 720 } \ 721 offset++; \ 722 } \ 723 \ 724 return 0; \ 725 } \ 726 \ 727 static void greatest_buffer_test_name(const char *name) { \ 728 struct greatest_run_info *g = &greatest_info; \ 729 size_t len = strlen(name), size = sizeof(g->name_buf); \ 730 memset(g->name_buf, 0x00, size); \ 731 (void)strncat(g->name_buf, name, size - 1); \ 732 if (g->name_suffix && (len + 1 < size)) { \ 733 g->name_buf[len] = '_'; \ 734 strncat(&g->name_buf[len+1], g->name_suffix, size-(len+2)); \ 735 } \ 736 } \ 737 \ 738 /* Before running a test, check the name filtering and \ 739 * test shuffling state, if applicable, and then call setup hooks. */ \ 740 int greatest_test_pre(const char *name) { \ 741 struct greatest_run_info *g = &greatest_info; \ 742 int match; \ 743 greatest_buffer_test_name(name); \ 744 match = greatest_name_match(g->name_buf, g->test_filter, 1) && \ 745 !greatest_name_match(g->name_buf, g->test_exclude, 0); \ 746 if (GREATEST_LIST_ONLY()) { /* just listing test names */ \ 747 if (match) { \ 748 GREATEST_FPRINTF(GREATEST_STDOUT, " %s\n", g->name_buf); \ 749 } \ 750 goto clear; \ 751 } \ 752 if (match && (!GREATEST_FIRST_FAIL() || g->suite.failed == 0)) { \ 753 struct greatest_prng *p = &g->prng[1]; \ 754 if (p->random_order) { \ 755 p->count++; \ 756 if (!p->initialized || ((p->count - 1) != p->state)) { \ 757 goto clear; /* don't run this test yet */ \ 758 } \ 759 } \ 760 if (g->running_test) { \ 761 fprintf(stderr, "Error: Test run inside another test.\n"); \ 762 return 0; \ 763 } \ 764 GREATEST_SET_TIME(g->suite.pre_test); \ 765 if (g->setup) { g->setup(g->setup_udata); } \ 766 p->count_run++; \ 767 g->running_test = 1; \ 768 return 1; /* test should be run */ \ 769 } else { \ 770 goto clear; /* skipped */ \ 771 } \ 772 clear: \ 773 g->name_suffix = NULL; \ 774 return 0; \ 775 } \ 776 \ 777 static void greatest_do_pass(void) { \ 778 struct greatest_run_info *g = &greatest_info; \ 779 if (GREATEST_IS_VERBOSE()) { \ 780 GREATEST_FPRINTF(GREATEST_STDOUT, "PASS %s: %s", \ 781 g->name_buf, g->msg ? g->msg : ""); \ 782 } else { \ 783 GREATEST_FPRINTF(GREATEST_STDOUT, "."); \ 784 } \ 785 g->suite.passed++; \ 786 } \ 787 \ 788 static void greatest_do_fail(void) { \ 789 struct greatest_run_info *g = &greatest_info; \ 790 if (GREATEST_IS_VERBOSE()) { \ 791 GREATEST_FPRINTF(GREATEST_STDOUT, \ 792 "FAIL %s: %s (%s:%u)", g->name_buf, \ 793 g->msg ? g->msg : "", g->fail_file, g->fail_line); \ 794 } else { \ 795 GREATEST_FPRINTF(GREATEST_STDOUT, "F"); \ 796 g->col++; /* add linebreak if in line of '.'s */ \ 797 if (g->col != 0) { \ 798 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 799 g->col = 0; \ 800 } \ 801 GREATEST_FPRINTF(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n", \ 802 g->name_buf, g->msg ? g->msg : "", \ 803 g->fail_file, g->fail_line); \ 804 } \ 805 g->suite.failed++; \ 806 } \ 807 \ 808 static void greatest_do_skip(void) { \ 809 struct greatest_run_info *g = &greatest_info; \ 810 if (GREATEST_IS_VERBOSE()) { \ 811 GREATEST_FPRINTF(GREATEST_STDOUT, "SKIP %s: %s", \ 812 g->name_buf, g->msg ? g->msg : ""); \ 813 } else { \ 814 GREATEST_FPRINTF(GREATEST_STDOUT, "s"); \ 815 } \ 816 g->suite.skipped++; \ 817 } \ 818 \ 819 void greatest_test_post(int res) { \ 820 GREATEST_SET_TIME(greatest_info.suite.post_test); \ 821 if (greatest_info.teardown) { \ 822 void *udata = greatest_info.teardown_udata; \ 823 greatest_info.teardown(udata); \ 824 } \ 825 \ 826 greatest_info.running_test = 0; \ 827 if (res <= GREATEST_TEST_RES_FAIL) { \ 828 greatest_do_fail(); \ 829 } else if (res >= GREATEST_TEST_RES_SKIP) { \ 830 greatest_do_skip(); \ 831 } else if (res == GREATEST_TEST_RES_PASS) { \ 832 greatest_do_pass(); \ 833 } \ 834 greatest_info.name_suffix = NULL; \ 835 greatest_info.suite.tests_run++; \ 836 greatest_info.col++; \ 837 if (GREATEST_IS_VERBOSE()) { \ 838 GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \ 839 greatest_info.suite.post_test); \ 840 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 841 } else if (greatest_info.col % greatest_info.width == 0) { \ 842 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 843 greatest_info.col = 0; \ 844 } \ 845 fflush(GREATEST_STDOUT); \ 846 } \ 847 \ 848 static void report_suite(void) { \ 849 if (greatest_info.suite.tests_run > 0) { \ 850 GREATEST_FPRINTF(GREATEST_STDOUT, \ 851 "\n%u test%s - %u passed, %u failed, %u skipped", \ 852 greatest_info.suite.tests_run, \ 853 greatest_info.suite.tests_run == 1 ? "" : "s", \ 854 greatest_info.suite.passed, \ 855 greatest_info.suite.failed, \ 856 greatest_info.suite.skipped); \ 857 GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \ 858 greatest_info.suite.post_suite); \ 859 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 860 } \ 861 } \ 862 \ 863 static void update_counts_and_reset_suite(void) { \ 864 greatest_info.setup = NULL; \ 865 greatest_info.setup_udata = NULL; \ 866 greatest_info.teardown = NULL; \ 867 greatest_info.teardown_udata = NULL; \ 868 greatest_info.passed += greatest_info.suite.passed; \ 869 greatest_info.failed += greatest_info.suite.failed; \ 870 greatest_info.skipped += greatest_info.suite.skipped; \ 871 greatest_info.tests_run += greatest_info.suite.tests_run; \ 872 memset(&greatest_info.suite, 0, sizeof(greatest_info.suite)); \ 873 greatest_info.col = 0; \ 874 } \ 875 \ 876 static int greatest_suite_pre(const char *suite_name) { \ 877 struct greatest_prng *p = &greatest_info.prng[0]; \ 878 if (!greatest_name_match(suite_name, greatest_info.suite_filter, 1) \ 879 || (GREATEST_FAILURE_ABORT())) { return 0; } \ 880 if (p->random_order) { \ 881 p->count++; \ 882 if (!p->initialized || ((p->count - 1) != p->state)) { \ 883 return 0; /* don't run this suite yet */ \ 884 } \ 885 } \ 886 p->count_run++; \ 887 update_counts_and_reset_suite(); \ 888 GREATEST_FPRINTF(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name); \ 889 GREATEST_SET_TIME(greatest_info.suite.pre_suite); \ 890 return 1; \ 891 } \ 892 \ 893 static void greatest_suite_post(void) { \ 894 GREATEST_SET_TIME(greatest_info.suite.post_suite); \ 895 report_suite(); \ 896 } \ 897 \ 898 static void greatest_run_suite(greatest_suite_cb *suite_cb, \ 899 const char *suite_name) { \ 900 if (greatest_suite_pre(suite_name)) { \ 901 suite_cb(); \ 902 greatest_suite_post(); \ 903 } \ 904 } \ 905 \ 906 int greatest_do_assert_equal_t(const void *expd, const void *got, \ 907 greatest_type_info *type_info, void *udata) { \ 908 int eq = 0; \ 909 if (type_info == NULL || type_info->equal == NULL) { return 0; } \ 910 eq = type_info->equal(expd, got, udata); \ 911 if (!eq) { \ 912 if (type_info->print != NULL) { \ 913 GREATEST_FPRINTF(GREATEST_STDOUT, "\nExpected: "); \ 914 (void)type_info->print(expd, udata); \ 915 GREATEST_FPRINTF(GREATEST_STDOUT, "\n Got: "); \ 916 (void)type_info->print(got, udata); \ 917 GREATEST_FPRINTF(GREATEST_STDOUT, "\n"); \ 918 } \ 919 } \ 920 return eq; \ 921 } \ 922 \ 923 static void greatest_usage(const char *name) { \ 924 GREATEST_FPRINTF(GREATEST_STDOUT, \ 925 "Usage: %s [-hlfavex] [-s SUITE] [-t TEST] [-x EXCLUDE]\n" \ 926 " -h, --help print this Help\n" \ 927 " -l List suites and tests, then exit (dry run)\n" \ 928 " -f Stop runner after first failure\n" \ 929 " -a Abort on first failure (implies -f)\n" \ 930 " -v Verbose output\n" \ 931 " -s SUITE only run suites containing substring SUITE\n" \ 932 " -t TEST only run tests containing substring TEST\n" \ 933 " -e only run exact name match for -s or -t\n" \ 934 " -x EXCLUDE exclude tests containing substring EXCLUDE\n", \ 935 name); \ 936 } \ 937 \ 938 static void greatest_parse_options(int argc, char **argv) { \ 939 int i = 0; \ 940 for (i = 1; i < argc; i++) { \ 941 if (argv[i][0] == '-') { \ 942 char f = argv[i][1]; \ 943 if ((f == 's' || f == 't' || f == 'x') && argc <= i + 1) { \ 944 greatest_usage(argv[0]); exit(EXIT_FAILURE); \ 945 } \ 946 switch (f) { \ 947 case 's': /* suite name filter */ \ 948 greatest_set_suite_filter(argv[i + 1]); i++; break; \ 949 case 't': /* test name filter */ \ 950 greatest_set_test_filter(argv[i + 1]); i++; break; \ 951 case 'x': /* test name exclusion */ \ 952 greatest_set_test_exclude(argv[i + 1]); i++; break; \ 953 case 'e': /* exact name match */ \ 954 greatest_set_exact_name_match(); break; \ 955 case 'f': /* first fail flag */ \ 956 greatest_stop_at_first_fail(); break; \ 957 case 'a': /* abort() on fail flag */ \ 958 greatest_abort_on_fail(); break; \ 959 case 'l': /* list only (dry run) */ \ 960 greatest_list_only(); break; \ 961 case 'v': /* first fail flag */ \ 962 greatest_info.verbosity++; break; \ 963 case 'h': /* help */ \ 964 greatest_usage(argv[0]); exit(EXIT_SUCCESS); \ 965 default: \ 966 case '-': \ 967 if (0 == strncmp("--help", argv[i], 6)) { \ 968 greatest_usage(argv[0]); exit(EXIT_SUCCESS); \ 969 } else if (0 == strcmp("--", argv[i])) { \ 970 return; /* ignore following arguments */ \ 971 } \ 972 GREATEST_FPRINTF(GREATEST_STDOUT, \ 973 "Unknown argument '%s'\n", argv[i]); \ 974 greatest_usage(argv[0]); \ 975 exit(EXIT_FAILURE); \ 976 } \ 977 } \ 978 } \ 979 } \ 980 \ 981 int greatest_all_passed(void) { return (greatest_info.failed == 0); } \ 982 \ 983 void greatest_set_test_filter(const char *filter) { \ 984 greatest_info.test_filter = filter; \ 985 } \ 986 \ 987 void greatest_set_test_exclude(const char *filter) { \ 988 greatest_info.test_exclude = filter; \ 989 } \ 990 \ 991 void greatest_set_suite_filter(const char *filter) { \ 992 greatest_info.suite_filter = filter; \ 993 } \ 994 \ 995 void greatest_set_exact_name_match(void) { \ 996 greatest_info.exact_name_match = 1; \ 997 } \ 998 \ 999 void greatest_stop_at_first_fail(void) { \ 1000 greatest_set_flag(GREATEST_FLAG_FIRST_FAIL); \ 1001 } \ 1002 \ 1003 void greatest_abort_on_fail(void) { \ 1004 greatest_set_flag(GREATEST_FLAG_ABORT_ON_FAIL); \ 1005 } \ 1006 \ 1007 void greatest_list_only(void) { \ 1008 greatest_set_flag(GREATEST_FLAG_LIST_ONLY); \ 1009 } \ 1010 \ 1011 void greatest_get_report(struct greatest_report_t *report) { \ 1012 if (report) { \ 1013 report->passed = greatest_info.passed; \ 1014 report->failed = greatest_info.failed; \ 1015 report->skipped = greatest_info.skipped; \ 1016 report->assertions = greatest_info.assertions; \ 1017 } \ 1018 } \ 1019 \ 1020 unsigned int greatest_get_verbosity(void) { \ 1021 return greatest_info.verbosity; \ 1022 } \ 1023 \ 1024 void greatest_set_verbosity(unsigned int verbosity) { \ 1025 greatest_info.verbosity = (unsigned char)verbosity; \ 1026 } \ 1027 \ 1028 void greatest_set_flag(greatest_flag_t flag) { \ 1029 greatest_info.flags = (unsigned char)(greatest_info.flags | flag); \ 1030 } \ 1031 \ 1032 void greatest_set_test_suffix(const char *suffix) { \ 1033 greatest_info.name_suffix = suffix; \ 1034 } \ 1035 \ 1036 void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) { \ 1037 greatest_info.setup = cb; \ 1038 greatest_info.setup_udata = udata; \ 1039 } \ 1040 \ 1041 void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata) { \ 1042 greatest_info.teardown = cb; \ 1043 greatest_info.teardown_udata = udata; \ 1044 } \ 1045 \ 1046 static int greatest_string_equal_cb(const void *expd, const void *got, \ 1047 void *udata) { \ 1048 size_t *size = (size_t *)udata; \ 1049 return (size != NULL \ 1050 ? (0 == strncmp((const char *)expd, (const char *)got, *size)) \ 1051 : (0 == strcmp((const char *)expd, (const char *)got))); \ 1052 } \ 1053 \ 1054 static int greatest_string_printf_cb(const void *t, void *udata) { \ 1055 (void)udata; /* note: does not check \0 termination. */ \ 1056 return GREATEST_FPRINTF(GREATEST_STDOUT, "%s", (const char *)t); \ 1057 } \ 1058 \ 1059 greatest_type_info greatest_type_info_string = { \ 1060 greatest_string_equal_cb, greatest_string_printf_cb, \ 1061 }; \ 1062 \ 1063 static int greatest_memory_equal_cb(const void *expd, const void *got, \ 1064 void *udata) { \ 1065 greatest_memory_cmp_env *env = (greatest_memory_cmp_env *)udata; \ 1066 return (0 == memcmp(expd, got, env->size)); \ 1067 } \ 1068 \ 1069 /* Hexdump raw memory, with differences highlighted */ \ 1070 static int greatest_memory_printf_cb(const void *t, void *udata) { \ 1071 greatest_memory_cmp_env *env = (greatest_memory_cmp_env *)udata; \ 1072 const unsigned char *buf = (const unsigned char *)t; \ 1073 unsigned char diff_mark = ' '; \ 1074 FILE *out = GREATEST_STDOUT; \ 1075 size_t i, line_i, line_len = 0; \ 1076 int len = 0; /* format hexdump with differences highlighted */ \ 1077 for (i = 0; i < env->size; i+= line_len) { \ 1078 diff_mark = ' '; \ 1079 line_len = env->size - i; \ 1080 if (line_len > 16) { line_len = 16; } \ 1081 for (line_i = i; line_i < i + line_len; line_i++) { \ 1082 if (env->exp[line_i] != env->got[line_i]) diff_mark = 'X'; \ 1083 } \ 1084 len += GREATEST_FPRINTF(out, "\n%04x %c ", \ 1085 (unsigned int)i, diff_mark); \ 1086 for (line_i = i; line_i < i + line_len; line_i++) { \ 1087 int m = env->exp[line_i] == env->got[line_i]; /* match? */ \ 1088 len += GREATEST_FPRINTF(out, "%02x%c", \ 1089 buf[line_i], m ? ' ' : '<'); \ 1090 } \ 1091 for (line_i = 0; line_i < 16 - line_len; line_i++) { \ 1092 len += GREATEST_FPRINTF(out, " "); \ 1093 } \ 1094 GREATEST_FPRINTF(out, " "); \ 1095 for (line_i = i; line_i < i + line_len; line_i++) { \ 1096 unsigned char c = buf[line_i]; \ 1097 len += GREATEST_FPRINTF(out, "%c", isprint(c) ? c : '.'); \ 1098 } \ 1099 } \ 1100 len += GREATEST_FPRINTF(out, "\n"); \ 1101 return len; \ 1102 } \ 1103 \ 1104 void greatest_prng_init_first_pass(int id) { \ 1105 greatest_info.prng[id].random_order = 1; \ 1106 greatest_info.prng[id].count_run = 0; \ 1107 } \ 1108 \ 1109 int greatest_prng_init_second_pass(int id, unsigned long seed) { \ 1110 struct greatest_prng *p = &greatest_info.prng[id]; \ 1111 if (p->count == 0) { return 0; } \ 1112 p->count_ceil = p->count; \ 1113 for (p->m = 1; p->m < p->count; p->m <<= 1) {} \ 1114 p->state = seed & 0x1fffffff; /* only use lower 29 bits */ \ 1115 p->a = 4LU * p->state; /* to avoid overflow when */ \ 1116 p->a = (p->a ? p->a : 4) | 1; /* multiplied by 4 */ \ 1117 p->c = 2147483647; /* and so p->c ((2 ** 31) - 1) is */ \ 1118 p->initialized = 1; /* always relatively prime to p->a. */ \ 1119 fprintf(stderr, "init_second_pass: a %lu, c %lu, state %lu\n", \ 1120 p->a, p->c, p->state); \ 1121 return 1; \ 1122 } \ 1123 \ 1124 /* Step the pseudorandom number generator until its state reaches \ 1125 * another test ID between 0 and the test count. \ 1126 * This use a linear congruential pseudorandom number generator, \ 1127 * with the power-of-two ceiling of the test count as the modulus, the \ 1128 * masked seed as the multiplier, and a prime as the increment. For \ 1129 * each generated value < the test count, run the corresponding test. \ 1130 * This will visit all IDs 0 <= X < mod once before repeating, \ 1131 * with a starting position chosen based on the initial seed. \ 1132 * For details, see: Knuth, The Art of Computer Programming \ 1133 * Volume. 2, section 3.2.1. */ \ 1134 void greatest_prng_step(int id) { \ 1135 struct greatest_prng *p = &greatest_info.prng[id]; \ 1136 do { \ 1137 p->state = ((p->a * p->state) + p->c) & (p->m - 1); \ 1138 } while (p->state >= p->count_ceil); \ 1139 } \ 1140 \ 1141 void GREATEST_INIT(void) { \ 1142 /* Suppress unused function warning if features aren't used */ \ 1143 (void)greatest_run_suite; \ 1144 (void)greatest_parse_options; \ 1145 (void)greatest_prng_step; \ 1146 (void)greatest_prng_init_first_pass; \ 1147 (void)greatest_prng_init_second_pass; \ 1148 (void)greatest_set_test_suffix; \ 1149 \ 1150 memset(&greatest_info, 0, sizeof(greatest_info)); \ 1151 greatest_info.width = GREATEST_DEFAULT_WIDTH; \ 1152 GREATEST_SET_TIME(greatest_info.begin); \ 1153 } \ 1154 \ 1155 /* Report passes, failures, skipped tests, the number of \ 1156 * assertions, and the overall run time. */ \ 1157 void GREATEST_PRINT_REPORT(void) { \ 1158 if (!GREATEST_LIST_ONLY()) { \ 1159 update_counts_and_reset_suite(); \ 1160 GREATEST_SET_TIME(greatest_info.end); \ 1161 GREATEST_FPRINTF(GREATEST_STDOUT, \ 1162 "\nTotal: %u test%s", \ 1163 greatest_info.tests_run, \ 1164 greatest_info.tests_run == 1 ? "" : "s"); \ 1165 GREATEST_CLOCK_DIFF(greatest_info.begin, \ 1166 greatest_info.end); \ 1167 GREATEST_FPRINTF(GREATEST_STDOUT, ", %u assertion%s\n", \ 1168 greatest_info.assertions, \ 1169 greatest_info.assertions == 1 ? "" : "s"); \ 1170 GREATEST_FPRINTF(GREATEST_STDOUT, \ 1171 "Pass: %u, fail: %u, skip: %u.\n", \ 1172 greatest_info.passed, \ 1173 greatest_info.failed, greatest_info.skipped); \ 1174 } \ 1175 } \ 1176 \ 1177 greatest_type_info greatest_type_info_memory = { \ 1178 greatest_memory_equal_cb, greatest_memory_printf_cb, \ 1179 }; \ 1180 \ 1181 greatest_run_info greatest_info 1182 1183 /* Handle command-line arguments, etc. */ 1184 #define GREATEST_MAIN_BEGIN() \ 1185 do { \ 1186 GREATEST_INIT(); \ 1187 greatest_parse_options(argc, argv); \ 1188 } while (0) 1189 1190 /* Report results, exit with exit status based on results. */ 1191 #define GREATEST_MAIN_END() \ 1192 do { \ 1193 GREATEST_PRINT_REPORT(); \ 1194 return (greatest_all_passed() ? EXIT_SUCCESS : EXIT_FAILURE); \ 1195 } while (0) 1196 1197 /* Make abbreviations without the GREATEST_ prefix for the 1198 * most commonly used symbols. */ 1199 #if GREATEST_USE_ABBREVS 1200 #define TEST GREATEST_TEST 1201 #define SUITE GREATEST_SUITE 1202 #define SUITE_EXTERN GREATEST_SUITE_EXTERN 1203 #define RUN_TEST GREATEST_RUN_TEST 1204 #define RUN_TEST1 GREATEST_RUN_TEST1 1205 #define RUN_SUITE GREATEST_RUN_SUITE 1206 #define IGNORE_TEST GREATEST_IGNORE_TEST 1207 #define ASSERT GREATEST_ASSERT 1208 #define ASSERTm GREATEST_ASSERTm 1209 #define ASSERT_FALSE GREATEST_ASSERT_FALSE 1210 #define ASSERT_EQ GREATEST_ASSERT_EQ 1211 #define ASSERT_NEQ GREATEST_ASSERT_NEQ 1212 #define ASSERT_GT GREATEST_ASSERT_GT 1213 #define ASSERT_GTE GREATEST_ASSERT_GTE 1214 #define ASSERT_LT GREATEST_ASSERT_LT 1215 #define ASSERT_LTE GREATEST_ASSERT_LTE 1216 #define ASSERT_EQ_FMT GREATEST_ASSERT_EQ_FMT 1217 #define ASSERT_IN_RANGE GREATEST_ASSERT_IN_RANGE 1218 #define ASSERT_EQUAL_T GREATEST_ASSERT_EQUAL_T 1219 #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ 1220 #define ASSERT_STRN_EQ GREATEST_ASSERT_STRN_EQ 1221 #define ASSERT_MEM_EQ GREATEST_ASSERT_MEM_EQ 1222 #define ASSERT_ENUM_EQ GREATEST_ASSERT_ENUM_EQ 1223 #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm 1224 #define ASSERT_EQm GREATEST_ASSERT_EQm 1225 #define ASSERT_NEQm GREATEST_ASSERT_NEQm 1226 #define ASSERT_GTm GREATEST_ASSERT_GTm 1227 #define ASSERT_GTEm GREATEST_ASSERT_GTEm 1228 #define ASSERT_LTm GREATEST_ASSERT_LTm 1229 #define ASSERT_LTEm GREATEST_ASSERT_LTEm 1230 #define ASSERT_EQ_FMTm GREATEST_ASSERT_EQ_FMTm 1231 #define ASSERT_IN_RANGEm GREATEST_ASSERT_IN_RANGEm 1232 #define ASSERT_EQUAL_Tm GREATEST_ASSERT_EQUAL_Tm 1233 #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm 1234 #define ASSERT_STRN_EQm GREATEST_ASSERT_STRN_EQm 1235 #define ASSERT_MEM_EQm GREATEST_ASSERT_MEM_EQm 1236 #define ASSERT_ENUM_EQm GREATEST_ASSERT_ENUM_EQm 1237 #define PASS GREATEST_PASS 1238 #define FAIL GREATEST_FAIL 1239 #define SKIP GREATEST_SKIP 1240 #define PASSm GREATEST_PASSm 1241 #define FAILm GREATEST_FAILm 1242 #define SKIPm GREATEST_SKIPm 1243 #define SET_SETUP GREATEST_SET_SETUP_CB 1244 #define SET_TEARDOWN GREATEST_SET_TEARDOWN_CB 1245 #define CHECK_CALL GREATEST_CHECK_CALL 1246 #define SHUFFLE_TESTS GREATEST_SHUFFLE_TESTS 1247 #define SHUFFLE_SUITES GREATEST_SHUFFLE_SUITES 1248 1249 #ifdef GREATEST_VA_ARGS 1250 #define RUN_TESTp GREATEST_RUN_TESTp 1251 #endif 1252 1253 #if GREATEST_USE_LONGJMP 1254 #define ASSERT_OR_LONGJMP GREATEST_ASSERT_OR_LONGJMP 1255 #define ASSERT_OR_LONGJMPm GREATEST_ASSERT_OR_LONGJMPm 1256 #define FAIL_WITH_LONGJMP GREATEST_FAIL_WITH_LONGJMP 1257 #define FAIL_WITH_LONGJMPm GREATEST_FAIL_WITH_LONGJMPm 1258 #endif 1259 1260 #endif /* USE_ABBREVS */ 1261 1262 #if defined(__cplusplus) && !defined(GREATEST_NO_EXTERN_CPLUSPLUS) 1263 } 1264 #endif 1265 1266 #endif